Append --force-update for specific helm versions. (#1494)

* Parse and process helm version using github.com/Masterminds/semver/v3.

* Add --force-update only when Helm version >= 3.3.2, < 3.3.4.

See: https://github.com/helm/helm/pull/8777.

* Add test cases.
This commit is contained in:
Wi1dcard
2020-10-12 09:20:55 +09:00
committed by GitHub
parent b284b7be83
commit 5d8eba9b29
11 changed files with 87 additions and 134 deletions
+33 -39
View File
@@ -6,11 +6,11 @@ import (
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"sync"
"github.com/Masterminds/semver/v3"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
@@ -22,7 +22,7 @@ type decryptedSecret struct {
type execer struct {
helmBinary string
version Version
version semver.Version
runner Runner
logger *zap.SugaredLogger
kubeContext string
@@ -48,51 +48,33 @@ func NewLogger(writer io.Writer, logLevel string) *zap.SugaredLogger {
return zap.New(core).Sugar()
}
// versionRegex matches versions like v1.1.1 and v1.1
var versionRegex = regexp.MustCompile("v(?P<major>\\d+)\\.(?P<minor>\\d+)(?:\\.(?P<patch>\\d+))?")
func parseHelmVersion(versionStr string) (Version, error) {
func parseHelmVersion(versionStr string) (semver.Version, error) {
if len(versionStr) == 0 {
return Version{}, nil
return semver.Version{}, nil
}
matches := versionRegex.FindStringSubmatch(versionStr)
if len(matches) == 0 {
return Version{}, fmt.Errorf("error parsing helm verion '%s'", versionStr)
}
result := make(map[string]string)
for i, name := range versionRegex.SubexpNames() {
result[name] = matches[i]
}
versionStr = strings.TrimLeft(versionStr, "Client: ")
versionStr = strings.TrimRight(versionStr, "\n")
// We ignore errors because regex matches only integers
// If any of the parts does not exist - default "0" will be used
major, _ := strconv.Atoi(result["major"])
minor, _ := strconv.Atoi(result["minor"])
patch, _ := strconv.Atoi(result["patch"])
ver, err := semver.NewVersion(versionStr)
if err != nil {
return semver.Version{}, fmt.Errorf("error parsing helm verion '%s'", versionStr)
}
// Support explicit helm3 opt-in via environment variable
if os.Getenv("HELMFILE_HELM3") != "" && major < 3 {
return Version{
Major: 3,
Minor: 0,
Patch: 0,
}, nil
if os.Getenv("HELMFILE_HELM3") != "" && ver.Major() < 3 {
return *semver.MustParse("v3.0.0"), nil
}
return Version{
Major: major,
Minor: minor,
Patch: patch,
}, nil
return *ver, nil
}
func getHelmVersion(helmBinary string, runner Runner) (Version, error) {
func getHelmVersion(helmBinary string, runner Runner) (semver.Version, error) {
// Autodetect from `helm verison`
bytes, err := runner.Execute(helmBinary, []string{"version", "--client", "--short"}, nil)
if err != nil {
return Version{}, fmt.Errorf("error determining helm version: %w", err)
return semver.Version{}, fmt.Errorf("error determining helm version: %w", err)
}
return parseHelmVersion(string(bytes))
@@ -130,9 +112,16 @@ func (helm *execer) AddRepo(name, repository, cafile, certfile, keyfile, usernam
return fmt.Errorf("empty field name")
}
args = append(args, "repo", "add", name, repository)
if helm.IsHelm3() && helm.IsVersionAtLeast(3, 3, 2) {
args = append(args, "--force-update")
// See https://github.com/helm/helm/pull/8777
if cons, err := semver.NewConstraint(">= 3.3.2, < 3.3.4"); err == nil {
if cons.Check(&helm.version) {
args = append(args, "--force-update")
}
} else {
panic(err)
}
if certfile != "" && keyfile != "" {
args = append(args, "--cert-file", certfile, "--key-file", keyfile)
}
@@ -394,13 +383,18 @@ func (helm *execer) write(out []byte) {
}
func (helm *execer) IsHelm3() bool {
return helm.version.Major == 3
return helm.version.Major() == 3
}
func (helm *execer) GetVersion() Version {
return helm.version
return Version{
Major: int(helm.version.Major()),
Minor: int(helm.version.Minor()),
Patch: int(helm.version.Patch()),
}
}
func (helm *execer) IsVersionAtLeast(major int, minor int, patch int) bool {
return helm.version.Major >= major && helm.version.Minor >= minor && helm.version.Patch >= patch
func (helm *execer) IsVersionAtLeast(versionStr string) bool {
ver := semver.MustParse(versionStr)
return helm.version.Equal(ver) || helm.version.GreaterThan(ver)
}