nix-community / home-manager

Manage a user environment using Nix [maintainer=@rycee]
https://nix-community.github.io/home-manager/
MIT License
7.05k stars 1.82k forks source link

bug: git-sync creates/uses the sync dir in the read-only nixstore #2289

Closed NelsonJeppesen closed 2 years ago

NelsonJeppesen commented 3 years ago

Is there an existing issue for this?

Issue description

I have the following configuration

services.git-sync.enable = true;
services.git-sync.repositories.notes.interval = 60;
services.git-sync.repositories.notes.uri = "<redacted>"
services.git-sync.repositories.notes.path = ~/s/notes;

I have created the repo with a simply git clone

❯ cd ~/s/notes

notes on  main [!]
❯ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   README.md

no changes added to commit (use "git add" and/or "git commit -a")

notes on  main [!]
❯

logs show issues with readonly fs

❯ journalctl --user -u git-sync-notes -f
-- Journal begins at Tue 2021-01-19 16:34:51 PST. --
Aug 22 20:21:21 g14 git-sync-on-inotify[13402]: git-sync: Fetching from origin/main
Aug 22 20:21:21 g14 git-sync-on-inotify[13436]: error: cannot open .git/FETCH_HEAD: Read-only file system
Aug 22 20:21:21 g14 git-sync-on-inotify[13402]: git-sync: git fetch origin returned non-zero. Likely a network problem; exiting.
Aug 22 20:22:21 g14 git-sync-on-inotify[8937]: Syncing due to timeout
Aug 22 20:22:21 g14 git-sync-on-inotify[13613]: git-sync: Preparing. Repo in .git /nix/store/2kv0ylqvprda9qd02fzjck676x584l3p-notes
Aug 22 20:22:21 g14 git-sync-on-inotify[13613]: git-sync: Mode sync
Aug 22 20:22:21 g14 git-sync-on-inotify[13613]: git-sync: Using origin/main
Aug 22 20:22:21 g14 git-sync-on-inotify[13613]: git-sync: Fetching from origin/main
Aug 22 20:22:21 g14 git-sync-on-inotify[13647]: error: cannot open .git/FETCH_HEAD: Read-only file system
Aug 22 20:22:21 g14 git-sync-on-inotify[13613]: git-sync: git fetch origin returned non-zero. Likely a network problem; exiting.

I belive the mistake is the dir is set to the nixstore, not the dir specifed in my configuration

❯ cat ~/.config/systemd/user/git-sync-notes.service|grep DIR
Environment=GIT_SYNC_DIRECTORY=/nix/store/2kv0ylqvprda9qd02fzjck676x584l3p-notes

I've read the code, but not really sure why it's doing this

Maintainer CC

@IvanMalison

System information

❯ nix-shell -p nix-info --run "nix-info -m"
these paths will be fetched (0.42 MiB download, 2.39 MiB unpacked):
  /nix/store/lpas0k4ca636czq0na9jv1wlbf10r5ww-bash-interactive-4.4-p23-doc
  /nix/store/nfvkbp8rvlfm9n1v4rv243hwrdpmwr9v-bash-interactive-4.4-p23-info
  /nix/store/wv1mbc34jaws00lyhgqr6aix5ql0c1r6-bash-interactive-4.4-p23-dev
copying path '/nix/store/lpas0k4ca636czq0na9jv1wlbf10r5ww-bash-interactive-4.4-p23-doc' from 'https://cache.nixos.org'...
copying path '/nix/store/nfvkbp8rvlfm9n1v4rv243hwrdpmwr9v-bash-interactive-4.4-p23-info' from 'https://cache.nixos.org'...
copying path '/nix/store/wv1mbc34jaws00lyhgqr6aix5ql0c1r6-bash-interactive-4.4-p23-dev' from 'https://cache.nixos.org'...
 - system: `"x86_64-linux"`
 - host os: `Linux 5.13.11, NixOS, 21.11 (Porcupine)`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.3.15`
 - channels(nelson): `"home-manager"`
 - channels(root): `"nixos-21.11pre309670.253aecf69ed"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`
colonelpanic8 commented 3 years ago

@NelsonJeppesen Without investigating at all, my first guess is that your use of the ~ to mean home might be an issue. That would typically be interpreted by a shell, but in this case that might not happen.

colonelpanic8 commented 3 years ago

Ah okay looking a bit more closely, you are using nix path objects, because you are not quoting the paths. These are likely getting coerced into strings, and in nix, this causes the path to be pulled in to the nix store.

I believe that if you provide a string instead, by quoting the values, you should get the behavior that you want.

colonelpanic8 commented 3 years ago

Specifically, I am saying: this line

services.git-sync.repositories.notes.path = ~/s/notes;

shoudl be replaced with

services.git-sync.repositories.notes.path = "~/s/notes";

colonelpanic8 commented 3 years ago

Hmm. I'm sort of surprised this even works for you. When I set the path to a similar value, I get:

error: A definition for option home-manager.users.imalison.services.git-sync.repositories.config.path' is not of typepath'.

colonelpanic8 commented 3 years ago

Ah wait, nevermind ignore what I said about the quoting fix, that does not quite work.

I think this question may be relevant to the issue: https://stackoverflow.com/questions/43850371/when-does-a-nix-path-type-make-it-into-the-nix-store-and-when-not

NelsonJeppesen commented 3 years ago

Wow, thank you for the feedback!

I just tiried this services.git-sync.repositories.notes.path = /home/nelson/s/notes; then this: services.git-sync.repositories.notes.path = "/home/nelson/s/notes";

The first made no change, but the second one worked, with quotes. So, for me, it works with quotes

Regardless of how it does work on my box, what is the prefered way to do this?

colonelpanic8 commented 3 years ago

Yeah so I had it set up for me like: services.git-sync.repositories.notes.path = "/home/nelson/s/notes";

and I hadn't tested other ways of specifying paths or the home directory.

It would be nice if there were some way to reference the home directory where you did not need to be explicit about it like that.

I'm going to look in to it some more and hopefully have it try to behave a bit more intelligently w.r.t. paths.

colonelpanic8 commented 3 years ago

Regardless of how it does work on my box, what is the prefered way to do this?

I do think that you have uncovered a genuine issue here, so I will do some more investigation and get back to you on this.

I do think it should be possible to use something like this: https://github.com/nix-community/home-manager/blob/f6d1cad6ba228b81bf7045f1124aa99dfdcf3daa/nixos/default.nix#L34

to interact with the home directory.

I think it also makes sense to put a warning, or perhaps fail, if the directory is found in the nix store.

NelsonJeppesen commented 3 years ago

Regardless of how it does work on my box, what is the prefered way to do this?

I do think that you have uncovered a genuine issue here, so I will do some more investigation and get back to you on this.

I do think it should be possible to use something like this:

https://github.com/nix-community/home-manager/blob/f6d1cad6ba228b81bf7045f1124aa99dfdcf3daa/nixos/default.nix#L34

to interact with the home directory.

I think it also makes sense to put a warning, or perhaps fail, if the directory is found in the nix store.

Anything I can test on my end to help?

Would it make sense to close this issue?

colonelpanic8 commented 3 years ago

@NelsonJeppesen Not quite yet. I think I can add some mitgations.

colonelpanic8 commented 3 years ago

@NelsonJeppesen I would recommend you do this the way I do it here: https://github.com/IvanMalison/dotfiles/blob/d505e8c79dd99af12d4790d27838acc71e58b666/nixos/home-manager.nix#L84

berbiche commented 3 years ago

I think the solution is to simply call toString when generating the configuration:

  mkUnit = name: repo: {
    Unit.Description = "Git Sync ${name}";

    Install.WantedBy = [ "default.target" ];

    Service = {
      Environment = [
        "GIT_SYNC_DIRECTORY=${repo.path}"
        "GIT_SYNC_COMMAND=${cfg.package}/bin/git-sync"
        "GIT_SYNC_REPOSITORY=${toString repo.uri}"
        "GIT_SYNC_INTERVAL=${toString repo.interval}"
      ];
      ExecStart = "${cfg.package}/bin/git-sync-on-inotify";
      Restart = "on-abort";
    };
  };

If someone wants to test this and open a PR it would be great.

stale[bot] commented 2 years ago

Thank you for your contribution! I marked this issue as stale due to inactivity. If this remains inactive for another 7 days, I will close this issue. Please read the relevant sections below before commenting.

If you are the original author of the issue

* If this is resolved, please consider closing it so that the maintainers know not to focus on this. * If this might still be an issue, but you are not interested in promoting its resolution, please consider closing it while encouraging others to take over and reopen an issue if they care enough. * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.

If you are not the original author of the issue

* If you are also experiencing this issue, please add details of your situation to help with the debugging process. * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.

Memorandum on closing issues

If you have nothing of substance to add, please refrain from commenting and allow the bot close the issue. Also, don't be afraid to manually close an issue, even if it holds valuable information.

Closed issues stay in the system for people to search, read, cross-reference, or even reopen--nothing is lost! Closing obsolete issues is an important way to help maintainers focus their time and effort.