Avoid ARG_MAX overflow in bootc image-mode builds#4793
Conversation
There was a problem hiding this comment.
Code Review
This pull request addresses an issue where large environment variables in bootc image-mode plans could exceed the OS ARG_MAX limit by being inlined into Containerfile RUN directives. The changes introduce a mechanism to emit environment variables as ENV directives once, and switch to using the guest.push() method for writing Containerfiles instead of relying on SSH command-line execution. A new test case has been added to verify this behavior. Please move the imports in tmt/package_managers/bootc.py to the top of the file to comply with PEP 8 standards.
6a4211e to
b600f8e
Compare
|
Would it make sense to simply Is it possible to somehow clear the environment before emitting new directives for new command? I'm thinking about |
This one is problematic, see #4793 (comment) - as long as
This one seems like a no-brainer, we absolutely can and should transfer the file via |
a5f4423 to
6b40981
Compare
|
@happz Thanks for the hints, that simplifies things tremendously. I tried something like but it seems like by then workdir never exists because when either |
|
@tcornell-bus Yes, I've fixed everything except the super()init problem. I can look at that this week. |
6b40981 to
0a4a1d7
Compare
|
Updated the branch to wire This means all PackageManager instances now technically have access to workdir, not just the bootc engine. This should be safe: Other Note: |
583a095 to
fb08432
Compare
|
/packit build |
I had to think quite hard to recall why |
fb08432 to
5307117
Compare
|
Updated the branch addressing all feedback and rebased on latest main. Forgive me for not replying in each thread, I figure this is better than the notification spam.
I also forgot what the original PR even looked like at this point. Here's what I got so far: @happz — Switched to
|
LecrisUT
left a comment
There was a problem hiding this comment.
I figure this is better than the notification spam.
Don't worry about that, we have plenty of notification "spam" we deal on a daily basis 😅. Also incremental commits are fine, we do squash commits.
|
@Lorquas please, check out the tests, they fail in our CI: https://artifacts.dev.testing-farm.io/2689664c-7b34-4464-a180-d2a7d5f80fc2/work-preparez7vj16yz/plans/provision/virtual/prepare/execute/data/guest/default-0/tests/prepare/large-env-3/output.txt. If I'm not mistaken, the large env file needs to be injected into the tree, tmt has a limitation in place to stick to the tree when it comes to loading files. |
|
@Lorquas, could you please update the pull request description so that it can be used as the git commit message when squashing? Currently it contains some outdated stuff like Fix A or unit tests. Could you also add a short release note? Thanks. |
3405d1a to
2471ca9
Compare
ARG_MAX overflow in bootc image-mode builds
|
/packit build |
2471ca9 to
e452b02
Compare
8fde6f2 to
9a99c09
Compare
When plan environments contain large values, collect_command() inlines them as export statements and build_container() passes the entire Containerfile via `cat <<EOF` over SSH — easily exceeding the OS ARG_MAX limit. Write the Containerfile to the package-manager workdir and transfer it with guest.push() (rsync/SCP) instead of passing it on the command line. To make self.workdir available in PackageManager instances, thread parent=guest through the PackageManager constructor so Common.workdir can resolve a directory. Adds an integration test (tests/prepare/bootc-large-env) that injects a 50 KB environment variable into a bootc image-mode build and verifies the build succeeds.
Co-authored-by: Cristian Le <github@lecris.me>
- Generate large-env.yaml inside the fmf data/ tree so tmt accepts it as an --environment-file source (fixes CI failure) - Add TODO comment for enabling container/virtual provision methods - Change link from verifies to relates (fix is partial for teemtee#4518) - Add release note for 1.74
9a99c09 to
4e668a2
Compare
|
/packit build |
Summary
When plan environment contains large values (e.g. base64-encoded SSH keys, certificates, and API tokens from CI systems like Testing Farm), bootc image-mode builds fail with
OSError: [Errno 7] Argument list too long: 'ssh'. Two patterns combine to hit the OSARG_MAXlimit:collect_command()inlines the full environment asexportstatements into every ContainerfileRUNdirective, multiplying the sizebuild_container()passes the entire generated Containerfile as acat <<EOFSSH command-line argumentChanges
tmt/package_managers/bootc.py: Transfer the generated Containerfile to the guest viapush()(rsync/SCP) instead of inlining it in acatheredoc SSH command, removing the command-line size ceiling entirely. Usesself.guest.guest_workdir / 'Containerfile'as the local staging path.Relates to #4518
Testing
tests/prepare/large-env/): End-to-end BeakerLib test that dynamically sizes a base64 environment variable based on the system'sMAX_ARG_STRLEN(PAGE_SIZE * 32). The test plan uses twoprepare: how: shellsteps so the full environment is inlined viacollect_command()into two separateRUNdirectives — making the combined Containerfile exceedMAX_ARG_STRLEN. This reliably triggers the oldcat <<EOFfailure while passing with thepush()fix.[Errno 7] Argument list too long: 'ssh', new code passes.Pull Request Checklist