Cap the size of the workload job environment
<
What does this MR do and why?
Workload jobs fail in prepare_script with dumb-init: argument list too long when their environment is too big for execve(). Linux caps one NAME=VALUE string at 128 KiB (MAX_ARG_STRLEN) and the whole environment at ARG_MAX, and nothing in Rails enforced either.
Ci::Workloads::RunWorkloadServicerejects a workload with a variable over 128 KiB (measured asNAME=VALUE\0, like the kernel). It returns an error naming the variable, creates no pipeline, and logs names and sizes only.- A total over 1 MiB is only logged as a warning, with the same names and sizes.
ARG_MAXscales with the runner's stack rlimit, so the total reject waits until the logs show how many workloads go over. Gitlab::DuoWorkflow::WorkspaceAgentsReadercapsDUO_WORKFLOW_AGENTSat 112 KiB. The old limits allowed 640 KiB. Agents that don't fit are dropped whole, and later agents that still fit are kept.
This is a backstop. Per-payload budgets and the recommend_reviewers dual-emit are follow-ups on the issue.
References
- #630285 (closed)
- #616260 (closed) (the goal cap this follows)
Screenshots or screen recordings
Not applicable, no UI change.
How to set up and validate locally
Prerequisites: a GDK with the Duo Agent Platform, a registered Docker runner, and a project where a catalog flow can be triggered by mentioning its service account, for example the Developer flow. Go through each part on master, then on this branch.
1. Oversized job environment
In production this happens with a mention on a long discussion thread. To reproduce it without one, pad the environment locally.
-
In
ee/app/services/ai/duo_workflows/start_workflow_service.rb, add this line to the hash inbase_variables, afterDUO_WORKFLOW_GOAL:DUO_WORKFLOW_PAD: 'a' * 200.kilobytes, -
Run
gdk restart rails-web rails-background-jobs. -
On an issue in the project, mention the flow's service account with a short request.
-
master: the agent says it started, and its session links to a pipeline. The job fails before cloning withexec /usr/bin/dumb-init: argument list too long. -
This branch: the agent replies
Failed to start the Duo workflow. Please try again., and Build > Pipelines shows no new pipeline. The log entry names the variable, with byte counts but no values:grep "exceeds the size limits" log/application_json.log | tail -1 | jq "{oversized_variables, variables_bytesize}"
To check the total threshold, replace the line with 20 variables that are each under 128 KiB, about 2.4 MiB in all, then restart and mention again:
**(1..20).to_h { |i| [:"DUO_WORKFLOW_PAD_#{i}", 'a' * 120.kilobytes] },master: the sameargument list too longfailure, from the kernel's 2 MiB total limit.- This branch: the same
argument list too longfailure, since the total is only logged.log/application_json.loghasWorkload job environment is over the total size thresholdwith an emptyoversized_variablesand avariables_bytesizeover 1048576.
Remove the line when done.
2. Workspace agents budget
-
Enable the flag:
echo 'Feature.enable(:dap_workspace_agents)' | gdk rails console. -
On the default branch, add four files under
.agents/agents/with Code > New file, nameda.md,b.md,c.mdandd.md. Give each one this content, using the file name as the description and sizing the body as listed:--- description: <file name> --- <body>File Body a.mdabout 63 KB: ruby -e 'print "x" * 63_000' | pbcopyb.mdabout 63 KB, same command c.mdone line d.mdabout 10 KB: ruby -e 'print "x" * 10_000' | pbcopy -
Trigger the flow with a short mention in a new thread.
master: all four agents go intoDUO_WORKFLOW_AGENTS, about 137 KB, and the job fails withargument list too long.- This branch: the session starts.
log/application_json.loghasIgnoring workspace agents over the total size budgetwithnames: ["b"], socandd, which come after it, are still sent.
To clean up, delete .agents/agents and disable the flag.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist.
- No feature flag. The only reject is for a variable over
MAX_ARG_STRLEN, which can't execute today on any runner. Changelog: fixedwithoutEE: true, since the change spansapp/andee/. The Danger warning about it is a false positive.- The branch was pushed with
ci.skip, so a full pipeline is needed before merge.
</