Copy closure and register GC root atomically?

Is there any way to copy a nix closure to a remote machine and protect it from being garbage collected remotely at the same time?


Nix currently has the nix copy (e.g. nix copy --to ssh://hostname /nix/store/n7kp7ascs2ifn4qwmqz3pcwrq893v9qg-bla.drv) command.

The manual page doesn’t say anything about gc root registration though.
Does anyone know how to make sure that the closure doesn’t get garbage collected?

One way: you can run nix build /nix/store/path-to-keep --out-link /path/for/GC/symlink (on the target machine) – that symlink will keep the path alive while it exists (can be put anywhere). I find these useful in work directories.

The question here is that there currently might be no (nice) way of doing the registration atomically with copying.

1 Like

I can confirm the nix build can create the link in the gcroots folder.

  1. given that now the user has to come up with his own name for the link, what are best practices in terms of location (e.g. should I put them in /nix/var/nix/gcroots/auto?) and naming (e.g. should I also use hashes like the automatically created links?)?
  2. should I create an issue on github? cause I would assume nix copy is supposed to be creating those links as otherwise you cannot even be sure that after the command successfully returns the path has not already been collected.
  1. I keep them in working directories that use those store paths, so that e.g. they get managed/deleted together, but other people might have completely different workflows. EDIT: usually they are just the automatic ./result symlinks from nix build invocations done in those workdirs.
  2. I suppose it might be interesting for nix copy to support -o/--outlink, but I’ve given it almost no thought, so there might be much better approaches.

Note: I’m not really familiar yet with how gcroots are searched.

Hydra seems to touch /nix/var/nix/gcroots/hydra/$(basename $path) to root a path.
This could be done before the copy, so it would be rooted before it even existed, and should be safe from GC.

Just an idea though, I haven’t tested this at all.

Yes, that should work, I think (or something similar). IIRC the disadvantage would be that you’d need to manually remove the link once you don’t want to keep it alive anymore. That’s different from gcroots/auto used e.g. by nix-build -o.

To do this atomically, I’ve always registered the upstream host as a substituter and run nix-store -r /nix/store/arstd....hneio-hello --indirect --add-root ./result.