Here’s the scenario:
I have 2 nixos machines, one laptop and one desktop. The desktop machine has limited or no internet access - enough to check emails but not enough to download 3GB for
nixos-rebuild switch --upgrade.
I keep the laptop up to date, and can build the whole desktop from my laptop:
nix-copy-closure --to desktop result/
Everything works fine in this scenario, until you want to nixos-rebuild on the desktop.
If I execute nixos-rebuild --switch from the desktop, it’s nix channel is super oudated and it can’t even parse the configuration.nix. If i run
sudo nixos-rebuild switch --upgrade from the desktop, it parses configuration.nix but wants to download 3GB of stuff that the laptop likely already has.
Am I missing something obvious?
Sounds like you are using channels and the stable Nix interface, which means that unless your channels on both machines match up to the exact same commit, that building the closure on the laptop and copying the closure won’t accomplish much, since a different commit of nixpkgs means the hash of everything will be different.
A simple workaround for this would be to use the in built remote functions of
nixos-rebuild, namely the
--target-host options. That way, the script will actually handle building and installing the desktop directly from the laptop. All that’s required is an ssh connection from one to the other, which it sounds like you already have.
Looking at your answer, I think my question was probably not super clear.
Both computers are on nix unstable FWIW.
You can run nix build, nix-copy-closure, and run
result/bin/switch-to-configuration switch on the desktop (–target-host) with my setup.
The only problem is that you always need to be building it’s configuration from the laptop.
What I want is the ability to copy all the relevant nix store contents from the laptop to desktop, so that
nix-build desktop.nix works the same on laptop and desktop.
Well if you are using
nix-build then you probably aren’t using flakes? What is really relevant is whether you are relying on
nix-channel to set your system revision, or if you are using a “flake.nix” to pin your system declaratively.
In the latter case, it’d be simple enough to build the system output as follows from the flake root:
nix build .#nixosConfigurations.\<someConfig\>.config.system.build.toplevel and then
nix copy result ssh://your-desktop-url.
If you are using channels then my previous answer still holds, the script just does what you are wanting to do, but automatically. If you insist on doing in manually though then you’ll need to build the system with something similar to this:
nix-build -I nixos-config=./configuration.nix '<nixpkgs/nixos>' -A system and then copy the result over to the desktop system. Unless the channel revisions match though, you’ll have to call the activation script manually, which irrc, doesn’t update the bootloader entry properly. So I still highly suggest you just use
nixos-rebuild in that case.