nix-community / impermanence

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

How to persist .config directory? #53

Closed robbins closed 2 years ago

robbins commented 2 years ago

The .config directory contains ./config/systemd/user/stuff.service, including the systemd services created by this module.

So after temporarily renaming the .config folder and activating the new generation to persist it, the bind mound services don't get started.

If I try to move the services into that directory, the bind mount fails because it's not empty.

What's the proper way to resolve this?

talyz commented 2 years ago

I don't think you want to persist the entire .config directory, since that kind of defeats the purpose of using the module.

To begin with, you need to use home-manager as a NixOS module (in the nixos directory of the home-manager repo). This makes sure home-manager's configuration is persisted and applied on boot, before you log in. This should also solve any directory conflicts, since it makes sure the bind mounts are set up very early in your session.

When you've made big changes to your configuration, you may have to run a nixos-rebuild boot and reboot to not have to solve the directory conflicts manually.

robbins commented 2 years ago

Oh, ok thanks, I mistakenly thought that was meant for Impermanence as a NixOS module.

I've added home-manager as a NixOS module, and tested adding a file to be persisted: home.persistence."/persist/home/nate" = { directories = [ ]; files = [ ".config/testfile" ]; allowOther = true; }; The file doesn't exist, so when I run nixos-rebuild switch I do see it created in ~/.config. It shows as a symlink to /nix/store/mdqq8fgjc8fwx5k1qrhiki5hj1h7bcpp-home-manager-files/.config/testfile, which is a symlink to /nix/store/vfib3x4nhr4wdxmsgfy65qx478ln4vb8-persist-home-nate-config-testfile, which is a symlink to /persist/home/nate/.config/testfile. However, that file in /persist doesn't seem to exist. In fact, the .config directory doesn't even exist in /persist/home/nate.

If I do create the file in /persist manually though, everything works fine. It also happens for files that do exist. So for some reason it's not creating the actual files in the persistent directory.

talyz commented 2 years ago

Oh, yeah, you're right. Apparently, I forgot to implement that logic - sorry about that. I've created #55 to address this; I would appreciate if you could try it out and make sure it solves this issue for you.

robbins commented 2 years ago

Sorry, was busy with midterms and stuff :P. I see that it's now been merged, so I updated my flake.lock, and tested again with .config/testfile. I now see the .config directory in /persist/home/nate.

However, testfile itself doesn't exist. I tried again with a file that exists (~/hello.txt), and after rebuild switch boot and rebooting, the file in ~ is a symlink to the nix store, but the file contents are gone as the file doesn't exist. The chain of symlinks resolves to nothing as /persist/home/nate doesn't contain hello.txt.

If I run touch hello1.txt, the symlink is fixed and I now see the file in /persist/home/nate/hello1.txt.

talyz commented 2 years ago

Yes, this is by design. When a symlink points to a nonexistent file, it's regarded as such by most programs. This means they will try to create the file, which in turn creates the real file the symlink targets. If we instead created empty files, many applications would consider them corrupt: they exist, but don't have the expected contents.

robbins commented 2 years ago

Thanks, and this is even for files that already exist? So if I am persisting a file that exists in home, I should nixos rebuild boot, and then copy it manually to the persistent directory?

talyz commented 2 years ago

Yes, that's correct. We don't automatically migrate any files, since that's hard or impossible to do atomically and can cause lots of issues with running applications.

robbins commented 2 years ago

Cool, thanks for the help in resolving this issue!