diff --git a/cmd/actions/diff.go b/cmd/actions/diff.go index 6394edf..9b3435d 100644 --- a/cmd/actions/diff.go +++ b/cmd/actions/diff.go @@ -33,6 +33,10 @@ var diffCmd = &cobra.Command{ return err } + if err := sq.UpdateLocalDependencies(cmd.Context(), flagParallel); err != nil { + return err + } + return sq.Diff(cmd.Context(), helmArgs, flagParallel) }, } diff --git a/cmd/actions/template.go b/cmd/actions/template.go index cd5a3ed..b940049 100644 --- a/cmd/actions/template.go +++ b/cmd/actions/template.go @@ -37,6 +37,10 @@ var templateCmd = &cobra.Command{ return err } + if err := sq.UpdateLocalDependencies(cmd.Context(), flagParallel); err != nil { + return err + } + out, err := sq.Template(cmd.Context(), helmArgs, flagParallel) if err != nil { return err diff --git a/cmd/actions/up.go b/cmd/actions/up.go index 27c36ff..4ddaaaa 100644 --- a/cmd/actions/up.go +++ b/cmd/actions/up.go @@ -53,6 +53,10 @@ var upCmd = &cobra.Command{ } } + if err := sq.UpdateLocalDependencies(cmd.Context(), flagParallel); err != nil { + return err + } + username := "unknown" if value, err := util.NewCommand("git").Args("config", "user.name").Run(cmd.Context()); err == nil { username = strings.TrimSpace(value) diff --git a/internal/config/unit.go b/internal/config/unit.go index f46f30f..24005a1 100644 --- a/internal/config/unit.go +++ b/internal/config/unit.go @@ -106,23 +106,6 @@ func (u *Unit) Template(ctx context.Context, name, squadron, unit, namespace str return ret.Bytes(), nil } -func (u *Unit) DependencyUpdate(ctx context.Context) error { - // update local chart dependencies - // https://stackoverflow.com/questions/59210148/error-found-in-chart-yaml-but-missing-in-charts-directory-mysql - if strings.HasPrefix(u.Chart.Repository, "file:///") { - pterm.Debug.Printfln("running helm dependency update for %s", u.Chart.Repository) - sh := util.NewHelmCommand(). - Cwd(strings.TrimPrefix(u.Chart.Repository, "file://")). - Args("dependency", "update", "--skip-refresh", "--debug") - if out, err := sh.Run(ctx); err != nil { - return errors.Wrap(err, out) - } else { - pterm.Debug.Println(out) - } - } - return nil -} - func (u *Unit) PostRendererArgs() []string { var ret []string if u.Kustomize != "" { diff --git a/squadron.go b/squadron.go index 88b9d08..4bb6e63 100644 --- a/squadron.go +++ b/squadron.go @@ -346,11 +346,6 @@ func (sq *Squadron) Diff(ctx context.Context, helmArgs []string, parallel int) e return err } - // update local chart dependencies - if err := v.DependencyUpdate(ctx); err != nil { - return err - } - pterm.Debug.Printfln("running helm diff for: %s", k) manifest, err := exec.CommandContext(ctx, "helm", "get", "manifest", name, "--namespace", namespace).CombinedOutput() if err != nil && string(bytes.TrimSpace(manifest)) != errHelmReleaseNotFound { @@ -520,6 +515,45 @@ func (sq *Squadron) Rollback(ctx context.Context, revision string, helmArgs []st return wg.Wait() } +// UpdateLocalDependencies work around +// https://stackoverflow.com/questions/59210148/error-found-in-chart-yaml-but-missing-in-charts-directory-mysql +func (sq *Squadron) UpdateLocalDependencies(ctx context.Context, parallel int) error { + // collect unique entrie + var repositories map[string]struct{} + err := sq.Config().Squadrons.Iterate(func(key string, value config.Map[*config.Unit]) error { + return value.Iterate(func(k string, v *config.Unit) error { + if strings.HasPrefix(v.Chart.Repository, "file:///") { + repositories[v.Chart.Repository] = struct{}{} + } + return nil + }) + }) + if err != nil { + return err + } + + wg, gctx := errgroup.WithContext(ctx) + wg.SetLimit(parallel) + + for repository := range repositories { + repository := repository + wg.Go(func() error { + pterm.Debug.Printfln("running helm dependency update for %s", repository) + if out, err := util.NewHelmCommand(). + Cwd(path.Clean(strings.TrimPrefix(repository, "file://"))). + Args("dependency", "update", "--skip-refresh", "--debug"). + Run(gctx); err != nil { + return errors.Wrap(err, out) + } else { + pterm.Debug.Println(out) + } + return nil + }) + } + + return wg.Wait() +} + func (sq *Squadron) Up(ctx context.Context, helmArgs []string, username, version, commit, branch string, parallel int) error { description := fmt.Sprintf("\nDeployed-By: %s\nManaged-By: Squadron %s\nGit-Commit: %s\nGit-Branch: %s", username, version, commit, branch) @@ -539,11 +573,6 @@ func (sq *Squadron) Up(ctx context.Context, helmArgs []string, username, version return err } - // update local chart dependencies - if err := v.DependencyUpdate(ctx); err != nil { - return err - } - // install chart pterm.Debug.Printfln("running helm upgrade for %s", name) cmd := util.NewHelmCommand(). @@ -606,11 +635,6 @@ func (sq *Squadron) Template(ctx context.Context, helmArgs []string, parallel in return err } - // update local chart dependencies - if err := v.DependencyUpdate(ctx); err != nil { - return err - } - pterm.Debug.Printfln("running helm template for chart: %s", name) out, err := v.Template(gctx, name, key, k, namespace, sq.c.Global, helmArgs) if err != nil { diff --git a/testdata/override/snapshop-template.yaml b/testdata/override/snapshop-template.yaml index 1791dda..f8ebc47 100644 --- a/testdata/override/snapshop-template.yaml +++ b/testdata/override/snapshop-template.yaml @@ -3,9 +3,9 @@ apiVersion: v1 kind: Service metadata: - name: frontend + name: storefinder-frontend labels: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend app.kubernetes.io/managed-by: Helm helm.sh/chart: 'frontend-0.0.1' @@ -13,7 +13,7 @@ metadata: spec: type: ClusterIP selector: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend ports: - name: http @@ -23,9 +23,9 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: frontend + name: storefinder-frontend labels: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend app.kubernetes.io/managed-by: Helm helm.sh/chart: 'frontend-0.0.1' @@ -33,16 +33,16 @@ metadata: spec: selector: matchLabels: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend template: metadata: labels: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend spec: containers: - - name: frontend + - name: storefinder-frontend image: 'docker.mycompany.com/mycomapny/frontend:nightly' ports: - name: http @@ -53,9 +53,9 @@ spec: apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - name: frontend + name: storefinder-frontend labels: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend app.kubernetes.io/managed-by: Helm helm.sh/chart: 'frontend-0.0.1' @@ -72,7 +72,7 @@ spec: path: / backend: service: - name: frontend + name: storefinder-frontend port: name: http number: 80 diff --git a/testdata/simple/snapshop-template.yaml b/testdata/simple/snapshop-template.yaml index d8dd981..1766fa0 100644 --- a/testdata/simple/snapshop-template.yaml +++ b/testdata/simple/snapshop-template.yaml @@ -3,9 +3,9 @@ apiVersion: v1 kind: Service metadata: - name: frontend + name: storefinder-frontend labels: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend app.kubernetes.io/managed-by: Helm helm.sh/chart: 'frontend-0.0.1' @@ -13,7 +13,7 @@ metadata: spec: type: ClusterIP selector: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend ports: - name: http @@ -23,9 +23,9 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: frontend + name: storefinder-frontend labels: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend app.kubernetes.io/managed-by: Helm helm.sh/chart: 'frontend-0.0.1' @@ -33,16 +33,16 @@ metadata: spec: selector: matchLabels: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend template: metadata: labels: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend spec: containers: - - name: frontend + - name: storefinder-frontend image: 'nginx:latest' ports: - name: http @@ -53,9 +53,9 @@ spec: apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - name: frontend + name: storefinder-frontend labels: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend app.kubernetes.io/managed-by: Helm helm.sh/chart: 'frontend-0.0.1' @@ -72,7 +72,7 @@ spec: path: / backend: service: - name: frontend + name: storefinder-frontend port: name: http number: 80 diff --git a/testdata/tags/snapshop-template.yaml b/testdata/tags/snapshop-template.yaml index 3b22b7f..27fa897 100644 --- a/testdata/tags/snapshop-template.yaml +++ b/testdata/tags/snapshop-template.yaml @@ -3,9 +3,9 @@ apiVersion: v1 kind: Service metadata: - name: backend + name: checkout-backend labels: - app.kubernetes.io/name: backend + app.kubernetes.io/name: checkout-backend app.kubernetes.io/component: backend app.kubernetes.io/managed-by: Helm helm.sh/chart: 'backend-0.0.1' @@ -13,7 +13,7 @@ metadata: spec: type: ClusterIP selector: - app.kubernetes.io/name: backend + app.kubernetes.io/name: checkout-backend app.kubernetes.io/component: backend ports: - name: http @@ -23,9 +23,9 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: backend + name: checkout-backend labels: - app.kubernetes.io/name: backend + app.kubernetes.io/name: checkout-backend app.kubernetes.io/component: backend app.kubernetes.io/managed-by: Helm helm.sh/chart: 'backend-0.0.1' @@ -33,16 +33,16 @@ metadata: spec: selector: matchLabels: - app.kubernetes.io/name: backend + app.kubernetes.io/name: checkout-backend app.kubernetes.io/component: backend template: metadata: labels: - app.kubernetes.io/name: backend + app.kubernetes.io/name: checkout-backend app.kubernetes.io/component: backend spec: containers: - - name: backend + - name: checkout-backend image: 'nginx:latest' ports: - name: http diff --git a/testdata/template/snapshop-template.yaml b/testdata/template/snapshop-template.yaml index 44d6b21..d64469b 100644 --- a/testdata/template/snapshop-template.yaml +++ b/testdata/template/snapshop-template.yaml @@ -3,9 +3,9 @@ apiVersion: v1 kind: Service metadata: - name: backend + name: storefinder-backend labels: - app.kubernetes.io/name: backend + app.kubernetes.io/name: storefinder-backend app.kubernetes.io/component: backend app.kubernetes.io/managed-by: Helm helm.sh/chart: 'backend-0.0.1' @@ -13,7 +13,7 @@ metadata: spec: type: ClusterIP selector: - app.kubernetes.io/name: backend + app.kubernetes.io/name: storefinder-backend app.kubernetes.io/component: backend ports: - name: http @@ -23,9 +23,9 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: backend + name: storefinder-backend labels: - app.kubernetes.io/name: backend + app.kubernetes.io/name: storefinder-backend app.kubernetes.io/component: backend app.kubernetes.io/managed-by: Helm helm.sh/chart: 'backend-0.0.1' @@ -33,16 +33,16 @@ metadata: spec: selector: matchLabels: - app.kubernetes.io/name: backend + app.kubernetes.io/name: storefinder-backend app.kubernetes.io/component: backend template: metadata: labels: - app.kubernetes.io/name: backend + app.kubernetes.io/name: storefinder-backend app.kubernetes.io/component: backend spec: containers: - - name: backend + - name: storefinder-backend image: 'docker.mycompany.com/mycomapny/frontend-admin:latest' ports: - name: http @@ -53,9 +53,9 @@ spec: apiVersion: v1 kind: Service metadata: - name: frontend + name: storefinder-frontend labels: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend app.kubernetes.io/managed-by: Helm helm.sh/chart: 'frontend-0.0.1' @@ -63,7 +63,7 @@ metadata: spec: type: ClusterIP selector: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend ports: - name: http @@ -73,9 +73,9 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: frontend + name: storefinder-frontend labels: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend app.kubernetes.io/managed-by: Helm helm.sh/chart: 'frontend-0.0.1' @@ -83,16 +83,16 @@ metadata: spec: selector: matchLabels: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend template: metadata: labels: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend spec: containers: - - name: frontend + - name: storefinder-frontend image: 'docker.mycompany.com/mycomapny/frontend:latest' ports: - name: http @@ -103,9 +103,9 @@ spec: apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - name: frontend + name: storefinder-frontend labels: - app.kubernetes.io/name: frontend + app.kubernetes.io/name: storefinder-frontend app.kubernetes.io/component: frontend app.kubernetes.io/managed-by: Helm helm.sh/chart: 'frontend-0.0.1' @@ -122,7 +122,7 @@ spec: path: / backend: service: - name: frontend + name: storefinder-frontend port: name: http number: 80