Skip to content

v0.2.0

Choose a tag to compare

@ananthb ananthb released this 27 Mar 20:55
· 40 commits to main since this release

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