feat(cli): add template rebuild --refresh-envd - #1818
Conversation
Old templates bake an old envd into their final snapshot, so a sandbox started from one resumes the old envd and can't use features gated on a newer envd (e.g. volume mounts need envd >= 0.5.14). The only fix is a rebuild, which users have been scripting by hand against the raw API -- easy to get wrong (specs silently drop to 2 vCPU / 1024 MiB, alias orphaned under a fresh template id). Add `e2b template rebuild <template> --refresh-envd`: one command that calls the companion server endpoint, which derives a new build FROM the template's own latest ready build (base layer cached, only the envd binary swapped) and inherits the source specs and alias in place. Streams build logs until ready. The command is CLI-only (raw endpoint via client.api + the public Template.getBuildStatus for polling), so no js/python SDK public-surface change and no parity burden. Preview note: spec/openapi.yml and packages/js-sdk/src/api/schema.gen.ts carry the new endpoint so this compiles, but spec/ is normally synced from e2b-dev/infra via Copybara. Once the companion endpoint (e2b-dev/runtime#3624) merges, bump spec/infra-ref and re-run `make codegen` -- that regenerates these two files identically and the manual preview drops out. Signed-off-by: AdaAibaby <shaolila@buaa.edu.cn>
🦋 Changeset detectedLatest commit: 9650937 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
TASTE.md review
Checked the changed files (packages/cli/src/commands/template/rebuild.ts, index.ts, the test, changeset, spec/openapi.yml, schema.gen.ts) against TASTE.md — API shape (T-3, T-7, T-9, T-12, T-14), timeouts/defaults (T-47), errors (T-32, T-61, T-62), and SDK parity (T-1/T-2, not applicable since no SDK surface changes).
Violations: 1 (inline, T-14 — the required boolean --refresh-envd flag is really a mode selector).
Compliant / notable:
- Poll interval in a named constant (
buildStatusPollFrequencyMs) rather than a magic number — T-47. - Accepts template ID or alias in one argument — T-7.
- Refusal message says what to do next — T-62.
- Polls via public
Template.getBuildStatusinstead of adding new SDK surface, so no JS/Python parity work is required — T-1.
Not tied to a line:
spec/openapi.yml/schema.gen.tsare hand-authored previews; perAGENTS.mdthese must be replaced by bumpingspec/infra-refand runningmake codegenafter e2b-dev/runtime#3624 merges (the PR already says so — flagging as a merge blocker, not a TASTE issue).- The
for (;;)drain loop reimplements the js-sdk's internalwaitForBuildFinish(packages/js-sdk/src/template/buildApi.ts). Not a TASTE violation, but if the SDK ever exposes a public wait/poll helper, the CLI should switch to it rather than carry a second copy of the terminal-status log-drain logic.
|
Hey, thanks for the PR - we'll handle this one internally. |
@mishushakov Thanks for taking this over internally! Just a gentle follow-up — we currently have a lot of older templates running on low envd versions that require migration for volume mount compatibility. Would you have a rough timeline for when this |
Summary
Old templates bake an old envd into their final snapshot, so a sandbox started from one resumes the old envd out of snapshot RAM. That blocks features gated on a newer envd — e.g. volume mounts need envd ≥ 0.5.14. The only way to lift such a template is a rebuild, and users have been scripting that by hand against the raw API, which has two footguns:
Change
Adds
e2b template rebuild <template> --refresh-envd(aliasrb). It calls the companion server endpointPOST /v2/templates/{templateID}/refresh-envd, which derives a new build FROM the template's own latest ready build (base layer cached, only the envd binary swapped) and inherits the source build's cpu/ram and alias in place. The command then streams build logs via the existing status endpoint until the new build is ready.Scope is deliberately CLI-only: it calls the raw endpoint through
client.api(thepublishcommand's pattern) and polls with the already-publicTemplate.getBuildStatus. No js-sdk / python-sdk public surface changes, so no JS/Python parity work.Usage
Without the flag it refuses (the flag is the only rebuild mode today, and gates a destructive-ish rebuild behind an explicit opt-in):
Companion infra PR (server half)
This is the client half. The server endpoint it calls is added in e2b-dev/runtime#3624 — e2b-dev/runtime#3624. That PR traces the full root cause (memory-snapshot resume keeps the old envd; live-upgrade is gated at envd ≥ 0.6.12; offline-upgrade only runs on the cold-boot path) and implements the endpoint that derives the cached-source-layer build which swaps envd.
Merge order: infra#3624 first, then here.
Tests run
pnpm --filter @e2b/cli run typecheck— OK (new typed path resolves).pnpm --filter @e2b/cli run build— OK.pnpm --filter @e2b/cli run lint— 0 warnings / 0 errors.pnpm --filter @e2b/cli run format— clean.pnpm --filter e2b run typecheck(js-sdk) — OK (schema change doesn't break the SDK).vitest run tests/commands/template/rebuild.test.ts— PASS (2 tests: refuses without--refresh-envd; command registered + documented). The rest of the CLI suite passes; the only failure in a full run is the pre-existingcreate.test.tsbackend-integration test, which is gated on a liveE2B_API_KEYand unrelated to this change.A changeset (
@e2b/cli: minor) is included perAGENTS.md.AI assistance
AI assistance was used to trace the resume/build call chains, design the command, and draft the code and tests. A human submitter has reviewed every changed line.