Merge pull request #395 from felipecrs/helm-show-version
Use helm show chart to identify chart version
This commit is contained in:
commit
e92c71f9d8
|
|
@ -3,6 +3,7 @@ package app
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
@ -18,6 +19,7 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/variantdev/vals"
|
"github.com/variantdev/vals"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
"helm.sh/helm/v3/pkg/chart"
|
||||||
|
|
||||||
"github.com/helmfile/helmfile/pkg/envvar"
|
"github.com/helmfile/helmfile/pkg/envvar"
|
||||||
"github.com/helmfile/helmfile/pkg/exectest"
|
"github.com/helmfile/helmfile/pkg/exectest"
|
||||||
|
|
@ -2596,6 +2598,10 @@ func (helm *mockHelmExec) IsVersionAtLeast(versionStr string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (helm *mockHelmExec) ShowChart(chartPath string) (chart.Metadata, error) {
|
||||||
|
return chart.Metadata{}, errors.New("tests logs rely on this error")
|
||||||
|
}
|
||||||
|
|
||||||
func TestTemplate_SingleStateFile(t *testing.T) {
|
func TestTemplate_SingleStateFile(t *testing.T) {
|
||||||
files := map[string]string{
|
files := map[string]string{
|
||||||
"/path/to/helmfile.yaml": `
|
"/path/to/helmfile.yaml": `
|
||||||
|
|
@ -3052,7 +3058,7 @@ GROUP RELEASES
|
||||||
|
|
||||||
processing releases in group 1/2: default//baz, default//bar
|
processing releases in group 1/2: default//baz, default//bar
|
||||||
processing releases in group 2/2: default//foo
|
processing releases in group 2/2: default//foo
|
||||||
getting deployed release version failed:Failed to get the version for:mychart1
|
getting deployed release version failed: Failed to get the version for: mychart1
|
||||||
|
|
||||||
UPDATED RELEASES:
|
UPDATED RELEASES:
|
||||||
NAME CHART VERSION
|
NAME CHART VERSION
|
||||||
|
|
@ -3162,7 +3168,7 @@ GROUP RELEASES
|
||||||
|
|
||||||
processing releases in group 1/2: default//baz, default//bar
|
processing releases in group 1/2: default//baz, default//bar
|
||||||
processing releases in group 2/2: default//foo
|
processing releases in group 2/2: default//foo
|
||||||
getting deployed release version failed:Failed to get the version for:mychart1
|
getting deployed release version failed: Failed to get the version for: mychart1
|
||||||
|
|
||||||
UPDATED RELEASES:
|
UPDATED RELEASES:
|
||||||
NAME CHART VERSION
|
NAME CHART VERSION
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
package app
|
package app
|
||||||
|
|
||||||
import "github.com/helmfile/helmfile/pkg/helmexec"
|
import (
|
||||||
|
"helm.sh/helm/v3/pkg/chart"
|
||||||
|
|
||||||
|
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||||
|
)
|
||||||
|
|
||||||
type noCallHelmExec struct {
|
type noCallHelmExec struct {
|
||||||
}
|
}
|
||||||
|
|
@ -113,3 +117,8 @@ func (helm *noCallHelmExec) IsVersionAtLeast(versionStr string) bool {
|
||||||
helm.doPanic()
|
helm.doPanic()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (helm *noCallHelmExec) ShowChart(chartPath string) (chart.Metadata, error) {
|
||||||
|
helm.doPanic()
|
||||||
|
return chart.Metadata{}, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,9 @@ GROUP RELEASES
|
||||||
2 default/tns1/foo
|
2 default/tns1/foo
|
||||||
|
|
||||||
processing releases in group 1/2: default/tns2/bar
|
processing releases in group 1/2: default/tns2/bar
|
||||||
getting deployed release version failed:Failed to get the version for:mychart2
|
getting deployed release version failed: Failed to get the version for: mychart2
|
||||||
processing releases in group 2/2: default/tns1/foo
|
processing releases in group 2/2: default/tns1/foo
|
||||||
getting deployed release version failed:Failed to get the version for:mychart1
|
getting deployed release version failed: Failed to get the version for: mychart1
|
||||||
|
|
||||||
UPDATED RELEASES:
|
UPDATED RELEASES:
|
||||||
NAME CHART VERSION
|
NAME CHART VERSION
|
||||||
|
|
|
||||||
|
|
@ -47,10 +47,10 @@ GROUP RELEASES
|
||||||
2 default//foo
|
2 default//foo
|
||||||
|
|
||||||
processing releases in group 1/2: default//baz, default//bar
|
processing releases in group 1/2: default//baz, default//bar
|
||||||
getting deployed release version failed:unexpected list key: listkey(filter=^baz$,flags=--kube-contextdefault--deleting--deployed--failed--pending) not found in
|
getting deployed release version failed: unexpected list key: listkey(filter=^baz$,flags=--kube-contextdefault--deleting--deployed--failed--pending) not found in
|
||||||
getting deployed release version failed:unexpected list key: listkey(filter=^bar$,flags=--kube-contextdefault--deleting--deployed--failed--pending) not found in
|
getting deployed release version failed: unexpected list key: listkey(filter=^bar$,flags=--kube-contextdefault--deleting--deployed--failed--pending) not found in
|
||||||
processing releases in group 2/2: default//foo
|
processing releases in group 2/2: default//foo
|
||||||
getting deployed release version failed:unexpected list key: listkey(filter=^foo$,flags=--kube-contextdefault--deleting--deployed--failed--pending) not found in
|
getting deployed release version failed: unexpected list key: listkey(filter=^foo$,flags=--kube-contextdefault--deleting--deployed--failed--pending) not found in
|
||||||
|
|
||||||
UPDATED RELEASES:
|
UPDATED RELEASES:
|
||||||
NAME CHART VERSION
|
NAME CHART VERSION
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,9 @@ GROUP RELEASES
|
||||||
2 default/testNamespace/bar
|
2 default/testNamespace/bar
|
||||||
|
|
||||||
processing releases in group 1/2: default/testNamespace/foo
|
processing releases in group 1/2: default/testNamespace/foo
|
||||||
getting deployed release version failed:Failed to get the version for:mychart1
|
getting deployed release version failed: Failed to get the version for: mychart1
|
||||||
processing releases in group 2/2: default/testNamespace/bar
|
processing releases in group 2/2: default/testNamespace/bar
|
||||||
getting deployed release version failed:Failed to get the version for:mychart2
|
getting deployed release version failed: Failed to get the version for: mychart2
|
||||||
|
|
||||||
UPDATED RELEASES:
|
UPDATED RELEASES:
|
||||||
NAME CHART VERSION
|
NAME CHART VERSION
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,9 @@ GROUP RELEASES
|
||||||
2 default//bar
|
2 default//bar
|
||||||
|
|
||||||
processing releases in group 1/2: default//foo
|
processing releases in group 1/2: default//foo
|
||||||
getting deployed release version failed:Failed to get the version for:mychart1
|
getting deployed release version failed: Failed to get the version for: mychart1
|
||||||
processing releases in group 2/2: default//bar
|
processing releases in group 2/2: default//bar
|
||||||
getting deployed release version failed:Failed to get the version for:mychart2
|
getting deployed release version failed: Failed to get the version for: mychart2
|
||||||
|
|
||||||
UPDATED RELEASES:
|
UPDATED RELEASES:
|
||||||
NAME CHART VERSION
|
NAME CHART VERSION
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,9 @@ GROUP RELEASES
|
||||||
2 default/testNamespace/foo
|
2 default/testNamespace/foo
|
||||||
|
|
||||||
processing releases in group 1/2: default/testNamespace/bar
|
processing releases in group 1/2: default/testNamespace/bar
|
||||||
getting deployed release version failed:Failed to get the version for:mychart2
|
getting deployed release version failed: Failed to get the version for: mychart2
|
||||||
processing releases in group 2/2: default/testNamespace/foo
|
processing releases in group 2/2: default/testNamespace/foo
|
||||||
getting deployed release version failed:Failed to get the version for:mychart1
|
getting deployed release version failed: Failed to get the version for: mychart1
|
||||||
|
|
||||||
UPDATED RELEASES:
|
UPDATED RELEASES:
|
||||||
NAME CHART VERSION
|
NAME CHART VERSION
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,9 @@ GROUP RELEASES
|
||||||
2 default//foo
|
2 default//foo
|
||||||
|
|
||||||
processing releases in group 1/2: default//bar
|
processing releases in group 1/2: default//bar
|
||||||
getting deployed release version failed:Failed to get the version for:mychart2
|
getting deployed release version failed: Failed to get the version for: mychart2
|
||||||
processing releases in group 2/2: default//foo
|
processing releases in group 2/2: default//foo
|
||||||
getting deployed release version failed:Failed to get the version for:mychart1
|
getting deployed release version failed: Failed to get the version for: mychart1
|
||||||
|
|
||||||
UPDATED RELEASES:
|
UPDATED RELEASES:
|
||||||
NAME CHART VERSION
|
NAME CHART VERSION
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,9 @@ GROUP RELEASES
|
||||||
2 default/ns1/foo
|
2 default/ns1/foo
|
||||||
|
|
||||||
processing releases in group 1/2: default/ns2/bar
|
processing releases in group 1/2: default/ns2/bar
|
||||||
getting deployed release version failed:Failed to get the version for:mychart2
|
getting deployed release version failed: Failed to get the version for: mychart2
|
||||||
processing releases in group 2/2: default/ns1/foo
|
processing releases in group 2/2: default/ns1/foo
|
||||||
getting deployed release version failed:Failed to get the version for:mychart1
|
getting deployed release version failed: Failed to get the version for: mychart1
|
||||||
|
|
||||||
UPDATED RELEASES:
|
UPDATED RELEASES:
|
||||||
NAME CHART VERSION
|
NAME CHART VERSION
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,9 @@ GROUP RELEASES
|
||||||
2 default/ns2/bar
|
2 default/ns2/bar
|
||||||
|
|
||||||
processing releases in group 1/2: default/ns1/foo
|
processing releases in group 1/2: default/ns1/foo
|
||||||
getting deployed release version failed:Failed to get the version for:mychart1
|
getting deployed release version failed: Failed to get the version for: mychart1
|
||||||
processing releases in group 2/2: default/ns2/bar
|
processing releases in group 2/2: default/ns2/bar
|
||||||
getting deployed release version failed:Failed to get the version for:mychart2
|
getting deployed release version failed: Failed to get the version for: mychart2
|
||||||
|
|
||||||
UPDATED RELEASES:
|
UPDATED RELEASES:
|
||||||
NAME CHART VERSION
|
NAME CHART VERSION
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ GROUP RELEASES
|
||||||
1 default/default/foo
|
1 default/default/foo
|
||||||
|
|
||||||
processing releases in group 1/1: default/default/foo
|
processing releases in group 1/1: default/default/foo
|
||||||
getting deployed release version failed:unexpected list key: {^foo$ --kube-contextdefault--deleting--deployed--failed--pending}
|
getting deployed release version failed: unexpected list key: {^foo$ --kube-contextdefault--deleting--deployed--failed--pending}
|
||||||
|
|
||||||
UPDATED RELEASES:
|
UPDATED RELEASES:
|
||||||
NAME CHART VERSION
|
NAME CHART VERSION
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/Masterminds/semver/v3"
|
"github.com/Masterminds/semver/v3"
|
||||||
|
"helm.sh/helm/v3/pkg/chart"
|
||||||
|
|
||||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||||
)
|
)
|
||||||
|
|
@ -227,3 +228,12 @@ func (helm *Helm) sync(m *sync.Mutex, f func()) {
|
||||||
|
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (helm *Helm) ShowChart(chartPath string) (chart.Metadata, error) {
|
||||||
|
switch chartPath {
|
||||||
|
case "../../foo-bar":
|
||||||
|
return chart.Metadata{Version: "3.2.0"}, nil
|
||||||
|
default:
|
||||||
|
return chart.Metadata{}, errors.New("fake test error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ import (
|
||||||
"github.com/Masterminds/semver/v3"
|
"github.com/Masterminds/semver/v3"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"go.uber.org/zap/zapcore"
|
"go.uber.org/zap/zapcore"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
"helm.sh/helm/v3/pkg/chart"
|
||||||
"helm.sh/helm/v3/pkg/cli"
|
"helm.sh/helm/v3/pkg/cli"
|
||||||
"helm.sh/helm/v3/pkg/plugin"
|
"helm.sh/helm/v3/pkg/plugin"
|
||||||
|
|
||||||
|
|
@ -599,3 +601,21 @@ func resolveOciChart(ociChart string) (ociChartURL, ociChartTag string) {
|
||||||
ociChartURL = fmt.Sprintf("oci://%s", ociChart[:urlTagIndex])
|
ociChartURL = fmt.Sprintf("oci://%s", ociChart[:urlTagIndex])
|
||||||
return ociChartURL, ociChartTag
|
return ociChartURL, ociChartTag
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (helm *execer) ShowChart(chartPath string) (chart.Metadata, error) {
|
||||||
|
if !helm.IsHelm3() {
|
||||||
|
// show chart command isn't supported in helm2
|
||||||
|
return chart.Metadata{}, fmt.Errorf("helm show isn't supported in helm2")
|
||||||
|
}
|
||||||
|
var helmArgs = []string{"show", "chart", chartPath}
|
||||||
|
out, error := helm.exec(helmArgs, map[string]string{}, nil)
|
||||||
|
if error != nil {
|
||||||
|
return chart.Metadata{}, error
|
||||||
|
}
|
||||||
|
var metadata chart.Metadata
|
||||||
|
error = yaml.Unmarshal(out, &metadata)
|
||||||
|
if error != nil {
|
||||||
|
return chart.Metadata{}, error
|
||||||
|
}
|
||||||
|
return metadata, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1008,3 +1008,32 @@ func Test_resolveOciChart(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_ShowChart(t *testing.T) {
|
||||||
|
helm2Runner := mockRunner{output: []byte("Client: v2.16.1+ge13bc94\n")}
|
||||||
|
helm := New("helm", false, NewLogger(os.Stdout, "info"), "dev", &helm2Runner)
|
||||||
|
_, err := helm.ShowChart("fake-chart")
|
||||||
|
if err == nil {
|
||||||
|
t.Error("helmexec.ShowChart() - helm show isn't supported in helm2")
|
||||||
|
}
|
||||||
|
|
||||||
|
showChartRunner := mockRunner{output: []byte("name: my-chart\nversion: 3.2.0\n")}
|
||||||
|
helm = &execer{
|
||||||
|
helmBinary: "helm",
|
||||||
|
version: *semver.MustParse("3.3.2"),
|
||||||
|
logger: NewLogger(os.Stdout, "info"),
|
||||||
|
kubeContext: "dev",
|
||||||
|
runner: &showChartRunner,
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata, err := helm.ShowChart("my-chart")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("helmexec.ShowChart() - unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if metadata.Name != "my-chart" {
|
||||||
|
t.Errorf("helmexec.ShowChart() - expected chart name was %s, received: %s", "my-chart", metadata.Name)
|
||||||
|
}
|
||||||
|
if metadata.Version != "3.2.0" {
|
||||||
|
t.Errorf("helmexec.ShowChart() - expected chart version was %s, received: %s", "3.2.0", metadata.Version)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package helmexec
|
package helmexec
|
||||||
|
|
||||||
|
import "helm.sh/helm/v3/pkg/chart"
|
||||||
|
|
||||||
// Version represents the version of helm
|
// Version represents the version of helm
|
||||||
type Version struct {
|
type Version struct {
|
||||||
Major int
|
Major int
|
||||||
|
|
@ -33,6 +35,7 @@ type Interface interface {
|
||||||
IsHelm3() bool
|
IsHelm3() bool
|
||||||
GetVersion() Version
|
GetVersion() Version
|
||||||
IsVersionAtLeast(versionStr string) bool
|
IsVersionAtLeast(versionStr string) bool
|
||||||
|
ShowChart(chart string) (chart.Metadata, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type DependencyUpdater interface {
|
type DependencyUpdater interface {
|
||||||
|
|
|
||||||
|
|
@ -867,7 +867,7 @@ func (st *HelmState) SyncReleases(affectedReleases *AffectedReleases, helm helme
|
||||||
m.Unlock()
|
m.Unlock()
|
||||||
installedVersion, err := st.getDeployedVersion(context, helm, release)
|
installedVersion, err := st.getDeployedVersion(context, helm, release)
|
||||||
if err != nil { // err is not really impacting so just log it
|
if err != nil { // err is not really impacting so just log it
|
||||||
st.logger.Debugf("getting deployed release version failed:%v", err)
|
st.logger.Debugf("getting deployed release version failed: %v", err)
|
||||||
} else {
|
} else {
|
||||||
release.installedVersion = installedVersion
|
release.installedVersion = installedVersion
|
||||||
}
|
}
|
||||||
|
|
@ -938,8 +938,11 @@ func (st *HelmState) getDeployedVersion(context helmexec.HelmContext, helm helme
|
||||||
if len(versions) > 0 {
|
if len(versions) > 0 {
|
||||||
return versions[1], nil
|
return versions[1], nil
|
||||||
} else {
|
} else {
|
||||||
//fails to find the version
|
chartMetadata, err := helm.ShowChart(release.Chart)
|
||||||
return "failed to get version", errors.New("Failed to get the version for:" + chartName)
|
if err != nil {
|
||||||
|
return "failed to get version", errors.New("Failed to get the version for: " + chartName)
|
||||||
|
}
|
||||||
|
return chartMetadata.Version, nil
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return "failed to get version", err
|
return "failed to get version", err
|
||||||
|
|
|
||||||
|
|
@ -1455,6 +1455,16 @@ func TestGetDeployedVersion(t *testing.T) {
|
||||||
foo-bar-release 1 Wed Apr 17 17:39:04 2019 DEPLOYED foo-bar-1.0.0-alpha+001 0.1.0 default`,
|
foo-bar-release 1 Wed Apr 17 17:39:04 2019 DEPLOYED foo-bar-1.0.0-alpha+001 0.1.0 default`,
|
||||||
installedVersion: "1.0.0-alpha+001",
|
installedVersion: "1.0.0-alpha+001",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "chart version from helm show chart",
|
||||||
|
release: ReleaseSpec{
|
||||||
|
Name: "foo",
|
||||||
|
Chart: "../../foo-bar",
|
||||||
|
},
|
||||||
|
listResult: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||||
|
foo 1 Wed Apr 17 17:39:04 2019 DEPLOYED foo-bar 0.1.0 default`,
|
||||||
|
installedVersion: "3.2.0",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for i := range tests {
|
for i := range tests {
|
||||||
tt := tests[i]
|
tt := tests[i]
|
||||||
|
|
@ -1467,6 +1477,7 @@ func TestGetDeployedVersion(t *testing.T) {
|
||||||
valsRuntime: valsRuntime,
|
valsRuntime: valsRuntime,
|
||||||
RenderedValues: map[string]interface{}{},
|
RenderedValues: map[string]interface{}{},
|
||||||
}
|
}
|
||||||
|
|
||||||
helm := &exectest.Helm{
|
helm := &exectest.Helm{
|
||||||
Lists: map[exectest.ListKey]string{},
|
Lists: map[exectest.ListKey]string{},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue