Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Symlinks created via the home-manager module are broken #177

Open
Janrupf opened this issue Apr 2, 2024 · 4 comments
Open

Symlinks created via the home-manager module are broken #177

Janrupf opened this issue Apr 2, 2024 · 4 comments

Comments

@Janrupf
Copy link

Janrupf commented Apr 2, 2024

Adding the following configuration creates a broken symlink persistent in /home/janrupf:

home.persistence."/persistent/home/janrupf" = {
  directories = [
    { directory = "persistent"; method = "symlink"; }
  ];
}

Inspecting:

$ readlink persistent
/nix/store/vlidns7s3sp46bkw65nmr8wj7lbhvkvx-home-manager-files/persistent
$ readlink /nix/store/vlidns7s3sp46bkw65nmr8wj7lbhvkvx-home-manager-files/persistent
/nix/store/iwbbjrdnqrffd8bjv4yi5yvanhj6w8f0-persistent-home-janrupf-persistent
$ readlink /nix/store/iwbbjrdnqrffd8bjv4yi5yvanhj6w8f0-persistent-home-janrupf-persistent
/persistent/home/janrupf/persistent

So the symlink does point to the correct location afterall - the issue is, that location is never created.
The creation is supposed to happen here:

createTargetFileDirectories =
dag.entryBefore
[ "writeBoundary" ]
(concatMapStrings
(persistentStorageName:
concatMapStrings
(targetFilePath: ''
mkdir -p ${escapeShellArg (concatPaths [ cfg.${persistentStorageName}.persistentStoragePath (dirOf targetFilePath) ])}
'')
(map getDirPath (cfg.${persistentStorageName}.files ++ (filter isSymlink cfg.${persistentStorageName}.directories))))
persistentStorageNames);

Inspecting the flake output reveals that the command added to home.activation.createTargetFileDirectories is mkdir -p /persistent/home/janrupf/. - notice the dot at the end. I think this is caused by the dirOf call on line 458.

@Janrupf
Copy link
Author

Janrupf commented Apr 2, 2024

Temporary fix:

  home.activation.createTargetFileDirectoriesFixup =
  let
    isSymlink = entry: (!lib.isString entry) && (entry.method == "symlink");
    entryPath = entry: if lib.isString entry then entry else entry.directory;

    cfg = config.home.persistence;

    persistenceRoots = lib.attrNames cfg;
    mkdirPersistentLocations = map (root:
      let
        persistentDiskPath = cfg.${root}.persistentStoragePath;
        persistentDirectories = 
          # Collect all directories which are symlinks
          (map entryPath (lib.filter isSymlink cfg.${root}.directories)) ++
          # And all directories of files
          (map lib.dirOf (map entryPath (cfg.${root}.files)));
        
        completePaths = map (path: lib.path.append (/. + root) path) persistentDirectories;
        mkdirCommands = lib.concatMapStrings (completePath: "run mkdir -p ${lib.escapeShellArg completePath}\n") completePaths;
      in ''
        # mkdir's for ${root}

        ${mkdirCommands}
      ''
    ) persistenceRoots;
  in
    config.lib.dag.entryBetween [ "writeBoundary" ] [ "createTargetFileDirectories" ] (
      lib.concatMapStrings (cmds: "${cmds}\n") mkdirPersistentLocations
    );

This should create all directories as intended when put into the home-manager configuration.

@Schwanzskala
Copy link

I've also ran into this problem.
The temporary fix works, although for me with one minor modification; I had to change lib.dirOf to just dirOf.

@bphenriques
Copy link

bphenriques commented Aug 23, 2024

I think I am running a similar issue. All my directories are working. If I add the following:

  home.persistence."${config.custom.impermanence.dataLocation}".directories = [
    { directory = ".dotfiles"; method = "symlink"; } # Testing something...
  ];

The chain leads to nowhere, leading to "No such file or directory". I suspect it is due to the . in the beginning.

It does work with .steam but that folder isn't using symlinks.

@Janrupf
Copy link
Author

Janrupf commented Aug 25, 2024

Its just generally broken with the symlink method because there's the bug in the logic mentioned above, doesn't matter whether the name has a leading dot or not

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants