-
Notifications
You must be signed in to change notification settings - Fork 436
feat(orch): distro-aware template base-image provisioning #3411
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
89ea91b
feat(orch): distro-aware template base-image provisioning
tomassrnka c5c9f88
fix(envd): degrade process-priority helpers when the image lacks them
tomassrnka 73df3d7
fix(orch): document Arch CA bundle needs no manual link
tomassrnka 6e03a1d
fix(orch): install ionice on Alpine so user processes leave realtime IO
tomassrnka d7408b3
fix(orch): refresh the CA trust store per family when packing and see…
tomassrnka ae044bb
fix(orch): keep the finalize cert pack Debian-only
tomassrnka 2f59d46
fix(orch): put -R before the mode in configure.sh chmods
tomassrnka 5f3899f
chore(envd): bump version to 0.6.12
tomassrnka c4ed072
fix(orch): enable the SSH unit on the systemd families
tomassrnka 418d925
chore(orch): make the OpenRC no-networking warning consistent
tomassrnka 0a71d3f
fix(orch): don't declare RHEL, Oracle Linux or Amazon Linux support
tomassrnka 5f123d1
Merge branch 'main' into feat/multi-distro-base-images
tomassrnka e91e5a4
refactor(envd): name the priority wrapper after its tools and lift io…
tomassrnka 45ecb71
fix(orch): surface the fsfreeze fallback in customer build logs
tomassrnka 57ceb93
chore(orch): chain the debian install with && instead of an embedded …
tomassrnka f98cec9
refactor(orch): source the admin group from the distro profile in lat…
tomassrnka 482c811
Merge branch 'main' into feat/multi-distro-base-images
tomassrnka 455de1e
fix(orch): pass --allowerasing after the dnf subcommand
tomassrnka 06f2fa9
fix(orch): tolerate templates provisioned before distro.env existed
tomassrnka File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
packages/envd/internal/services/process/handler/handler_test.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| package handler | ||
|
|
||
| import ( | ||
| "errors" | ||
| "testing" | ||
|
|
||
| "github.com/stretchr/testify/assert" | ||
| ) | ||
|
|
||
| // The process wrapper must degrade cleanly when the priority helpers are absent | ||
| // — the user command still runs; a present helper is applied with its resolved | ||
| // path. | ||
| func TestWrapperPrefix(t *testing.T) { | ||
| t.Parallel() | ||
|
|
||
| notFound := func(string) (string, error) { return "", errors.New("not found") } | ||
| all := func(name string) (string, error) { return "/usr/bin/" + name, nil } | ||
| only := func(want string) func(string) (string, error) { | ||
| return func(name string) (string, error) { | ||
| if name == want { | ||
| return "/bin/" + name, nil | ||
| } | ||
|
|
||
| return "", errors.New("not found") | ||
| } | ||
| } | ||
|
|
||
| t.Run("both present", func(t *testing.T) { | ||
| t.Parallel() | ||
| assert.Equal(t, "/usr/bin/ionice -c 2 -n 4 /usr/bin/nice -n 5 ", ioniceNicePrefix(2, 4, 5, all)) | ||
| }) | ||
|
|
||
| t.Run("both absent degrades to bare exec", func(t *testing.T) { | ||
| t.Parallel() | ||
| assert.Empty(t, ioniceNicePrefix(2, 4, 5, notFound)) | ||
| }) | ||
|
|
||
| t.Run("only nice", func(t *testing.T) { | ||
| t.Parallel() | ||
| assert.Equal(t, "/bin/nice -n -3 ", ioniceNicePrefix(2, 4, -3, only("nice"))) | ||
| }) | ||
|
|
||
| t.Run("only ionice", func(t *testing.T) { | ||
| t.Parallel() | ||
| assert.Equal(t, "/bin/ionice -c 2 -n 4 ", ioniceNicePrefix(2, 4, 0, only("ionice"))) | ||
| }) | ||
|
|
||
| t.Run("class and priority are caller-controlled", func(t *testing.T) { | ||
| t.Parallel() | ||
| assert.Equal(t, "/bin/ionice -c 1 -n 6 ", ioniceNicePrefix(1, 6, 0, only("ionice"))) | ||
| }) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
packages/orchestrator/pkg/template/build/core/rootfs/files/envd.openrc.tpl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| {{- /*gotype:github.com/e2b-dev/infra/packages/orchestrator/pkg/template/build/core/rootfs.templateModel*/ -}} | ||
| {{ .WriteFile "/usr/local/share/e2b/envd.openrc" 0o755 }} | ||
|
|
||
| #!/sbin/openrc-run | ||
| # E2B env daemon — the OpenRC counterpart of envd.service (see envd.service.tpl | ||
| # for the full rationale on each step; this mirrors it for the Alpine/OpenRC | ||
| # family). Baked at a neutral path and installed to /etc/init.d/envd by the | ||
| # OpenRC e2b_init_setup only: if it lived in /etc/init.d on every image, | ||
| # Debian's `systemctl enable envd` would hand it to update-rc.d, which aborts | ||
| # on a non-LSB script and fails the whole provisioning. | ||
| # | ||
| # /tmp-wipe ordering note: OpenRC's bootmisc (boot runlevel) wipes /tmp before | ||
| # the default runlevel starts, so envd — in default — can never answer an | ||
| # update-envd upload before the wipe. The race envd.service needs an explicit | ||
| # After=systemd-tmpfiles-setup.service for cannot happen here. | ||
|
|
||
| description="E2B env daemon" | ||
|
|
||
| supervisor=supervise-daemon | ||
| command=/usr/bin/envd | ||
| # --nicelevel/--ionice/--oom-score-adj mirror envd.service's Nice=-20, | ||
| # IOSchedulingClass=realtime + IOSchedulingPriority=4 (ionice class 1, data 4) | ||
| # and OOMScoreAdjust=-1000 — without them envd runs at default priority and is | ||
| # the first OOM-kill candidate on Alpine. (The unit's cgroup weights — | ||
| # MemoryMin/CPUWeight/IOWeight — have no supervise-daemon equivalent.) | ||
| supervise_daemon_args="--nicelevel -20 --ionice 1:4 --oom-score-adj -1000 --env GOTRACEBACK=all --env GOMEMLIMIT={{ .MemoryLimit }}MiB --stdout /var/log/envd.log --stderr /var/log/envd.log" | ||
| # Retry forever (envd.service uses Restart=always + StartLimitIntervalSec=0). | ||
| respawn_delay=1 | ||
| respawn_max=0 | ||
|
|
||
| depend() { | ||
| need localmount | ||
| after bootmisc | ||
| use net | ||
| } | ||
|
|
||
| start_pre() { | ||
| # Shared with envd.service's ExecStartPre; warns-and-continues by design. | ||
| /usr/local/bin/e2b-seed-certs | ||
| # systemd-tmpfiles applies the fuse.conf tmpfiles.d rule on the systemd | ||
| # family; OpenRC has no tmpfiles pass, so set the mode here. | ||
| if [ -e /dev/fuse ]; then | ||
| chmod 666 /dev/fuse | ||
| fi | ||
| return 0 | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 9 additions & 11 deletions
20
packages/orchestrator/pkg/template/build/core/rootfs/files/inittab.tpl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,16 @@ | ||
| {{- /*gotype:github.com/e2b-dev/infra/packages/orchestrator/pkg/template/build/core/rootfs.templateModel*/ -}} | ||
| {{ .WriteFile "/etc/inittab" 0o777 }} | ||
|
|
||
| # Run system init | ||
| ::sysinit:/etc/init.d/rcS | ||
|
|
||
| # Run the provision script, prefix the output with a log prefix | ||
| ::wait:/bin/sh -c '/usr/local/bin/provision.sh 2>&1 | sed "s/^/{{ .ProvisionLogPrefix }}/"' | ||
| # Provisioning-boot inittab (busybox init). Every entry is a plain exec with | ||
| # NO shell metacharacters: busybox init hands metachar lines to /bin/sh, and | ||
| # minimal images (distroless) may have no /bin/sh — the pipeline logic lives in | ||
| # e2b-provision-runner instead. | ||
|
|
||
| # Flush filesystem changes to disk | ||
| ::wait:/usr/bin/busybox sync | ||
| ::wait:fsfreeze --freeze / | ||
| # Run system init (mounts /proc /sys /dev /tmp /run through the baked busybox) | ||
| ::sysinit:/etc/init.d/rcS | ||
|
|
||
| # Report the exit code of the provisioning script | ||
| ::wait:/bin/sh -c 'echo "{{ .ProvisionExitPrefix }}$(cat {{ .ProvisionResultPath }} || printf 1)"' | ||
| # Run the provisioning pipeline and report its exit code | ||
| ::wait:/usr/bin/busybox ash /usr/local/bin/e2b-provision-runner | ||
|
|
||
| # Wait forever to prevent the VM from exiting until the sandbox is paused and snapshot is taken | ||
| ::wait:/usr/bin/busybox sleep infinity | ||
| ::wait:/usr/bin/busybox sleep infinity |
34 changes: 34 additions & 0 deletions
34
packages/orchestrator/pkg/template/build/core/rootfs/files/provision-runner.sh.tpl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| {{- /*gotype:github.com/e2b-dev/infra/packages/orchestrator/pkg/template/build/core/rootfs.templateModel*/ -}} | ||
| {{ .WriteFile "usr/local/bin/e2b-provision-runner" 0o755 }} | ||
|
|
||
| #!/usr/bin/busybox ash | ||
| # Drives the provisioning pipeline for the busybox-init boot. This logic lives | ||
| # in a script — NOT in /etc/inittab — because busybox init hands any inittab | ||
| # line containing shell metacharacters to /bin/sh, and minimal images | ||
| # (distroless) may have no /bin/sh; a plain-exec inittab line running this | ||
| # script through the baked busybox works on every image. | ||
| BB=/usr/bin/busybox | ||
|
|
||
| # Run the provision script, prefix its output with the log prefix the | ||
| # orchestrator forwards to the customer's build logs. | ||
| $BB sh /usr/local/bin/provision.sh 2>&1 | $BB sed "s/^/{{ .ProvisionLogPrefix }}/" | ||
|
|
||
| # Flush filesystem changes to disk before the snapshot. | ||
| $BB sync | ||
| if command -v fsfreeze >/dev/null 2>&1; then | ||
| fsfreeze --freeze / | ||
| else | ||
| # No util-linux on this image; the double sync flushes the ext4 journal | ||
| # and the VM is paused before the snapshot is taken. Prefixed so the | ||
| # fallback shows up in the customer's build logs. | ||
| echo "{{ .ProvisionLogPrefix }}fsfreeze not available on this image; using sync-only flush" | ||
| $BB sync | ||
| fi | ||
|
|
||
| # Report the provisioning exit code: provision.sh writes "0" on success and | ||
| # (running under set -e) leaves no file behind on failure. | ||
| if result=$($BB cat {{ .ProvisionResultPath }} 2>/dev/null); then | ||
| echo "{{ .ProvisionExitPrefix }}${result}" | ||
| else | ||
| echo "{{ .ProvisionExitPrefix }}1" | ||
| fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
packages/orchestrator/pkg/template/build/core/rootfs/files/seed-certs.sh.tpl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| {{- /*gotype:github.com/e2b-dev/infra/packages/orchestrator/pkg/template/build/core/rootfs.templateModel*/ -}} | ||
| {{ .WriteFile "usr/local/bin/e2b-seed-certs" 0o755 }} | ||
|
|
||
| #!/bin/sh | ||
| # Seeds the tmpfs-backed /etc/ssl/certs before envd starts — shared by | ||
| # envd.service (systemd) and /etc/init.d/envd (OpenRC). See envd.service.tpl | ||
| # for the full rationale (why a tar, why a bind mount, the egress-CA contract). | ||
| # | ||
| # Every failure path here WARNS and continues deliberately: a sandbox with a | ||
| # degraded trust store is recoverable (envd's POST /init reinstalls the egress | ||
| # CA), a sandbox whose envd never starts is not. | ||
|
|
||
| # The copies DEREFERENCE symlinks (-L; the build-time tar already packs with | ||
| # -h): some images ship the /etc/ssl/certs bundle as symlinks into a read-only | ||
| # store, and envd's egress-proxy CA install APPENDS to | ||
| # /etc/ssl/certs/ca-certificates.crt — that only works if the tmpfs copy is a | ||
| # real file, not a copied symlink to an immutable target. | ||
| if ! mountpoint -q /etc/ssl/certs; then | ||
| mkdir -p /run/e2b/certs | ||
| if [ -f /usr/local/share/e2b/ssl-certs.tar ]; then | ||
| if ! tar -C /run/e2b/certs -xf /usr/local/share/e2b/ssl-certs.tar; then | ||
| echo "e2b-seed-certs: ssl-certs.tar extraction failed; seeding from the live cert dir instead" >&2 | ||
| cp -aL /etc/ssl/certs/. /run/e2b/certs/ | ||
| fi | ||
| else | ||
| # Only expected during the base-layer boot, before finalize packs the tar. | ||
| echo "e2b-seed-certs: ssl-certs.tar not packed yet; seeding from the live cert dir" | ||
| cp -aL /etc/ssl/certs/. /run/e2b/certs/ | ||
| fi | ||
| if ! mount -o bind /run/e2b/certs /etc/ssl/certs; then | ||
| echo "e2b-seed-certs: bind mount failed; envd runs with the image's certs as-is" >&2 | ||
| fi | ||
| fi | ||
|
|
||
| if [ ! -s /etc/ssl/certs/ca-certificates.crt ]; then | ||
| if command -v update-ca-certificates >/dev/null 2>&1; then | ||
| update-ca-certificates | ||
| elif command -v update-ca-trust >/dev/null 2>&1; then | ||
| # RHEL family and Arch refresh with update-ca-trust. Arch's extract emits | ||
| # the Debian-named bundle itself; RHEL keeps it under /etc/pki, and the | ||
| # symlink provisioning made was dereferenced into this tmpfs, so copy it. | ||
| update-ca-trust extract | ||
| if [ ! -s /etc/ssl/certs/ca-certificates.crt ] && [ -s /etc/pki/tls/certs/ca-bundle.crt ]; then | ||
| cp -L /etc/pki/tls/certs/ca-bundle.crt /etc/ssl/certs/ca-certificates.crt | ||
| fi | ||
| else | ||
| # Provisioning guarantees the bundle on every supported family; | ||
| # reaching this means the image diverged after the build. | ||
| echo "e2b-seed-certs: CA bundle missing and no CA refresh tool on this image; TLS trust will be degraded" >&2 | ||
| fi | ||
|
tomassrnka marked this conversation as resolved.
|
||
| fi | ||
|
|
||
| exit 0 | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.