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.
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).
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
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.
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
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.