Skip to content

feat(orch): support RPM-based and Arch base images for template builds#2941

Draft
mishushakov wants to merge 6 commits into
mainfrom
mishushakov/alpine-image-support
Draft

feat(orch): support RPM-based and Arch base images for template builds#2941
mishushakov wants to merge 6 commits into
mainfrom
mishushakov/alpine-image-support

Conversation

@mishushakov
Copy link
Copy Markdown
Member

Makes template build provisioning distro-aware so any systemd-based base image works, not just Debian/Ubuntu. provision.sh now detects the package manager (apt / dnf / yum / microdnf / zypper / pacman), maps required package names per distro family, resolves the systemd binary path and the correct time-sync unit name (chrony vs chronyd), and ensures the CA bundle exists at the Debian-style /etc/ssl/certs/ca-certificates.crt path. envd.service now seeds the cert tmpfs and falls back across update-ca-certificates/update-ca-trust so envd starts on RPM/Arch. Alpine and other non-systemd distros remain unsupported (rejected with a clear error). The package-availability integration test is now table-driven across Ubuntu, Fedora, AlmaLinux, openSUSE, and Arch, and the README limitations are updated accordingly.

🤖 Generated with Claude Code

Make the template build provisioning distro-aware so any systemd-based
base image works, not just Debian/Ubuntu. provision.sh now detects the
package manager (apt/dnf/yum/microdnf/zypper/pacman), maps package names
per family, picks the systemd binary path and time-sync unit name, and
ensures the CA bundle exists at the Debian-style path. envd.service seeds
the cert tmpfs and falls back across update-ca-certificates/update-ca-trust
so envd starts on RPM/Arch. Alpine remains unsupported (no systemd).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@cursor
Copy link
Copy Markdown

cursor Bot commented Jun 6, 2026

PR Summary

Medium Risk
Core template provisioning and envd boot paths change for all non-Debian bases; regressions would break builds or TLS/init on new distros, though Debian behavior is largely preserved.

Overview
Template builds now target systemd-based Debian/Ubuntu, RHEL-family (dnf/yum/microdnf), and Arch bases instead of Debian-only apt provisioning. provision.sh detects the package manager, installs distro-specific package names (e.g. iptables-nft, nfs-utils), enables chronyd/chrony per image, resolves the systemd binary for /usr/sbin/init, and ensures /etc/ssl/certs/ca-certificates.crt exists on RPM images. User creation and sudo setup switch from Debian adduser/sudo to portable useradd and sudo/wheel group handling in build commands and finalize scripts. envd.service seeds the cert bind-mount more safely and falls back across update-ca-certificates and update-ca-trust. Rootfs layers no longer hard-link chrony.service; chrony autostart is left to provisioning. Integration tests table-drive package checks across Ubuntu, AlmaLinux, and Arch, plus a CA bundle path assertion; README limitations are updated (Alpine/non-systemd and openSUSE remain unsupported).

Reviewed by Cursor Bugbot for commit 14306ca. Bugbot is set up for automated code reviews on this repo. Configure here.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 6, 2026

❌ 3 Tests Failed:

Tests completed Failed Passed Skipped
2749 3 2746 7
View the full list of 3 ❄️ flaky test(s)
github.com/e2b-dev/infra/tests/integration/internal/tests/orchestrator::TestSandboxMemoryIntegrity

Flake rate in main: 54.21% (Passed 913 times, Failed 1081 times)

Stack Traces | 67.8s run time
=== RUN   TestSandboxMemoryIntegrity
=== PAUSE TestSandboxMemoryIntegrity
=== CONT  TestSandboxMemoryIntegrity
    sandbox_memory_integrity_test.go:27: Build completed successfully
--- FAIL: TestSandboxMemoryIntegrity (67.84s)
github.com/e2b-dev/infra/tests/integration/internal/tests/orchestrator::TestSandboxMemoryIntegrity/tmpfs_hash

Flake rate in main: 54.28% (Passed 903 times, Failed 1072 times)

