mirror of
https://github.com/helmfile/helmfile.git
synced 2026-10-21 02:26:43 +02:00
Issue-1883 fix (#2058)
* Issue-1883 fix Signed-off-by: zhaque44 <haque.zubair@gmail.com> Signed-off-by: yxxhero <aiopsclub@163.com>
This commit is contained in:
+17
-2
@@ -2144,13 +2144,19 @@ func (a *App) withNeeds(r *Run, c DAGConfig, includeDisabled bool, f func(*state
|
||||
includeNeeds = true
|
||||
}
|
||||
|
||||
batches, err := st.PlanReleases(state.PlanOptions{Reverse: false, SelectedReleases: selectedReleases, IncludeNeeds: includeNeeds, IncludeTransitiveNeeds: c.IncludeTransitiveNeeds(), SkipNeeds: c.SkipNeeds()})
|
||||
batches, err := st.PlanReleases(state.PlanOptions{
|
||||
Reverse: false,
|
||||
SelectedReleases: selectedReleases,
|
||||
IncludeNeeds: includeNeeds,
|
||||
IncludeTransitiveNeeds: c.IncludeTransitiveNeeds(),
|
||||
SkipNeeds: c.SkipNeeds(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return false, []error{err}
|
||||
}
|
||||
|
||||
var selectedReleasesWithNeeds []state.ReleaseSpec
|
||||
|
||||
for _, rs := range batches {
|
||||
for _, r := range rs {
|
||||
selectedReleasesWithNeeds = append(selectedReleasesWithNeeds, r.ReleaseSpec)
|
||||
@@ -2185,6 +2191,15 @@ func (a *App) withNeeds(r *Run, c DAGConfig, includeDisabled bool, f func(*state
|
||||
}
|
||||
}
|
||||
|
||||
if c.EnforceNeedsAreInstalled() {
|
||||
for _, r := range toRender {
|
||||
visited := make(map[string]bool)
|
||||
if depErr := st.HasTransitiveDependencyWithInstalledFalse(r, visited); depErr != nil {
|
||||
return false, []error{fmt.Errorf("Release %s has a transitive dependency %s marked as installed=false", depErr.Release.Name, depErr.Dependency.Name)}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if includeDisabled {
|
||||
for _, d := range releasesToUninstall {
|
||||
rels = append(rels, d)
|
||||
|
||||
+55
-45
@@ -2195,11 +2195,12 @@ type configImpl struct {
|
||||
skipSchemaValidation bool
|
||||
skipRefresh bool
|
||||
|
||||
skipNeeds bool
|
||||
includeNeeds bool
|
||||
includeTransitiveNeeds bool
|
||||
skipCharts bool
|
||||
kubeVersion string
|
||||
skipNeeds bool
|
||||
includeNeeds bool
|
||||
includeTransitiveNeeds bool
|
||||
enforceNeedsAreInstalled bool
|
||||
skipCharts bool
|
||||
kubeVersion string
|
||||
}
|
||||
|
||||
func (c configImpl) Selectors() []string {
|
||||
@@ -2306,51 +2307,56 @@ func (c configImpl) ShowOnly() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c configImpl) EnforceNeedsAreInstalled() bool {
|
||||
return c.enforceNeedsAreInstalled
|
||||
}
|
||||
|
||||
type applyConfig struct {
|
||||
args string
|
||||
cascade string
|
||||
values []string
|
||||
|
||||
set []string
|
||||
validate bool
|
||||
skipCleanup bool
|
||||
skipCRDs bool
|
||||
skipDeps bool
|
||||
skipRefresh bool
|
||||
skipNeeds bool
|
||||
includeNeeds bool
|
||||
includeTransitiveNeeds bool
|
||||
includeTests bool
|
||||
suppress []string
|
||||
suppressSecrets bool
|
||||
showSecrets bool
|
||||
noHooks bool
|
||||
suppressDiff bool
|
||||
noColor bool
|
||||
color bool
|
||||
context int
|
||||
diffOutput string
|
||||
concurrency int
|
||||
detailedExitcode bool
|
||||
stripTrailingCR bool
|
||||
interactive bool
|
||||
skipDiffOnInstall bool
|
||||
syncArgs string
|
||||
diffArgs string
|
||||
logger *zap.SugaredLogger
|
||||
wait bool
|
||||
waitRetries int
|
||||
waitForJobs bool
|
||||
reuseValues bool
|
||||
postRenderer string
|
||||
postRendererArgs []string
|
||||
skipSchemaValidation bool
|
||||
kubeVersion string
|
||||
suppressOutputLineRegex []string
|
||||
showOnly []string
|
||||
hideNotes bool
|
||||
takeOwnership bool
|
||||
syncReleaseLabels bool
|
||||
set []string
|
||||
validate bool
|
||||
skipCleanup bool
|
||||
skipCRDs bool
|
||||
skipDeps bool
|
||||
skipRefresh bool
|
||||
skipNeeds bool
|
||||
includeNeeds bool
|
||||
includeTransitiveNeeds bool
|
||||
includeTests bool
|
||||
suppress []string
|
||||
suppressSecrets bool
|
||||
showSecrets bool
|
||||
noHooks bool
|
||||
suppressDiff bool
|
||||
noColor bool
|
||||
color bool
|
||||
context int
|
||||
diffOutput string
|
||||
concurrency int
|
||||
detailedExitcode bool
|
||||
stripTrailingCR bool
|
||||
interactive bool
|
||||
skipDiffOnInstall bool
|
||||
syncArgs string
|
||||
diffArgs string
|
||||
logger *zap.SugaredLogger
|
||||
wait bool
|
||||
waitRetries int
|
||||
waitForJobs bool
|
||||
reuseValues bool
|
||||
postRenderer string
|
||||
postRendererArgs []string
|
||||
skipSchemaValidation bool
|
||||
kubeVersion string
|
||||
suppressOutputLineRegex []string
|
||||
showOnly []string
|
||||
hideNotes bool
|
||||
takeOwnership bool
|
||||
syncReleaseLabels bool
|
||||
enforceNeedsAreInstalled bool
|
||||
|
||||
// template-only options
|
||||
includeCRDs, skipTests bool
|
||||
@@ -2409,6 +2415,10 @@ func (a applyConfig) SkipNeeds() bool {
|
||||
return a.skipNeeds
|
||||
}
|
||||
|
||||
func (a applyConfig) EnforceNeedsAreInstalled() bool {
|
||||
return a.enforceNeedsAreInstalled
|
||||
}
|
||||
|
||||
func (a applyConfig) IncludeNeeds() bool {
|
||||
return a.includeNeeds || a.IncludeTransitiveNeeds()
|
||||
}
|
||||
|
||||
@@ -242,6 +242,7 @@ type DAGConfig interface {
|
||||
SkipNeeds() bool
|
||||
IncludeNeeds() bool
|
||||
IncludeTransitiveNeeds() bool
|
||||
EnforceNeedsAreInstalled() bool
|
||||
}
|
||||
|
||||
type WriteValuesConfigProvider interface {
|
||||
|
||||
+36
-31
@@ -16,37 +16,38 @@ import (
|
||||
)
|
||||
|
||||
type diffConfig struct {
|
||||
args string
|
||||
diffArgs string
|
||||
values []string
|
||||
retainValuesFiles bool
|
||||
set []string
|
||||
validate bool
|
||||
skipCRDs bool
|
||||
skipDeps bool
|
||||
skipRefresh bool
|
||||
includeTests bool
|
||||
skipNeeds bool
|
||||
includeNeeds bool
|
||||
includeTransitiveNeeds bool
|
||||
suppress []string
|
||||
suppressSecrets bool
|
||||
showSecrets bool
|
||||
noHooks bool
|
||||
suppressDiff bool
|
||||
suppressOutputLineRegex []string
|
||||
noColor bool
|
||||
context int
|
||||
diffOutput string
|
||||
concurrency int
|
||||
detailedExitcode bool
|
||||
stripTrailingCR bool
|
||||
interactive bool
|
||||
skipDiffOnInstall bool
|
||||
skipSchemaValidation bool
|
||||
reuseValues bool
|
||||
logger *zap.SugaredLogger
|
||||
takeOwnership bool
|
||||
args string
|
||||
diffArgs string
|
||||
values []string
|
||||
retainValuesFiles bool
|
||||
set []string
|
||||
validate bool
|
||||
skipCRDs bool
|
||||
skipDeps bool
|
||||
skipRefresh bool
|
||||
includeTests bool
|
||||
skipNeeds bool
|
||||
includeNeeds bool
|
||||
includeTransitiveNeeds bool
|
||||
suppress []string
|
||||
suppressSecrets bool
|
||||
showSecrets bool
|
||||
noHooks bool
|
||||
suppressDiff bool
|
||||
suppressOutputLineRegex []string
|
||||
noColor bool
|
||||
context int
|
||||
diffOutput string
|
||||
concurrency int
|
||||
detailedExitcode bool
|
||||
stripTrailingCR bool
|
||||
interactive bool
|
||||
skipDiffOnInstall bool
|
||||
skipSchemaValidation bool
|
||||
reuseValues bool
|
||||
logger *zap.SugaredLogger
|
||||
takeOwnership bool
|
||||
enforceNeedsAreInstalled bool
|
||||
}
|
||||
|
||||
func (a diffConfig) Args() string {
|
||||
@@ -188,6 +189,10 @@ func (a diffConfig) TakeOwnership() bool {
|
||||
return a.takeOwnership
|
||||
}
|
||||
|
||||
func (a diffConfig) EnforceNeedsAreInstalled() bool {
|
||||
return a.enforceNeedsAreInstalled
|
||||
}
|
||||
|
||||
func TestDiff(t *testing.T) {
|
||||
type flags struct {
|
||||
skipNeeds bool
|
||||
|
||||
@@ -28,6 +28,8 @@ type ApplyOptions struct {
|
||||
IncludeNeeds bool
|
||||
// IncludeTransitiveNeeds is true if the transitive needs should be included
|
||||
IncludeTransitiveNeeds bool
|
||||
// EnforceNeedsAreInstalled is true if we should error if/when there are unmeetable dependencies
|
||||
EnforceNeedsAreInstalled bool
|
||||
// SkipDiffOnInstall is true if the diff should be skipped on install
|
||||
SkipDiffOnInstall bool
|
||||
// DiffArgs is the list of arguments to pass to the helm-diff.
|
||||
@@ -139,6 +141,11 @@ func (a *ApplyImpl) IncludeTransitiveNeeds() bool {
|
||||
return a.ApplyOptions.IncludeTransitiveNeeds
|
||||
}
|
||||
|
||||
// EnforceNeedsAreInstalled is true we should error if/when there are unmeetable dependencies
|
||||
func (a *ApplyImpl) EnforceNeedsAreInstalled() bool {
|
||||
return a.ApplyOptions.EnforceNeedsAreInstalled
|
||||
}
|
||||
|
||||
// ShowSecrets returns the show secrets.
|
||||
func (a *ApplyImpl) ShowSecrets() bool {
|
||||
return a.ApplyOptions.ShowSecrets
|
||||
|
||||
@@ -18,6 +18,8 @@ type DiffOptions struct {
|
||||
IncludeNeeds bool
|
||||
// IncludeTransitiveNeeds is the include transitive needs flag
|
||||
IncludeTransitiveNeeds bool
|
||||
// EnforceNeedsAreInstalled is the enforce needs are installed flag
|
||||
EnforceNeedsAreInstalled bool
|
||||
// SkipDiffOnInstall is the skip diff on install flag
|
||||
SkipDiffOnInstall bool
|
||||
// ShowSecrets is the show secrets flag
|
||||
@@ -87,6 +89,11 @@ func (t *DiffImpl) IncludeTransitiveNeeds() bool {
|
||||
return t.DiffOptions.IncludeTransitiveNeeds
|
||||
}
|
||||
|
||||
// EnforceNeedsAreInstalled errors if the transitive dependencies are not installable
|
||||
func (t *DiffImpl) EnforceNeedsAreInstalled() bool {
|
||||
return t.DiffOptions.EnforceNeedsAreInstalled
|
||||
}
|
||||
|
||||
// Set returns the Set
|
||||
func (t *DiffImpl) Set() []string {
|
||||
return t.DiffOptions.Set
|
||||
|
||||
@@ -14,6 +14,8 @@ type LintOptions struct {
|
||||
IncludeNeeds bool
|
||||
// IncludeTransitiveNeeds is the include transitive needs flag
|
||||
IncludeTransitiveNeeds bool
|
||||
// EnforceNeedsAreInstalled is the enforce needs are installed flag
|
||||
EnforceNeedsAreInstalled bool
|
||||
// SkipDeps is the skip deps flag
|
||||
}
|
||||
|
||||
@@ -66,6 +68,11 @@ func (l *LintImpl) IncludeTransitiveNeeds() bool {
|
||||
return l.LintOptions.IncludeTransitiveNeeds
|
||||
}
|
||||
|
||||
// EnforceNeedsAreInstalled errors if the transitive dependencies are not installable
|
||||
func (l *LintImpl) EnforceNeedsAreInstalled() bool {
|
||||
return l.LintOptions.EnforceNeedsAreInstalled
|
||||
}
|
||||
|
||||
// SkipNeeds returns the skip needs
|
||||
func (l *LintImpl) SkipNeeds() bool {
|
||||
if !l.IncludeNeeds() {
|
||||
|
||||
@@ -16,6 +16,8 @@ type SyncOptions struct {
|
||||
IncludeNeeds bool
|
||||
// IncludeTransitiveNeeds is the include transitive needs flag
|
||||
IncludeTransitiveNeeds bool
|
||||
// EnforceNeedsAreInstalled indicates whether to error when there are unmeetable dependencies
|
||||
EnforceNeedsAreInstalled bool
|
||||
// SkipCrds is the skip crds flag
|
||||
SkipCRDs bool
|
||||
// Wait is the wait flag
|
||||
@@ -82,6 +84,11 @@ func (t *SyncImpl) IncludeTransitiveNeeds() bool {
|
||||
return t.SyncOptions.IncludeTransitiveNeeds
|
||||
}
|
||||
|
||||
// EnforceNeedsAreInstalled errors if the transitive dependencies are not installable
|
||||
func (t *SyncImpl) EnforceNeedsAreInstalled() bool {
|
||||
return t.SyncOptions.EnforceNeedsAreInstalled
|
||||
}
|
||||
|
||||
// Set returns the Set
|
||||
func (t *SyncImpl) Set() []string {
|
||||
return t.SyncOptions.Set
|
||||
|
||||
@@ -30,6 +30,8 @@ type TemplateOptions struct {
|
||||
IncludeNeeds bool
|
||||
// IncludeTransitiveNeeds is the include transitive needs flag
|
||||
IncludeTransitiveNeeds bool
|
||||
// EnforceNeedsAreInstalled indicates whether to error when there are unmeetable dependencies
|
||||
EnforceNeedsAreInstalled bool
|
||||
// No-Hooks is the no hooks flag
|
||||
NoHooks bool
|
||||
// SkipCleanup is the skip cleanup flag
|
||||
@@ -158,3 +160,8 @@ func (t *TemplateImpl) KubeVersion() string {
|
||||
func (t *TemplateImpl) ShowOnly() []string {
|
||||
return t.TemplateOptions.ShowOnly
|
||||
}
|
||||
|
||||
// EnforceNeedsAreInstalled errors if the transitive dependencies are not installable
|
||||
func (t *TemplateImpl) EnforceNeedsAreInstalled() bool {
|
||||
return t.TemplateOptions.EnforceNeedsAreInstalled
|
||||
}
|
||||
|
||||
@@ -2738,6 +2738,34 @@ func (st *HelmState) UpdateDeps(helm helmexec.Interface, includeTransitiveNeeds
|
||||
return nil
|
||||
}
|
||||
|
||||
// DependencyError holds information about a release and its dependency that is not installed.
|
||||
type DependencyError struct {
|
||||
Release ReleaseSpec
|
||||
Dependency ReleaseSpec
|
||||
}
|
||||
|
||||
// hasTransitiveDependencyWithInstallFalse checks if a release has a transitive dependency with Install set to false.
|
||||
func (st *HelmState) HasTransitiveDependencyWithInstalledFalse(release ReleaseSpec, visited map[string]bool) *DependencyError {
|
||||
if visited[release.Name] {
|
||||
return nil
|
||||
}
|
||||
visited[release.Name] = true
|
||||
|
||||
for _, dep := range release.Needs {
|
||||
for _, r := range st.Releases {
|
||||
if r.Name == dep {
|
||||
if r.Installed != nil && !*r.Installed {
|
||||
return &DependencyError{Release: release, Dependency: r}
|
||||
}
|
||||
if depErr := st.HasTransitiveDependencyWithInstalledFalse(r, visited); depErr != nil {
|
||||
return depErr
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// find "Chart.yaml"
|
||||
func findChartDirectory(topLevelDir string) (string, error) {
|
||||
var files []string
|
||||
|
||||
Reference in New Issue
Block a user