{
"request": "Triage Jira ticket MZCLD-3725: MozCloud Helm charts: tasks.common.container overrides are ignored for Jobs",
"references": [
"https://mozilla-hub.atlassian.net/browse/MZCLD-3725"
],
"sourceContext": {
"issue": "MZCLD-3725"
}
}MZCLD-3725 reports that `tasks.common.container` overrides are silently discarded for Job containers (but work correctly for CronJobs) in the MozCloud Helm charts. The ticket description is an unusually complete, self-contained root-cause analysis and fix proposal (not just a bug report), including reproduction steps, a second independently-discovered nil-pointer crash bug in the container formatter, a concrete two-part fix, a call-out of four fields needing careful reconciliation, and explicit acceptance criteria. Status is "In Progress" with zero comments so far, so no triage/consensus has been recorded yet despite the depth of analysis.
[
{
"capability": "jira.issue.read",
"args": {
"key": "MZCLD-3725"
},
"result": {
"key": "MZCLD-3725",
"summary": "MozCloud Helm charts: tasks.common.container overrides are ignored for Jobs",
"status": "In Progress",
"description_text": "Problem tasks.common.container is documented as supplying defaults for all job and cron job containers. For Jobs it is completely inert \u2014 every key it defines is silently discarded. CronJobs are unaffected. Reproduction Against the current chart, using tests/values/basic-job-configuration.yaml : helm template t . -f tests/values/globals.yaml \\\n -f tests/values/basic-job-configuration.yaml \\\n --set tasks.common.container.resources.cpu=500m \\\n --set tasks.common.container.secrets[0]=my-secret \\\n --set tasks.common.container.configMaps[0]=my-cm Result: requests.cpu is still 100m , and no envFrom block is rendered at all \u2014 the secret and configMap are dropped. The identical overrides applied to a cronJob work correctly : cpu: 500m and secretRef: my-secret both appear. That contrast is what isolates the cause. Root cause tasks.jobs.default.containers.default ( values.yaml L484-760) re-declares concrete values for every key tasks.common.container owns \u2014 args , command , configMaps , envVars , secrets , image , imagePullPolicy , resources , security , and volumes (L749) \u2014 plus envFromFields and lifecycle . mozcloud.formatter.containers merges that block into every job container. So by the time templates/task/_jobTemplate.yaml:92 runs: {{- $containerConfig = mergeOverwrite (deepCopy (default dict $common.container)) $containerConfig }} $containerConfig already carries a chart-supplied value for every key, and it is the override side, so it wins every time. The merge direction at L92 is correct \u2014 the layer above it is opaque. CronJobs work because tasks.cronJobs.default.jobConfig is {} , so nothing shadows the common block. That proves the intended mechanism is sound and the fix belongs in values.yaml, not in the templates. Second bug found while validating mozcloud.formatter.containers ( templates/_formatter.yaml:113 ) calls index $containerValues \"default\" and deepCopy s the result with no nil guard. Any task with 2+ containers and no explicit default key crashes: error calling deepCopy: reflect: call of reflect.Value.Type on zero Value This breaks cronJobs today , independently of the above. It is also a hard prerequisite for the main fix: removing the jobs' containers.default would expose the same crash to Jobs. Proposed fix Harden the formatter \u2014 {{- $defaults := default dict (index $containerValues $defaultKey) -}} . One-line nil guard. Strip the duplicated defaults from tasks.jobs.default.containers.default , converting them to commented documentation so tasks.common.container becomes the single source of container defaults for jobs. Mirrors tasks.cronJobs.default.jobConfig: {} . No further template change is needed. Resulting precedence, matching documented intent: tasks.common.container < tasks.jobs.<name>.containers.default (user-set) < per-container Four keys differ between the two blocks and need care: resources (jobs.default adds limits: {} ), image ( {repository: '', tag: ''} vs {} ), and envFromFields / lifecycle (only in jobs.default). CronJobs already render correctly without any of them, so dropping them should be render-neutral. Acceptance criteria A job container with no per-container value inherits tasks.common.container ( resources , secrets , configMaps ). A per-container value still beats tasks.common.container \u2014 precedence is not inverted. A user-set tasks.jobs.default.containers.default sits between the two. CronJob inheritance continues to work. A task with 2+ containers and no default key renders instead of crashing. Every pre-existing snapshot is unchanged \u2014 the strip must be render-neutral. Source DIFF_ANALYSIS_dev.md L149 and chart gap #2 in CHANGES_dev.md , from the lando migration (MZCLD-3089). lando worked around this by configuring every job container individually.",
"comment_count": 0,
"comments": []
}
},
{
"capability": "jira.issue.read",
"args": {
"key": "MZCLD-3089"
},
"result": {
"error": "read blocked by policy: resource not in run subject",
"args": {
"key": "MZCLD-3089"
}
},
"blocked": true
}
]{
"model": "claude-sonnet-5",
"input_tokens": 7791,
"output_tokens": 2298,
"estimated_cost_usd": 0.057843000000000006
}[]