snix/tvix/boot
Florian Klink 1acf37c054 feat(tvix/boot/tests): reenable
This got disabled in 5f17df8548 without
much investigation.

After some more digging, I found the root cause -
173de320197ba97f2daf46b7d229055cd3732df4 in nixpkgs changed the files
produced by `mkBinaryCache` to use FileHash, not NarHash to name NAR
files.

While this is more correct and consistent with how it's produced by Nix,
it unfortunately means our uploads will now get rejected.
We didn't notice this, as curl (and rush) were not configured to bail
out - which now is the case again.

Deal with the change, by decompressing twice, once to get the NarHash
again, the second time to feed the data to curl.

Change-Id: Ic1deb470801250e7967083ac78cd46be39f3caa3
Reviewed-on: https://cl.tvl.fyi/c/depot/+/13122
Reviewed-by: Ilan Joselevich <personal@ilanjoselevich.com>
Tested-by: BuildkiteCI
Autosubmit: flokli <flokli@flokli.de>
2025-02-17 07:49:39 +00:00
..
tests feat(tvix/boot/tests): reenable 2025-02-17 07:49:39 +00:00
default.nix feat(tvix/boot): Use buildGoModule instead of buildGo for tvix-init 2024-08-19 12:42:44 +00:00
README.md chore(tvix/[ca]store): Drop sled support completely in favor of redb 2024-10-03 18:16:03 +00:00
tvix-init.go chore(tvix/tests): rename to //tvix/boot 2023-09-25 12:46:10 +00:00

tvix/boot

This directory provides tooling to boot VMs with /nix/store provided by virtiofs.

In the tests/ subdirectory, there's some integration tests.

//tvix/boot:runVM

A script spinning up a tvix-store virtiofs daemon, then starting a cloud- hypervisor VM.

The cloud-hypervisor VM is using a (semi-)minimal kernel image with virtiofs support, and a custom initrd (using u-root). It supports various command line options, to be able to do VM tests, act as an interactive shell or exec a binary from a closure.

It supports the following env vars:

  • CH_NUM_CPUS=1 controls the number of CPUs available to the VM
  • CH_MEM_SIZE=512M controls the memory availabe to the VM
  • CH_CMDLINE= controls the kernel cmdline (which can be used to control the boot)

Usage

First, ensure you have tvix-store in $PATH, as that's what run-tvix-vm expects:

Assuming you ran cargo build --profile=release-with-debug before, and are in the tvix directory:

export PATH=$PATH:$PWD/target/release-with-debug

Now, spin up tvix-daemon, connecting to some (local) backends:

tvix-store --otlp=false daemon \
  --blob-service-addr=objectstore+file://$PWD/blobs \
  --directory-service-addr=redb://$PWD/directories.redb \
  --path-info-service-addr=redb://$PWD/pathinfo.redb &

Copy some data into tvix-store (we use nar-bridge for this for now):

mg run //tvix:nar-bridge -- --otlp=false &
rm -Rf ~/.cache/nix; nix copy --to http://localhost:9000\?compression\=none $(mg build //third_party/nixpkgs:hello)
pkill nar-bridge

By default, the tvix-store virtiofs command used in the runVM script connects to a running tvix-store daemon via gRPC - in which case you want to keep tvix-store daemon running.

In case you want to have tvix-store virtiofs open the stores directly, kill tvix-store daemon too, and export the addresses from above:

pkill tvix-store
export BLOB_SERVICE_ADDR=objectstore+file://$PWD/blobs
export DIRECTORY_SERVICE_ADDR=redb://$PWD/directories.redb
export PATH_INFO_SERVICE_ADDR=redb://$PWD/pathinfo.redb

Interactive shell

Run the VM like this:

CH_CMDLINE=tvix.shell mg run //tvix/boot:runVM --

You'll get dropped into an interactive shell, from which you can do things with the store:

  ______      _         ____      _ __
 /_  __/   __(_)  __   /  _/___  (_) /_
  / / | | / / / |/_/   / // __ \/ / __/
 / /  | |/ / />  <   _/ // / / / / /_
/_/   |___/_/_/|_|  /___/_/ /_/_/\__/

/# ls -la /nix/store/
dr-xr-xr-x root 0 0   Jan  1 00:00 .
dr-xr-xr-x root 0 989 Jan  1 00:00 aw2fw9ag10wr9pf0qk4nk5sxi0q0bn56-glibc-2.37-8
dr-xr-xr-x root 0 3   Jan  1 00:00 jbwb8d8l28lg9z0xzl784wyb9vlbwss6-xgcc-12.3.0-libgcc
dr-xr-xr-x root 0 82  Jan  1 00:00 k8ivghpggjrq1n49xp8sj116i4sh8lia-libidn2-2.3.4
dr-xr-xr-x root 0 141 Jan  1 00:00 mdi7lvrn2mx7rfzv3fdq3v5yw8swiks6-hello-2.12.1
dr-xr-xr-x root 0 5   Jan  1 00:00 s2gi8pfjszy6rq3ydx0z1vwbbskw994i-libunistring-1.1

Once you exit the shell, the VM will power off itself.

Execute a specific binary

Run the VM like this:

hello_cmd=$(mg build //third_party/nixpkgs:hello)/bin/hello
CH_CMDLINE=tvix.run=$hello_cmd mg run //tvix/boot:runVM --

Observe it executing the file (and closure) from the tvix-store:

[    0.277486] Run /init as init process
  ______      _         ____      _ __
 /_  __/   __(_)  __   /  _/___  (_) /_
  / / | | / / / |/_/   / // __ \/ / __/
 / /  | |/ / />  <   _/ // / / / / /_
/_/   |___/_/_/|_|  /___/_/ /_/_/\__/

Hello, world!
2023/09/24 21:10:19 Nothing left to be done, powering off.
[    0.299122] ACPI: PM: Preparing to enter system sleep state S5
[    0.299422] reboot: Power down

Boot a NixOS system closure

It's also possible to boot a system closure. To do this, tvix-init honors the init= cmdline option, and will switch_root to it.

Make sure to first copy that system closure into tvix-store, using a similar nix copy comamnd as above.

CH_CMDLINE=init=/nix/store/…-nixos-system-…/init mg run //tvix/boot:runVM --
  ______      _         ____      _ __
 /_  __/   __(_)  __   /  _/___  (_) /_
  / / | | / / / |/_/   / // __ \/ / __/
 / /  | |/ / />  <   _/ // / / / / /_
/_/   |___/_/_/|_|  /___/_/ /_/_/\__/

2023/09/24 21:16:43 switch_root: moving mounts
2023/09/24 21:16:43 switch_root: Skipping "/run" as the dir does not exist
2023/09/24 21:16:43 switch_root: Changing directory
2023/09/24 21:16:43 switch_root: Moving /
2023/09/24 21:16:43 switch_root: Changing root!
2023/09/24 21:16:43 switch_root: Deleting old /
2023/09/24 21:16:43 switch_root: executing init

<<< NixOS Stage 2 >>>

[    0.322096] booting system configuration /nix/store/g657sdxinpqfcdv0162zmb8vv9b5c4c5-nixos-system-client-23.11.git.82102fc37da
running activation script...
setting up /etc...
starting systemd...
[    0.980740] systemd[1]: systemd 253.6 running in system mode (+PAM +AUDIT -SELINUX +APPARMOR +IMA +SMACK +SECCOMP +GCRYPT -GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 -PWQUALITY +P11KIT -QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD +BPF_FRAMEWORK -XKBCOMMON +UTMP -SYSVINIT default-hierarchy=unified)

This effectively replaces the NixOS Stage 1 entirely.