Stack Traces | 202s run time
=== RUN   TestSandboxMemoryIntegrity/tmpfs_hash
=== PAUSE TestSandboxMemoryIntegrity/tmpfs_hash
=== CONT  TestSandboxMemoryIntegrity/tmpfs_hash
    sandbox_memory_integrity_test.go:70: Command [bash] output: event:{start:{pid:401}}
    sandbox_memory_integrity_test.go:70: Command [bash] output: event:{data:{stdout:"Total memory: 985 MB\nUsed memory before tmpfs mount: 185 MB\nFree memory before tmpfs mount: 799 MB\nMemory to use in integrity test (60% of free, min 64MB): 479 MB\n"}}
    sandbox_memory_integrity_test.go:70: Command [bash] output: event:{data:{stderr:"479+0 records in\n479+0 records out\n502267904 bytes (502 MB, 479 MiB) copied, 2.33241 s, 215 MB/s\n"}}
    sandbox_memory_integrity_test.go:70: Command [bash] output: event:{data:{stderr:"\tCommand being timed: \"dd if=/dev/urandom of=/mnt/testfile bs=1M count=479\"\n\tUser time (seconds): 0.00\n\tSystem time (seconds): 2.32\n\tPercent of CPU this job got: 99%\n\tElapsed (wall clock) time (h:mm:ss or m:ss): 0:02.34\n\tAverage shared text size (kbytes): 0\n\tAverage unshared data size (kbytes): 0\n\tAverage stack size (kbytes): 0\n\tAverage total size (kbytes): 0\n\tMaximum resident set size (kbytes): 2656\n\tAverage resident set size (kbytes): 0\n\tMajor (requiring I/O) page faults: 2\n\tMinor (reclaiming a frame) page faults: 343\n\tVoluntary context switches: 3\n\tInvoluntary context switches: 8\n\tSwaps: 0\n\tFile system inputs: 176\n\tFile system outputs: 0\n\tSocket messages sent: 0\n\tSocket messages received: 0\n\tSignals delivered: 0\n\tPage size (bytes): 4096\n\tExit status: 0\n"}}
    sandbox_memory_integrity_test.go:70: Command [bash] output: event:{data:{stdout:"Used memory after tmpfs mount and file fill: 668 MB\n"}}
    sandbox_memory_integrity_test.go:70: Command [bash] output: event:{end:{exited:true  status:"exit status 0"}}
    sandbox_memory_integrity_test.go:70: Command [bash] completed successfully in sandbox izyv1fafjbp3a35s9zhxp
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
    sandbox_memory_integrity_test.go:80: Command [bash] output: event:{start:{pid:417}}
Executing command bash in sandbox idiw3zetla1x5ktajws58 (user: root)
    sandbox_memory_integrity_test.go:80: Command [bash] output: event:{data:{stdout:"9a4d310fa857f321135b8322dfa91cf99239b3ec61ac68df97930b35e894f76b\n"}}
    sandbox_memory_integrity_test.go:80: Command [bash] output: event:{end:{exited:true  status:"exit status 0"}}
    sandbox_memory_integrity_test.go:80: Command [bash] completed successfully in sandbox izyv1fafjbp3a35s9zhxp
    sandbox_memory_integrity_test.go:80: Command [bash] output: event:{start:{pid:421}}
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
Executing command bash in sandbox izyv1fafjbp3a35s9zhxp (user: root)
    sandbox_memory_integrity_test.go:110: 
        	Error Trace:	.../tests/orchestrator/sandbox_memory_integrity_test.go:81
        	            				.../hostedtoolcache/go/1.26.3.../src/runtime/asm_amd64.s:1771
        	Error:      	Received unexpected error:
        	            	failed to execute command bash in sandbox izyv1fafjbp3a35s9zhxp: unavailable: HTTP status 502 Bad Gateway
    sandbox_memory_integrity_test.go:110: 
        	Error Trace:	.../tests/orchestrator/sandbox_memory_integrity_test.go:78
        	            				.../tests/orchestrator/sandbox_memory_integrity_test.go:110
        	Error:      	Condition never satisfied
        	Test:       	TestSandboxMemoryIntegrity/tmpfs_hash
--- FAIL: TestSandboxMemoryIntegrity/tmpfs_hash (201.66s)
github.com/e2b-dev/infra/tests/integration/internal/tests/proxies::TestSandboxAutoResumeViaProxy

Flake rate in main: 39.77% (Passed 907 times, Failed 599 times)

Stack Traces | 14s run time
=== RUN   TestSandboxAutoResumeViaProxy
=== PAUSE TestSandboxAutoResumeViaProxy
=== CONT  TestSandboxAutoResumeViaProxy
Executing command ls in sandbox i2yz7tcwnnhkv54vhy66f
    auto_resume_test.go:116: 
        	Error Trace:	.../tests/proxies/auto_resume_test.go:116
        	Error:      	Received unexpected error:
        	            	Get "http://localhost:3002": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
        	Test:       	TestSandboxAutoResumeViaProxy
