Snowfall Lib v2 with per system flake.lock

Hey everyone, so I’m using Snowfall Lib v2 for having a relatively structured approach to managing my nix configs.

I was wondering if there was a way to have a flake.lock file per host. The reason I ask this is because, running nix flake update will update the flakes for all hosts. Under normal circumstances this is not a problem. But recently I ran into an issue where nixos-rebuild switch worked successfully on host 1, but not on host 2 after the nix flake update. Host 2 had the cloud-init module which was breaking for some reason. Anyways long story short if I could manage 2 flake.lock files per host, this wouldn’t have been a problem, since after the failed updated on host 2. I would 've just reverted the flake.lock file for host 2, thereby having a perfectly reproducible config.

Please do suggest any other ways of solving the problem as well. The simplest I thought was to manage 2 flake.locks, but if there are more, do suggest.

1 Like
  1. You’re better off by investigating the build failure.
  2. Me personally, I do not update the flake.lock file that’s tracked by git. Instead, I run a nix flake update on each machine so I can roll it back to a previous version manually.
2 Likes
  1. Investigating the build failure is a given. However in the meantime, I don’t want my system to be in an inconsistent state from my git repo.
  2. Commiting flake.lock is also a very standard practice I feel. Examples: package-json.lock (for npm), poetry.lock (for python) projects. Its makes things a notch closer to reproducible. Also the whole point of using flakes was to maintain package versions for easier reverts. Running nix flake update on each machine is good, but that limits me to not push remote updates via using --target-host and --build-host. I update my remote systems from my local workstation, thereby always having my git repo being the single source of truth.

You could temporary switch to a separate git branch on the host that fails to build.

Merge changes from the main branch except for flake.lock.

Switch to your main branch to test the frequently updated flake.lock, and back to the temporary branch for as long as that fails.

1 Like

The names of any flake inputs are quite arbitrary.
You can name an input, for example, nixpkgs-host1, i.e.

inputs.nixpkgs-host1.url = "github:NixOS/nixpkgs/nixpkgs-unstable";

And then only update the nixpkgs-host1 input when you’re ready to update that, leaving the -host2, -host3, etc. alone.
I’d personally find this extra work, but I guess either way you’ll end up doing work here.

1 Like

Did you manage to figure anything out for this? I too would like this approach. I’m considering snowfall-lib but don’t want to lose the flake.lock per system I currently have.

The ethos of NixOS is reproducibility and a per system flake.lock is the answer to that. My systems differ enough to need this, e.g. I update laptop frequently/daily, but the server underlying OS/hypervisor is not.

Currently (non-snowfall-lib) I have a folder per system, then just import modules from a “common” folder when shared. Each system folder has a flake.lock. I have a manage.sh wrapper that simplifies the moving around for me, cd systems/${system}, before running commands, such as “nix flake update”. I’m trying to figure out if I can do similarly with snowfall-lib.

/flake.nix
/manage.sh
/systems/common/
/systems/common/config/modules/
/systems/laptop/
/systems/laptop/flake.nix
/systems/laptop/flake.lock
/systems/laptop/config/modules/
/systems/nas/
/systems/nas/flake.nix
/systems/nas/flake.lock
/systems/nas/config/modules/

“manage nas update”

cd system/${system} # system = nas
if ${action} == update # action = update
nix flake update # updates only flake.lock within system/nas
cd -

“manage nas switch”

cd system/${system} # system = nas
if ${action} == switch # action = switch
colmena apply switch --on system # all flake.nix are identical with "system" as the colmena target name
cd -

To add to the above. I did try a nixpkgs flake input per system, then doing nix flake update for the specific input, e.g. laptop-nixpkgs, nas-nixpkgs, etc. However, I was not comfortable with the managing of unique inputs names and impact of human error (aka I was nervous about making changes that would affect another system). I prefer the split flakes as they’re identical too, they are basically unmanaged templates to import ./config