diff --git a/pkg/app/app.go b/pkg/app/app.go index fd947645..1e7c5887 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -2354,10 +2354,11 @@ func (a *App) withNeeds(r *Run, c DAGConfig, includeDisabled bool, f func(*state if len(toRender) > 0 { // toRender already contains the direct and transitive needs depending on the DAG options. - // That's why we don't pass in `IncludeNeeds: c.IncludeNeeds(), IncludeTransitiveNeeds: c.IncludeTransitiveNeeds()` here. + // That's why we don't pass in `IncludeNeeds` or `IncludeTransitiveNeeds` here. // Otherwise, in case include-needs=true, it will include the needs of needs, which results in unexpectedly introducing transitive needs, // even if include-transitive-needs=true is unspecified. - if _, errs := withDAG(st, r.helm, a.Logger, state.PlanOptions{SelectedReleases: toRender, Reverse: false, SkipNeeds: c.SkipNeeds(), IncludeNeeds: includeNeeds}, a.WrapWithoutSelector(func(subst *state.HelmState, helm helmexec.Interface) []error { + // We also set SkipNeeds=true because toRender already contains all the needs we want to process. + if _, errs := withDAG(st, r.helm, a.Logger, state.PlanOptions{SelectedReleases: toRender, Reverse: false, SkipNeeds: true}, a.WrapWithoutSelector(func(subst *state.HelmState, helm helmexec.Interface) []error { rels = append(rels, subst.Releases...) return nil })); len(errs) > 0 { diff --git a/pkg/app/testdata/testapply_2/include-transitive-needs=true/log b/pkg/app/testdata/testapply_2/include-transitive-needs=true/log index d00bbb0d..df204aec 100644 --- a/pkg/app/testdata/testapply_2/include-transitive-needs=true/log +++ b/pkg/app/testdata/testapply_2/include-transitive-needs=true/log @@ -29,15 +29,11 @@ Affected releases are: serviceB (my/chart) UPDATED serviceC (my/chart) UPDATED -invoking preapply hooks for 3 groups of releases in this order: +invoking preapply hooks for 1 groups of releases in this order: GROUP RELEASES 1 default//serviceA -2 default//serviceB -3 default//serviceC -invoking preapply hooks for releases in group 1/3: default//serviceA -invoking preapply hooks for releases in group 2/3: default//serviceB -invoking preapply hooks for releases in group 3/3: default//serviceC +invoking preapply hooks for releases in group 1/1: default//serviceA processing 3 groups of releases in this order: GROUP RELEASES 1 default//serviceC diff --git a/pkg/app/testdata/testapply_2/skip-needs=false_include-needs=true/log b/pkg/app/testdata/testapply_2/skip-needs=false_include-needs=true/log index 62337d68..0b0bad62 100644 --- a/pkg/app/testdata/testapply_2/skip-needs=false_include-needs=true/log +++ b/pkg/app/testdata/testapply_2/skip-needs=false_include-needs=true/log @@ -33,28 +33,23 @@ Affected releases are: kubernetes-external-secrets (incubator/raw) UPDATED my-release (incubator/raw) UPDATED -invoking preapply hooks for 3 groups of releases in this order: +invoking preapply hooks for 2 groups of releases in this order: GROUP RELEASES 1 default/default/my-release 2 default/default/external-secrets -3 default/kube-system/kubernetes-external-secrets -invoking preapply hooks for releases in group 1/3: default/default/my-release -invoking preapply hooks for releases in group 2/3: default/default/external-secrets -invoking preapply hooks for releases in group 3/3: default/kube-system/kubernetes-external-secrets -processing 3 groups of releases in this order: +invoking preapply hooks for releases in group 1/2: default/default/my-release +invoking preapply hooks for releases in group 2/2: default/default/external-secrets +processing 2 groups of releases in this order: GROUP RELEASES -1 default/kube-system/kubernetes-external-secrets -2 default/default/external-secrets -3 default/default/my-release +1 default/default/external-secrets +2 default/default/my-release -processing releases in group 1/3: default/kube-system/kubernetes-external-secrets -processing releases in group 2/3: default/default/external-secrets -processing releases in group 3/3: default/default/my-release +processing releases in group 1/2: default/default/external-secrets +processing releases in group 2/2: default/default/my-release UPDATED RELEASES: -NAME NAMESPACE CHART VERSION DURATION -kubernetes-external-secrets kube-system incubator/raw 3.1.0 0s -external-secrets default incubator/raw 3.1.0 0s -my-release default incubator/raw 3.1.0 0s +NAME NAMESPACE CHART VERSION DURATION +external-secrets default incubator/raw 3.1.0 0s +my-release default incubator/raw 3.1.0 0s diff --git a/pkg/app/testdata/testapply_2/skip-needs=false_include-needs=true_but_no_diff_on_needed_release/log b/pkg/app/testdata/testapply_2/skip-needs=false_include-needs=true_but_no_diff_on_needed_release/log index 77069b44..6af67687 100644 --- a/pkg/app/testdata/testapply_2/skip-needs=false_include-needs=true_but_no_diff_on_needed_release/log +++ b/pkg/app/testdata/testapply_2/skip-needs=false_include-needs=true_but_no_diff_on_needed_release/log @@ -32,15 +32,13 @@ Affected releases are: external-secrets (incubator/raw) UPDATED my-release (incubator/raw) UPDATED -invoking preapply hooks for 3 groups of releases in this order: +invoking preapply hooks for 2 groups of releases in this order: GROUP RELEASES 1 default/default/my-release 2 default/default/external-secrets -3 default/kube-system/kubernetes-external-secrets -invoking preapply hooks for releases in group 1/3: default/default/my-release -invoking preapply hooks for releases in group 2/3: default/default/external-secrets -invoking preapply hooks for releases in group 3/3: default/kube-system/kubernetes-external-secrets +invoking preapply hooks for releases in group 1/2: default/default/my-release +invoking preapply hooks for releases in group 2/2: default/default/external-secrets processing 2 groups of releases in this order: GROUP RELEASES 1 default/default/external-secrets diff --git a/pkg/app/testdata/testapply_2/skip-needs=false_include-needs=true_with_installed_but_disabled_release/log b/pkg/app/testdata/testapply_2/skip-needs=false_include-needs=true_with_installed_but_disabled_release/log index 1a00d70c..f00d2c4f 100644 --- a/pkg/app/testdata/testapply_2/skip-needs=false_include-needs=true_with_installed_but_disabled_release/log +++ b/pkg/app/testdata/testapply_2/skip-needs=false_include-needs=true_with_installed_but_disabled_release/log @@ -36,20 +36,20 @@ Affected releases are: kubernetes-external-secrets (incubator/raw) DELETED my-release (incubator/raw) UPDATED -invoking preapply hooks for 3 groups of releases in this order: +invoking preapply hooks for 2 groups of releases in this order: GROUP RELEASES 1 default/default/my-release 2 default/default/external-secrets -3 default/kube-system/kubernetes-external-secrets -invoking preapply hooks for releases in group 1/3: default/default/my-release -invoking preapply hooks for releases in group 2/3: default/default/external-secrets -invoking preapply hooks for releases in group 3/3: default/kube-system/kubernetes-external-secrets -processing 1 groups of releases in this order: +invoking preapply hooks for releases in group 1/2: default/default/my-release +invoking preapply hooks for releases in group 2/2: default/default/external-secrets +processing 2 groups of releases in this order: GROUP RELEASES -1 default/kube-system/kubernetes-external-secrets +1 default/default/my-release +2 default/default/external-secrets -processing releases in group 1/1: default/kube-system/kubernetes-external-secrets +processing releases in group 1/2: default/default/my-release +processing releases in group 2/2: default/default/external-secrets processing 2 groups of releases in this order: GROUP RELEASES 1 default/default/external-secrets @@ -64,8 +64,3 @@ NAME NAMESPACE CHART VERSION DURATION external-secrets default incubator/raw 3.1.0 0s my-release default incubator/raw 3.1.0 0s - -DELETED RELEASES: -NAME NAMESPACE DURATION -kubernetes-external-secrets kube-system 0s - diff --git a/pkg/app/testdata/testapply_2/skip-needs=false_include-needs=true_with_not_installed_and_disabled_release/log b/pkg/app/testdata/testapply_2/skip-needs=false_include-needs=true_with_not_installed_and_disabled_release/log index 58c602da..d0d92835 100644 --- a/pkg/app/testdata/testapply_2/skip-needs=false_include-needs=true_with_not_installed_and_disabled_release/log +++ b/pkg/app/testdata/testapply_2/skip-needs=false_include-needs=true_with_not_installed_and_disabled_release/log @@ -35,15 +35,13 @@ Affected releases are: external-secrets (incubator/raw) UPDATED my-release (incubator/raw) UPDATED -invoking preapply hooks for 3 groups of releases in this order: +invoking preapply hooks for 2 groups of releases in this order: GROUP RELEASES 1 default/default/my-release 2 default/default/external-secrets -3 default/kube-system/kubernetes-external-secrets -invoking preapply hooks for releases in group 1/3: default/default/my-release -invoking preapply hooks for releases in group 2/3: default/default/external-secrets -invoking preapply hooks for releases in group 3/3: default/kube-system/kubernetes-external-secrets +invoking preapply hooks for releases in group 1/2: default/default/my-release +invoking preapply hooks for releases in group 2/2: default/default/external-secrets processing 2 groups of releases in this order: GROUP RELEASES 1 default/default/external-secrets diff --git a/pkg/app/testdata/testapply_2/skip-needs=true_with_no_diff_on_a_release/log b/pkg/app/testdata/testapply_2/skip-needs=true_with_no_diff_on_a_release/log index 17ac4bf2..0fb7610c 100644 --- a/pkg/app/testdata/testapply_2/skip-needs=true_with_no_diff_on_a_release/log +++ b/pkg/app/testdata/testapply_2/skip-needs=true_with_no_diff_on_a_release/log @@ -38,11 +38,13 @@ GROUP RELEASES invoking preapply hooks for releases in group 1/2: default/default/my-release invoking preapply hooks for releases in group 2/2: default/default/external-secrets -processing 1 groups of releases in this order: +processing 2 groups of releases in this order: GROUP RELEASES 1 default/default/external-secrets +2 default/default/my-release -processing releases in group 1/1: default/default/external-secrets +processing releases in group 1/2: default/default/external-secrets +processing releases in group 2/2: default/default/my-release UPDATED RELEASES: NAME NAMESPACE CHART VERSION DURATION diff --git a/pkg/app/testdata/testapply_3/skip-needs=false_include-needs=true/log b/pkg/app/testdata/testapply_3/skip-needs=false_include-needs=true/log index 3706c59d..dc06cef0 100644 --- a/pkg/app/testdata/testapply_3/skip-needs=false_include-needs=true/log +++ b/pkg/app/testdata/testapply_3/skip-needs=false_include-needs=true/log @@ -33,28 +33,23 @@ Affected releases are: kubernetes-external-secrets (incubator/raw) UPDATED my-release (incubator/raw) UPDATED -invoking preapply hooks for 3 groups of releases in this order: +invoking preapply hooks for 2 groups of releases in this order: GROUP RELEASES 1 default/my-release 2 default/external-secrets -3 kube-system/kubernetes-external-secrets -invoking preapply hooks for releases in group 1/3: default/my-release -invoking preapply hooks for releases in group 2/3: default/external-secrets -invoking preapply hooks for releases in group 3/3: kube-system/kubernetes-external-secrets -processing 3 groups of releases in this order: +invoking preapply hooks for releases in group 1/2: default/my-release +invoking preapply hooks for releases in group 2/2: default/external-secrets +processing 2 groups of releases in this order: GROUP RELEASES -1 kube-system/kubernetes-external-secrets -2 default/external-secrets -3 default/my-release +1 default/external-secrets +2 default/my-release -processing releases in group 1/3: kube-system/kubernetes-external-secrets -processing releases in group 2/3: default/external-secrets -processing releases in group 3/3: default/my-release +processing releases in group 1/2: default/external-secrets +processing releases in group 2/2: default/my-release UPDATED RELEASES: -NAME NAMESPACE CHART VERSION DURATION -kubernetes-external-secrets kube-system incubator/raw 3.1.0 0s -external-secrets default incubator/raw 3.1.0 0s -my-release default incubator/raw 3.1.0 0s +NAME NAMESPACE CHART VERSION DURATION +external-secrets default incubator/raw 3.1.0 0s +my-release default incubator/raw 3.1.0 0s diff --git a/pkg/app/testdata/testapply_3/skip-needs=false_include-needs=true_but_no_diff_on_needed_release/log b/pkg/app/testdata/testapply_3/skip-needs=false_include-needs=true_but_no_diff_on_needed_release/log index 7f9b3818..a01ac5c9 100644 --- a/pkg/app/testdata/testapply_3/skip-needs=false_include-needs=true_but_no_diff_on_needed_release/log +++ b/pkg/app/testdata/testapply_3/skip-needs=false_include-needs=true_but_no_diff_on_needed_release/log @@ -32,15 +32,13 @@ Affected releases are: external-secrets (incubator/raw) UPDATED my-release (incubator/raw) UPDATED -invoking preapply hooks for 3 groups of releases in this order: +invoking preapply hooks for 2 groups of releases in this order: GROUP RELEASES 1 default/my-release 2 default/external-secrets -3 kube-system/kubernetes-external-secrets -invoking preapply hooks for releases in group 1/3: default/my-release -invoking preapply hooks for releases in group 2/3: default/external-secrets -invoking preapply hooks for releases in group 3/3: kube-system/kubernetes-external-secrets +invoking preapply hooks for releases in group 1/2: default/my-release +invoking preapply hooks for releases in group 2/2: default/external-secrets processing 2 groups of releases in this order: GROUP RELEASES 1 default/external-secrets diff --git a/pkg/app/testdata/testapply_3/skip-needs=false_include-needs=true_with_installed_but_disabled_release/log b/pkg/app/testdata/testapply_3/skip-needs=false_include-needs=true_with_installed_but_disabled_release/log index 0144f44a..6bd8dc32 100644 --- a/pkg/app/testdata/testapply_3/skip-needs=false_include-needs=true_with_installed_but_disabled_release/log +++ b/pkg/app/testdata/testapply_3/skip-needs=false_include-needs=true_with_installed_but_disabled_release/log @@ -36,20 +36,20 @@ Affected releases are: kubernetes-external-secrets (incubator/raw) DELETED my-release (incubator/raw) UPDATED -invoking preapply hooks for 3 groups of releases in this order: +invoking preapply hooks for 2 groups of releases in this order: GROUP RELEASES 1 default/my-release 2 default/external-secrets -3 kube-system/kubernetes-external-secrets -invoking preapply hooks for releases in group 1/3: default/my-release -invoking preapply hooks for releases in group 2/3: default/external-secrets -invoking preapply hooks for releases in group 3/3: kube-system/kubernetes-external-secrets -processing 1 groups of releases in this order: +invoking preapply hooks for releases in group 1/2: default/my-release +invoking preapply hooks for releases in group 2/2: default/external-secrets +processing 2 groups of releases in this order: GROUP RELEASES -1 kube-system/kubernetes-external-secrets +1 default/my-release +2 default/external-secrets -processing releases in group 1/1: kube-system/kubernetes-external-secrets +processing releases in group 1/2: default/my-release +processing releases in group 2/2: default/external-secrets processing 2 groups of releases in this order: GROUP RELEASES 1 default/external-secrets @@ -64,8 +64,3 @@ NAME NAMESPACE CHART VERSION DURATION external-secrets default incubator/raw 3.1.0 0s my-release default incubator/raw 3.1.0 0s - -DELETED RELEASES: -NAME NAMESPACE DURATION -kubernetes-external-secrets kube-system 0s - diff --git a/pkg/app/testdata/testapply_3/skip-needs=false_include-needs=true_with_not_installed_and_disabled_release/log b/pkg/app/testdata/testapply_3/skip-needs=false_include-needs=true_with_not_installed_and_disabled_release/log index b67a15d7..a603737b 100644 --- a/pkg/app/testdata/testapply_3/skip-needs=false_include-needs=true_with_not_installed_and_disabled_release/log +++ b/pkg/app/testdata/testapply_3/skip-needs=false_include-needs=true_with_not_installed_and_disabled_release/log @@ -35,15 +35,13 @@ Affected releases are: external-secrets (incubator/raw) UPDATED my-release (incubator/raw) UPDATED -invoking preapply hooks for 3 groups of releases in this order: +invoking preapply hooks for 2 groups of releases in this order: GROUP RELEASES 1 default/my-release 2 default/external-secrets -3 kube-system/kubernetes-external-secrets -invoking preapply hooks for releases in group 1/3: default/my-release -invoking preapply hooks for releases in group 2/3: default/external-secrets -invoking preapply hooks for releases in group 3/3: kube-system/kubernetes-external-secrets +invoking preapply hooks for releases in group 1/2: default/my-release +invoking preapply hooks for releases in group 2/2: default/external-secrets processing 2 groups of releases in this order: GROUP RELEASES 1 default/external-secrets diff --git a/pkg/app/testdata/testapply_3/skip-needs=true_with_no_diff_on_a_release/log b/pkg/app/testdata/testapply_3/skip-needs=true_with_no_diff_on_a_release/log index 47aff850..48848dc8 100644 --- a/pkg/app/testdata/testapply_3/skip-needs=true_with_no_diff_on_a_release/log +++ b/pkg/app/testdata/testapply_3/skip-needs=true_with_no_diff_on_a_release/log @@ -38,11 +38,13 @@ GROUP RELEASES invoking preapply hooks for releases in group 1/2: default/my-release invoking preapply hooks for releases in group 2/2: default/external-secrets -processing 1 groups of releases in this order: +processing 2 groups of releases in this order: GROUP RELEASES 1 default/external-secrets +2 default/my-release -processing releases in group 1/1: default/external-secrets +processing releases in group 1/2: default/external-secrets +processing releases in group 2/2: default/my-release UPDATED RELEASES: NAME NAMESPACE CHART VERSION DURATION diff --git a/pkg/state/state.go b/pkg/state/state.go index b234aa7f..ba227ae8 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -3048,7 +3048,7 @@ func unmarkNeedsAndTransitives(filteredReleases []Release, allReleases []Release func unmarkNeedsDirectOnly(filteredReleases []Release) { directNeeds := collectDirectNeedsOnly(filteredReleases) - unmarkReleases(directNeeds, filteredReleases) + unmarkReleasesByNeedID(directNeeds, filteredReleases) } func collectDirectNeedsOnly(filteredReleases []Release) map[string]struct{} { @@ -3063,6 +3063,18 @@ func collectDirectNeedsOnly(filteredReleases []Release) map[string]struct{} { return directNeeds } +func unmarkReleasesByNeedID(toUnmark map[string]struct{}, releases []Release) { + for needID := range toUnmark { + parts := strings.Split(needID, "/") + needName := parts[len(parts)-1] + for i, r := range releases { + if r.Name == needName { + releases[i].Filtered = false + } + } + } +} + func collectAllNeedsWithTransitives(filteredReleases []Release, allReleases []ReleaseSpec) map[string]struct{} { needsWithTranstives := map[string]struct{}{} for _, r := range filteredReleases { diff --git a/pkg/state/state_run.go b/pkg/state/state_run.go index cdd42d6b..0f0befbf 100644 --- a/pkg/state/state_run.go +++ b/pkg/state/state_run.go @@ -132,6 +132,12 @@ func SortedReleaseGroups(releases []Release, opts PlanOptions) ([][]Release, err func GroupReleasesByDependency(releases []Release, opts PlanOptions) ([][]Release, error) { idToReleases := map[string][]Release{} idToIndex := map[string]int{} + nameToID := map[string]string{} + + for _, r := range releases { + id := ReleaseToID(&r.ReleaseSpec) + nameToID[r.Name] = id + } d := dag.New() for i, r := range releases { @@ -143,7 +149,11 @@ func GroupReleasesByDependency(releases []Release, opts PlanOptions) ([][]Releas var needs []string for i := 0; i < len(r.Needs); i++ { n := r.Needs[i] - needs = append(needs, n) + if fullID, ok := nameToID[n]; ok { + needs = append(needs, fullID) + } else { + needs = append(needs, n) + } } d.Add(id, dag.Dependencies(needs)) } @@ -154,17 +164,22 @@ func GroupReleasesByDependency(releases []Release, opts PlanOptions) ([][]Releas } var selectedReleaseIDs []string + for _, r := range releases { + if !r.Filtered { + id := ReleaseToID(&r.ReleaseSpec) + selectedReleaseIDs = append(selectedReleaseIDs, id) + } + } - for _, r := range opts.SelectedReleases { - release := r - id := ReleaseToID(&release) - selectedReleaseIDs = append(selectedReleaseIDs, id) + skipDepValidation := opts.SkipNeeds + if opts.IncludeNeeds && !opts.IncludeTransitiveNeeds { + skipDepValidation = true } plan, err := d.Plan(dag.SortOptions{ Only: selectedReleaseIDs, - WithDependencies: opts.IncludeNeeds || opts.IncludeTransitiveNeeds, - WithoutDependencies: opts.SkipNeeds, + WithDependencies: false, + WithoutDependencies: skipDepValidation, }) if err != nil { if ude, ok := err.(*dag.UnhandledDependencyError); ok {