commit
24810a45ae
|
|
@ -1183,6 +1183,7 @@ Once `events` are triggered, associated `hooks` are executed, by running the `co
|
||||||
Currently supported `events` are:
|
Currently supported `events` are:
|
||||||
|
|
||||||
- `prepare`
|
- `prepare`
|
||||||
|
- `preapply`
|
||||||
- `presync`
|
- `presync`
|
||||||
- `preuninstall`
|
- `preuninstall`
|
||||||
- `postuninstall`
|
- `postuninstall`
|
||||||
|
|
@ -1192,9 +1193,12 @@ Currently supported `events` are:
|
||||||
Hooks associated to `prepare` events are triggered after each release in your helmfile is loaded from YAML, before execution.
|
Hooks associated to `prepare` events are triggered after each release in your helmfile is loaded from YAML, before execution.
|
||||||
`prepare` hooks are triggered on the release as long as it is not excluded by the helmfile selector(e.g. `helmfile -l key=value`).
|
`prepare` hooks are triggered on the release as long as it is not excluded by the helmfile selector(e.g. `helmfile -l key=value`).
|
||||||
|
|
||||||
Hooks associated to `presync` events are triggered before each release is applied to the remote cluster.
|
Hooks associated to `presync` events are triggered before each release is installed or upgraded on the remote cluster.
|
||||||
This is the ideal event to execute any commands that may mutate the cluster state as it will not be run for read-only operations like `lint`, `diff` or `template`.
|
This is the ideal event to execute any commands that may mutate the cluster state as it will not be run for read-only operations like `lint`, `diff` or `template`.
|
||||||
|
|
||||||
|
`preapply` hooks are triggered before a release is uninstalled, installed, or upgraded as part of `helmfile apply`.
|
||||||
|
This is the ideal event to hook into when you are going to use `helmfile apply` for every kind of change, and you want the hook to be called only when any kind of change is being made.
|
||||||
|
|
||||||
`preuninstall` hooks are triggered immediately before a release is uninstalled as part of `helmfile apply`, `helmfile sync`, `helmfile delete`, and `helmfile destroy`.
|
`preuninstall` hooks are triggered immediately before a release is uninstalled as part of `helmfile apply`, `helmfile sync`, `helmfile delete`, and `helmfile destroy`.
|
||||||
|
|
||||||
`postuninstall` hooks are triggered immediately after successful uninstall of a release while running `helmfile apply`, `helmfile sync`, `helmfile delete`, `helmfile destroy`.
|
`postuninstall` hooks are triggered immediately after successful uninstall of a release while running `helmfile apply`, `helmfile sync`, `helmfile delete`, `helmfile destroy`.
|
||||||
|
|
|
||||||
3
go.mod
3
go.mod
|
|
@ -29,12 +29,14 @@ require (
|
||||||
github.com/variantdev/vals v0.18.0
|
github.com/variantdev/vals v0.18.0
|
||||||
go.uber.org/multierr v1.6.0
|
go.uber.org/multierr v1.6.0
|
||||||
go.uber.org/zap v1.23.0
|
go.uber.org/zap v1.23.0
|
||||||
|
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
gotest.tools v2.2.0+incompatible
|
gotest.tools v2.2.0+incompatible
|
||||||
helm.sh/helm/v3 v3.8.1
|
helm.sh/helm/v3 v3.8.1
|
||||||
k8s.io/apimachinery v0.24.4
|
k8s.io/apimachinery v0.24.4
|
||||||
|
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|
@ -194,7 +196,6 @@ require (
|
||||||
k8s.io/client-go v0.23.4 // indirect
|
k8s.io/client-go v0.23.4 // indirect
|
||||||
k8s.io/klog/v2 v2.60.1 // indirect
|
k8s.io/klog/v2 v2.60.1 // indirect
|
||||||
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 // indirect
|
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 // indirect
|
||||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
|
|
||||||
oras.land/oras-go v1.1.0 // indirect
|
oras.land/oras-go v1.1.0 // indirect
|
||||||
sigs.k8s.io/kustomize/api v0.10.1 // indirect
|
sigs.k8s.io/kustomize/api v0.10.1 // indirect
|
||||||
sigs.k8s.io/kustomize/kyaml v0.13.0 // indirect
|
sigs.k8s.io/kustomize/kyaml v0.13.0 // indirect
|
||||||
|
|
|
||||||
2
go.sum
2
go.sum
|
|
@ -1373,6 +1373,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||||
|
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
|
||||||
|
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
|
|
||||||
|
|
@ -790,7 +790,7 @@ func (a *App) visitStates(fileOrDir string, defOpts LoadOpts, converge func(*sta
|
||||||
go func() {
|
go func() {
|
||||||
sig := <-sigs
|
sig := <-sigs
|
||||||
|
|
||||||
errs := []error{fmt.Errorf("Received [%s] to shutdown ", sig)}
|
errs := []error{fmt.Errorf("received [%s] to shutdown ", sig)}
|
||||||
_ = context{app: a, st: st, retainValues: defOpts.RetainValuesFiles}.clean(errs)
|
_ = context{app: a, st: st, retainValues: defOpts.RetainValuesFiles}.clean(errs)
|
||||||
// See http://tldp.org/LDP/abs/html/exitcodes.html
|
// See http://tldp.org/LDP/abs/html/exitcodes.html
|
||||||
switch sig {
|
switch sig {
|
||||||
|
|
@ -1342,7 +1342,7 @@ Do you really want to apply?
|
||||||
a.Logger.Debug(*infoMsg)
|
a.Logger.Debug(*infoMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
applyErrs := []error{}
|
var applyErrs []error
|
||||||
|
|
||||||
affectedReleases := state.AffectedReleases{}
|
affectedReleases := state.AffectedReleases{}
|
||||||
|
|
||||||
|
|
@ -1355,15 +1355,27 @@ Do you really want to apply?
|
||||||
// We deleted releases by traversing the DAG in reverse order
|
// We deleted releases by traversing the DAG in reverse order
|
||||||
if len(releasesToBeDeleted) > 0 {
|
if len(releasesToBeDeleted) > 0 {
|
||||||
_, deletionErrs := withDAG(st, helm, a.Logger, state.PlanOptions{Reverse: true, SelectedReleases: toDelete, SkipNeeds: true}, a.WrapWithoutSelector(func(subst *state.HelmState, helm helmexec.Interface) []error {
|
_, deletionErrs := withDAG(st, helm, a.Logger, state.PlanOptions{Reverse: true, SelectedReleases: toDelete, SkipNeeds: true}, a.WrapWithoutSelector(func(subst *state.HelmState, helm helmexec.Interface) []error {
|
||||||
var rs []state.ReleaseSpec
|
var (
|
||||||
|
rs []state.ReleaseSpec
|
||||||
|
preapplyErrors []error
|
||||||
|
)
|
||||||
|
|
||||||
for _, r := range subst.Releases {
|
for _, r := range subst.Releases {
|
||||||
release := r
|
release := r
|
||||||
if r2, ok := releasesToBeDeleted[state.ReleaseToID(&release)]; ok {
|
if r2, ok := releasesToBeDeleted[state.ReleaseToID(&release)]; ok {
|
||||||
|
if _, err := st.TriggerPreapplyEvent(&r2, "apply"); err != nil {
|
||||||
|
preapplyErrors = append(applyErrs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
rs = append(rs, r2)
|
rs = append(rs, r2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(preapplyErrors) > 0 {
|
||||||
|
return preapplyErrors
|
||||||
|
}
|
||||||
|
|
||||||
subst.Releases = rs
|
subst.Releases = rs
|
||||||
|
|
||||||
return subst.DeleteReleasesForSync(&affectedReleases, helm, c.Concurrency())
|
return subst.DeleteReleasesForSync(&affectedReleases, helm, c.Concurrency())
|
||||||
|
|
@ -1377,15 +1389,27 @@ Do you really want to apply?
|
||||||
// We upgrade releases by traversing the DAG
|
// We upgrade releases by traversing the DAG
|
||||||
if len(releasesToBeUpdated) > 0 {
|
if len(releasesToBeUpdated) > 0 {
|
||||||
_, updateErrs := withDAG(st, helm, a.Logger, state.PlanOptions{SelectedReleases: toUpdate, Reverse: false, SkipNeeds: true, IncludeTransitiveNeeds: c.IncludeTransitiveNeeds()}, a.WrapWithoutSelector(func(subst *state.HelmState, helm helmexec.Interface) []error {
|
_, updateErrs := withDAG(st, helm, a.Logger, state.PlanOptions{SelectedReleases: toUpdate, Reverse: false, SkipNeeds: true, IncludeTransitiveNeeds: c.IncludeTransitiveNeeds()}, a.WrapWithoutSelector(func(subst *state.HelmState, helm helmexec.Interface) []error {
|
||||||
var rs []state.ReleaseSpec
|
var (
|
||||||
|
rs []state.ReleaseSpec
|
||||||
|
preapplyErrors []error
|
||||||
|
)
|
||||||
|
|
||||||
for _, r := range subst.Releases {
|
for _, r := range subst.Releases {
|
||||||
release := r
|
release := r
|
||||||
if r2, ok := releasesToBeUpdated[state.ReleaseToID(&release)]; ok {
|
if r2, ok := releasesToBeUpdated[state.ReleaseToID(&release)]; ok {
|
||||||
|
if _, err := st.TriggerPreapplyEvent(&r2, "apply"); err != nil {
|
||||||
|
preapplyErrors = append(applyErrs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
rs = append(rs, r2)
|
rs = append(rs, r2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(preapplyErrors) > 0 {
|
||||||
|
return preapplyErrors
|
||||||
|
}
|
||||||
|
|
||||||
subst.Releases = rs
|
subst.Releases = rs
|
||||||
|
|
||||||
syncOpts := state.SyncOpts{
|
syncOpts := state.SyncOpts{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,485 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
|
"github.com/variantdev/vals"
|
||||||
|
|
||||||
|
"github.com/helmfile/helmfile/pkg/exectest"
|
||||||
|
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||||
|
"github.com/helmfile/helmfile/pkg/testhelper"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestApply_hooks(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
skipNeeds bool
|
||||||
|
includeNeeds bool
|
||||||
|
includeTransitiveNeeds bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type testcase struct {
|
||||||
|
fields fields
|
||||||
|
ns string
|
||||||
|
concurrency int
|
||||||
|
skipDiffOnInstall bool
|
||||||
|
error string
|
||||||
|
files map[string]string
|
||||||
|
selectors []string
|
||||||
|
lists map[exectest.ListKey]string
|
||||||
|
diffs map[exectest.DiffKey]error
|
||||||
|
upgraded []exectest.Release
|
||||||
|
deleted []exectest.Release
|
||||||
|
log string
|
||||||
|
logLevel string
|
||||||
|
}
|
||||||
|
|
||||||
|
check := func(t *testing.T, tc testcase) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
wantUpgrades := tc.upgraded
|
||||||
|
wantDeletes := tc.deleted
|
||||||
|
|
||||||
|
var helm = &exectest.Helm{
|
||||||
|
FailOnUnexpectedList: true,
|
||||||
|
FailOnUnexpectedDiff: true,
|
||||||
|
Lists: tc.lists,
|
||||||
|
Diffs: tc.diffs,
|
||||||
|
DiffMutex: &sync.Mutex{},
|
||||||
|
ChartsMutex: &sync.Mutex{},
|
||||||
|
ReleasesMutex: &sync.Mutex{},
|
||||||
|
}
|
||||||
|
|
||||||
|
bs := &bytes.Buffer{}
|
||||||
|
|
||||||
|
func() {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
logReader, logWriter := io.Pipe()
|
||||||
|
|
||||||
|
logFlushed := &sync.WaitGroup{}
|
||||||
|
// Ensure all the log is consumed into `bs` by calling `logWriter.Close()` followed by `logFlushed.Wait()`
|
||||||
|
logFlushed.Add(1)
|
||||||
|
go func() {
|
||||||
|
scanner := bufio.NewScanner(logReader)
|
||||||
|
for scanner.Scan() {
|
||||||
|
bs.Write(scanner.Bytes())
|
||||||
|
bs.WriteString("\n")
|
||||||
|
}
|
||||||
|
logFlushed.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
// This is here to avoid data-trace on bytes buffer `bs` to capture logs
|
||||||
|
if err := logWriter.Close(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
logFlushed.Wait()
|
||||||
|
}()
|
||||||
|
|
||||||
|
logger := helmexec.NewLogger(logWriter, tc.logLevel)
|
||||||
|
|
||||||
|
valsRuntime, err := vals.New(vals.Options{CacheSize: 32})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error creating vals runtime: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
app := appWithFs(&App{
|
||||||
|
OverrideHelmBinary: DefaultHelmBinary,
|
||||||
|
OverrideKubeContext: "default",
|
||||||
|
Env: "default",
|
||||||
|
Logger: logger,
|
||||||
|
helms: map[helmKey]helmexec.Interface{
|
||||||
|
createHelmKey("helm", "default"): helm,
|
||||||
|
},
|
||||||
|
valsRuntime: valsRuntime,
|
||||||
|
}, tc.files)
|
||||||
|
|
||||||
|
if tc.ns != "" {
|
||||||
|
app.Namespace = tc.ns
|
||||||
|
}
|
||||||
|
|
||||||
|
if tc.selectors != nil {
|
||||||
|
app.Selectors = tc.selectors
|
||||||
|
}
|
||||||
|
|
||||||
|
syncErr := app.Apply(applyConfig{
|
||||||
|
// if we check log output, concurrency must be 1. otherwise the test becomes non-deterministic.
|
||||||
|
concurrency: tc.concurrency,
|
||||||
|
logger: logger,
|
||||||
|
skipDiffOnInstall: tc.skipDiffOnInstall,
|
||||||
|
skipNeeds: tc.fields.skipNeeds,
|
||||||
|
includeNeeds: tc.fields.includeNeeds,
|
||||||
|
includeTransitiveNeeds: tc.fields.includeTransitiveNeeds,
|
||||||
|
})
|
||||||
|
|
||||||
|
var gotErr string
|
||||||
|
if syncErr != nil {
|
||||||
|
gotErr = syncErr.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
if d := cmp.Diff(tc.error, gotErr); d != "" {
|
||||||
|
t.Fatalf("unexpected error: want (-), got (+): %s", d)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(wantUpgrades) > len(helm.Releases) {
|
||||||
|
t.Fatalf("insufficient number of upgrades: got %d, want %d", len(helm.Releases), len(wantUpgrades))
|
||||||
|
}
|
||||||
|
|
||||||
|
for relIdx := range wantUpgrades {
|
||||||
|
if wantUpgrades[relIdx].Name != helm.Releases[relIdx].Name {
|
||||||
|
t.Errorf("releases[%d].name: got %q, want %q", relIdx, helm.Releases[relIdx].Name, wantUpgrades[relIdx].Name)
|
||||||
|
}
|
||||||
|
for flagIdx := range wantUpgrades[relIdx].Flags {
|
||||||
|
if wantUpgrades[relIdx].Flags[flagIdx] != helm.Releases[relIdx].Flags[flagIdx] {
|
||||||
|
t.Errorf("releases[%d].flags[%d]: got %v, want %v", relIdx, flagIdx, helm.Releases[relIdx].Flags[flagIdx], wantUpgrades[relIdx].Flags[flagIdx])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(wantDeletes) > len(helm.Deleted) {
|
||||||
|
t.Fatalf("insufficient number of deletes: got %d, want %d", len(helm.Deleted), len(wantDeletes))
|
||||||
|
}
|
||||||
|
|
||||||
|
for relIdx := range wantDeletes {
|
||||||
|
if wantDeletes[relIdx].Name != helm.Deleted[relIdx].Name {
|
||||||
|
t.Errorf("releases[%d].name: got %q, want %q", relIdx, helm.Deleted[relIdx].Name, wantDeletes[relIdx].Name)
|
||||||
|
}
|
||||||
|
for flagIdx := range wantDeletes[relIdx].Flags {
|
||||||
|
if wantDeletes[relIdx].Flags[flagIdx] != helm.Deleted[relIdx].Flags[flagIdx] {
|
||||||
|
t.Errorf("releaes[%d].flags[%d]: got %v, want %v", relIdx, flagIdx, helm.Deleted[relIdx].Flags[flagIdx], wantDeletes[relIdx].Flags[flagIdx])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if tc.log != "" {
|
||||||
|
actual := bs.String()
|
||||||
|
|
||||||
|
diff, exists := testhelper.Diff(tc.log, actual, 3)
|
||||||
|
if exists {
|
||||||
|
t.Errorf("unexpected log:\nDIFF\n%s\nEOD", diff)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assertEqualsToSnapshot(t, "log", bs.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("apply release with preapply hook", func(t *testing.T) {
|
||||||
|
check(t, testcase{
|
||||||
|
files: map[string]string{
|
||||||
|
"/path/to/helmfile.yaml": `
|
||||||
|
releases:
|
||||||
|
- name: foo
|
||||||
|
chart: incubator/raw
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: test
|
||||||
|
hooks:
|
||||||
|
- events: ["preapply"]
|
||||||
|
command: echo
|
||||||
|
showlogs: true
|
||||||
|
args: ["foo"]
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
selectors: []string{"name=foo"},
|
||||||
|
upgraded: []exectest.Release{
|
||||||
|
{Name: "foo"},
|
||||||
|
},
|
||||||
|
diffs: map[exectest.DiffKey]error{
|
||||||
|
{Name: "foo", Chart: "incubator/raw", Flags: "--kube-contextdefault--namespacedefault--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||||
|
},
|
||||||
|
error: "",
|
||||||
|
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||||
|
concurrency: 1,
|
||||||
|
logLevel: "info",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("apply release with preapply hook", func(t *testing.T) {
|
||||||
|
check(t, testcase{
|
||||||
|
files: map[string]string{
|
||||||
|
"/path/to/helmfile.yaml": `
|
||||||
|
releases:
|
||||||
|
- name: foo
|
||||||
|
chart: incubator/raw
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: test
|
||||||
|
hooks:
|
||||||
|
- events: ["prepare", "preapply", "presync"]
|
||||||
|
command: echo
|
||||||
|
showlogs: true
|
||||||
|
args: ["foo"]
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
selectors: []string{"name=foo"},
|
||||||
|
upgraded: []exectest.Release{
|
||||||
|
{Name: "foo"},
|
||||||
|
},
|
||||||
|
diffs: map[exectest.DiffKey]error{
|
||||||
|
{Name: "foo", Chart: "incubator/raw", Flags: "--kube-contextdefault--namespacedefault--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||||
|
},
|
||||||
|
error: "",
|
||||||
|
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||||
|
concurrency: 1,
|
||||||
|
logLevel: "info",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("apply release with preapply hook", func(t *testing.T) {
|
||||||
|
check(t, testcase{
|
||||||
|
files: map[string]string{
|
||||||
|
"/path/to/helmfile.yaml": `
|
||||||
|
releases:
|
||||||
|
- name: foo
|
||||||
|
chart: incubator/raw
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: test
|
||||||
|
hooks:
|
||||||
|
- events: ["presync"]
|
||||||
|
command: echo
|
||||||
|
showlogs: true
|
||||||
|
args: ["foo"]
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
selectors: []string{"name=foo"},
|
||||||
|
upgraded: []exectest.Release{
|
||||||
|
{Name: "foo"},
|
||||||
|
},
|
||||||
|
diffs: map[exectest.DiffKey]error{
|
||||||
|
{Name: "foo", Chart: "incubator/raw", Flags: "--kube-contextdefault--namespacedefault--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||||
|
},
|
||||||
|
error: "",
|
||||||
|
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||||
|
concurrency: 1,
|
||||||
|
logLevel: "info",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("hooks for no-diff release", func(t *testing.T) {
|
||||||
|
check(t, testcase{
|
||||||
|
files: map[string]string{
|
||||||
|
"/path/to/helmfile.yaml": `
|
||||||
|
releases:
|
||||||
|
- name: foo
|
||||||
|
chart: incubator/raw
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: test
|
||||||
|
hooks:
|
||||||
|
# only prepare and cleanup are run
|
||||||
|
- events: ["prepare", "preapply", "presync", "cleanup"]
|
||||||
|
command: echo
|
||||||
|
showlogs: true
|
||||||
|
args: ["foo"]
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
selectors: []string{"app=test"},
|
||||||
|
diffs: map[exectest.DiffKey]error{
|
||||||
|
{Name: "foo", Chart: "incubator/raw", Flags: "--kube-contextdefault--namespacedefault--detailed-exitcode"}: nil,
|
||||||
|
},
|
||||||
|
error: "",
|
||||||
|
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||||
|
concurrency: 1,
|
||||||
|
logLevel: "info",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("hooks are run on enabled release", func(t *testing.T) {
|
||||||
|
check(t, testcase{
|
||||||
|
files: map[string]string{
|
||||||
|
"/path/to/helmfile.yaml": `
|
||||||
|
values:
|
||||||
|
- bar:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
releases:
|
||||||
|
- name: foo
|
||||||
|
chart: incubator/raw
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: test
|
||||||
|
hooks:
|
||||||
|
- events: ["prepare", "preapply", "presync"]
|
||||||
|
command: echo
|
||||||
|
showlogs: true
|
||||||
|
args: ["foo"]
|
||||||
|
- name: bar
|
||||||
|
condition: bar.enabled
|
||||||
|
chart: incubator/raw
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: test
|
||||||
|
hooks:
|
||||||
|
- events: ["prepare", "preapply", "presync"]
|
||||||
|
command: echo
|
||||||
|
showlogs: true
|
||||||
|
args: ["bar"]
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
selectors: []string{"app=test"},
|
||||||
|
upgraded: []exectest.Release{
|
||||||
|
{Name: "foo"},
|
||||||
|
{Name: "bar"},
|
||||||
|
},
|
||||||
|
diffs: map[exectest.DiffKey]error{
|
||||||
|
{Name: "foo", Chart: "incubator/raw", Flags: "--kube-contextdefault--namespacedefault--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||||
|
{Name: "bar", Chart: "incubator/raw", Flags: "--kube-contextdefault--namespacedefault--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||||
|
},
|
||||||
|
error: "",
|
||||||
|
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||||
|
concurrency: 1,
|
||||||
|
logLevel: "info",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("hooks are not run on disabled release", func(t *testing.T) {
|
||||||
|
check(t, testcase{
|
||||||
|
files: map[string]string{
|
||||||
|
"/path/to/helmfile.yaml": `
|
||||||
|
values:
|
||||||
|
- bar:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
releases:
|
||||||
|
- name: foo
|
||||||
|
chart: incubator/raw
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: test
|
||||||
|
hooks:
|
||||||
|
- events: ["prepare", "preapply", "presync"]
|
||||||
|
command: echo
|
||||||
|
showlogs: true
|
||||||
|
args: ["foo"]
|
||||||
|
- name: bar
|
||||||
|
condition: bar.enabled
|
||||||
|
chart: incubator/raw
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: test
|
||||||
|
hooks:
|
||||||
|
- events: ["prepare", "preapply", "presync"]
|
||||||
|
command: echo
|
||||||
|
showlogs: true
|
||||||
|
args: ["bar"]
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
selectors: []string{"app=test"},
|
||||||
|
upgraded: []exectest.Release{
|
||||||
|
{Name: "foo"},
|
||||||
|
},
|
||||||
|
diffs: map[exectest.DiffKey]error{
|
||||||
|
{Name: "foo", Chart: "incubator/raw", Flags: "--kube-contextdefault--namespacedefault--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||||
|
},
|
||||||
|
error: "",
|
||||||
|
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||||
|
concurrency: 1,
|
||||||
|
logLevel: "info",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("hooks are run on to-be-uninstalled release", func(t *testing.T) {
|
||||||
|
check(t, testcase{
|
||||||
|
files: map[string]string{
|
||||||
|
"/path/to/helmfile.yaml": `
|
||||||
|
releases:
|
||||||
|
- name: foo
|
||||||
|
chart: incubator/raw
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: test
|
||||||
|
hooks:
|
||||||
|
- events: ["prepare", "preapply", "presync"]
|
||||||
|
command: echo
|
||||||
|
showlogs: true
|
||||||
|
args: ["foo"]
|
||||||
|
- name: bar
|
||||||
|
installed: false
|
||||||
|
chart: incubator/raw
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: test
|
||||||
|
hooks:
|
||||||
|
- events: ["prepare", "preapply", "presync"]
|
||||||
|
command: echo
|
||||||
|
showlogs: true
|
||||||
|
args: ["bar"]
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
selectors: []string{"app=test"},
|
||||||
|
lists: map[exectest.ListKey]string{
|
||||||
|
{Filter: "^foo$", Flags: helmV2ListFlags}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||||
|
foo 4 Fri Nov 1 08:40:07 2019 DEPLOYED raw-3.1.0 3.1.0 default
|
||||||
|
`,
|
||||||
|
{Filter: "^bar$", Flags: helmV2ListFlags}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||||
|
bar 4 Fri Nov 1 08:40:07 2019 DEPLOYED raw-3.1.0 3.1.0 default
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
upgraded: []exectest.Release{
|
||||||
|
{Name: "foo"},
|
||||||
|
},
|
||||||
|
diffs: map[exectest.DiffKey]error{
|
||||||
|
{Name: "foo", Chart: "incubator/raw", Flags: "--kube-contextdefault--namespacedefault--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||||
|
},
|
||||||
|
error: "",
|
||||||
|
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||||
|
concurrency: 1,
|
||||||
|
logLevel: "info",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("hooks are not run on alreadyd uninstalled release", func(t *testing.T) {
|
||||||
|
check(t, testcase{
|
||||||
|
files: map[string]string{
|
||||||
|
"/path/to/helmfile.yaml": `
|
||||||
|
releases:
|
||||||
|
- name: foo
|
||||||
|
chart: incubator/raw
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: test
|
||||||
|
hooks:
|
||||||
|
- events: ["prepare", "preapply", "presync"]
|
||||||
|
command: echo
|
||||||
|
showlogs: true
|
||||||
|
args: ["foo"]
|
||||||
|
- name: bar
|
||||||
|
installed: false
|
||||||
|
chart: incubator/raw
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: test
|
||||||
|
hooks:
|
||||||
|
- events: ["prepare", "preapply", "presync"]
|
||||||
|
command: echo
|
||||||
|
showlogs: true
|
||||||
|
args: ["bar"]
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
selectors: []string{"app=test"},
|
||||||
|
lists: map[exectest.ListKey]string{
|
||||||
|
{Filter: "^foo$", Flags: helmV2ListFlags}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||||
|
foo 4 Fri Nov 1 08:40:07 2019 DEPLOYED raw-3.1.0 3.1.0 default
|
||||||
|
`,
|
||||||
|
{Filter: "^bar$", Flags: helmV2ListFlags}: ``,
|
||||||
|
},
|
||||||
|
upgraded: []exectest.Release{
|
||||||
|
{Name: "foo"},
|
||||||
|
},
|
||||||
|
diffs: map[exectest.DiffKey]error{
|
||||||
|
{Name: "foo", Chart: "incubator/raw", Flags: "--kube-contextdefault--namespacedefault--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||||
|
},
|
||||||
|
error: "",
|
||||||
|
// as we check for log output, set concurrency to 1 to avoid non-deterministic test result
|
||||||
|
concurrency: 1,
|
||||||
|
logLevel: "info",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -137,7 +137,7 @@ func TestApply_2(t *testing.T) {
|
||||||
}
|
}
|
||||||
for flagIdx := range wantUpgrades[relIdx].Flags {
|
for flagIdx := range wantUpgrades[relIdx].Flags {
|
||||||
if wantUpgrades[relIdx].Flags[flagIdx] != helm.Releases[relIdx].Flags[flagIdx] {
|
if wantUpgrades[relIdx].Flags[flagIdx] != helm.Releases[relIdx].Flags[flagIdx] {
|
||||||
t.Errorf("releaes[%d].flags[%d]: got %v, want %v", relIdx, flagIdx, helm.Releases[relIdx].Flags[flagIdx], wantUpgrades[relIdx].Flags[flagIdx])
|
t.Errorf("releases[%d].flags[%d]: got %v, want %v", relIdx, flagIdx, helm.Releases[relIdx].Flags[flagIdx], wantUpgrades[relIdx].Flags[flagIdx])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) 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) 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) 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
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
processing file "helmfile.yaml" in directory "."
|
||||||
|
first-pass rendering starting for "helmfile.yaml.part.0": inherited=&{default map[] map[]}, overrode=<nil>
|
||||||
|
first-pass uses: &{default map[] map[]}
|
||||||
|
first-pass rendering output of "helmfile.yaml.part.0":
|
||||||
|
0:
|
||||||
|
1: releases:
|
||||||
|
2: - name: foo
|
||||||
|
3: chart: incubator/raw
|
||||||
|
4: namespace: default
|
||||||
|
5: labels:
|
||||||
|
6: app: test
|
||||||
|
7: hooks:
|
||||||
|
8: - events: ["preapply"]
|
||||||
|
9: command: echo
|
||||||
|
10: showlogs: true
|
||||||
|
11: args: ["foo"]
|
||||||
|
12:
|
||||||
|
|
||||||
|
first-pass produced: &{default map[] map[]}
|
||||||
|
first-pass rendering result of "helmfile.yaml.part.0": {default map[] map[]}
|
||||||
|
vals:
|
||||||
|
map[]
|
||||||
|
defaultVals:[]
|
||||||
|
second-pass rendering result of "helmfile.yaml.part.0":
|
||||||
|
0:
|
||||||
|
1: releases:
|
||||||
|
2: - name: foo
|
||||||
|
3: chart: incubator/raw
|
||||||
|
4: namespace: default
|
||||||
|
5: labels:
|
||||||
|
6: app: test
|
||||||
|
7: hooks:
|
||||||
|
8: - events: ["preapply"]
|
||||||
|
9: command: echo
|
||||||
|
10: showlogs: true
|
||||||
|
11: args: ["foo"]
|
||||||
|
12:
|
||||||
|
|
||||||
|
merged environment: &{default map[] map[]}
|
||||||
|
1 release(s) matching name=foo found in helmfile.yaml
|
||||||
|
|
||||||
|
Affected releases are:
|
||||||
|
foo (incubator/raw) UPDATED
|
||||||
|
Releases with preapply hooks:
|
||||||
|
foo (incubator/raw)
|
||||||
|
|
||||||
|
Running preapply hook for foo:
|
||||||
|
hook[echo]: stateFilePath=helmfile.yaml, basePath=.
|
||||||
|
hook[echo]: triggered by event "preapply"
|
||||||
|
|
||||||
|
echo:XlBWj> foo
|
||||||
|
hook[echo]: foo
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
hook[preapply] logs | foo
|
||||||
|
hook[preapply] logs |
|
||||||
|
processing 1 groups of releases in this order:
|
||||||
|
GROUP RELEASES
|
||||||
|
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}
|
||||||
|
|
||||||
|
UPDATED RELEASES:
|
||||||
|
NAME CHART VERSION
|
||||||
|
foo incubator/raw
|
||||||
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
hook[prepare] logs | foo
|
||||||
|
hook[prepare] logs |
|
||||||
|
|
||||||
|
hook[preapply] logs | foo
|
||||||
|
hook[preapply] logs |
|
||||||
|
|
||||||
|
hook[presync] logs | foo
|
||||||
|
hook[presync] logs |
|
||||||
|
|
||||||
|
UPDATED RELEASES:
|
||||||
|
NAME CHART VERSION
|
||||||
|
foo incubator/raw
|
||||||
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
hook[presync] logs | foo
|
||||||
|
hook[presync] logs |
|
||||||
|
|
||||||
|
UPDATED RELEASES:
|
||||||
|
NAME CHART VERSION
|
||||||
|
foo incubator/raw
|
||||||
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
hook[preapply] logs | foo
|
||||||
|
hook[preapply] logs |
|
||||||
|
|
||||||
|
UPDATED RELEASES:
|
||||||
|
NAME CHART VERSION
|
||||||
|
foo incubator/raw
|
||||||
|
|
||||||
14
pkg/app/testdata/testapply_hooks/hooks_are_not_run_on_alreadyd_uninstalled_release/log
vendored
Normal file
14
pkg/app/testdata/testapply_hooks/hooks_are_not_run_on_alreadyd_uninstalled_release/log
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
hook[prepare] logs | foo
|
||||||
|
hook[prepare] logs |
|
||||||
|
|
||||||
|
hook[preapply] logs | foo
|
||||||
|
hook[preapply] logs |
|
||||||
|
|
||||||
|
hook[presync] logs | foo
|
||||||
|
hook[presync] logs |
|
||||||
|
|
||||||
|
UPDATED RELEASES:
|
||||||
|
NAME CHART VERSION
|
||||||
|
foo incubator/raw 3.1.0
|
||||||
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
hook[prepare] logs | foo
|
||||||
|
hook[prepare] logs |
|
||||||
|
|
||||||
|
hook[preapply] logs | foo
|
||||||
|
hook[preapply] logs |
|
||||||
|
|
||||||
|
hook[presync] logs | foo
|
||||||
|
hook[presync] logs |
|
||||||
|
|
||||||
|
UPDATED RELEASES:
|
||||||
|
NAME CHART VERSION
|
||||||
|
foo incubator/raw
|
||||||
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
|
||||||
|
hook[prepare] logs | foo
|
||||||
|
hook[prepare] logs |
|
||||||
|
|
||||||
|
hook[prepare] logs | bar
|
||||||
|
hook[prepare] logs |
|
||||||
|
|
||||||
|
hook[preapply] logs | foo
|
||||||
|
hook[preapply] logs |
|
||||||
|
|
||||||
|
hook[preapply] logs | bar
|
||||||
|
hook[preapply] logs |
|
||||||
|
|
||||||
|
hook[presync] logs | foo
|
||||||
|
hook[presync] logs |
|
||||||
|
|
||||||
|
hook[presync] logs | bar
|
||||||
|
hook[presync] logs |
|
||||||
|
|
||||||
|
UPDATED RELEASES:
|
||||||
|
NAME CHART VERSION
|
||||||
|
foo incubator/raw
|
||||||
|
bar incubator/raw
|
||||||
|
|
||||||
24
pkg/app/testdata/testapply_hooks/hooks_are_run_on_to-be-uninstalled_release/log
vendored
Normal file
24
pkg/app/testdata/testapply_hooks/hooks_are_run_on_to-be-uninstalled_release/log
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
|
||||||
|
hook[prepare] logs | foo
|
||||||
|
hook[prepare] logs |
|
||||||
|
|
||||||
|
hook[preapply] logs | bar
|
||||||
|
hook[preapply] logs |
|
||||||
|
|
||||||
|
hook[presync] logs | bar
|
||||||
|
hook[presync] logs |
|
||||||
|
|
||||||
|
hook[preapply] logs | foo
|
||||||
|
hook[preapply] logs |
|
||||||
|
|
||||||
|
hook[presync] logs | foo
|
||||||
|
hook[presync] logs |
|
||||||
|
|
||||||
|
UPDATED RELEASES:
|
||||||
|
NAME CHART VERSION
|
||||||
|
foo incubator/raw 3.1.0
|
||||||
|
|
||||||
|
|
||||||
|
DELETED RELEASES:
|
||||||
|
NAME
|
||||||
|
bar
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
hook[prepare] logs | foo
|
||||||
|
hook[prepare] logs |
|
||||||
|
|
||||||
|
hook[cleanup] logs | foo
|
||||||
|
hook[cleanup] logs |
|
||||||
|
|
@ -161,7 +161,7 @@ func (helm *Helm) List(context helmexec.HelmContext, filter string, flags ...str
|
||||||
for k := range helm.Lists {
|
for k := range helm.Lists {
|
||||||
keys = append(keys, k.String())
|
keys = append(keys, k.String())
|
||||||
}
|
}
|
||||||
return "", fmt.Errorf("unexpected list key: %v in %v", key, strings.Join(keys, ", "))
|
return "", fmt.Errorf("unexpected list key: %v not found in %v", key, strings.Join(keys, ", "))
|
||||||
}
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2251,6 +2251,10 @@ func (st *HelmState) triggerPostsyncEvent(r *ReleaseSpec, evtErr error, helmfile
|
||||||
return st.triggerReleaseEvent("postsync", evtErr, r, helmfileCommand)
|
return st.triggerReleaseEvent("postsync", evtErr, r, helmfileCommand)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (st *HelmState) TriggerPreapplyEvent(r *ReleaseSpec, helmfileCommand string) (bool, error) {
|
||||||
|
return st.triggerReleaseEvent("preapply", nil, r, helmfileCommand)
|
||||||
|
}
|
||||||
|
|
||||||
func (st *HelmState) triggerReleaseEvent(evt string, evtErr error, r *ReleaseSpec, helmfileCmd string) (bool, error) {
|
func (st *HelmState) triggerReleaseEvent(evt string, evtErr error, r *ReleaseSpec, helmfileCmd string) (bool, error) {
|
||||||
bus := &event.Bus{
|
bus := &event.Bus{
|
||||||
Hooks: r.Hooks,
|
Hooks: r.Hooks,
|
||||||
|
|
@ -2268,6 +2272,7 @@ func (st *HelmState) triggerReleaseEvent(evt string, evtErr error, r *ReleaseSpe
|
||||||
"Release": r,
|
"Release": r,
|
||||||
"HelmfileCommand": helmfileCmd,
|
"HelmfileCommand": helmfileCmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
return bus.Trigger(evt, evtErr, data)
|
return bus.Trigger(evt, evtErr, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue