|
1 | | -// Package deploy preflight.go implements a self-diagnosing check of the |
2 | | -// secrets/environment setup a deployment needs, mirroring tools like |
3 | | -// `flyctl doctor` and `gh auth status`. The same checks back both the |
4 | | -// standalone `deploy-camunda doctor` command and the fail-fast guard that runs |
5 | | -// before any cluster mutation, so a missing credential surfaces up front with a |
6 | | -// remediation hint instead of mid-deploy as an ImagePullBackOff or a |
7 | | -// `kubectl apply` parse error. |
| 1 | +// Package deploy preflight.go runs the secrets/environment checks that back |
| 2 | +// both `deploy-camunda doctor` and the fail-fast guard in deploy.Execute. |
8 | 3 | package deploy |
9 | 4 |
|
10 | 5 | import ( |
@@ -101,10 +96,16 @@ func Preflight(ctx context.Context, flags *config.RuntimeFlags, opts PreflightOp |
101 | 96 | // and companion placeholder checks don't false-positive on values the deploy |
102 | 97 | // supplies itself. Vault-mapping and docker checks use baseEnv — those vars are |
103 | 98 | // never deploy-computed. |
| 99 | + // Resolve the chart path first: doctor skips root.go's PersistentPreRunE, so |
| 100 | + // the check both validates the path and rewrites flags.Chart.ChartPath to the |
| 101 | + // resolved directory the scenario checks below depend on. |
| 102 | + chartCheck := checkChartPath(flags) |
| 103 | + |
104 | 104 | baseEnv := effectiveEnv(flags) |
105 | 105 | deployEnv := scenarioDeployEnv(flags, baseEnv) |
106 | 106 |
|
107 | 107 | r.Checks = append(r.Checks, checkConfigFile(opts)) |
| 108 | + r.Checks = append(r.Checks, chartCheck) |
108 | 109 | r.Checks = append(r.Checks, checkKubeContext(ctx, flags, opts)) |
109 | 110 | r.Checks = append(r.Checks, checkDockerCredentials(flags, baseEnv)...) |
110 | 111 | r.Checks = append(r.Checks, checkVaultMapping(flags, baseEnv)) |
@@ -312,6 +313,36 @@ func checkVaultMapping(flags *config.RuntimeFlags, envMap map[string]string) Che |
312 | 313 | } |
313 | 314 | } |
314 | 315 |
|
| 316 | +// checkChartPath resolves the configured chart path the same way root.go's |
| 317 | +// PersistentPreRunE does — a relative path is joined against repoRoot — and |
| 318 | +// fails when it does not resolve to a directory. On success it rewrites |
| 319 | +// flags.Chart.ChartPath to the resolved path so the scenario/companion checks |
| 320 | +// scan the same directory a deploy would. |
| 321 | +func checkChartPath(flags *config.RuntimeFlags) Check { |
| 322 | + path := strings.TrimSpace(flags.Chart.ChartPath) |
| 323 | + if path == "" { |
| 324 | + return Check{Name: "chart path", Status: StatusOK, Detail: "no chart configured"} |
| 325 | + } |
| 326 | + if !filepath.IsAbs(path) && flags.Chart.RepoRoot != "" { |
| 327 | + if _, err := os.Stat(path); err != nil { |
| 328 | + resolved := filepath.Join(flags.Chart.RepoRoot, path) |
| 329 | + if fi, err := os.Stat(resolved); err == nil && fi.IsDir() { |
| 330 | + path = resolved |
| 331 | + } |
| 332 | + } |
| 333 | + } |
| 334 | + if fi, err := os.Stat(path); err != nil || !fi.IsDir() { |
| 335 | + return Check{ |
| 336 | + Name: "chart path", |
| 337 | + Status: StatusFail, |
| 338 | + Detail: fmt.Sprintf("%q does not exist or is not a directory", path), |
| 339 | + Remediation: "set --repo-root/--chart/--version or --chart-path to a valid chart directory", |
| 340 | + } |
| 341 | + } |
| 342 | + flags.Chart.ChartPath = path |
| 343 | + return Check{Name: "chart path", Status: StatusOK, Detail: path} |
| 344 | +} |
| 345 | + |
315 | 346 | // checkScenarioEnv scans the values file(s) for the selected scenario(s) and |
316 | 347 | // reports any $PLACEHOLDER env vars that are unset. Resolution failures are a |
317 | 348 | // soft warning rather than a hard fail so `doctor` is still useful when no |
|
0 commit comments