Build a system tarball without archiving at all?

Is there a way to build a directory of a nixos system like nixos-generators’s lxc format would do, but without archiving the content? Too much time is wasted in tar then untar while rsync should be must faster for my use case.

Btw, my use case is deploying nixos to a termux proot-distro environment. (It only partly works now, with systemd can’t start yet - I guess I should look into how Nixos-WSL achieved it)

Do you just mean you want to rsync all the /nix/store paths required for a NixOS system to a directory? You can build a NixOS closure and then use nix-store --query --requisites ./result to get the list of directories that you need to copy.

no, I want the top level files as well, there are etc/, sbin/

I am using nixos-generators which means result is a tarball. If I build #nixosConfigurations.{namehere}.config.system.build.toplevel with nixos.lib.nixosSystem {...} the directory inside result is a bit different from the tarball. Should I specify another attribute to build?

Other than the following, the only files in the tarball are in /nix/store

$ tar -tf $(nix run github:nix-community/nixos-generators -- -f lxc) | grep -v '^nix/store'
dev/
etc/
etc/os-release
nix/
nix-path-registration
proc/
sbin/
sbin/init
sys/

The only actual files in the tarball outside /nix/store are os-release, nix-path-registration, and init. Everything is in the store, and the root fs is populated by init when the image is started. And init is a symlink pointing to the toplevel derivation’s init program.

The important code to look at is system.build.tarball, defined here. Also note the variety of other configuration options set in that file, such as boot.isContainer = true;. And the script that actually assembles the tarball is here.

So I think you can make a configuration.nix with imports = ["${modulesPath}/virtualisation/lxc-container.nix"];, and assemble a directory with etc/os-release and sbin/init pointing at the files in system.build.toplevel, and that’ll be basically the same as the tarball. The nix-path-registration is a bit more complicated though, but also not entirely necessary.

That’s all I need, thank you very much for the pointer

hmm, I’m curious how to call that system.build.tarball from nix build + flake, without involving nixos-generators?

The nixos-generators thing for lxc is extremely simple. Essentially all it does is import the lxc-container.nix file from nixpkgs. You can just do that, and then you can build .#nixosConfigurations.${name}.config.system.build.tarball just like you would toplevel.

Thanks, it took me a while to read the source code of nixos-generators and several nixos modules that nixos-generators use to understand how things work together.