fix: prevent confusing error messages when `installed: false` (#508)

This removes `release: "your_release_name" not found` errors seen for releases with `installed: false` when running `helmfile sync` and `helmfile apply`.

The problem was that helmfile had been running `helm status` to detect releases to be deleted. helmfile now use `helm list ^YOUR_RELEASE_NAME$` to detect if the release is currently installed or not, which emits no error-like logs on against uninstalled releases.

Fixes #507

Fixes #507
This commit is contained in:
KUOKA Yusuke 2019-03-28 18:14:29 +09:00 committed by GitHub
parent 0639714136
commit d3c5417177
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 14 deletions

View File

@ -110,6 +110,13 @@ func (helm *execer) ReleaseStatus(name string) error {
return err return err
} }
func (helm *execer) List(filter string) (string, error) {
helm.logger.Infof("Listing releases matching %v", filter)
out, err := helm.exec(append([]string{"list", filter})...)
helm.write(out)
return string(out), err
}
func (helm *execer) DecryptSecret(name string) (string, error) { func (helm *execer) DecryptSecret(name string) (string, error) {
// Prevents https://github.com/roboll/helmfile/issues/258 // Prevents https://github.com/roboll/helmfile/issues/258
helm.decryptionMutex.Lock() helm.decryptionMutex.Lock()

View File

@ -17,6 +17,6 @@ type Interface interface {
ReleaseStatus(name string) error ReleaseStatus(name string) error
DeleteRelease(name string, flags ...string) error DeleteRelease(name string, flags ...string) error
TestRelease(name string, flags ...string) error TestRelease(name string, flags ...string) error
List(filter string) (string, error)
DecryptSecret(name string) (string, error) DecryptSecret(name string) (string, error)
} }

View File

@ -252,24 +252,25 @@ func (st *HelmState) prepareSyncReleases(helm helmexec.Interface, additionalValu
return res, errs return res, errs
} }
func isReleaseInstalled(helm helmexec.Interface, release ReleaseSpec) (bool, error) {
out, err := helm.List("^" + release.Name + "$")
if err != nil {
return false, err
} else if out != "" {
return true, nil
}
return false, nil
}
func (st *HelmState) DetectReleasesToBeDeleted(helm helmexec.Interface) ([]*ReleaseSpec, error) { func (st *HelmState) DetectReleasesToBeDeleted(helm helmexec.Interface) ([]*ReleaseSpec, error) {
detected := []*ReleaseSpec{} detected := []*ReleaseSpec{}
for i, _ := range st.Releases { for i, _ := range st.Releases {
release := st.Releases[i] release := st.Releases[i]
if release.Installed != nil && !*release.Installed { if release.Installed != nil && !*release.Installed {
err := helm.ReleaseStatus(release.Name) installed, err := isReleaseInstalled(helm, release)
if err != nil { if err != nil {
switch e := err.(type) { return nil, err
case *exec.ExitError: } else if installed {
// Propagate any non-zero exit status from the external command like `helm` that is failed under the hood
status := e.Sys().(syscall.WaitStatus)
if status.ExitStatus() != 1 {
return nil, e
}
default:
return nil, e
}
} else {
detected = append(detected, &release) detected = append(detected, &release)
} }
} }
@ -304,7 +305,10 @@ func (st *HelmState) SyncReleases(helm helmexec.Interface, additionalValues []st
chart := normalizeChart(st.basePath, release.Chart) chart := normalizeChart(st.basePath, release.Chart)
var relErr *ReleaseError var relErr *ReleaseError
if release.Installed != nil && !*release.Installed { if release.Installed != nil && !*release.Installed {
if err := helm.ReleaseStatus(release.Name); err == nil { installed, err := isReleaseInstalled(helm, *release)
if err != nil {
relErr = &ReleaseError{release, err}
} else if installed {
if err := helm.DeleteRelease(release.Name, "--purge"); err != nil { if err := helm.DeleteRelease(release.Name, "--purge"); err != nil {
relErr = &ReleaseError{release, err} relErr = &ReleaseError{release, err}
} }

View File

@ -614,6 +614,9 @@ func (helm *mockHelmExec) ReleaseStatus(release string) error {
func (helm *mockHelmExec) DeleteRelease(name string, flags ...string) error { func (helm *mockHelmExec) DeleteRelease(name string, flags ...string) error {
return nil return nil
} }
func (helm *mockHelmExec) List(filter string) (string, error) {
return "", nil
}
func (helm *mockHelmExec) DecryptSecret(name string) (string, error) { func (helm *mockHelmExec) DecryptSecret(name string) (string, error) {
return "", nil return "", nil
} }