Skip to content

fix(codeapi-chart): de-hook package-init Job so it runs once, not per-sync#12

Merged
rschlaefli merged 1 commit into
mainfrom
fix/codeapi-chart-package-init-dehook
Jul 5, 2026
Merged

fix(codeapi-chart): de-hook package-init Job so it runs once, not per-sync#12
rschlaefli merged 1 commit into
mainfrom
fix/codeapi-chart-package-init-dehook

Conversation

@rschlaefli

Copy link
Copy Markdown
Member

What

De-hook the codeapi package-init Job in the Helm chart so it runs once and persists instead of re-running on every ArgoCD sync.

  • Remove argocd.argoproj.io/hook: Sync + argocd.argoproj.io/hook-delete-policy annotations.
  • Drop ttlSecondsAfterFinished.
  • The Job now renders as a plain managed resource at argocd.argoproj.io/sync-wave: -5 (same pattern as the chart's PVC).

Files: helm/codeapi/templates/package-init-job.yaml, helm/codeapi/values.yaml, helm/codeapi/README.md.

Why

The package-init Job compiles the language runtimes into the shared codeapi-packages PVC. It targets the sandboxspot node pool — the only x86 pool, and scale-to-zero. As an ArgoCD Sync hook, the Job was re-created and re-run on every sync of the codeapi Application, and each run scheduled a pod onto sandboxspot, waking the spot pool from zero even when the runtimes were already built. That is wasted spot-node churn on every reconcile.

De-hooking makes the Job ordinary desired state: ArgoCD creates it once (wave -5, before the app), it builds against the marker (fast no-op when already initialized), Completes, and persists. Subsequent syncs apply an unchanged, completed Job → no new pod → the spot pool is not re-woken.

Behavior change to be aware of

A completed Kubernetes Job spec is immutable, and (de-hooked) the Job now persists. Because of that, helm upgrade/ArgoCD sync alone cannot patch it. To force a rebuild or bump runtime versions you must delete the Job first:

kubectl delete job codeapi-package-init

…then set forceRebuild=true (or bump the version values) and sync. The README documents this at all three forceRebuild sites. If skipped, forceRebuild=true silently no-ops (stale runtimes stay in the PVC) — ArgoCD surfaces this as an OutOfSync diff rather than an error.

No change to pod identity, serviceAccount, NetworkPolicy selection (component: package-init label unchanged — the Job stays outside the sandbox-runner deny-internet policy, as required to fetch runtimes), nodeSelector/tolerations (still sandboxspot), capabilities, or mounted secrets. Job env is version strings + FORCE_REBUILD only — no secrets.

Verification

Deployed via df-cloud's per-app Pulumi stack (ArgoCD Application targetRevision repinned to this branch's HEAD) and empirically verified on both stg and prd:

  • Transition sync: Job created at wave -5, woke sandboxspot once, pod Completed, Job persists 1/1 with no TTL. Live annotations = sync-wave: -5 only (no hook, no hook-delete-policy).
  • No-op re-sync: Job UID unchanged, zero new pods created → Job did not re-run → spot pool not re-woken.
  • Drain: after the one-time transition wake, sandboxspot scaled back to 0 on the autoscaler idle timer.

Security review: no security-boundary, credential, or privilege change.

Manual check before merge

  • None blocking. Merging lands the chart change on main and keeps this commit permanently reachable — the stg + prd codeapi ArgoCD Applications pin this exact SHA, so the branch must not be deleted before it is on main.

…-sync

The package-init Job was an Argo CD Sync hook (hook + hook-delete-policy), so
every sync recreated and re-ran it. Its nodeSelector targets the scale-to-zero
`sandboxspot` spot pool, so each sync woke a spot node just to re-check an
already-populated PVC.

Remove the Sync-hook annotations and drop ttlSecondsAfterFinished so the Job
becomes a plain managed resource at sync-wave -5 (matching pvc.yaml). It runs
once; an unchanged sync is an apply no-op that neither re-runs the Job nor
wakes the pool. Keeping it a separate pod preserves internet access for cold
builds (the sandbox-runner pod's NetworkPolicy denies egress).

The completed Job now persists with an immutable spec, so forcing a rebuild or
bumping runtime versions requires deleting the Job first; document this at the
forceRebuild value and in the README (which also no longer mislabels the Job as
a Helm pre-install hook).
@rschlaefli rschlaefli marked this pull request as ready for review July 5, 2026 09:18
Copilot AI review requested due to automatic review settings July 5, 2026 09:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@rschlaefli rschlaefli merged commit 356123a into main Jul 5, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants