Nixmaker: Tool to convert a flake to a tarball per each NixOS config

I was inspired by the huge effort of @iFreilicht answering @mark.c 's question and I decided to start working on Nixmaker.

Most of NixOS deployment tools are missing one feature. They don’t have any other option than SSH. And that makes sense since the nix itself understands ssh://.

One deployment tool that is not limited to pull model or SSH is fantastic Bento from @Solene. The only downside of Bento is that it requires a specific layout and my preference is to have no limitations on how to structure the flake repository.

Nixmaker is a CLI tool that takes a flake and creates a tarball for each NixOS host.

Benefits

  • The initial resource-intensive evaluation is done by the host running Nixmaker. The actual build which will be in most cases served from cache is done by the target.
  • The flake repository doesn’t need to be copied to the target and therefore target won’t store easily readable code and values about other hosts in the flake.
  • Tarballs are relatively small (in MiB) and can be served by either push, pull or sneakernet.

How to use the tool

  • List hosts
nix run github:rudolfvesely/nixmaker -- list --flake sample/ --directory /tmp
  • Build tarballs
nix run github:rudolfvesely/nixmaker -- build --flake sample/ --directory /tmp

Deploy a tarball by

mkdir /tmp/tobuild && tar -xf /tmp/second/second.tar.gz -C $_
nix shell nixpkgs#nix # more current nix
drv=$(head -n1 /tmp/second/meta)
nix store ls --store /tmp/tobuild $drv
nix copy --from /tmp/tobuild $drv
nix build "$drv^*"
path=$(tail -n1 /tmp/second/meta)
$path/bin/switch-to-configuration # switch|boot|test|dry-activate

This is definitely WIP and I’m interested in ideas how to modify existing deployment tools or create new projects that can use such tarballs.

11 Likes

This is great. It just works :wink: . Something like this I imagined when I started the linked thread.

$path/bin/switch-to-configuration # switch|boot|test|dry-activate

Unfortunately, switch-to-configuration boot doesn’t work. See NixOS: switch-to-configuration script does not correctly add a boot entry when executed standalone · Issue #82851 · NixOS/nixpkgs · GitHub.

Nice ! So sad this is not included by default !

Quick question… Is the archive reproducible ?

Usually we strip the modification time from tar, but I don’t see it in your code.

Also, you should do your script inside the flake nix file with writeShellApplication, so you can have shellcheck running on it by default, you don’t have to declare the shebang and use the tar binary provided by the script runtimeInputs attribute (and maybe some other binaries if needed).

Also, you could use [bashly](https://github.com/DannyBen/bashly) to generate your bash script, but it’s not yet available in Nix… but it will be in less than 1 week ! (bashly: init at 1.1.1 by drupol · Pull Request #262340 · NixOS/nixpkgs · GitHub)

2 Likes

Very cool idea! I would just like to point out that in the end we did find a way to do this with nix copy directly (cc @drupol), and I see you’re using it as well for the deployment:

So I guess a next step would be to automate that as well? A simple

nix run github:rudolfvesely/nixmaker -- switch --tarball /tmp/second/second.tar.gz

would make the workflow super sleek.

(Also, who is this @iFreilichtBob guy? :wink:)

Thank you for your feedback @drupol . I’ll add that.

I use mkDerivation so I can copy README.md into /share and in future I just need to add a single line to copy man page.

I want to declare shebang, the script has to run as it is when you just download it from Github. That’s important for other maintainers.

I use patsh and this amazing tool replaces every single binary in the script by full path.

Thank you for pointing this out @bjornfor . It worked for me but I’ll try again to make sure. And this is exactly how nixos-rebuild does it.

I guess markdown spell-check in VSCode. Thank you, I’ll fix that.

Yes! I needed an initial feedback if this tool makes sense and thank you everybody for it. And thank you @iFreilicht for the great debugging/research work.

2 Likes

Actually, I think this is perfect as a concept to test with a separate repository like yours, and once you found a good implementation and the concept is proven to work, it might make sense to integrate into nixos-rebuild directly. Just imagine the magic of

nixos-rebuild build-tarball --flake .#myserver
nixos-rebuild switch --tarball myserver.tar.gz

Perfection.

Absolutely. Another option:

... | nixos-rebuild switch --tarball -

Also nixos-rebuild is already clever enough to build new nix which is a problem you had in the thread when the old version of nix didn’t work. This is the reason why nixos-rebuild works like a magic all the time - it hides a lot of complexity from the user.

1 Like