nix-community / impermanence

Modules to help you handle persistent state on systems with ephemeral root storage [maintainer=@talyz]
MIT License
1.14k stars 85 forks source link

A file already exists at /etc/group! #122

Closed avanderbergh closed 1 year ago

avanderbergh commented 1 year ago

I've been trying to set up impermanence, but I'm running into this error. Am I supposed to manually move the file to /persist/... before activation?

A file already exists at /etc/group!
Activation script snippet 'persist-files' failed (1)
reloading user units for avanderbergh...
setting up tmpfiles
warning: the following units failed: persist--persist-etc-group-.service

× persist--persist-etc-group-.service - Bind mount or link '/persist/etc/group' to '/etc/group'
     Loaded: loaded (/etc/systemd/system/persist--persist-etc-group-.service; enabled; preset: enabled)
     Active: failed (Result: exit-code) since Wed 2023-04-05 22:57:11 CEST; 72ms ago
    Process: 27114 ExecStart=/nix/store/05xlkxg2g62h6gp07rha8chb44drfpv7-impermanence-mount-file /etc/group /persist/etc/group  (code=exited, status=1/FAILURE)
   Main PID: 27114 (code=exited, status=1/FAILURE)
         IP: 0B in, 0B out
        CPU: 5ms

Apr 05 22:57:11 zoidberg systemd[1]: Starting Bind mount or link '/persist/etc/group' to '/etc/group'...
Apr 05 22:57:11 zoidberg 05xlkxg2g62h6gp07rha8chb44drfpv7-impermanence-mount-file[27114]: A file already exists at /etc/group!
Apr 05 22:57:11 zoidberg systemd[1]: persist--persist-etc-group-.service: Main process exited, code=exited, status=1/FAILURE
Apr 05 22:57:11 zoidberg systemd[1]: persist--persist-etc-group-.service: Failed with result 'exit-code'.
Apr 05 22:57:11 zoidberg systemd[1]: Failed to start Bind mount or link '/persist/etc/group' to '/etc/group'.
warning: error(s) occurred while switching to the new configuration

Here's my config.

  environment.persistence."/persist" = {
    directories = [
      "/etc/NetworkManager/system-connections"
      "/var/lib/bluetooth"
      "/var/lib/boltd/"
      "/var/lib/colord"
      "/var/lib/systemd/coredump"
      "/var/lib/systemd/rfkill/"
      "/var/lib/NetworkManager/"
      "/var/lib/upower"
    ];
    files = [
      "/etc/group"
    #   "/etc/machine-id"
    #   "/etc/passwd"
    #   "/etc/shadow"
    #   "/etc/subgid"
    #   "/etc/subuid"
    #   "/etc/sudoers"
    #   "/var/lib/alsa/asound.state"
    #   "/var/lib/power-profiles-daemon/state.ini"
    ];
  };

Looking at mount-file.bash I can see where this error is coming from and it looks to me here that it does not expect the file you want to persist to already exist? Am I missing something here?

if [[ -L "$mountPoint" && $(readlink -f "$mountPoint") == "$targetFile" ]]; then
    trace "$mountPoint already links to $targetFile, ignoring"
elif mount | grep -F "$mountPoint"' ' >/dev/null && ! mount | grep -F "$mountPoint"/ >/dev/null; then
    trace "mount already exists at $mountPoint, ignoring"
elif [[ -e "$mountPoint" ]]; then
    echo "A file already exists at $mountPoint!" >&2
    exit 1
elif [[ -e "$targetFile" ]]; then
    touch "$mountPoint"
    mount -o bind "$targetFile" "$mountPoint"
else
    ln -s "$targetFile" "$mountPoint"
fi
otavio commented 1 year ago

I believe #88 might help. The force param might be used, no?

avanderbergh commented 1 year ago

@otavio Thanks!

I believe #88 might help. The force param might be used, no?

Yes, I believe that might help.

Perhaps I misunderstood how I needed to set this up in the first place. I thought it would handle moving the files to the persisted volume for me. I manually moved the files to the persisted volume before building and it works great. Perhaps some clearer documentation on how to set this up wold help?

avanderbergh commented 1 year ago

BTW, I ended up adding a passwordFile to my config and using immutable users.

This is the config I ended up with.

  environment.persistence."/persist" = {
    directories = [
      "/etc/NetworkManager/system-connections"
      "/etc/secureboot"
      "/var/lib/bluetooth"
      "/var/lib/boltd/"
      "/var/lib/colord"
      "/var/lib/systemd/coredump"
      "/var/lib/upower"
    ];
    files = [
      "/var/lib/NetworkManager/secret_key"
      "/var/lib/NetworkManager/seen-bssids"
      "/var/lib/NetworkManager/timestamps"
    ];
  };
talyz commented 1 year ago

Yes, this is indeed how it's supposed to work. The documentation should be clearer on this.