diff --git a/.circleci/config.yml b/.circleci/config.yml index b3ff4b86..3996095b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -41,7 +41,7 @@ jobs: - run: name: Install helm environment: - HELM_VERSION: v2.12.0 + HELM_VERSION: v2.13.0 command: | HELM_FILENAME="helm-${HELM_VERSION}-linux-amd64.tar.gz" curl -Lo ${HELM_FILENAME} "https://kubernetes-helm.storage.googleapis.com/${HELM_FILENAME}" diff --git a/Dockerfile b/Dockerfile index 79def234..2f3e757a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ FROM alpine:3.8 RUN apk add --no-cache ca-certificates git bash curl -ARG HELM_VERSION=v2.12.0 +ARG HELM_VERSION=v2.13.0 ARG HELM_LOCATION="https://kubernetes-helm.storage.googleapis.com" ARG HELM_FILENAME="helm-${HELM_VERSION}-linux-amd64.tar.gz" ARG HELM_SHA256="9f96a6e4fc52b5df906da381532cc2eb2f3f57cc203ccaec2b11cf5dc26a7dfc" diff --git a/README.md b/README.md index e571cac8..3bf978d5 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,8 @@ releases: force: true # set `false` to uninstall on sync installed: true + # restores previous state in case of failed release + atomic: true # Local chart example - name: grafana # name of this release diff --git a/state/state.go b/state/state.go index 8a2fddf5..affac2fd 100644 --- a/state/state.go +++ b/state/state.go @@ -66,6 +66,8 @@ type HelmSpec struct { RecreatePods bool `yaml:"recreatePods"` // Force, when set to true, forces resource update through delete/recreate if needed Force bool `yaml:"force"` + // Atomic, when set to true, restore previous state in case of a failed install/upgrade attempt + Atomic bool `yaml:"atomic"` } // RepositorySpec that defines values for a helm repo @@ -96,6 +98,8 @@ type ReleaseSpec struct { Force *bool `yaml:"force"` // Installed, when set to true, `delete --purge` the release Installed *bool `yaml:"installed"` + // Atomic, when set to true, restore previous state in case of a failed install/upgrade attempt + Atomic *bool `yaml:"atomic"` // MissingFileHandler is set to either "Error" or "Warn". "Error" instructs helmfile to fail when unable to find a values or secrets file. When "Warn", it prints the file and continues. // The default value for MissingFileHandler is "Error". @@ -948,6 +952,10 @@ func (st *HelmState) flagsForUpgrade(helm helmexec.Interface, release *ReleaseSp flags = append(flags, "--recreate-pods") } + if release.Atomic != nil && *release.Atomic || st.HelmDefaults.Atomic { + flags = append(flags, "--atomic") + } + common, err := st.namespaceAndValuesFlags(helm, release) if err != nil { return nil, err diff --git a/state/state_test.go b/state/state_test.go index 914baaf9..367402f1 100644 --- a/state/state_test.go +++ b/state/state_test.go @@ -376,6 +376,42 @@ func TestHelmState_flagsForUpgrade(t *testing.T) { "--namespace", "test-namespace", }, }, + { + name: "atomic", + defaults: HelmSpec{ + Atomic: false, + }, + release: &ReleaseSpec{ + Chart: "test/chart", + Version: "0.1", + Atomic: &enable, + Name: "test-charts", + Namespace: "test-namespace", + }, + want: []string{ + "--version", "0.1", + "--atomic", + "--namespace", "test-namespace", + }, + }, + { + name: "atomic-from-default", + defaults: HelmSpec{ + Atomic: true, + }, + release: &ReleaseSpec{ + Chart: "test/chart", + Version: "0.1", + Atomic: &disable, + Name: "test-charts", + Namespace: "test-namespace", + }, + want: []string{ + "--version", "0.1", + "--atomic", + "--namespace", "test-namespace", + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {