home-manager
home-manager copied to clipboard
files: don't handle symlinks in a special way when home.file.<name>.recursive is set to true
Description
I'm using pass as my password manager.
In order to use it in Firefox, I use the passff extension. The passff extension needs the passff-host native messaging host to access the passwords. Here is what the file structure of the passff-host package looks like:
result
├── etc
│ ├── chromium
│ │ └── native-messaging-hosts
│ │ └── passff.json -> ../../../share/passff-host/passff.json
│ ├── opt
│ │ └── chrome
│ │ └── native-messaging-hosts
│ │ └── passff.json -> ../../../../share/passff-host/passff.json
│ └── vivaldi
│ └── native-messaging-hosts
│ └── passff.json -> ../../../share/passff-host/passff.json
├── lib
│ ├── librewolf
│ │ └── native-messaging-hosts
│ │ └── passff.json -> ../../../share/passff-host/passff.json
│ └── mozilla
│ └── native-messaging-hosts
│ └── passff.json -> ../../../share/passff-host/passff.json
└── share
└── passff-host
├── passff.json
└── passff.py
As you can see, lib/mozilla/native-messaging-hosts/passff.json is a relative symlink. This is perfectly reasonable.
When adding programs.firefox.nativeMessagingHosts = [ pkgs.passff-host ] to the home-manager configuration, the firefox module first joins all the nativeMessagingHosts using symlinkJoin and stores the result in a variable called nativeMessagingHostsJoined. This creates ff_native-messaging-hosts in the Nix store:
/nix/store/bv62k5yl7jwzkhyci838ir3vgz59gqsa-ff_native-messaging-hosts
├── bin
│ └── firefox -> /nix/store/0zqxaz44w75gjq32xj53i32jl2j91pzy-firefox-125.0.1/bin/firefox
├── etc
│ ├── chromium
│ │ └── native-messaging-hosts
│ │ └── passff.json -> ../../../share/passff-host/passff.json
│ ├── opt
│ │ └── chrome
│ │ └── native-messaging-hosts
│ │ └── passff.json -> ../../../../share/passff-host/passff.json
│ └── vivaldi
│ └── native-messaging-hosts
│ └── passff.json -> ../../../share/passff-host/passff.json
├── lib
│ ├── [...]
│ ├── librewolf
│ │ └── native-messaging-hosts
│ │ └── passff.json -> ../../../share/passff-host/passff.json
│ └── mozilla
│ ├── native-messaging-hosts
│ │ └── passff.json -> ../../../share/passff-host/passff.json
│ └── pkcs11-modules
└── share
├── [...]
└── passff-host
├── passff.json -> /nix/store/pag1akgbmls1xa63h6rzmb0h6xxwwzmy-passff-host-1.2.4/share/passff-host/passff.json
└── passff.py -> /nix/store/pag1akgbmls1xa63h6rzmb0h6xxwwzmy-passff-host-1.2.4/share/passff-host/passff.py
Still perfectly fine.
Then the firefox module sets
home.file.".mozilla/native-messaging-hosts" = {
source = "${nativeMessagingHostsJoined}/lib/mozilla/native-messaging-hosts";
recursive = true;
}
The file module then calls lndir -silent "/nix/store/bv62k5yl7jwzkhyci838ir3vgz59gqsa-ff_native-messaging-hosts/lib/mozilla/native-messaging-hosts" ".mozilla/native-messaging-hosts" To see the problem, here is the resulting directory tree:
.mozilla
├── [...]
└── native-messaging-hosts
└── passff.json -> ../../../share/passff-host/passff.json
Obviously this symlink doesn't go anywhere. lndir created a broken symlink. To fix this, add the -ignorelinks argument to lndir, which causes it to instead just create a symlink to the symlink in ff_native-messaging-hosts:
.mozilla
├── [...]
└── native-messaging-hosts
└── passff.json -> /nix/store/bv62k5yl7jwzkhyci838ir3vgz59gqsa-ff_native-messaging-hosts/lib/mozilla/native-messaging-hosts/passff.json
Checklist
-
[ ] Change is backwards compatible. (I'm honestly not 100% sure on this one)
-
[x] Code formatted with
./format. -
[x] Code tested through
nix-shell --pure tests -A run.allornix develop --ignore-environment .#allusing Flakes. -
[ ] Test cases updated/added. See example.
-
[x] Commit messages are formatted like
{component}: {description} {long description}See CONTRIBUTING for more information and recent commit messages for examples.
-
If this PR adds a new module
- [ ] Added myself as module maintainer. See example.
Maintainer CC
@rycee @kira-bruneau @Lillecarl @mlyxshi
This comes back to bite again!
-ignorelinks
Causes the program to not treat symbolic links in fromdir spe-
cially. The link created in todir will point back to the corre-
sponding (symbolic link) file in fromdir. If the link is to a
directory, this is almost certainly the wrong thing.
This option exists mostly to emulate the behavior the C version
of lndir had in X11R6. Its use is not recommended.
@Luflosi For another native messenger i changed the package to copy the files instead of symlinking within the package. While it's not "pretty" and duplicates some kilobytes of data it worked just fine. Considering the "It's use is not recommended" mention and how wide the blast radius of this change is, I'd try that option first even though it's not "covering all bases".
https://gist.github.com/Lillecarl/1e4669bd7546eed5cdfcea900fa1c64e <- nixpkgs patch
final: prev: {
passff-host = prev.passff-host.overrideAttrs (pattrs: {
installPhase = ''
substituteInPlace bin/${version}/passff.json \
--replace PLACEHOLDER $out/share/passff-host/passff.py
install -Dt $out/share/passff-host \
bin/${version}/passff.{py,json}
nativeMessagingPaths=(
/lib/mozilla/native-messaging-hosts
/etc/opt/chrome/native-messaging-hosts
/etc/chromium/native-messaging-hosts
/etc/vivaldi/native-messaging-hosts
/lib/librewolf/native-messaging-hosts
)
for manifestDir in "''${nativeMessagingPaths[@]}"; do
install -d $out$manifestDir
cp $out/share/passff-host/passff.json $out$manifestDir/
done
'';
});
}
You could also try this (untested) overlay.
Thank you for your contribution! I marked this pull request as stale due to inactivity. Please read the relevant sections below before commenting.
If you are the original author of the PR
- GitHub sometimes doesn't notify people who commented / reviewed a PR previously when you (force) push commits. If you have addressed the reviews you can officially ask for a review from those who commented to you or anyone else.
- If it is unfinished but you plan to finish it, please mark it as a draft.
- If you don't expect to work on it any time soon, please consider closing it with a short comment encouraging someone else to pick up your work.
- To get things rolling again, rebase the PR against the target branch and address valid comments.
If you are not the original author of the PR
- If you want to pick up the work on this PR, please create a new PR and indicate that it supercedes and closes this PR.