Skip to content

Commit

Permalink
Use helmfile build --embed-values for diff_output stabilization for…
Browse files Browse the repository at this point in the history
… Helmfile v0.126.0 or greater

Ref #28
  • Loading branch information
mumoshu committed Aug 30, 2020
1 parent 4dbef80 commit f108f58
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 4 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/mumoshu/terraform-provider-helmfile
go 1.13

require (
github.com/Masterminds/semver v1.5.0
github.com/hashicorp/terraform-plugin-sdk v1.0.0
github.com/mitchellh/go-linereader v0.0.0-20190213213312-1b945b3263eb
github.com/rs/xid v1.2.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbf
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE=
Expand Down
75 changes: 71 additions & 4 deletions pkg/helmfile/release_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"path/filepath"
"strconv"
"strings"

"github.com/Masterminds/semver"
)

type ReleaseSet struct {
Expand Down Expand Up @@ -210,11 +212,13 @@ func ReadReleaseSet(fs *ReleaseSet, d ResourceReadWrite) error {
return nil
}

func runBuild(fs *ReleaseSet) (*State, error) {
func runBuild(fs *ReleaseSet, flags ...string) (*State, error) {
args := []string{
"build",
}

args = append(args, flags...)

cmd, err := NewCommand(fs, args...)
if err != nil {
return nil, err
Expand All @@ -228,6 +232,39 @@ func runBuild(fs *ReleaseSet) (*State, error) {
return runCommand(cmd, state, true)
}

func getHelmfileVersion(fs *ReleaseSet) (*semver.Version, error) {
args := []string{
"version",
}

cmd, err := NewCommand(fs, args...)
if err != nil {
return nil, err
}

//obtain exclusive lock
mutexKV.Lock(fs.WorkingDirectory)
defer mutexKV.Unlock(fs.WorkingDirectory)

state := NewState()
st, err := runCommand(cmd, state, false)
if err != nil {
return nil, err
}

splits := strings.Split(strings.TrimSpace(st.Output), " ")

versionPart := strings.TrimLeft(splits[len(splits)-1], "v")

v, err := semver.NewVersion(versionPart)

if err != nil {
logf("Failed to parse %q as semver: %v", versionPart, err)
}

return v, nil
}

func runTemplate(fs *ReleaseSet) (*State, error) {
args := []string{
"template",
Expand Down Expand Up @@ -295,18 +332,48 @@ func runDiff(fs *ReleaseSet, opts ...DiffOption) (*State, error) {
}

func getDiffFile(fs *ReleaseSet) (string, error) {
tmpl, err := runTemplate(fs)
helmfileVersion, err := getHelmfileVersion(fs)
if err != nil {
return "", err
}

determinisitcOutput, err := removeNondeterministicLogLines(tmpl.Output)
cons, err := semver.NewConstraint(">= 0.126.0")
if err != nil {
return "", err
}

var determinisiticOutput string

if helmfileVersion != nil && cons.Check(helmfileVersion) {
logf("Detected Helmfile version greater than 0.126.0(=%s). Using `helmfile build --embed-values` to compute the unique ID of the desired state.", helmfileVersion)
tmpl, err := runBuild(fs, "--embed-values")
if err != nil {
return "", err
}

determinisiticOutput = tmpl.Output
} else {
// `helmfile template` output is not stable and reliable when you have randomness in manifest generation,
// like using random id in test pods.
//
// Since helmfile v0.126.0, we can use `helmfile build --embed-values` whose output
// is stable as long as there's no randomness in helmfile state itself.
// For prior helmfile versions, we fallback to `helmfile template`, as follows.
//
// Also see https://github.com/mumoshu/terraform-provider-helmfile/issues/28 for more context.
tmpl, err := runTemplate(fs)
if err != nil {
return "", err
}

determinisiticOutput, err = removeNondeterministicLogLines(tmpl.Output)
if err != nil {
return "", err
}
}

hash := sha256.New()
hash.Write([]byte(determinisitcOutput))
hash.Write([]byte(determinisiticOutput))
bs, err := json.Marshal(fs)
if err != nil {
return "", err
Expand Down

0 comments on commit f108f58

Please sign in to comment.