Copying a channel's state from one install to another

Hi, I have 2 installations of nixos on two different harddrives on my computer. I am attempting to set up the second installation in largely the same way as the first. (But with the addition of “erase your darlings”)

However, I’ve had a lot of issues where things that used to work no longer do in the new installation. I’ve fixed most of them, but now I’m having an issue with a particular game not being playable in proton. The proton logs show: .808:0128:012c:warn:seh:handle_syscall_fault backtrace: --- Exception 0xc0000005 at 0x7773b42d: /nix/store/pkpf5lf47m8k34hw9chqk62yrhxlb0cw-nvidia-x11-535.86.05-6.1.62-lib32/lib/ + 0x173b42d

This nvidia-x11 is a different version than I had on the old installation. I want to try matching the new installation to the old installation. Both installations are tracking Is there a way I can copy the state of the old installation’s channel over to the new one? So that if I do a nixos-rebuild switch I’ll get the same versions of all the packages I had on the old installation.

This is what flakes are used for. Maybe look into switching to a flake based configuration. With a flake the channels are declared and the versions are pinned to an exact version in the lockfile. I found this short video tutorial very helpful. But there are a lot of guides and blog articles about it as well.

It’s true that flakes make this more explicit and with better locality. But in practice the mechanisms are similar, if the implementation is different.

The channels are indexed as symlinks in /nix/var/nix/profiles/per-user/root with the usual generation format. Each link is to a nix store path, which contains a manifest (with revision information) and the downloaded contents of (for example) the nixpkgs revision in question.

These store paths can be copied between machines, and the symlinks manipulated manually to achieve what you want.

1 Like

For channels you do sth. like

STOREPATH=$(realpath /nix/var/nix/profiles/per-user/root/channels)
nix-copy-closure --to ssh://$HOST $STOREPATH
NEXTCHANNELS=$(ssh root@${HOST} 'ls /nix/var/nix/profiles/per-user/root/ | grep link | sed -e "s/channels-\([0-9]*\)-link/\1/g" | sort -n | tail -1 | xargs -n 1 expr 1 +')
ssh root@${HOST} "ln -s ${STOREPATH} /nix/var/nix/profiles/per-user/root/channels-${NEXTCHANNELS}-link"
ssh root@${HOST} "rm /nix/var/nix/profiles/per-user/root/channels; ln -s channels-${NEXTCHANNELS}-link /nix/var/nix/profiles/per-user/root/channels"

with Flakes you would do

nix flake archive --no-update-lock-file --to ssh://root@${HOST} ${FLAKE}
scp ${FLAKE}/flake.lock root@${HOST}:/etc/nixos/.
1 Like

Thanks for the pointers, they helped.

I didn’t really want to do complicated fiddling with the symlinks myself, so I dug into it a little more and found another way that was easier for me:

  • Run nixos-version on the old, working system and get the version number, in my case 23.05.4584.1a3c95e3b23b. The last component of this is the nixpkgs git hash.
  • On the new, nonworking system, use nix-channel --add to replace the channel from the generic “lastest revision of 23.05” link with the link to the specific version, in this case nixos-23.05 release nixos-23.05.4584.1a3c95e3b23b
  • Then nix-chanel --update and nixos-rebuild switch as normal.

Unfortunately this still didn’t fix my issue :frowning: But I guess I’ll have to investigate more.

Give flakes a try.

I had a setup where I copied around the channels and fiddled with the symlinks to keep machines in sync, then migrated this to flakes. Copying around a flake.lock is much easier.

I should eventually, I’d just like to try and get everything working first.

I don’t really understand flakes though, it seems like if I could just write the hash of a specific nixpkgs commit into the configuration.nix that would solve the versioning problem much more simply. And the documentation for flakes doesn’t seem to be all there.

Yes, Flakes are not official yet, so the documentation is a bit hard to find.

If pinning nixpkgs to a revision in your configuration.nix is enough for you, that can easily be done. But mind that commands like nix-shell -p will not respect that pinning and instead use the channel.

Flakes replace the channel with the “flake registry” and provide a sort of wrapper around your configuration that automates pinning of nixpkgs (and other inputs). The flake registry can also be made to follow the pinning done by the Flake-Framework to have the command line use the same revision of nixpkgs as used in the config.