Port the `needs` fix for `helmfile apply` to `sync`, and make `template` DAG-aware (#940)
This ports the fix for `helfmile apply` to `sync`, so that specifying `--selector` doesn't break `helmfile sync`. Also make `helmfile template` DAG-aware, so that the manifests are rendered in the order of dependency. Ref #919
This commit is contained in:
parent
35adb8ae22
commit
ed7a6d9051
159
pkg/app/app.go
159
pkg/app/app.go
|
|
@ -128,8 +128,8 @@ func (a *App) Diff(c DiffConfigProvider) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) Template(c TemplateConfigProvider) error {
|
func (a *App) Template(c TemplateConfigProvider) error {
|
||||||
return a.ForEachStateFiltered(func(run *Run) []error {
|
return a.ForEachState(func(run *Run) (bool, []error) {
|
||||||
return run.Template(c)
|
return a.template(run, c)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,8 +140,8 @@ func (a *App) Lint(c LintConfigProvider) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) Sync(c SyncConfigProvider) error {
|
func (a *App) Sync(c SyncConfigProvider) error {
|
||||||
return a.ForEachStateFiltered(func(run *Run) []error {
|
return a.ForEachState(func(run *Run) (bool, []error) {
|
||||||
return run.Sync(c)
|
return a.sync(run, c)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -901,6 +901,157 @@ Do you really want to delete?
|
||||||
return any, errs
|
return any, errs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) sync(r *Run, c SyncConfigProvider) (bool, []error) {
|
||||||
|
st := r.state
|
||||||
|
helm := r.helm
|
||||||
|
ctx := r.ctx
|
||||||
|
|
||||||
|
affectedReleases := state.AffectedReleases{}
|
||||||
|
if !c.SkipDeps() {
|
||||||
|
if errs := ctx.SyncReposOnce(st, helm); errs != nil && len(errs) > 0 {
|
||||||
|
return false, errs
|
||||||
|
}
|
||||||
|
if errs := st.BuildDeps(helm); errs != nil && len(errs) > 0 {
|
||||||
|
return false, errs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if errs := st.PrepareReleases(helm, "sync"); errs != nil && len(errs) > 0 {
|
||||||
|
return false, errs
|
||||||
|
}
|
||||||
|
|
||||||
|
var syncedReleases []state.ReleaseSpec
|
||||||
|
|
||||||
|
if len(st.Selectors) > 0 {
|
||||||
|
var err error
|
||||||
|
syncedReleases, err = st.GetFilteredReleases()
|
||||||
|
if err != nil {
|
||||||
|
return false, []error{err}
|
||||||
|
}
|
||||||
|
if len(syncedReleases) == 0 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
syncedReleases = st.Releases
|
||||||
|
}
|
||||||
|
|
||||||
|
releasesToBeSynced := map[string]state.ReleaseSpec{}
|
||||||
|
for _, r := range syncedReleases {
|
||||||
|
id := state.ReleaseToID(&r)
|
||||||
|
releasesToBeSynced[id] = r
|
||||||
|
}
|
||||||
|
|
||||||
|
names := make([]string, len(syncedReleases))
|
||||||
|
for i, r := range syncedReleases {
|
||||||
|
names[i] = fmt.Sprintf(" %s (%s)", r.Name, r.Chart)
|
||||||
|
}
|
||||||
|
|
||||||
|
var errs []error
|
||||||
|
var any bool
|
||||||
|
|
||||||
|
r.helm.SetExtraArgs(argparser.GetArgs(c.Args(), r.state)...)
|
||||||
|
|
||||||
|
if len(releasesToBeSynced) > 0 {
|
||||||
|
synced, syncErrs := withDAG(st, helm, a.Logger, false, a.Wrap(func(subst *state.HelmState, helm helmexec.Interface) []error {
|
||||||
|
var rs []state.ReleaseSpec
|
||||||
|
|
||||||
|
for _, r := range subst.Releases {
|
||||||
|
if _, ok := releasesToBeSynced[state.ReleaseToID(&r)]; ok {
|
||||||
|
rs = append(rs, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subst.Releases = rs
|
||||||
|
|
||||||
|
opts := &state.SyncOpts{
|
||||||
|
Set: c.Set(),
|
||||||
|
}
|
||||||
|
return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), opts)
|
||||||
|
}))
|
||||||
|
|
||||||
|
any = any || synced
|
||||||
|
|
||||||
|
if syncErrs != nil && len(syncErrs) > 0 {
|
||||||
|
errs = append(errs, syncErrs...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
affectedReleases.DisplayAffectedReleases(c.Logger())
|
||||||
|
return any, errs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *App) template(r *Run, c TemplateConfigProvider) (bool, []error) {
|
||||||
|
st := r.state
|
||||||
|
helm := r.helm
|
||||||
|
ctx := r.ctx
|
||||||
|
|
||||||
|
if !c.SkipDeps() {
|
||||||
|
if errs := ctx.SyncReposOnce(st, helm); errs != nil && len(errs) > 0 {
|
||||||
|
return false, errs
|
||||||
|
}
|
||||||
|
if errs := st.BuildDeps(helm); errs != nil && len(errs) > 0 {
|
||||||
|
return false, errs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if errs := st.PrepareReleases(helm, "template"); errs != nil && len(errs) > 0 {
|
||||||
|
return false, errs
|
||||||
|
}
|
||||||
|
|
||||||
|
var templatedReleases []state.ReleaseSpec
|
||||||
|
|
||||||
|
if len(st.Selectors) > 0 {
|
||||||
|
var err error
|
||||||
|
templatedReleases, err = st.GetFilteredReleases()
|
||||||
|
if err != nil {
|
||||||
|
return false, []error{err}
|
||||||
|
}
|
||||||
|
if len(templatedReleases) == 0 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
templatedReleases = st.Releases
|
||||||
|
}
|
||||||
|
|
||||||
|
releasesToBeTemplated := map[string]state.ReleaseSpec{}
|
||||||
|
for _, r := range templatedReleases {
|
||||||
|
id := state.ReleaseToID(&r)
|
||||||
|
releasesToBeTemplated[id] = r
|
||||||
|
}
|
||||||
|
|
||||||
|
names := make([]string, len(templatedReleases))
|
||||||
|
for i, r := range templatedReleases {
|
||||||
|
names[i] = fmt.Sprintf(" %s (%s)", r.Name, r.Chart)
|
||||||
|
}
|
||||||
|
|
||||||
|
var errs []error
|
||||||
|
var any bool
|
||||||
|
|
||||||
|
if len(releasesToBeTemplated) > 0 {
|
||||||
|
synced, templateErrs := withDAG(st, helm, a.Logger, false, a.Wrap(func(subst *state.HelmState, helm helmexec.Interface) []error {
|
||||||
|
var rs []state.ReleaseSpec
|
||||||
|
|
||||||
|
for _, r := range subst.Releases {
|
||||||
|
if _, ok := releasesToBeTemplated[state.ReleaseToID(&r)]; ok {
|
||||||
|
rs = append(rs, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subst.Releases = rs
|
||||||
|
|
||||||
|
args := argparser.GetArgs(c.Args(), st)
|
||||||
|
opts := &state.TemplateOpts{
|
||||||
|
Set: c.Set(),
|
||||||
|
}
|
||||||
|
return subst.TemplateReleases(helm, c.OutputDir(), c.Values(), args, c.Concurrency(), opts)
|
||||||
|
}))
|
||||||
|
|
||||||
|
any = any || synced
|
||||||
|
|
||||||
|
if templateErrs != nil && len(templateErrs) > 0 {
|
||||||
|
errs = append(errs, templateErrs...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return any, errs
|
||||||
|
}
|
||||||
|
|
||||||
func fileExistsAt(path string) bool {
|
func fileExistsAt(path string) bool {
|
||||||
fileInfo, err := os.Stat(path)
|
fileInfo, err := os.Stat(path)
|
||||||
return err == nil && fileInfo.Mode().IsRegular()
|
return err == nil && fileInfo.Mode().IsRegular()
|
||||||
|
|
|
||||||
|
|
@ -89,58 +89,6 @@ func (r *Run) Diff(c DiffConfigProvider) []error {
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Run) Sync(c SyncConfigProvider) []error {
|
|
||||||
st := r.state
|
|
||||||
helm := r.helm
|
|
||||||
ctx := r.ctx
|
|
||||||
|
|
||||||
affectedReleases := state.AffectedReleases{}
|
|
||||||
if !c.SkipDeps() {
|
|
||||||
if errs := ctx.SyncReposOnce(st, helm); errs != nil && len(errs) > 0 {
|
|
||||||
return errs
|
|
||||||
}
|
|
||||||
if errs := st.BuildDeps(helm); errs != nil && len(errs) > 0 {
|
|
||||||
return errs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if errs := st.PrepareReleases(helm, "sync"); errs != nil && len(errs) > 0 {
|
|
||||||
return errs
|
|
||||||
}
|
|
||||||
|
|
||||||
r.helm.SetExtraArgs(argparser.GetArgs(c.Args(), r.state)...)
|
|
||||||
|
|
||||||
opts := &state.SyncOpts{
|
|
||||||
Set: c.Set(),
|
|
||||||
}
|
|
||||||
errs := st.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), opts)
|
|
||||||
affectedReleases.DisplayAffectedReleases(c.Logger())
|
|
||||||
return errs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Run) Template(c TemplateConfigProvider) []error {
|
|
||||||
st := r.state
|
|
||||||
helm := r.helm
|
|
||||||
ctx := r.ctx
|
|
||||||
|
|
||||||
if !c.SkipDeps() {
|
|
||||||
if errs := ctx.SyncReposOnce(st, helm); errs != nil && len(errs) > 0 {
|
|
||||||
return errs
|
|
||||||
}
|
|
||||||
if errs := st.BuildDeps(helm); errs != nil && len(errs) > 0 {
|
|
||||||
return errs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if errs := st.PrepareReleases(helm, "template"); errs != nil && len(errs) > 0 {
|
|
||||||
return errs
|
|
||||||
}
|
|
||||||
|
|
||||||
args := argparser.GetArgs(c.Args(), st)
|
|
||||||
opts := &state.TemplateOpts{
|
|
||||||
Set: c.Set(),
|
|
||||||
}
|
|
||||||
return st.TemplateReleases(helm, c.OutputDir(), c.Values(), args, c.Concurrency(), opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Run) Test(c TestConfigProvider) []error {
|
func (r *Run) Test(c TestConfigProvider) []error {
|
||||||
cleanup := c.Cleanup()
|
cleanup := c.Cleanup()
|
||||||
timeout := c.Timeout()
|
timeout := c.Timeout()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue