NixOS / nix

Nix, the purely functional package manager
https://nixos.org/
GNU Lesser General Public License v2.1
11.47k stars 1.44k forks source link

garbage-collection internals are not documented / toString produces store path without context #10924

Open DaniD3v opened 2 weeks ago

DaniD3v commented 2 weeks ago

Problem

I'm using home-manager for my ssh secrets... which I know I shouldn't be doing but this is a documentation issue so my use-case doesn't really matter.

Anyways there is this option for ssh identities

image

My identity file is in my flake and I don't want to use an absolute path to the directory my flake is in (obviously), Which is why I did this instead.

programs.ssh = {
    matchBlocks = {
      "aur.archlinux.org" = {
        identityFile = toString ../../secrets/ssh/aur;
        user = "aur";
      };
      "github.com" = {
        identityFile = toString ../../secrets/ssh/github;
        user = "git";
      };
    };
  };

Surprisingly after every garbage collect my git push stops working

no such identity: /nix/store/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-source/secrets/ssh/github: No such file or directory
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

This behavior is weird because it definitely works in e.g. my hyprland config where I use ${pkgs.something} all the time and it never gets garbage collected. Also from what I've read in the nix docs a garbage collect should never change my system state.
This definitely did change my system.

Even after searching specifically for this issue I couldn't come across any information on how the garbage collectors decides which "relative path derivations" it keeps and which ones it doesn't.

I suspect the toString is somehow deleting that information
If this is actually a bug and not a documentation issue let me known I'll change the title.

TLDR

The garbage collector collects the ../../file derivation in this expression toString ../../file and there's no documentation explaining why.

Checklist

Priorities

Add :+1: to issues you find important.

roberth commented 2 weeks ago

Technically this is about the expression language semantics more so than the store-level garbage collection behavior. I honestly don't know how we should address this in the manual. Where would you expect to find this information?

As for the behavior, toString traditionally did not need to return a string with a string context, because e.g. toString /home == "/home". It seems likely that you're using Flakes, which makes this behavior easy to encounter by putting sources in the store first. Based on the discussion in #8428, I think the best way to prevent this mistake is not to create path values (what you referred to by relative paths, iiuc) that refer to the store.

Regardless, the toString documentation is lacking.