Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Commit

Permalink
Log and return early if release is not upgradable
Browse files Browse the repository at this point in the history
Before this change the operator would follow the installation path if
a Helm release was not in a 'DEPLOYED' state, which would fail later on
as a release with the name already existed.

We now detect what the state of the release is and return (and log)
a descriptive error message in case we can not upgrade the release.
  • Loading branch information
hiddeco committed May 2, 2019
1 parent 04323d1 commit 886048d
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 11 deletions.
12 changes: 7 additions & 5 deletions integrations/helm/chartsync/chartsync.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,11 +293,13 @@ func (chs *ChartChangeSync) ReconcileReleaseDef(fhr fluxv1beta1.HelmRelease) {
func (chs *ChartChangeSync) reconcileReleaseDef(fhr fluxv1beta1.HelmRelease) {
releaseName := release.GetReleaseName(fhr)

// There's no exact way in the Helm API to test whether a release
// exists or not. Instead, try to fetch it, and treat an error as
// not existing (and possibly fail further below, if it meant
// something else).
rel, _ := chs.release.GetDeployedRelease(releaseName)
// Attempt to retrieve an upgradable release, in case no release
// or error is returned, install it.
rel, err := chs.release.GetUpgradableRelease(releaseName)
if err != nil {
chs.logger.Log("warning", "unable to proceed with release", "resource", fhr.ResourceID().String(), "release", releaseName, "err", err)
return
}

opts := release.InstallOptions{DryRun: false}

Expand Down
30 changes: 24 additions & 6 deletions integrations/helm/release/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os"
"os/exec"
"path/filepath"
"strings"
"time"

"github.com/ghodss/yaml"
Expand Down Expand Up @@ -45,7 +46,7 @@ type Release struct {
}

type Releaser interface {
GetDeployedRelease(name string) (*hapi_release.Release, error)
GetUpgradableRelease(name string) (*hapi_release.Release, error)
Install(dir string, releaseName string, fhr flux_v1beta1.HelmRelease, action Action, opts InstallOptions) (*hapi_release.Release, error)
}

Expand Down Expand Up @@ -82,16 +83,33 @@ func GetReleaseName(fhr flux_v1beta1.HelmRelease) string {
return releaseName
}

// GetDeployedRelease returns a release with Deployed status
func (r *Release) GetDeployedRelease(name string) (*hapi_release.Release, error) {
// GetUpgradableRelease returns a release if the current state of it
// allows an upgrade, a descriptive error if it is not allowed, or
// nil if the release does not exist.
func (r *Release) GetUpgradableRelease(name string) (*hapi_release.Release, error) {
rls, err := r.HelmClient.ReleaseContent(name)
if err != nil {
if strings.Contains(err.Error(), "not found") {
return nil, nil
}
return nil, err
}
if rls.Release.Info.Status.GetCode() == hapi_release.Status_DEPLOYED {
return rls.GetRelease(), nil

release := rls.GetRelease()
status := release.GetInfo().GetStatus()

switch status.GetCode() {
case hapi_release.Status_DEPLOYED:
return release, nil
case hapi_release.Status_FAILED:
return nil, fmt.Errorf("release requires a rollback before it can be upgraded (%s)", status.GetCode().String())
case hapi_release.Status_PENDING_INSTALL,
hapi_release.Status_PENDING_UPGRADE,
hapi_release.Status_PENDING_ROLLBACK:
return nil, fmt.Errorf("operation pending for release (%s)", status.GetCode().String())
default:
return nil, fmt.Errorf("current state prevents it from being upgraded (%s)", status.GetCode().String())
}
return nil, nil
}

func (r *Release) canDelete(name string) (bool, error) {
Expand Down

0 comments on commit 886048d

Please sign in to comment.