Repository navigation
Releases: terrarium-sh/terrarium
Release list
v0.4.0-alpha.3
v0.3.1-beta
Updated dependencies.
Full Changelog: v0.3.0-alpha.2...v0.3.1-beta
v0.3.0-beta
Upgrading from 0.2.0-beta: rebuild every box.
terra <box> stop # if it is running
terra <box> setup --rebuildBoxes made by 0.2.0-beta do not boot on 0.3.0-beta. terra ls shows them as
needs_setup and terra <box> refuses to start them with a pointer to setup.
This is a real rebuild, not a re-pin: 0.3 prepares a box's root filesystem only
during setup and never during boot, and the root it prepares is the new layout
(workload user and home baked into the image, per-boot files symlinked under
/run/terra, mount points created up front). An image left by 0.2 does not have
that shape, and reusing it is what --rebuild is for.
A rebuild replaces the root filesystem: installed packages, edits under /etc,
and the workload's home (/home/terri) are gone, and on_create runs again
from a clean image. lifetime: box volumes keep their data, and mounts are
untouched. Run terra <box> storage export first if the root holds anything you
cannot recreate with on_create.
Setup and boot are now two separate steps
terra <box>only boots a box thatsetupfinished. It never pins a recipe,
never builds a filesystem and never runson_create.- A recipe path belongs to
setupandshowonly:terra ./ci.yaml setup,
notterra ./ci.yaml. terra <box> setuprunson_createin an isolated VM with no shares, grows
the root andlifetime: boxvolume images, and creates the directories, user
and mount points the boot expects. Running it again on an unchanged recipe
boots no VM.- A box whose setup is unfinished, whose pinned recipe changed, or whose root
image was imported isneeds_setupuntilsetupcompletes.
terra ls --state needs_setupfinds them;stoppedno longer means "ready to
start" for those. terra <box>still boots the pinned recipe when yourterra.yamlhas moved
on, but now says so instead of silently re-pinning.
Read-only root
hw.rootfs_readonly: true opens the root image read-only on the host, so not
even guest root can change it after setup. on_create still writes it during
setup. Without an overlay volume, every later root write fails with EROFS
(apk add, sudo, terra exec --root, terra sync, and /home/terri), while
/tmp, /var/tmp and /run stay tmpfs in guest RAM.
Overlay volume
A volume with rootfs_overlay: true makes a read-only root writable for exactly
one boot: the image below stays untouched, the volume takes the writes, and the
next boot starts from the image again. It needs hw.rootfs_readonly: true and
lifetime: boot, and a box has at most one. EXDEV on directory renames from
the lower layer, inode changes on first write, and hard-link splits come with
overlays and are documented.
Volume lifetimes
lifetime: box (the default) keeps data across restarts. lifetime: boot gives
the volume an empty filesystem of its configured size on every boot, can shrink
as well as grow, and is deleted when the VM exits; storage export leaves it
out.
Containers
Rootless podman works as terri out of the box: subordinate IDs and a
guest-suitable containers.conf ship in the image. On a read-only root, point
graphroot at a volume — podman cannot keep storage on the overlay or on the
read-only root. docs/recipe.md#containers has the recipe.
Smaller changes
- Volume and root images are created by
setup, and a missinglifetime: box
volume at boot is refused with a pointer tosetup. storage importof a root image needsterra <box> setupbefore the box will
boot.terra setup --rebuildstill removes volume images the recipe no longer
names.- Wording throughout changes "bake" to "setup"; a box being prepared reports
setting_uprather than looking like a running workload.
v0.3.0-alpha.2
v0.3.0-alpha.1
v0.2.0-beta
Changes since v0.1.0-beta.
Highlights
- Faster starts and less memory per box. The guest kernel and boot disk are now compressed in chunks and read straight into guest memory. The code that runs a box's devices now runs directly from the terra binary, and all boxes share it instead of each holding a private copy. On our Linux test host, starting a box dropped from about 260 ms to about 145 ms, and each VM uses about 7 MB less private memory.
- Idle boxes use almost no CPU. A per-box background timer thread is gone, so an idle box wakes the host about 6 times a second instead of about 110.
- Each guest's hostname is its box name. The name is turned into a valid hostname: lowercase, with
.and_replaced by-. - An agent skill for coding assistants.
skills/terra-box/SKILL.mdteaches AI coding agents how to use terra boxes, and the website serves it at/skill.md. - Graceful stop under systemd. Stopping a
terra@unit now stops the box gracefully, sopre_stophooks and the guest's final disk sync run.
Windows
- Device code now runs from the terra binary on Windows too. Windows' Control Flow Guard (CFG) security check would otherwise block it.
- Rapid repeated writes to a shared file no longer flood the guest with duplicate file-change notifications, so later changes are no longer delayed.
Installers
curl … | shandirm … | iexare safe to pipe: a download cut off midway runs nothing. You can choose the version withTERRA_VERSIONorTERRA_PRERELEASE.- The Windows installer keeps
%VAR%entries in your user PATH when it adds terra.
Behavior changes
- In allowlist mode, or when a box defines
hostsrecords, anallowrule for port 53 is now refused, because all guest DNS goes through terra's resolver. A config containing one will no longer load. - Share names containing
\or:are refused on every host.
Fixes
- A guest with more than one CPU that rebooted or panicked could hang its box instead of ending it.
- A volume whose name differed from another only by letter case (
Data/data) could be pruned as unused while in use. - On Linux, a share whose parent directory you can enter but not list now mounts, as it already did on macOS and Windows.
- Shared-directory and network hardening, plus a new fuzzer that checks guest file operations on shares never change anything outside the share.
Under the hood
- Updated to Wasmtime 50.
Full Changelog: v0.1.0-beta...v0.2.0-beta
v0.2.0-alpha.2
What's Changed
- build: update kernel pins by @github-actions[bot] in #57
- build: update rust pins by @github-actions[bot] in #58
- build: update containers pins by @github-actions[bot] in #59
- build(deps-dev): bump vite from 7.3.6 to 7.3.7 in /web in the npm_and_yarn group across 1 directory by @dependabot[bot] in #60
New Contributors
- @github-actions[bot] made their first contribution in #57
Full Changelog: v0.1.0-beta...v0.2.0-alpha.2
v0.1.0-beta
Full Changelog: v0.1.0-alpha.5...v0.1.0-beta