--- FAIL: TestSandboxAutoResumeViaProxy (14.04s)
Executing command cat in sandbox i58zqrcihoikwcs52ovw7 (user: root)

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

There are no critical findings or feedback to provide on these changes.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@mishushakov mishushakov marked this pull request as draft June 6, 2026 12:45
Comment thread packages/orchestrator/pkg/template/build/phases/base/provision.sh
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 49bfe8ea6d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/orchestrator/pkg/template/build/phases/base/provision.sh Outdated
Comment thread packages/orchestrator/pkg/template/build/phases/base/provision.sh
Comment thread packages/orchestrator/pkg/template/build/phases/base/provision.sh
…s distros

Addresses integration test failures and PR review on non-Debian base images:

- user.go: replace Debian-only `adduser` with `useradd -m -s /bin/bash`
  (shadow-utils, present on all supported distros) — fixes "create user:
  exit 127" on Arch/openSUSE. Add user to `wheel` group as fallback when
  `sudo` group is absent (RHEL/Fedora/openSUSE/Arch).
- provision.sh: pass `--allowerasing` to dnf/yum so the preinstalled
  curl-minimal is swapped for curl instead of failing the transaction
  (fixes AlmaLinux provisioning).
- provision.sh: run update-ca-certificates and update-ca-trust sequentially
  (not if/elif) and fall back to symlinking the distro bundle, so the
  Debian-style /etc/ssl/certs/ca-certificates.crt always exists on openSUSE.
- rootfs.go: drop the static chrony.service wants symlink that dangled on
  non-Debian images; provision.sh now enables the correct unit for all distros.
- build_template_test.go: assert the CA bundle path exists per distro family.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread packages/orchestrator/pkg/template/build/commands/user.go
…portable

Second round of cross-distro fixes after CI:

- provision.sh: add the passwd/useradd/usermod provider package per family
  (passwd on Debian, shadow-utils+passwd on RHEL, shadow on SUSE/Arch).
  Minimal almalinux:9 ships without `passwd`, so `passwd -d root` failed
  with "command not found" and aborted provisioning under `set -eu`.
- configure.sh (finalize): replace Debian-only `adduser` with `useradd`,
  guard on an existing user, copy skel explicitly, and make the admin-group
  add tolerant (sudo -> wheel -> skip) — fixes arch's `usermod -aG sudo`
  exit 6. The /etc/sudoers entry is what grants privileges.
- user.go: make the wheel fallback best-effort too (openSUSE ships neither
  sudo nor wheel group) so group membership never fails the build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread packages/orchestrator/pkg/template/build/phases/base/provision.sh
On RHEL 9 / AlmaLinux 9 the iptables command ships in the iptables-nft
package; bare "iptables" is only a virtual provide, so `dnf install iptables`
succeeds but `rpm -q iptables` never matches. Use iptables-nft in the rhel
package list and in the fedora/almalinux integration test cases. openSUSE
(real `iptables` package) and Arch are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 61aa403. Configure here.

Comment thread packages/orchestrator/pkg/template/build/phases/base/provision.sh
mishushakov and others added 2 commits June 6, 2026 16:36
…malinux)

Fedora takes the identical "rhel" provisioning path as AlmaLinux (same
PKG_FAMILY, package list, and install commands), so it adds no provisioning
coverage. The fedora:40 base is also the heaviest image and, when all distro
cases run in parallel, boots past envd's init timeout under CI node
contention — a test-harness/boot-time issue, not a provisioning bug. Keep
AlmaLinux for dnf/RHEL-family coverage; Fedora remains supported at runtime.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
openSUSE was the only distro exercising the zypper path, and its base ships
neither a usable Debian-style CA bundle path nor a sudo/wheel group, requiring
SUSE-specific provisioning branches. Drop support rather than carry that
surface for a single family:

- provision.sh: remove the zypper detection branch, the suse package list and
  install branch, and the suse package-presence check. openSUSE now falls
  through to the clear "no supported package manager" rejection.
- provision.sh: trim the CA-bundle fallback to the /etc/pki source (RHEL);
  the /var/lib/ca-certificates and /etc/ssl/ca-bundle.pem sources were
  SUSE-only. The wheel-group fallback in user.go/configure.sh stays — RHEL
  and Arch still need it.
- README: move openSUSE from supported families to the unsupported note.
- integration: remove the opensuse template-build case.

Supported families remain Debian/Ubuntu (apt), Fedora/RHEL/Rocky/Alma
(dnf/yum/microdnf), and Arch (pacman).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant