Skip to content

Releases: ananthb/xenomorph

v0.3.1

28 Mar 11:03

Choose a tag to compare

xenomorph v0.3.1

Replace your running Linux root filesystem with a new one live, without rebooting.

Highlights

Zero external dependencies — xenomorph no longer shells out to tar, gzip, cp, or any other tool for core operations. Layer extraction uses Zig's std.tar and std.compress natively. The only remaining child processes are init system coordination (systemctl, rc-service) and Containerfile RUN commands (intentional chroot+exec).

Secure container isolationRUN commands in Containerfiles execute inside Linux namespaces (user, mount, PID, network) with a seccomp filter blocking 20 dangerous syscalls. Minimal /dev (5 devices via bind mount, not host /dev). Read-only /proc and /sys. Auto-detects the best isolation level and falls back gracefully.

Build caching — built rootfs images are cached as OCI layouts. Repeated pivot or build invocations with the same layers skip all image pulls and merging. CACHE_DIRECTORY env var support for systemd integration.

systemd rescue.target integration — NixOS module and systemd unit files for running xenomorph as a rescue target service. Cache warmup service pre-pulls images on boot so the pivot is instant. Ships with ready-to-use unit files in init/systemd/.

Dropbear SSH--ssh-port, --ssh-password, --ssh-keyfile install and start a dropbear SSH server in the new rootfs. Random password printed before fork if not specified. Firewall rules flushed by default (--keep-firewall to opt out).

In-memory logging — all log messages are captured in a memory buffer alongside stderr output. The buffer is written to <log_dir>/xenomorph.log in the new rootfs just before pivot, so logs survive the exec and are available after reconnecting. No dependency on the old root filesystem for log persistence.

OCI library extracted — all OCI operations (registry client, layer handling, Containerfile parsing, layout writing, container isolation) live in oci-zig, a standalone Zig library.

Breaking changes

  • --exec renamed to --entrypoint. Use --command/--cmd for arguments.
  • --tailscale flag removed. --tailscale-authkey adds the image and creates the init script.
  • --containerfile is mutually exclusive with --image/--rootfs.
  • xenomorph build with no -o flag is cache-only (no output written).
  • Release tarballs no longer include raw binaries or qemu-test.

New flags

  • --entrypoint <cmd> — entrypoint for the new rootfs (replaces --exec)
  • --command, --cmd <arg> — arguments passed to entrypoint (repeatable)
  • --ssh-port <port> — start dropbear SSH server
  • --ssh-password <pw> — set root password (default: random)
  • --ssh-keyfile <path> — install authorized_keys
  • --keep-firewall — don't flush iptables/nftables before pivot
  • --systemd-mode — skip init coordination and process kill (for systemd units)
  • --log-dir <path> — configurable log directory for headless mode
  • --tailscale-image <ref> — override the tailscale OCI image
  • --containerfile, --dockerfile — build from Containerfile
  • --context <dir> — build context for Containerfile
  • --rootfs-output <file> — also write a rootfs tarball from build

Bug fixes

  • Fix crash when pulling registry images (estimateImageSize catch block caused unreachable panic)
  • Fix aarch64 build (use clone syscall instead of fork which doesn't exist on arm64)
  • Fix work directory auto-creation (create parent dirs for tmpfs mount point)
  • Fix init script only created when services are actually configured
  • Deduplicate --image/--rootfs with normalized image references
  • Fix nix release build with upstream oci-spec-zig dependency

v0.2.0

27 Mar 20:55

Choose a tag to compare

xenomorph v0.2.0

Replace a running Linux root filesystem with a new one built from OCI images — live, without rebooting.

What's new

  • Native OCI registry client — xenomorph pulls container images directly using Zig's HTTP/TLS
    stack. No external tools (docker, curl, skopeo) required. Supports Docker Hub, GHCR, and any
    Docker-distribution-compatible registry with automatic authentication and multi-platform
    image resolution (x86_64, aarch64, armv7).

  • Multi-layer rootfs merging — combine multiple --image and --rootfs layers in a single
    command. Later layers overwrite earlier ones on file conflicts. Entrypoint, env vars, and
    working directory from OCI image configs are merged field-by-field (env merges by key).

  • Build subcommand — xenomorph build creates OCI images without pivoting. Use it to pre-warm
    the cache or produce images for later use with xenomorph pivot.

  • Build caching — built rootfs images are cached as OCI layouts. Repeated invocations with the
    same layers skip all image pulls and merging. Set CACHE_DIRECTORY or --cache-dir to control
    the cache location.

  • systemd rescue.target integration — run xenomorph as a systemd service that triggers on
    rescue.target. A warmup service pre-pulls images during normal boot so the pivot is instant.
    Ships with ready-to-use systemd unit files and a NixOS module.

  • Tailscale integration — --tailscale-authkey adds the Tailscale image, creates a startup
    script that runs tailscaled and authenticates, then execs your entrypoint. Combined with
    --headless, this lets you pivot a remote machine over SSH and reconnect via Tailscale.

  • Containerfile support — --containerfile parses Dockerfiles/Containerfiles (FROM, COPY, ADD,
    ENV, WORKDIR, ENTRYPOINT, CMD, LABEL, ARG). RUN is not yet supported.

  • Headless mode — --headless forks into the background before the pivot, surviving SSH
    disconnection. Logs to a configurable directory.

Breaking changes

  • --exec is now --entrypoint. Use --command/--cmd for arguments.
  • The image argument is no longer positional. Use --image or --rootfs .
  • --tailscale flag removed. Use --tailscale-authkey which implicitly adds the
    tailscale image.
  • Default image is docker.io/library/alpine:latest when no layers are specified.

Installation

Static binaries for Linux x86_64, aarch64, and armv7:

  curl -LO
  https://github.com/ananthb/xenomorph/releases/download/v0.2.0/xenomorph-x86_64-linux
  chmod +x xenomorph-x86_64-linux
  sudo mv xenomorph-x86_64-linux /usr/local/bin/xenomorph

Or with Nix:

nix run github:ananthb/xenomorph

Quick start

  # Pivot to alpine (default)
  sudo xenomorph pivot

  # Pivot with Tailscale over SSH
  sudo xenomorph pivot --headless --tailscale-authkey tskey-auth-xxxxx

  # Pre-warm the cache
  sudo xenomorph build --image alpine:latest --tailscale-authkey tskey-auth-xxxxx

  # Build an OCI image
  sudo xenomorph build --image alpine:latest --rootfs ./extra-files/ -o my-image.oci

Full Changelog: v0.1.0...v0.2.0

v0.1.0 - Initial Release

08 Feb 16:50

Choose a tag to compare

Xenomorph v0.1.0

Initial release of Xenomorph - a Linux pivot_root tool for OCI images.

  • Pivot a running Linux system into a new root filesystem
  • In-memory rootfs building from local images
  • Process termination for clean pivot
  • Switch-root fallback when pivot_root fails
  • Fully static binaries (no dependencies)