GithubHelp home page GithubHelp logo

nix-community / impermanence Goto Github PK

View Code? Open in Web Editor NEW
910.0 17.0 63.0 145 KB

Modules to help you handle persistent state on systems with ephemeral root storage [maintainer=@talyz]

License: MIT License

Nix 92.73% Shell 7.27%
nixos home-manager nix tmpfs

impermanence's Introduction

Impermanence

Lets you choose what files and directories you want to keep between reboots - the rest are thrown away.

Why would you want this?

  • It keeps your system clean by default.
  • It forces you to declare settings you want to keep.
  • It lets you experiment with new software without cluttering up your system.

There are a few different things to set up for this to work:

  • A root filesystem which somehow gets wiped on reboot. There are a few ways to achieve this. See the System setup section for more info.
  • At least one mounted volume where the files and directories you want to keep are stored permanently.
  • At least one of the modules in this repository, which take care of linking or bind mounting files between the persistent storage mount point and the root file system. See the Module usage section for more info.

Contact

Join the matrix room to chat about the project.

System setup

There are many ways to wipe your root partition between boots. This section lists a few common ways to accomplish this, but is by no means an exhaustive list.

tmpfs

The easiest method is to use a tmpfs filesystem for the root. This is the easiest way to set up impermanence on systems which currently use a traditional filesystem (ext4, xfs, etc) as the root filesystem, since you don’t have to repartition.

All data stored in tmpfs only resides in system memory, not on disk. This automatically takes care of cleaning up between boots, but also comes with some pretty significant drawbacks:

  • Downloading big files or trying programs that generate large amounts of data can easily result in either an out-of-memory or disk-full scenario.
  • If the system crashes or loses power before you’ve had a chance to move files you want to keep to persistent storage, they’re gone forever.

Using tmpfs as the root filesystem, the filesystem setup would look something like this:

{
  fileSystems."/" = {
    device = "none";
    fsType = "tmpfs";
    options = [ "defaults" "size=25%" "mode=755" ];
  };

  fileSystems."/persistent" = {
    device = "/dev/root_vg/root";
    neededForBoot = true;
    fsType = "btrfs";
    options = [ "subvol=persistent" ];
  };

  fileSystems."/nix" = {
    device = "/dev/root_vg/root";
    fsType = "btrfs";
    options = [ "subvol=nix" ];
  };

  fileSystems."/boot" = {
    device = "/dev/disk/by-uuid/XXXX-XXXX";
    fsType = "vfat";
  };
}

where the size option determines how much system memory is allowed to be used by the filesystem.

BTRFS subvolumes

A more advanced solution which doesn’t have the same drawbacks as using tmpfs is to use a regular filesystem, but clean it up between boots. A relatively easy way to do this is to use BTRFS and create a new subvolume to use as root on boot. This also allows you to keep a number of old roots around, in case of crashes, power outages or other accidents.

A setup which would remove automatically remove roots that are older than 30 days could look like this:

{
  fileSystems."/" = {
    device = "/dev/root_vg/root";
    fsType = "btrfs";
    options = [ "subvol=root" ];
  };

  boot.initrd.postDeviceCommands = lib.mkAfter ''
    mkdir /btrfs_tmp
    mount /dev/root_vg/root /btrfs_tmp
    if [[ -e /btrfs_tmp/root ]]; then
        mkdir -p /btrfs_tmp/old_roots
        timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S")
        mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp"
    fi

    delete_subvolume_recursively() {
        IFS=$'\n'
        for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
            delete_subvolume_recursively "/btrfs_tmp/$i"
        done
        btrfs subvolume delete "$1"
    }

    for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +30); do
        delete_subvolume_recursively "$i"
    done

    btrfs subvolume create /btrfs_tmp/root
    umount /btrfs_tmp
  '';

  fileSystems."/persistent" = {
    device = "/dev/root_vg/root";
    neededForBoot = true;
    fsType = "btrfs";
    options = [ "subvol=persistent" ];
  };

  fileSystems."/nix" = {
    device = "/dev/root_vg/root";
    fsType = "btrfs";
    options = [ "subvol=nix" ];
  };

  fileSystems."/boot" = {
    device = "/dev/disk/by-uuid/XXXX-XXXX";
    fsType = "vfat";
  };
}

This assumes the BTRFS filesystem can be found in an LVM volume group called root_vg. Adjust the path as necessary.

Module usage

There are currently two modules: one for NixOS and one for home-manager.

NixOS

To use the module, import it into your configuration with

{
  imports = [ /path/to/impermanence/nixos.nix ];
}

or use the provided nixosModules.impermanence flake output:

{
  inputs = {
    impermanence.url = "github:nix-community/impermanence";
  };

  outputs = { self, nixpkgs, impermanence, ... }:
    {
      nixosConfigurations.sythe = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        modules = [
          impermanence.nixosModules.impermanence
          ./machines/sythe/configuration.nix
        ];
      };
    };
}

This adds the environment.persistence option, which is an attribute set of submodules, where the attribute name is the path to persistent storage.

Usage is shown best with an example:

{
  environment.persistence."/persistent" = {
    hideMounts = true;
    directories = [
      "/var/log"
      "/var/lib/bluetooth"
      "/var/lib/nixos"
      "/var/lib/systemd/coredump"
      "/etc/NetworkManager/system-connections"
      { directory = "/var/lib/colord"; user = "colord"; group = "colord"; mode = "u=rwx,g=rx,o="; }
    ];
    files = [
      "/etc/machine-id"
      { file = "/var/keys/secret_file"; parentDirectory = { mode = "u=rwx,g=,o="; }; }
    ];
    users.talyz = {
      directories = [
        "Downloads"
        "Music"
        "Pictures"
        "Documents"
        "Videos"
        "VirtualBox VMs"
        { directory = ".gnupg"; mode = "0700"; }
        { directory = ".ssh"; mode = "0700"; }
        { directory = ".nixops"; mode = "0700"; }
        { directory = ".local/share/keyrings"; mode = "0700"; }
        ".local/share/direnv"
      ];
      files = [
        ".screenrc"
      ];
    };
  };
}
  • ~”/persistent”~ is the path to your persistent storage location

    This allows for multiple different persistent storage locations. If you, for example, have one location you back up and one you don’t, you can use both by defining two separate attributes under environment.persistence.

  • directories are all directories you want to bind mount to persistent storage. A directory can be represented either as a string, simply denoting its path, or as a submodule. The submodule representation is useful when the default assumptions, mainly regarding permissions, are incorrect. The available options are:
    • directory, the path to the directory you want to bind mount to persistent storage. Only setting this option is equivalent to the string representation.
    • persistentStoragePath, the path to persistent storage. Defaults to the environment.persistence submodule name, i.e. ~”/persistent”~ in the example. This should most likely be left to its default value - don’t change it unless you’re certain you really need to.
    • user, the user who should own the directory. If the directory doesn’t already exist in persistent storage, it will be created and this user will be its owner. This also applies to any parent directories which don’t yet exist. Changing this once the directory has been created has no effect.
    • group, the group who should own the directory. If the directory doesn’t already exist in persistent storage, it will be created and this group will be its owner. This also applies to any parent directories which don’t yet exist. Changing this once the directory has been created has no effect.
    • mode, the permissions to set for the directory. If the directory doesn’t already exist in persistent storage, it will be created with this mode. Can be either an octal mode (e.g. 0700) or a symbolic mode (e.g. u=rwx,g=,o=). Parent directories that don’t yet exist are created with default permissions. Changing this once the directory has been created has no effect.
  • files are all files you want to link or bind to persistent storage. A file can be represented either as a string, simply denoting its path, or as a submodule. The submodule representation is useful when the default assumptions, mainly regarding the permissions of its parent directory, are incorrect. The available options are:
    • file, the path to the file you want to bind mount to persistent storage. Only setting this option is equivalent to the string representation.
    • persistentStoragePath, the path to persistent storage. Defaults to the environment.persistence submodule name, i.e. ~”/persistent”~ in the example. This should most likely be left to its default value - don’t change it unless you’re certain you really need to.
    • parentDirectory, the permissions that should be applied to the file’s parent directory, if it doesn’t already exist. Available options are user, group and mode. See their definition in directories above.

    If the file exists in persistent storage, it will be bind mounted to the target path; otherwise it will be symlinked.

  • hideMounts allows you to specify whether to hide the bind mounts from showing up as mounted drives in the file manager. If enabled, it sets the mount option x-gvfs-hide on all the bind mounts.
  • users.talyz handles files and directories in talyz’s home directory

    The users option defines a set of submodules which correspond to the users’ names. The directories and files options of each submodule work like their root counterparts, but the paths are automatically prefixed with with the user’s home directory.

    If the user has a non-standard home directory (i.e. not /home/<username>), the users.<username>.home option has to be set to this path - it can’t currently be automatically deduced due to a limitation in nixpkgs.

Important note: Make sure your persistent volumes are marked with neededForBoot, otherwise you will run into problems.

home-manager

Usage of the home-manager module is very similar to the one of the NixOS module - the key differences are that the persistence option is now under home, rather than environment, and the addition of the submodule option removePrefixDirectory.

Important note: You have to use the home-manager NixOS module (in the nixos directory of home-manager’s repo) in order for this module to work as intended.

To use the module, import it into your configuration with

{
  imports = [ /path/to/impermanence/home-manager.nix ];
}

This adds the home.persistence option, which is an attribute set of submodules, where the attribute name is the path to persistent storage.

Usage is shown best with an example:

{
  home.persistence."/persistent/home/talyz" = {
    directories = [
      "Downloads"
      "Music"
      "Pictures"
      "Documents"
      "Videos"
      "VirtualBox VMs"
      ".gnupg"
      ".ssh"
      ".nixops"
      ".local/share/keyrings"
      ".local/share/direnv"
      {
        directory = ".local/share/Steam";
        method = "symlink";
      }
    ];
    files = [
      ".screenrc"
    ];
    allowOther = true;
  };
}
  • ~”/persistent/home/talyz”~ is the path to your persistent storage location
  • directories are all directories you want to link to persistent storage
    • It is possible to switch the linking method between bindfs (the default) and symbolic links.
  • files are all files you want to link to persistent storage. These are symbolic links to their target location.
  • allowOther allows other users, such as root, to access files through the bind mounted directories listed in directories. Useful for sudo operations, Docker, etc. Requires the NixOS configuration programs.fuse.userAllowOther = true.

Additionally, the home-manager module allows for compatibility with dotfiles repos structured for use with GNU Stow, where the files linked to are one level deeper than where they should end up. This can be achieved by setting removePrefixDirectory to true:

{
  home.persistence."/etc/nixos/home-talyz-nixpkgs/dotfiles" = {
    removePrefixDirectory = true;
    files = [
      "screen/.screenrc"
    ];
    directories = [
      "fish/.config/fish"
    ];
  };
}

In the example, the .screenrc file and .config/fish directory should be linked to from the home directory; removePrefixDirectory removes the first part of the path when deciding where to put the links.

Note: When using bindfs fuse filesystem for directories, the names of the directories you add will be visible in the /etc/mtab file and in the output of mount to all users.

Further reading

The following blog posts provide more information on the concept of ephemeral roots:

impermanence's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

impermanence's Issues

error: While opening repository /home/*/.local/share/flatpak/repo: opening repo: opendir(objects): No such file or directory

$ flatpak --version;lsb_release -d;uname -r;kde

Flatpak 1.10.7
Description:    Debian GNU/Linux 11 (bullseye)
5.10.0-11-amd64

KDE desktop

"sudo flatpak install qbittorrent"
"sudo flatpak list"
"flatpak run org.qbittorrent.qBittorrent"

error: While opening repository /home/user/.local/share/flatpak/repo: opening repo: opendir(objects): No such file or directory

some Debian/flatpak bug, that can be fixed by command "mkdir /home/$(whoami)/.local/share/flatpak/repo/objects"

can this be made the way so this objects is created and user is not bothered by that error?

Does not work with Docker

If you cd to some dir, that is managed with impermanence, and do

docker run --rm -it -v $(pwd):/src alpine

Then you will get a error like docker: Error response from daemon: error while creating mount source path '/home/eyjhb/projects': mkdir /home/eyjhb/projects: file exists.

This seems to be a problem with the bindfs method, as it worked just fine with symlinks (and works fine if I use the actual dir, not the one it bindfs).

Why a bindfs rather than a symlink?

Just wondered why we bother with bindfs rather than just using a symlink? Wouldn't a bindfs allow blocking until the persistent filesystem is mounted, and wouldn't it not have to wait until half way through the user's session start to be able to be used?

I'm just seeing a lot of things that aren't yet mounted on login even though I should see every mount first, e.g. desktop settings, wifi password keychains etc

New API

I find the current API to be a bit weird with the home/system distinction. On top of this the usage of symlinks is somewhat cumbersome. Here's an idea I had:

{
  persist = {
    directory = "/state";
    environment.directories = [
      "/var/lib/iwd"
      "/var/lib/bluetooth"
    ];
    environment.files = [
      "/etc/machine-id"
    ];
    users.bemeurer.directories = [
      "pictures"
      "src"
    ];
    users.bemeurer.files = [
      ".gist"
      ".zsh_history"
    ];
  };
}

For the directories we add a mkdir to system.activationScripts and a bind-mount to fileSystems.

For the files we'd touch and bind-mount just the same, which I think @etu noted was possible.

I did a poor's man attempt at this earlier which got lost in a state-mixup, but I had a lot of trouble there with the mountpoints that were supposed to be files ending up as directories somehow.

Error installing file outside $HOME

While using the impermanence module for home-manager and trying to persist .mozilla (for Firefox), I get the following error:

$ sudo nixos-rebuild boot --flake /etc/nixos
Applying Configuration...
building the system configuration...
error: builder for '/nix/store/pd68csjfh8k48gvsi72k5gr2awnjvg5d-home-manager-files.drv' failed with exit code 1;
       last 1 log lines:
       > Error installing file '.mozilla/firefox/profiles.ini' outside $HOME

This may be due to the presence of symlinks in .mozilla, because I use home-manager to manage my Firefox config

Relevant parts from configuration:

{
  home-manager.users.${username} = {
    imports = [ nixosModules.home-manager.impermanence ];
    home.persistence."/persist/home/${username}".directories = [ ".mozilla" ];
    programs.firefox = {
      enable = true;
      profiles.${username}.settings = {
        # Settings
      };
    };
  };
}

Apart from this, impermanence has been amazing! Thanks a lot :)

Error in home-manager generation activation: Couldn't perform regular umount of [], Attempting lazy unmount

Hi, I'm setting up home-manager with impermanence and in configuring I got some issue, the problem is same with #17, different with exist issue, I got the error for fusermount: entry for [] not found in /etc/mtab
Here is the executing activate script result:

Starting Home Manager activation
Activating checkFilesChanged
Activating checkLinkTargets
Activating unmountPersistentStoragePaths
Activating createAndMountPersistentStoragePaths
Activating createTargetFileDirectories
Activating writeBoundary
Activating installPackages
replacing old 'home-manager-path'
installing 'home-manager-path'
Activating linkGeneration
Cleaning up orphan links from /home/c4droid
No change so reusing latest profile generation 5
Creating home file links in /home/c4droid
Activating onFilesChange
Activating runUnmountPersistentStoragePaths
Activating reloadSystemd
No files found for bindMount--persistent-home-c4droid-Projects-.service.
No files found for bindMount--persistent-home-c4droid-config-.service.
No files found for bindMount--persistent-home-c4droid-flake-.service.
No files found for bindMount--persistent-home-c4droid-ssh-.service.
Starting: bindMount--persistent-home-c4droid-Projects-.service bindMount--persistent-home-c4droid-config-.service bindMount--persistent-home-c4droid-flake-.service bindMount--persistent-home-c4droid-ssh-.service
Failed to start bindMount--persistent-home-c4droid-Projects-.service: Unit bindMount--persistent-home-c4droid-Projects-.service not found.
Failed to start bindMount--persistent-home-c4droid-config-.service: Unit bindMount--persistent-home-c4droid-config-.service not found.
Failed to start bindMount--persistent-home-c4droid-flake-.service: Unit bindMount--persistent-home-c4droid-flake-.service not found.
Failed to start bindMount--persistent-home-c4droid-ssh-.service: Unit bindMount--persistent-home-c4droid-ssh-.service not found.
fusermount: entry for /home/c4droid/Projects not found in /etc/mtab
fusermount: entry for /home/c4droid/Projects not found in /etc/mtab
fusermount: entry for /home/c4droid/Projects not found in /etc/mtab
Couldn't perform regular unmount of '/home/c4droid/Projects'. Attempting lazy unmount.
fusermount: entry for /home/c4droid/Projects not found in /etc/mtab
fusermount: entry for /home/c4droid/flake not found in /etc/mtab
fusermount: entry for /home/c4droid/flake not found in /etc/mtab
fusermount: entry for /home/c4droid/flake not found in /etc/mtab
Couldn't perform regular unmount of '/home/c4droid/flake'. Attempting lazy unmount.
fusermount: entry for /home/c4droid/flake not found in /etc/mtab
fusermount: entry for /home/c4droid/.ssh not found in /etc/mtab
fusermount: entry for /home/c4droid/.ssh not found in /etc/mtab
fusermount: entry for /home/c4droid/.ssh not found in /etc/mtab
Couldn't perform regular unmount of '/home/c4droid/.ssh'. Attempting lazy unmount.
fusermount: entry for /home/c4droid/.ssh not found in /etc/mtab
fusermount: entry for /home/c4droid/.config not found in /etc/mtab
fusermount: entry for /home/c4droid/.config not found in /etc/mtab
fusermount: entry for /home/c4droid/.config not found in /etc/mtab
Couldn't perform regular unmount of '/home/c4droid/.config'. Attempting lazy unmount.
fusermount: entry for /home/c4droid/.config not found in /etc/mtab

issues with Steam

I'm having issues with games not being able to load. From what I have been able to piece together it seems to be related to wiring up graphics libraries or something. I'm just testing the waters here to see if anyone else has seen this.

The only directory I have under impermanence for steam is .local/share/Steam. Maybe I'm missing something else?

ERROR: ld.so: object '/home/--/.local/share/Steam/ubuntu12_64/gameoverlayrenderer.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS64): ignored.

I've tried things like link among other things.

LD_LIBRARY_PATH=~/.steam/bin32:$LD_LIBRARY_PATH steam

Oddly this exists and and I can view the executable but can't run it. Not sure if it's related

$ /home/--/.local/share/Steam/ubuntu12_32/reaper
zsh: no such file or directory: /home/--/.local/share/Steam/ubuntu12_32/reaper

Thanks for any help!

Speed up `setting up /etc...'

Hello! Sorry, it's me again! 😅

Is there any way to speed up setting up /etc..., or is it unavoidable with a lot of files and directories to bind-mount?

Thank you kindly for the information!

/nix/store/[hash]-sshd.conf-validated line 59: Subsystem 'sftp' already defined, and `sshd_config' not being created

Hello! I do sincerely apologize for all these issues! 😭

With the following:

{ config, ... }:
{
    services.openssh = {
        enable = true;
        extraConfig = mkOrder 0 ''
            TCPKeepAlive yes
            ClientAliveCountMax 480
            ClientAliveInterval 3m
        '';
        permitRootLogin = "yes";
    };
    environment.persistence."/persist".directories = [ "/etc/ssh" ];
}

I get the errors in the issue title. While the first is resolved with allowSFTP = false;, the sshd_config file itself is still prevented from being created, and I'd still like to use sftp. I still want the /etc/ssh directory to persist in case I create any manually controlled files down the line. Could you give any insight into what might be happening?

Thank you kindly for all the help, and again, I do sincerely apologize for taking up so much of your time!

[Bug] Created user directories is owned by root, and not the user

My $HOME is rolled back to a blank ZFS snapshot at every startup. The dotfiles that I want to keep between reboots is listed in Impermanence's directory and file lists; and the other files that I want to keep is located inside ZFS datasets that gets mounted in $HOME.

My problem using the new way to list users' directories and files is that the parent directories is created and owned by root. This cause a lot of problems. For example, if I have this in my NixOS configuration

environment.persistence."/persistent".users.a12l.directories = [ ".local/share/fonts" ];

then I get this when I log in

$ ls -la|rg .local
drwxr-xr-x  4 root root     4 Feb  1 21:33 .local

$ ls -lR .local
.local:
total 33
drwxr-xr-x 3 root root 3 Feb  1 21:33 share

.local/share:
total 17
drwxr-xr-x 3 a12l users 9 Jan 18 15:39 fonts

.local/share/fonts:
total 852
-rw-r--r-- 1 a12l users  44732 Jan 18 15:31 all-the-icons.ttf
-rw-r--r-- 1 a12l users 489672 Jan 18 15:31 file-icons.ttf
-rw-r--r-- 1 a12l users 152796 Jan 18 15:31 fontawesome.ttf
-rw-r--r-- 1 a12l users 128180 Jan 18 15:31 material-design-icons.ttf
-rw-r--r-- 1 a12l users  52544 Jan 18 15:31 octicons.ttf
drwxr-xr-x 2 a12l users     18 Jan 30 03:37 p
-rw-r--r-- 1 a12l users  99564 Jan 18 15:31 weathericons.ttf

.local/share/fonts/p:
total 19744
-rw-r--r-- 1 a12l users 2379348 Jan 30 03:26 PragmataProB_0829.ttf
-rw-r--r-- 1 a12l users 2404140 Jan 30 03:26 PragmataProB_liga_0829.ttf
-rw-r--r-- 1 a12l users 2262112 Jan 30 03:26 PragmataProI_0829.ttf
-rw-r--r-- 1 a12l users 2287048 Jan 30 03:26 PragmataProI_liga_0829.ttf
-rw-r--r-- 1 a12l users 1326160 Jan 30 03:26 PragmataPro_Mono_B_0829.ttf
-rw-r--r-- 1 a12l users 1351116 Jan 30 03:26 PragmataPro_Mono_B_liga_0829.ttf
-rw-r--r-- 1 a12l users 1212296 Jan 30 03:26 PragmataPro_Mono_I_0829.ttf
-rw-r--r-- 1 a12l users 1239864 Jan 30 03:26 PragmataPro_Mono_I_liga_0829.ttf
-rw-r--r-- 1 a12l users 1950440 Jan 30 03:26 PragmataPro_Mono_R_0829.ttf
-rw-r--r-- 1 a12l users 1974976 Jan 30 03:26 PragmataPro_Mono_R_liga_0829.ttf
-rw-r--r-- 1 a12l users 1146460 Jan 30 03:26 PragmataPro_Mono_Z_0829.ttf
-rw-r--r-- 1 a12l users 1170496 Jan 30 03:26 PragmataPro_Mono_Z_liga_0829.ttf
-rw-r--r-- 1 a12l users 3182624 Jan 30 03:26 PragmataProR_0829.ttf
-rw-r--r-- 1 a12l users 3207080 Jan 30 03:26 PragmataProR_liga_0829.ttf
-rw-r--r-- 1 a12l users 2184928 Jan 30 03:26 PragmataProZ_0829.ttf
-rw-r--r-- 1 a12l users 2209928 Jan 30 03:26 PragmataProZ_liga_0829.ttf

Note that ~/.local and ~/.local/share is owned by root:root, while ~/.local/share/fonts and below is owned by a12l:users.

I expected that all directories that is automatically created by Impermanence should be owned by the user with the username listed in environment.persistence."/persistent".users.<user>, I.e. a12l in my case.

Issue when installing NixOS with impermanence

Hello,

I recently decided to try out the tmpfs root setup described here.

I used the following configuration for NixOS:

environment = {
  persistence."/persist" = {
    directories = [
      "/etc/nixos"
      "/etc/NetworkManager/system-connections"
      "/var/lib/bluetooth"
    ];

    files = [
      "/etc/machine-id"
    ];
  };
};

And for home-manager:

home.persistence."/persist/home/jmc-figueira" = {
  directories = [
    "Documentos"
    "Imagens"
    "Jogos"
    "Música"
    "Transferências"
    "Vídeos"
  ];
  files = [
    ".bash_history"
    ".zsh_history"
  ];
};

However, upon running nixos-install, the following error occurred:

realpath: /persist/etc/nixos: No such file or directory
Error when executing realpath "$sourceBase$target" at line 38!
Error when executing realSource="$(realpath "$sourceBase$target")" at line 38!
realpath: /persist/etc/NetworkManager/system-connections: No such file or directory
Error when executing realpath "$sourceBase$target" at line 38!
Error when executing realSource="$(realpath "$sourceBase$target")" at line 38!
realpath: /persist/var/lib/bluetooth: No such file or directory
Error when executing realpath "$sourceBase$target" at line 38!
Error when executing realSource="$(realpath "$sourceBase$target")" at line 38!
Warning: Source directory '/persist/etc' does not exist: it will be created for you. Make sure the permissions are correct!
Activation script snippet 'createDirsIn--persist' failed (1)

This results in an empty /persist/etc folder and nothing else.

Is there any prior setup I should be aware of before using impermanence?

Mention that filesystems are mounted alphabetically

I just switched my root to be on tmpfs. I decided to start with mounting the real root fs to /persistent and bind-mounting everything from there. Except that it wouldn't boot because it tried to mount /etc before mounting /persistent.
I discovered that naming the mount point /apersistent fixed it tho x) Apparently the filesystems are loaded alphabetically. Is that expected or did I miss something? Will this stay that way with future nix versions? If that's expected behavior then I think it deserves to be mentioned in the README.

bind mounts sometimes fail on rebuild switch

i have impermance set for this dir

/nix/persist/home/mog/code                               942686456 80784172 813946728  10% /home/mog/code

when I tried to

nixos-rebuild switch --upgrade

results with this error

● home-manager-mog.service - Home Manager environment for mog
     Loaded: loaded (/nix/store/71i95wbpwd32jyz4a7a0y7wkcai3300c-unit-home-manager-mog.service/home-manager-mog.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Thu 2020-09-10 03:35:43 EDT; 44ms ago
    Process: 1902 ExecStart=/nix/store/lmfyfcf7liyhfq78s2m32vwd1aaihfm7-activate-mog (code=exited, status=1/FAILURE)
   Main PID: 1902 (code=exited, status=1/FAILURE)
         IP: 0B in, 0B out
        CPU: 486ms

Sep 10 03:35:42 zaphod hm-activate-mog[1902]: Activating checkFilesChanged
Sep 10 03:35:42 zaphod hm-activate-mog[1902]: Activating checkLinkTargets
Sep 10 03:35:42 zaphod hm-activate-mog[1902]: Activating unmountPersistentStoragePaths
Sep 10 03:35:42 zaphod hm-activate-mog[1902]: Activating createAndMountPersistentStoragePaths
Sep 10 03:35:42 zaphod hm-activate-mog[2064]: fuse: mountpoint is not empty
Sep 10 03:35:42 zaphod hm-activate-mog[2064]: fuse: if you are sure this is safe, use the 'nonempty' mount option
Sep 10 03:35:42 zaphod hm-activate-mog[2070]: fusermount: failed to unmount /home/mog/code: Device or resource busy
Sep 10 03:35:43 zaphod systemd[1]: home-manager-mog.service: Main process exited, code=exited, status=1/FAILURE
Sep 10 03:35:43 zaphod systemd[1]: home-manager-mog.service: Failed with result 'exit-code'.
Sep 10 03:35:43 zaphod systemd[1]: Failed to start Home Manager environment for mog.
warning: error(s) occurred while switching to the new configuration

this does not always happen, but when it does it happens consistently.

impermanenced

I imagine a super leightweight impermanenced which helps setting up a sytemd cron job for syncing whole state folders with either 1) rsync or 2) syncthing wired up.

This can be thought of as a convenience service to give a hand to less-than-power-users.

Context: divnix/digga#180 (reply in thread)

Not permission to create the `/persistent/home` directory

I get an error message when I start my computer and when I rebuild my configuration.

# nixos-rebuild switch --flake '.#'
building the system configuration...
activating the configuration...
setting up /etc...
mount already exists at '/etc/machine-id', ignoring
mount already exists at '/etc/mullvad-vpn/settings.json', ignoring
'/etc/nix/id_rsa' already links to '/persistent/etc/nix/id_rsa', ignoring
'/etc/ssh/ssh_host_ed25519_key' already links to '/persistent/etc/ssh/ssh_host_ed25519_key', ignoring
'/etc/ssh/ssh_host_ed25519_key.pub' already links to '/persistent/etc/ssh/ssh_host_ed25519_key.pub', ignoring
'/etc/ssh/ssh_host_rsa_key' already links to '/persistent/etc/ssh/ssh_host_rsa_key', ignoring
'/etc/ssh/ssh_host_rsa_key.pub' already links to '/persistent/etc/ssh/ssh_host_rsa_key.pub', ignoring
reloading user units for a12l...
setting up tmpfiles
warning: the following units failed: home-manager-a12l.service

× home-manager-a12l.service - Home Manager environment for a12l
     Loaded: loaded (/etc/systemd/system/home-manager-a12l.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Wed 2021-12-15 12:17:05 CET; 65ms ago
    Process: 32485 ExecStart=/nix/store/k7q69xknc9vg8ikwpf8ff5lbawb27pn1-hm-setup-env /nix/store/p9k6zsqj6z56idmjd37lzlzqvxxsiccx-home-manager-generation (code=exited, status=1/FAILURE)
   Main PID: 32485 (code=exited, status=1/FAILURE)
         IP: 0B in, 0B out
        CPU: 249ms

Dec 15 12:17:05 mobile-p-ep1 systemd[1]: Starting Home Manager environment for a12l...
Dec 15 12:17:05 mobile-p-ep1 hm-activate-a12l[32485]: Starting home manager activation
Dec 15 12:17:05 mobile-p-ep1 hm-activate-a12l[32485]: Activating checkFilesChanged
Dec 15 12:17:05 mobile-p-ep1 hm-activate-a12l[32485]: Activating checkLinkTargets
Dec 15 12:17:05 mobile-p-ep1 hm-activate-a12l[32485]: Activating unmountPersistentStoragePaths
Dec 15 12:17:05 mobile-p-ep1 hm-activate-a12l[32485]: Activating createAndMountPersistentStoragePaths
Dec 15 12:17:05 mobile-p-ep1 hm-activate-a12l[32508]: mkdir: cannot create directory ‘/persistent/home’: Permission denied
Dec 15 12:17:05 mobile-p-ep1 systemd[1]: home-manager-a12l.service: Main process exited, code=exited, status=1/FAILURE
Dec 15 12:17:05 mobile-p-ep1 systemd[1]: home-manager-a12l.service: Failed with result 'exit-code'.
Dec 15 12:17:05 mobile-p-ep1 systemd[1]: Failed to start Home Manager environment for a12l.
warning: error(s) occurred while switching to the new configuration

The relevant parts of my (flake based) config

modules = [
    home-manager.nixosModules.home-manager
    {
        home-manager.users.a12l = {
            home.username = "a12l";
            home.homeDirectory = "/home/a12l";

            imports = [ impermanence.nixosModules.home-manager.impermanence ];

            home.persistence."/persistent/home/a12l" = {
                directories = [
                    ".cache/lorri"
                    ".cache/nix"
                    ".config/pijul"
                    ".gnupg"
                    ".local/share/keyrings"
                    ".local/share/direnv"
                    ".mozilla"
                    ".scribus"
                    ".ssh"
                    ".thunderbird"
                    ".zoom"
                    "Long-Term_Memory"
                    "Short-Term Memory"
                ];

                allowOther = true;
            };
        };
    }
    
    impermanence.nixosModules.impermanence
    {
        environment.persistence."/persistent" = {
            directories = [
                "/var/log"
                "/var/lib/systemd/coredump"
                "/etc/NetworkManager/system-connections"
            ];

            files = [
                "/etc/machine-id"
                "/etc/mullvad-vpn/settings.json"
                "/etc/nix/id_rsa"
                "/etc/ssh/ssh_host_ed25519_key"
                "/etc/ssh/ssh_host_ed25519_key.pub"
                "/etc/ssh/ssh_host_rsa_key"
                "/etc/ssh/ssh_host_rsa_key.pub"
            ];
        };
    }
]

What should I do? I don't want to manually have to create the /persistent/home directory.

home-manager systemd user units aren't auto-started?

I'm on a new box setting up impermanence for the first time.

I'm having to move some dirs out of the way to get home-manager-cole.service to activate properly.

However, it did start, but the actual bind mount units are all dead/inactive. I've had to start them myself?

nginx cannot use persistent mounted directories

I tried pointing nginx to the persistence mounted directories and it kept saying everything was "permission denied", which was weird because /bin/sh as the nginx user can access the mounted files, but the nginx process itself can't.

Is there any reason for this¸ or config for this, is it intentional or a bug? I'm using nixos.nix as environment.persistence and have a list of directories to pull in from my persistence directory.

As a workaround I have to point nginx to the /persist directory instead of where it's mounted to.

Thanks

permissions on .gnupg

I realize this isn't really a bug.

    home.persistence."/nix/persist/home/mog" = {
      directories = [
        ".gnupg/private-keys-v1.d" ".gnupg/openpgp-revocs.d"
      ];
      files = [ ".gnupg/trustdb.gpg" ".gnupg/random_seed" ".gnupg/sshcontrol" ".gnupg/pubring.kbx" ];
    };

because of how this is done impermanence has to create the .gnupg directory because it does not exist. it creates the .gnupg with mkdir and has standard permissions. and gpg complains

gpg: WARNING: unsafe permissions on homedir '/home/mog/.gnupg'

chmoding it resolves issue obviously, but I have to do that every boot.

How would you feel about a special check for .gnupg and chmoding it impermanence is going to create it. or is there a better way to solve this problem?

"Failed unmounting /nix/store" with a bind-mounted `/nix`

I just changed my system to have a tmpfs root, and found impermanence amazing! But my /nix is bind-mounted and I get the following error on boot:

Nov 09 20:41:02 meluin systemd[1]: Listening on Journal Audit Socket.
Nov 09 20:41:02 meluin systemd[1]: Listening on Journal Socket (/dev/log).
Nov 09 20:41:02 meluin systemd[1]: Listening on udev Control Socket.
Nov 09 20:41:02 meluin systemd[1]: Listening on udev Kernel Socket.
Nov 09 20:41:02 meluin systemd[1]: Unmounting /nix/store...
Nov 09 20:41:02 meluin systemd[736]: nix-store.mount: Failed to connect stdout to the journal socket, ignoring: No such file or directory
Nov 09 20:41:02 meluin systemd[1]: nix-store.mount: Mount process exited, code=exited, status=32/n/a
Nov 09 20:41:02 meluin systemd[1]: Failed unmounting /nix/store.

So far everything seems to be working normally, but I don't really know what this means so I hope nothing is broken.

impermanence home-manager module does not work

Hello there, first of all thanks to all the contributors for this awesome project.

I am a new NixOS user and have been playing around within a VM trying to setup tmpfs as root and home based on the blog from elis (https://elis.nu/blog/2020/05/nixos-tmpfs-as-root/). All seems to be working fine with the exception of the home-manager module.

Whenever I activate the home-manager module as explained (https://github.com/nix-community/impermanence#home-manager) and do a nixos-rebuild it fails with:

attribute 'dag' missing --> home-manager.nix line 206

I tried various home-manager releases (19.03 onwards) as well as stable/unstable NixOS but the issue persists.

I wonder if it has anything to do with this commit? There are also some notes from that release:

image

I also tried the open PR that enables file management with systemd services and whereas that works fine it messes up the permissions for anything under home (chown fixes it but it is tedious to do it on every boot).

Here are some snippets of my config;

image

image

and the error itself:

image

Commenting out the home-manager module works meaning that the nixos module has no issues (checking the source i can see that there are no references to dag).

It could be something wrong with my setup so apologies if that is the case, any help would be appreciated.

Thank you.

Couldn't perform regular unmount of [...]. Attempting lazy unmount.

Initially reported on infinisil/nixus#27

I'm able to push my config to my desktop which also uses impermanence but my desktop doesn't clear /home while my laptop does.

I was able to switch config by basically clearing my home directory.

system-switcher log

❯ ssh 'laptop' sudo cat /var/lib/system-switcher/system-0/log                                                                                                                                     nix-shell rsync
stopping the following units: nix-daemon.service, nix-daemon.socket, nscd.service, systemd-udevd-control.socket, systemd-udevd-kernel.socket, systemd-udevd.service, tlp.service
NOT restarting the following changed units: systemd-fsck@dev-disk-by\x2duuid-5E57\x2d78A0.service
activating the configuration...
renamed '/var/lib/nixus-secrets/pending' -> '/var/lib/nixus-secrets/active'
setting up /etc...
reloading user units for bbigras...
setting up tmpfiles
reloading the following units: dbus.service
starting the following units: nix-daemon.socket, nscd.service, systemd-udevd-control.socket, systemd-udevd-kernel.socket, tlp.service
the following new units were started: persist-home-bbigras-.local-share-remmina.mount, sys-fs-fuse-connections.mount, sys-module-fuse.device, tmp.mount
warning: the following units failed: home-manager-bbigras.service

● home-manager-bbigras.service - Home Manager environment for bbigras
     Loaded: loaded (/nix/store/9c815rn0zhpxgzwjd7pwhi41ln1zk5m2-unit-home-manager-bbigras.service/home-manager-bbigras.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Sat 2020-09-05 16:24:49 EDT; 512ms ago
    Process: 3806 ExecStart=/nix/store/w53wvkpl4k2vzi3d3jp970h4c8100rjp-activate-bbigras (code=exited, status=1/FAILURE)
   Main PID: 3806 (code=exited, status=1/FAILURE)
         IP: 0B in, 0B out
        CPU: 561ms

sep 05 16:24:37 laptop hm-activate-bbigras[3806]: Couldn't perform regular unmount of /home/bbigras/.local/share/direnv. Attempting lazy unmount.
sep 05 16:24:39 laptop hm-activate-bbigras[3806]: Couldn't perform regular unmount of /home/bbigras/.local/share/keyrings. Attempting lazy unmount.
sep 05 16:24:41 laptop hm-activate-bbigras[3806]: Couldn't perform regular unmount of /home/bbigras/.local/share/remmina. Attempting lazy unmount.
sep 05 16:24:43 laptop hm-activate-bbigras[3806]: Couldn't perform regular unmount of /home/bbigras/.local/share/zoxide. Attempting lazy unmount.
sep 05 16:24:45 laptop hm-activate-bbigras[3806]: Couldn't perform regular unmount of /home/bbigras/.mozilla. Attempting lazy unmount.
sep 05 16:24:47 laptop hm-activate-bbigras[3806]: Couldn't perform regular unmount of /home/bbigras/Documents. Attempting lazy unmount.
sep 05 16:24:49 laptop hm-activate-bbigras[3806]: Couldn't perform regular unmount of /home/bbigras/Downloads. Attempting lazy unmount.
sep 05 16:24:49 laptop systemd[1]: home-manager-bbigras.service: Main process exited, code=exited, status=1/FAILURE
sep 05 16:24:49 laptop systemd[1]: home-manager-bbigras.service: Failed with result 'exit-code'.
sep 05 16:24:49 laptop systemd[1]: Failed to start Home Manager environment for bbigras.
Activation of /nix/store/vldp095i97dw81q6y3wffl4g01j8i8sg-nixos-system-laptop-20.09pre-git failed
System activation failed
Rolling back..
stopping the following units: nix-daemon.service, nix-daemon.socket, nscd.service, systemd-udevd-control.socket, systemd-udevd-kernel.socket, systemd-udevd.service, tlp.service, tmp.mount
Job for tmp.mount canceled.
NOT restarting the following changed units: systemd-fsck@dev-disk-by\x2duuid-5E57\x2d78A0.service
activating the configuration...
setting up /etc...
Failed to list users: Unit dbus-org.freedesktop.login1.service not found.
setting up tmpfiles
reloading the following units: dbus.service
starting the following units: nix-daemon.socket, nscd.service, systemd-udevd-control.socket, systemd-udevd-kernel.socket, tlp.service
the following new units were started: NetworkManager-dispatcher.service
warning: the following units failed: home-manager-bbigras.service

● home-manager-bbigras.service - Home Manager environment for bbigras
     Loaded: loaded (/nix/store/nb78lgx933hnlvpbpf9v46cy7jny9z7c-unit-home-manager-bbigras.service/home-manager-bbigras.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Sat 2020-09-05 16:24:58 EDT; 617ms ago
    Process: 8841 ExecStart=/nix/store/3zsmjxbai15q0amx7dxswrfqchbpnczr-activate-bbigras (code=exited, status=1/FAILURE)
   Main PID: 8841 (code=exited, status=1/FAILURE)
         IP: 0B in, 0B out
        CPU: 286ms

sep 05 16:24:58 laptop hm-activate-bbigras[8841]:   newGenGcPath=/nix/var/nix/gcroots/per-user/bbigras/current-home
sep 05 16:24:58 laptop hm-activate-bbigras[8841]:   genProfilePath=/nix/var/nix/profiles/per-user/bbigras/home-manager
sep 05 16:24:58 laptop hm-activate-bbigras[8841]: Activating checkFilesChanged
sep 05 16:24:58 laptop hm-activate-bbigras[8841]: Activating checkLinkTargets
sep 05 16:24:58 laptop hm-activate-bbigras[8841]: Activating writeBoundary
sep 05 16:24:58 laptop hm-activate-bbigras[8841]: Activating createDirsIn--persist-home-bbigras
sep 05 16:24:58 laptop hm-activate-bbigras[8996]: mkdir: cannot stat ‘/persist/home/bbigras/.local/share/remmina’: Transport endpoint is not connected
sep 05 16:24:58 laptop systemd[1]: home-manager-bbigras.service: Main process exited, code=exited, status=1/FAILURE
sep 05 16:24:58 laptop systemd[1]: home-manager-bbigras.service: Failed with result 'exit-code'.
sep 05 16:24:58 laptop systemd[1]: Failed to start Home Manager environment for bbigras.
Activation of /nix/store/z6913zjfzp7ncs7cmsw7h1k20pqvlkl4-nixos-system-laptop-20.09pre-git failed
Waiting for confirmation..
Successfully rolled back without rebooting

home-manager-bbigras log

❯ journalctl -b 1 -u home-manager-bbigras
-- Logs begin at Wed 2020-08-12 14:35:49 EDT, end at Sat 2020-09-05 16:25:49 EDT. --
aoû 12 14:35:52 laptop systemd[1]: Starting Home Manager environment for bbigras...
aoû 12 14:35:52 laptop hm-activate-bbigras[1203]: Activating home-manager configuration for bbigras
aoû 12 14:35:52 laptop hm-activate-bbigras[1203]: Starting home manager activation
aoû 12 14:35:52 laptop hm-activate-bbigras[1203]: Sanity checking Nix
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]: Sanity checking oldGenNum and oldGenPath
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]: This is a live run
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]: Using Nix version:
aoû 12 14:35:53 laptop hm-activate-bbigras[1390]: Using Nix version:
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]: Activation variables:
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]:   oldGenNum=2
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]:   oldGenPath=/nix/store/gs105rzfvwfwvbgs47xrsm6r23x6cm9p-home-manager-generation
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]:   newGenPath=/nix/store/gs105rzfvwfwvbgs47xrsm6r23x6cm9p-home-manager-generation
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]:   newGenNum=3
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]:   newGenGcPath=/nix/var/nix/gcroots/per-user/bbigras/current-home
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]:   genProfilePath=/nix/var/nix/profiles/per-user/bbigras/home-manager
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]: Activating checkFilesChanged
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]: Activating checkLinkTargets
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]: Activating writeBoundary
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]: Activating createDirsIn--persist-home-bbigras
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]: Activating installPackages
aoû 12 14:35:53 laptop hm-activate-bbigras[1495]: replacing old 'home-manager-path'
aoû 12 14:35:53 laptop hm-activate-bbigras[1495]: installing 'home-manager-path'
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]: Activating dconfSettings
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]: Activating linkGeneration
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]: Cleaning up orphan links from /home/bbigras
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.Xresources: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.cache/.keep: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/afew/config: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/alacritty/alacritty.yml: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/aria2/aria2.conf: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/broot/conf.toml: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/broot/launcher/installed-v1: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/fish/config.fish: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/git/config: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/git/ignore: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/gtk-3.0/gtk.css: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/gtk-3.0/settings.ini: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/htop/htoprc: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/mako/config: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/mpv/mpv.conf: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/notmuch/notmuchrc: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/obs-studio/plugins: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/sway/config: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/swaylock/config: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/default.target.wants/dropbox.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/default.target.wants/matrix-yggdrasil.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/default.target.wants/spotifyd.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/dropbox.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/lieer-bbigras.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/lieer-bbigras.timer: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/lorri.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/lorri.socket: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/mako.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/matrix-yggdrasil.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/mute.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/polkit.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/redshift.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/sockets.target.wants/lorri.socket: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/spotifyd.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/sway-session.target: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/sway-session.target.wants/mako.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/sway-session.target.wants/mute.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/sway-session.target.wants/polkit.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/sway-session.target.wants/redshift.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/sway-session.target.wants/swayidle.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/sway-session.target.wants/waybar.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/swayidle.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/timers.target.wants/lieer-bbigras.timer: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/systemd/user/waybar.service: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/waybar/config: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.config/waybar/style.css: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.emacs.d/init.el: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.gdbinit: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.gnupg/private-keys-v1.d: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.gnupg/pubring.kbx: gone (deleting)
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.gnupg/random_seed: gone (deleting)
aoû 12 14:35:53 laptop hm-activate-bbigras[1518]: rmdir: removing directory, '.gnupg'
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.gnupg/sshcontrol: gone (deleting)
aoû 12 14:35:53 laptop hm-activate-bbigras[1520]: removed '/home/bbigras/.gnupg/sshcontrol'
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.gnupg/trustdb.gpg: gone (deleting)
aoû 12 14:35:53 laptop hm-activate-bbigras[1526]: rmdir: removing directory, '.gnupg'
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.gtkrc-2.0: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.icons/default: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.local/share/direnv: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.local/share/fish/home-manager_generated_completions: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.local/share/keyrings: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.restic-excludes: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/.ssh/config: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/Documents: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/Downloads: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/Maildir/.notmuch/hooks/post-new: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/Maildir/bbigras/.gmailieer.json: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/Music: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/Pictures: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/Videos: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/dev: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1509]: Checking /home/bbigras/tmp: exists
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]: No change so reusing latest profile generation 2
aoû 12 14:35:53 laptop hm-activate-bbigras[1203]: Creating home file links in /home/bbigras
aoû 12 14:35:53 laptop hm-activate-bbigras[1532]: '/home/bbigras/.Xresources' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.Xresources'
aoû 12 14:35:53 laptop hm-activate-bbigras[1568]: '/home/bbigras/.config/htop/htoprc' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/htop/htoprc'
aoû 12 14:35:53 laptop hm-activate-bbigras[1571]: '/home/bbigras/.config/mako/config' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/mako/config'
aoû 12 14:35:53 laptop hm-activate-bbigras[1574]: '/home/bbigras/.config/mpv/mpv.conf' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/mpv/mpv.conf'
aoû 12 14:35:53 laptop hm-activate-bbigras[1577]: '/home/bbigras/.config/notmuch/notmuchrc' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/notmuch/notmuchrc'
aoû 12 14:35:53 laptop hm-activate-bbigras[1580]: '/home/bbigras/.config/obs-studio/plugins' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/obs-studio/plugins'
aoû 12 14:35:53 laptop hm-activate-bbigras[1583]: '/home/bbigras/.config/sway/config' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/sway/config'
aoû 12 14:35:53 laptop hm-activate-bbigras[1589]: '/home/bbigras/.config/systemd/user/default.target.wants/dropbox.service' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/systemd/user/default.target.wants/dropbox.service'
aoû 12 14:35:53 laptop hm-activate-bbigras[1592]: '/home/bbigras/.config/systemd/user/default.target.wants/matrix-yggdrasil.service' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/systemd/user/default.target.wants/matrix-yggdrasil.service'
aoû 12 14:35:53 laptop hm-activate-bbigras[1595]: '/home/bbigras/.config/systemd/user/default.target.wants/spotifyd.service' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/systemd/user/default.target.wants/spotifyd.service'
aoû 12 14:35:53 laptop hm-activate-bbigras[1598]: '/home/bbigras/.config/systemd/user/dropbox.service' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/systemd/user/dropbox.service'
aoû 12 14:35:53 laptop hm-activate-bbigras[1601]: '/home/bbigras/.config/systemd/user/lieer-bbigras.service' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/systemd/user/lieer-bbigras.service'
aoû 12 14:35:53 laptop hm-activate-bbigras[1604]: '/home/bbigras/.config/systemd/user/lieer-bbigras.timer' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/systemd/user/lieer-bbigras.timer'
aoû 12 14:35:53 laptop hm-activate-bbigras[1610]: '/home/bbigras/.config/systemd/user/lorri.socket' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/systemd/user/lorri.socket'
aoû 12 14:35:53 laptop hm-activate-bbigras[1617]: '/home/bbigras/.config/systemd/user/matrix-yggdrasil.service' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/systemd/user/matrix-yggdrasil.service'
aoû 12 14:35:53 laptop hm-activate-bbigras[1620]: '/home/bbigras/.config/systemd/user/mute.service' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/systemd/user/mute.service'
aoû 12 14:35:53 laptop hm-activate-bbigras[1626]: '/home/bbigras/.config/systemd/user/polkit.service' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/systemd/user/polkit.service'
aoû 12 14:35:53 laptop hm-activate-bbigras[1629]: '/home/bbigras/.config/systemd/user/redshift.service' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/systemd/user/redshift.service'
aoû 12 14:35:53 laptop hm-activate-bbigras[1632]: '/home/bbigras/.config/systemd/user/sockets.target.wants/lorri.socket' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/systemd/user/sockets.target.wants/lorri.socket'
aoû 12 14:35:53 laptop hm-activate-bbigras[1635]: '/home/bbigras/.config/systemd/user/spotifyd.service' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.config/systemd/user/spotifyd.service'
aoû 12 14:35:53 laptop hm-activate-bbigras[1675]: '/home/bbigras/.emacs.d/init.el' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.emacs.d/init.el'
aoû 12 14:35:53 laptop hm-activate-bbigras[1678]: '/home/bbigras/.gdbinit' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.gdbinit'
aoû 12 14:35:53 laptop hm-activate-bbigras[1681]: '/home/bbigras/.gnupg/private-keys-v1.d' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.gnupg/private-keys-v1.d'
aoû 12 14:35:53 laptop hm-activate-bbigras[1684]: '/home/bbigras/.gnupg/pubring.kbx' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.gnupg/pubring.kbx'
aoû 12 14:35:53 laptop hm-activate-bbigras[1687]: '/home/bbigras/.gnupg/random_seed' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.gnupg/random_seed'
aoû 12 14:35:53 laptop hm-activate-bbigras[1693]: '/home/bbigras/.gnupg/sshcontrol' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.gnupg/sshcontrol'
aoû 12 14:35:53 laptop hm-activate-bbigras[1696]: '/home/bbigras/.gnupg/trustdb.gpg' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.gnupg/trustdb.gpg'
aoû 12 14:35:53 laptop hm-activate-bbigras[1701]: '/home/bbigras/.gtkrc-2.0' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.gtkrc-2.0'
aoû 12 14:35:53 laptop hm-activate-bbigras[1717]: '/home/bbigras/.restic-excludes' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.restic-excludes'
aoû 12 14:35:54 laptop hm-activate-bbigras[1720]: '/home/bbigras/.ssh/config' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/.ssh/config'
aoû 12 14:35:54 laptop hm-activate-bbigras[1727]: '/home/bbigras/Downloads' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/Downloads'
aoû 12 14:35:54 laptop hm-activate-bbigras[1730]: '/home/bbigras/Maildir/.notmuch/hooks/post-new' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/Maildir/.notmuch/hooks/post-new'
aoû 12 14:35:54 laptop hm-activate-bbigras[1733]: '/home/bbigras/Maildir/bbigras/.gmailieer.json' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/Maildir/bbigras/.gmailieer.json'
aoû 12 14:35:54 laptop hm-activate-bbigras[1736]: '/home/bbigras/Music' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/Music'
aoû 12 14:35:54 laptop hm-activate-bbigras[1742]: '/home/bbigras/Videos' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/Videos'
aoû 12 14:35:54 laptop hm-activate-bbigras[1745]: '/home/bbigras/dev' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/dev'
aoû 12 14:35:54 laptop hm-activate-bbigras[1748]: '/home/bbigras/tmp' -> '/nix/store/s3a66anlqalp6zapkmzj4fpwpd9zvlzw-home-manager-files/tmp'
aoû 12 14:35:54 laptop hm-activate-bbigras[1203]: Activating onFilesChange
aoû 12 14:35:54 laptop hm-activate-bbigras[1203]: Activating reloadSystemD
aoû 12 14:35:54 laptop hm-activate-bbigras[1203]: User systemd daemon not running. Skipping reload.
aoû 12 14:35:54 laptop systemd[1]: Finished Home Manager environment for bbigras.
aoû 12 14:40:24 laptop systemd[1]: home-manager-bbigras.service: Succeeded.
aoû 12 14:40:24 laptop systemd[1]: Stopped Home Manager environment for bbigras.

How do I enable Home Manager support with a Flake configuration?

I've a NixOS configuration based on Nix Flakes. I've imported Home Manager as a module.

Minimal viable example of my NixOS configuration flake.nix:

{
  description = "NixOS configuration";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-21.11";

    home-manager.url = "github:nix-community/home-manager/master";

    impermanence.url = "github:nix-community/impermanence/master";
  };

  outputs = { self, nixpkgs, home-manager, impermanence }: {
    nixosConfigurations = let
      system = "x86_64-linux";

      lib = nixpkgs.lib;
    in {
      computerName = nixpkgs.lib.nixosSystem {
        inherit system;

        modules = [
          ({ pkgs, ... }: {
            # Safely erasing the root dataset on each boot
            boot.initrd.postDeviceCommands = lib.mkAfter ''
              zfs rollback -r zroot/ROOT/root@blank
            '';

            networking.hostName = "computerName";

            users.users.a12l = {
              home = "/home/a12l";
              isNormalUser = true;
            };

            nix.extraOptions = ''
              experimental-features = nix-command flakes
            '';

            system.stateVersion = "21.11";
          })

          home-manager.nixosModules.home-manager
          {
            home-manager.useGlobalPkgs = true;
            home-manager.useUserPackages = true;
            home-manager.users.a12l = {
              home.username = "a12l";
              home.homeDirectory = "/home/a12l";
            };
          }

          impermanence.nixosModules.impermanence
          {
            environment.persistence."/persistent" = {
              directories = [
                "/var/log"
                "/var/lib/bluetooth"
                "/var/lib/systemd/coredump"
                "/etc/NetworkManager/system-connections"
              ];

              files = [ "/etc/machine-id" ];
            };
          }
        ];
      };
    };
  };
}

To where should I send this attribute set?

{
  home.persistence."/persistent/home/a12l" = {
    directories = [
      "Example"
    ];

    files = [
      ".examplerc"
    ];

    allowOther = true;
  };
}

When I look at impermanence's flake.nix, it seems that only the module for system configurations is available via the flake interface?

{
  outputs = { self }: {
    nixosModules.impermanence = import ./nixos.nix;
  };
}

I can use environment.persistence."/persistent/home/a12l", but then I don't for example have the allowOther attribute.

{
  environment.persistence."/persistent/home/a12l" = {
    directories = [
      "Example"
    ];
  
    files = [
      ".examplerc"
    ];
  
    allowOther = true;
  };
}

impermanence doesn't work with `qemu-vm.nix built systems.

I'm using nixos testing machinery to setup several nixos VMs for ad-hoc testing of a distributed service. I want to persist some state between run (in particular ssh host keys and tailscale configuration). I tried using impermanence, but it looks like it doesn't work, since qemu-vm.nix overrides config.fileSystems set by impermanence.

Doesn't work with spaces

I've added .config/Mullvad VPN/gui_settings.json to home.persistence."/persistent/home/a12l".files, I.e., home.persistence."/persistent/home/a12l".files = [ ".config/Mullvad VPN/gui_settings.json" ];. Impermanence creates a broken symlink. It creates an empty directory Mullvad in my persistent storage, and an empty VPN directory in my home directory. The configuration builds without any error messages.

$ ls -l ~/.config/Mullvad\ VPN/gui_settings.json 
lrwxrwxrwx 1 a12l users 100 Dec 29 22:31 '/home/a12l/.config/Mullvad VPN/gui_settings.json' -> '/nix/store/pyzav7b94vniqx2m55360vlpx5jjwnis-home-manager-files/.config/Mullvad VPN/gui_settings.json'

$ ls -l /nix/store/pyzav7b94vniqx2m55360vlpx5jjwnis-home-manager-files/.config/Mullvad\ VPN/gui_settings.json 
lrwxrwxrwx 1 root root 100 Jan  1  1970 '/nix/store/pyzav7b94vniqx2m55360vlpx5jjwnis-home-manager-files/.config/Mullvad VPN/gui_settings.json' -> /nix/store/3c7i5zzzv6pm5ar1l4y31da5ccz31ksh-persistent-home-a12l-config-Mullvad-VPN-gui_settingsjson

$ ls -l /nix/store/3c7i5zzzv6pm5ar1l4y31da5ccz31ksh-persistent-home-a12l-config-Mullvad-VPN-gui_settingsjson 
lrwxrwxrwx 1 root root 59 Jan  1  1970 /nix/store/3c7i5zzzv6pm5ar1l4y31da5ccz31ksh-persistent-home-a12l-config-Mullvad-VPN-gui_settingsjson -> '/persistent/home/a12l/.config/Mullvad VPN/gui_settings.json'

$ ls -l /persistent/home/a12l/.config/
total 99
[...]
drwxr-xr-x  2 a12l users  2 Dec 29 20:46 Mullvad
[...]

$ ls -l /persistent/home/a12l/.config/Mullvad/
total 0

$ ls -l ~/VPN/
total 0

If I add the directory with quotes, I.e., home.persistence."/persistent/home/a12l".files = [ ".config/Mullvad VPN/gui_settings.json" ];, a directory with the correct name is created in /persistent/home/a12l/.config/, but the directory is empty and no symlink is created

$ ls -l /persistent/home/a12l/.config/Mullvad\ VPN/
total 0

$ ls -l ~/.config/Mullvad\ VPN/gui_settings.json 
-rw-r--r-- 1 a12l users 193 Dec 30 14:02 '/home/a12l/.config/Mullvad VPN/gui_settings.json'

I haven't tested having spaces in environment.persistence."/persistent".{directories | files}, or in home.persistence."/persistent/home/a12l".directories.

Support configuring other dirs as tmpfs, or a sync daemon

Hello.

I was reading a user raving about Firefox performance after moving the cache to an SSD and using a daemon to synchronize their firefox profile between a tmpfs dir and actual persistent storage.

These to me feel like very related-features to impermanence. I'd love to be able to specify some further configuration that would allow me to mount tmpfs at ~/.cache and then mount a tmpfs at ~/.mozilla that is then synchronized with a persistent directory in the same storage that impermanence is using.

Alternatively, maybe just an HM service to run ASD/PSD.

related links/apps:

Issue with per-directory history

After having removed the /etc/NIXOS file from the persisted files (as, it turns out, it's unecessary to persist it, as NixOS will regenerate it if not present), I am now facing another issue, upon opening a shell with the per-directory-history oh-my-zsh plugin:

_per-directory-history-set-directory-history:1: can't rename /home/jmc-figueira/.zsh_history.new to $HISTFILE
error: Invalid value for '--jobs <JOBS>': cannot parse integer from empty string

For more information try --help

Somehow, impermanence interferes with the mechanism this plugin uses to manage the zsh histories per directory. I wonder if there are other issues present of the sort; the following error (about the --jobs argument) does not seem to be related to this, but I was unable to pinpoint its cause as of yet.

EDIT: the --jobs error is related to starship, which is even more odd, as I do not have the starship config persisted through impermanence; it might be unrelated to the issue at hand, however.

Argument list too long

Hello!

While setting up the build environment: executing '/nix/store/...-bash-5.1-p8/bin/bash': Argument list too long.

I'm getting this while installing nixos with a presumably large number of files and directories.

How might I go about fixing this?

Thank you kindly for the help!

HM module: bind mounts not working with HM xsession

While playing with the Home Manager module of impermanence I ran into an issue with the systemd user services used by impermanence to do the bind mounts where the mounts seemingly do not work in a graphical session.

After further investigation I noticed that the mounts actually work fine but the systemd services immediately get stopped after a graphical login using HM's xsession module.

Home Manager creates two files that are involved in starting an X session: ~/.xsession and ~/.xprofile.

(Depending on the system configuration) the display manager executes .xsession which in turn sources .xprofile.

.xsession:

if [ -z "$HM_XPROFILE_SOURCED" ]; then
  . ~/.xprofile
fi
unset HM_XPROFILE_SOURCED

systemctl --user start hm-graphical-session.target

[...]

.xprofile:

[...]
if [ -e "$HOME/.profile" ]; then
  . "$HOME/.profile"
fi

# If there are any running services from a previous session.
# Need to run this in xprofile because the NixOS xsession
# script starts up graphical-session.target.
systemctl --user stop graphical-session.target graphical-session-pre.target
[...]

So upon login using a display manager HM actually stops the user services graphical-session.target and graphical-session-pre.target.
According to my research this leads to the following systemd user targets being reached in this order when doing a graphical login:

  1. default.target
  2. graphical-session-pre.target
  3. graphical-session.target

impermanence generates systemd user service descriptions that are:

  • WantedBy=default.target
  • PartOf=graphical-session-pre.target

From what I understand this means that those services get executed to reach default.target and get stopped when graphical-session-pre.target ist stopped.

So in combination this leads to the observed behavior of the bind mounts immediately getting unmounted upon graphical login.

In my opinion HM doing the systemctl --user stop thing in .xprofile is questionable.
I'm posting the issue with the impermanence project nonetheless because I'm not sure using PartOf=graphical-session-pre.target is the correct way to handle the unmounting.

Since I don't know much about systemd I'm not even sure what an alternative would be. But I wonder why the mount services are not stopped with default.target?

Conflicting definition values when regenerating `hardware-configuration.nix'

Hello!

If you regenerate hardware-configuration.nix, you get something like the following:

error: The option `fileSystem./home/curtis/VirtualBox VMs.device' has conflicting definition values:
       - In `/etc/nixos/hardware-configuration.nix': "/persist/home/curtis/VirtualBox040VMs"
       - In `/nix/store/[hash]/nixos.nix': "/persist/home/curtis/VirtualBox VMs"

Can I mkForce the latter somehow, instead of constantly having to edit the former?

Thank you kindly for the help!

Configuration for common programs

I haven't thought this through, but what about supplementing the files= and directories= with programs= or services= which would know that

  • bluetooth=true means persist /var/lib/bluetooth and
  • networkManager=true means persist /var/lib/NetworkManager/system-connections

and so on?

This has the advantage that "what files does this program need to persist" can be figured out by the community once instead of by each user individually.

How to use impermanence + home-manager module with flake

Hi,

I'm trying to switch my configuration by using a flake, everything work so far except impermanence and its home-manager module.

I get this error

[root@t470:/etc/nixos]# nixos-rebuild build --flake '.#t470'
building the system configuration...
warning: Git tree '/etc/nixos' is dirty
error: The option `home' does not exist. Definition values:
       - In `/nix/store/j4n45y0r4ybms9vz64wisbffq7hbf78q-source/flake.nix':
           {
             persistence = {
               "/nix/home/solene" = {
                 allowOther = true;
                 directories = [
           ...

when using the following configuration

{
  inputs = {
    nixpkgs.url = "nixpkgs/nixos-unstable";

    home-manager = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    impermanence = {
      url = "github:nix-community/impermanence";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };


  outputs = { self, nixpkgs, impermanence, home-manager, ... }@inputs:
    let
      system = "x86_64-linux";
      pkgs = import nixpkgs { inherit system; config = { allowUnfree = true; }; };
      lib = nixpkgs.lib;

    in
    {

      # begin nixosConfigurations
      nixosConfigurations = {
        t470 = lib.nixosSystem {
          inherit system;
          inherit lib;
          specialArgs = { inherit inputs; };

          # begin modules
          modules = [
            (import ./configuration.nix)

            # begin home-manager
            home-manager.nixosModules.home-manager
            {
              home-manager.useGlobalPkgs = true;
              home-manager.useUserPackages = true;
              home-manager.users.solene = {
                home.username = "solene";
                home.homeDirectory = "/home/solene";
              };
            } # end home-manager

            # begin impermanence
            impermanence.nixosModules.impermanence
            impermanence.nixosModules
            {
              environment.persistence."/nix/" = {
                directories = [
                  "/etc/nixos"
                  "/nix/var/nix"
                  "/var/lib"
                  "/var/log"
                  "/tmp"
                ];
              };
              environment.etc."machine-id".source = "/nix/etc/machine-id";

              home.persistence."/nix/home/solene" = {
                allowOther = true;
                removePrefixDirectory = false;
                directories = [
                  ".gnupg"
                  ".ssh"
                ];
                files = [
                  ".gitconfig"
                ];

              };
            } # end impermanence
          ]; # end modules
        }; # end nixosConfigurations
      };
    };
}

I tried to look at the issues and PR but I really don't understand how the home.persistence is supposed to work in this situation. I'd appreciate hints or help to get it to work.

(home-manager) File manager (Nautilus) shows persistent folders as ejectable drives

Nautilus shows my Documents and Downloads folder as ejectable drive as well as showing drive icons beside them in the file view in /home. A solution I am thinking of would be to allow setting mount options with impermanence so the x-gvfs-hide option can be used.

Unsure whether this option would be set per directory/file or per persistent mount (set mount option that affects all of /nix/persist for example).

Kernel panic resulting from a possible precedence issue

Hi!

I was previously using impermanence pinned to commit 5855884 and, having seen the recent improvements to the module, decided to update to commit ff540db.

Unfortunately, somewhere in between, possibly due to the addition of #44, I believe that the /etc/NIXOS file, which I currently have configured to be persisted, as it is stated to be necessary for NixOS to recognize its own root partition, became involved in a precedence issue, where it causes NixOS to panic due to its potentially premature loading. The following screenshot exemplifies this occurrence (sorry for the poor quality but, as I do not have systemctl logs persisted, I am unable to directly copy the relevant log lines):

image

What occurs after the /etc/NIXOS clash is that systemd is not found and the boot process is aborted.

I apologize for the vagueness of my explanation, but I am at a loss as to what else may be the root cause of this issue, as well as any potential workarounds.

Does the nixos module work with paths or only a root device?

I tried following the blog post

On my machine I get the following error when trying to switch

[root@dent:/etc/nixos]# nixos-rebuild boot --show-trace
building Nix...
building the system configuration...
error: while evaluating the attribute 'config.system.build.toplevel' at /nix/var/nix/profiles/per-user/root/channels/nixos/nixos/modules/system/activation/top-level.nix:275:5:
while evaluating 'foldr' at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/lists.nix:52:20, called from /nix/var/nix/profiles/per-user/root/channels/nixos/nixos/modules/system/activation/top-level.nix:139:12:
while evaluating 'fold'' at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/lists.nix:55:15, called from /nix/var/nix/profiles/per-user/root/channels/nixos/lib/lists.nix:59:8:
while evaluating anonymous function at /nix/var/nix/profiles/per-user/root/channels/nixos/nixos/modules/system/activation/top-level.nix:132:50, called from undefined position:
while evaluating the attribute 'assertion' at /nix/store/26s6bkfh6gvq0zg0a9lgjs6p4i66r1hx-source/nixos.nix:190:11:
while evaluating 'markedNeededForBoot' at /nix/store/26s6bkfh6gvq0zg0a9lgjs6p4i66r1hx-source/nixos.nix:168:37, called from /nix/store/26s6bkfh6gvq0zg0a9lgjs6p4i66r1hx-source/nixos.nix:190:23:
while evaluating the attribute 'fileSystems."/nix/persist".neededForBoot' at undefined position:
attribute '/nix/persist' missing, at /nix/store/26s6bkfh6gvq0zg0a9lgjs6p4i66r1hx-source/nixos.nix:168:42

my machine is setup that /nix is filesystem and /nix/persist is a folder inside of it.

This config from the blog post is working with the home-manager module but not with the nixos one.

Is there a way to make this work without making my persist dir the root dir of a filesystem?

Issues with systemd's DynamicUser and StateDirectory options

When using systemd's DynamicUser and StateDirectory options together, and trying to persist /var/lib/<service name>, the service fails to start because systemd expects the directory not to exist in order to setup the directory. This is obviously incompatible with how we bind mount the directory, but a simple solution for this issue doesn't come to mind. This may be unfixable, but I figured I'd open a issue in case anyone has any ideas.

Are files read-only?

I just tried this for the first time. I had to create /persist/etc/machine-id but now /etc/machine-id points to a file in the nix store. Which I expect to be read-only. It's fine for the machine-id but it wouldn't be for network-manager stuff or logs. Which I would prefer to be writable but still persistent between reboots.

  environment.persistence."/persist" = {
    files = [
      "/etc/machine-id"
    ];
  };

home-manager: 'Filesystem "FUSE" not supported' error with Dropbox

I'm using 2cda5cd

I was using:

    home.persistence."/persist/home/bbigras" = {
      directories = [
        ".dropbox-dist"
        ".dropbox-hm"
      ];

switching them to environment.persistence."/persist".directories seems to work.

journalctl

déc 29 17:28:24 laptop vsbgld509hg85p3lblwxzcfmj6wvm18x-dropbox-start[30035]: Impossible de d\xe9marrer Dropbox.
déc 29 17:28:24 laptop vsbgld509hg85p3lblwxzcfmj6wvm18x-dropbox-start[30035]: Une erreur d'autorisation est g\xe9n\xe9ralement \xe0 l'origine de ce probl\xe8me. Une erreur p>
déc 29 17:28:24 laptop vsbgld509hg85p3lblwxzcfmj6wvm18x-dropbox-start[30035]: Pour obtenir une aide suppl\xe9mentaire, consultez https://www.dropbox.com/c/help/permissions_e>
déc 29 17:28:24 laptop vsbgld509hg85p3lblwxzcfmj6wvm18x-dropbox-start[30035]: Veuillez contacter l'assistance Dropbox et indiquer les informations suivantes pour obtenir de >
déc 29 17:28:24 laptop vsbgld509hg85p3lblwxzcfmj6wvm18x-dropbox-start[30035]: /tmp/dropbox_error1l3ed21w.txt

error file

Traceback (most recent call last):
  File "dropbox/client/main.pyc", line 806, in wrapper
  File "dropbox/client/main.pyc", line 6595, in finish_dropbox_boot
  File "dropbox/client/main.pyc", line 6060, in _init_components_for_account
  File "dropbox/client/main.pyc", line 5999, in create_sync_engine
  File "dropbox/sync_engine_boundary/factory.pyc", line 261, in make_sync_engine
  File "dropbox/sync_engine/nucleus/classic_client/sync_engine.pyc", line 340, in __init__
  File "dropbox/sync_engine/nucleus/classic_client/modern_client/modern_client.pyc", line 158, in __init__
  File "dropbox/sync_engine/nucleus/classic_client/modern_client/base.pyc", line 155, in __init__
  File "dropbox/sync_engine/nucleus/classic_client/thin_adapter/in_proc.pyc", line 222, in __init__
  File "dropbox/sync_engine/nucleus/classic_client/thin_adapter/in_proc.pyc", line 602, in _init_new_engine_locked
  File "dropbox/sync_engine/nucleus/thin_client/client.pyc", line 217, in __init__
  File "extensions/nucleus/nucleus_python.pyx", line 88, in nucleus_python.NucleusSyncEngine.__cinit__
nucleus_python.SyncEngineError: "Initializing engine |>> Initializing platform |>> Checking if filesystem is supported |>> Filesystem \"FUSE\" not supported! See dropbox.com>
(END)

`systemd` service doesn't start if `home-manager` is not used as a `nixosModule`

Hi, I'm pretty new to Nix, and am trying to use the impermanence home-manager module in my configuration (using Flakes), and I have some difficulties understanding how it all works. You can find my dotfiles here

Problem

Every single time the system boots, the home directory is regenerated (because of tmpfs), so all files in ~ are deleted (including the user systemd units to bind-mount the directories), and I need to re-apply the user configuration every time after login to get back all the files, which I hope isn't the desired method of operation. Also, I must run rm -rf ~ before re-applying, else it errors out with this message:

fuse: mountpoint is not empty
fuse: if you are sure this is safe, use the 'nonempty' mount option

and the home-manager configuration is not applied. It is also not possible for me to define a user systemd service to re-apply the configuration on login, so every boot requires a manual rebuild, which is not ideal.

Expected Behaviour

The directories (both the persisted ones and the ones linked using the home-manager option home.file are present on login, w/o any interference from the user.

Important Configuration Files

shortened, for decreasing complexity
flake.nix

{
  description = "My Reproducible, Hermetic, Derivational, Portable, Atomic, Multi-PC NixOS Dotfiles";
  
  ## Package Repositories ##
  inputs =
  {
    ## Main Repositories ##
    # NixOS Stable Release
    nixpkgs.url = "github:NixOS/nixpkgs?ref=nixos-21.05";
    
    # Home Manager
    home-manager =
    {
      url = "github:nix-community/home-manager?ref=release-21.05";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    
    # Persistent State Handler
    impermanence.url = "github:nix-community/impermanence";
  };
  
  ## Output Configuration ##
  outputs = { self, ... } @ inputs:
  let
    ## Variable Declaration ##
    # Architecture
    system = "x86_64-linux";
    
    # NixOS Version
    version = "21.05";
    
    # Package Configuration
    pkgs = import inputs.nixpkgs
    {
      inherit system overlays;
      config =
      {
        allowUnfree = true;
        allowBroken = true;
      };
    };
    
    # System Libraries
    inherit (inputs.nixpkgs) lib;
    inherit (lib) attrValues;
    
    # Custom Functions
    util = import ./lib { inherit system lib inputs pkgs; };
    inherit (util) user;
    inherit (util) host;
  in
  {
    ## User Specific Configuration ##
    homeManagerConfigurations =
    {
      # User V7
      v7 = user.mkHome
      {
        username = "v7";
        roles = [ "dconf" "discord" "firefox" "git" "zsh" ];
        inherit version;
        persist = true;
      };
    };
    
    ## Device Specific Configuration ##
    nixosConfigurations =
    {
      # PC - Dell Inspiron 15 5000
      Vortex = host.mkHost
      {
        inherit version;
        name = "Vortex";
        kernelPackage = pkgs.linuxPackages_lqx;
        initrdMods = [ "xhci_pci" "thunderbolt" "nvme" "usb_storage" "sd_mod" ];
        kernelMods = [ "kvm-intel" ];
        kernelParams = [ "quiet" "splash" "rd.systemd.show_status=false" "rd.udev.log_level=3" "udev.log_priority=3" ];
        modprobe = "options kvm_intel nested=1";
        cpuCores = 8;
        filesystem = "btrfs";
        ssd = true;
        roles = [ "android" "fonts" "git" "gnome" "libvirt" "office" "security" "xorg" ];
        users =
        [
          {
            name = "v7";
            description = "V 7";
            groups = [ "wheel" "networkmanager" "audio" "video" "cdrom" "disk" "kvm" "libvirtd" "adbusers" ];
            uid = 1000;
            shell = pkgs.zsh;
          }
        ];
      };
    };
  };
}

filesystem module

{ config, lib, pkgs, ... }:
with lib;
with builtins;
let
  cfg = config.hardware.filesystem;
in rec
{
  options.hardware.filesystem = mkOption
  {
    type = types.enum [ "btrfs" "ext4" ];
    description = "This is the File System to be used by the disk";
    default = "ext4";
  };
  
  config =
  {
    # Partitions
    fileSystems = (if (cfg == "ext4")
    then
    ## EXT4 File System Configuration ##
    {
      "/" =
      {
        device = "/dev/disk/by-label/System";
        fsType = "ext4";
      };
    }
    else
    ## BTRFS Opt-in State File System Configuration ##
    {
      # ROOT Partition
      # Opt-in State with TMPFS
      "/" =
      {
        device = "tmpfs";
        fsType = "tmpfs";
        options = [ "defaults" "size=3G" "mode=755" ];
      };
      # BTRFS Partition
      "/mnt/btrfs" =
      {
        device = "/dev/disk/by-label/System";
        fsType = "btrfs";
        options = [ "subvolid=5" "compress=zstd" "autodefrag" "noatime" ];
      };
      # NIX Subvolume
      "/nix" =
      {
        device = "/dev/disk/by-label/System";
        fsType = "btrfs";
        options = [ "subvol=nix" ];
      };
      # PERSISTENT Subvolume
      "/persist" =
      {
        device = "/dev/disk/by-label/System";
        fsType = "btrfs";
        options = [ "subvol=persist" ];
        neededForBoot = true;
      };
    });
    
    # Persisted Files
    environment.persistence."/persist" = (mkIf (cfg == "btrfs")
    {
      directories =
      [
        "/etc/nixos"
        "/etc/NetworkManager/system-connections"
        "/var/log"
        "/var/lib/AccountsService"
        "/var/lib/bluetooth"
        "/var/lib/libvirt"
      ];
      
      files =
      [
        "/etc/machine-id"
      ];
    });
    
    # Snapshots
    services.btrbk = (mkIf (cfg == "btrfs")
    {
      instances =
      {
        persist =
        {
          onCalendar = "daily";
          settings =
          {
            timestamp_format = "long";
            snapshot_preserve = "31d";
            snapshot_preserve_min = "7d";
            volume."/mnt/btrfs".subvolume =
            {
              persist.snapshot_create = "always";
            };
          };
        };
      };
    });
  };
}

lib/user.nix

{ system, lib, inputs, pkgs, ... }:
with builtins;
{
  ## User Home Configuration ##
  mkHome = { username, roles, version, persist ? false, ... }:
  inputs.home-manager.lib.homeManagerConfiguration
  {
    inherit system username pkgs;
    stateVersion = version;
    homeDirectory = "/home/${username}";
    configuration =
    let
      # Module Import Function
      mkRole = name: import (../roles/user + "/${name}");
      user_roles = map (r: mkRole r) roles;
      
      # Extra Configuration Modules
      extra_modules =
      [
        ../modules/user
        "${inputs.impermanence}/home-manager.nix"
      ];
    in
    {
      _module.args =
      {
        inherit inputs pkgs username;
      };
            
      # Modulated Configuration Imports
      imports = shared_roles ++ user_roles ++ extra_modules;
            
      # Home Manager Configuration
      home.username = username;
      programs.home-manager.enable = true;
      systemd.user.startServices = true;
      home.persist = persist;
    };
  };
}

persist module

{ config, lib, pkgs, username, ... }:
with lib;
with builtins;
let
  cfg = config.home.persist;
in rec
{
  options.home.persist = mkOption
  {
    description = "Persist User Folders";
    type = types.bool;
    default = false;
  };
  
  config = mkIf (cfg == true)
  {
    # Persist files in Home Directory
    home.persistence."/persist/home/${username}" =
    {
      directories =
      [
        "Desktop"
        "Documents"
        "Downloads"
        "Music"
        "Pictures"
        "Templates"
        "Videos"
        ".config/dconf"
        ".config/discord"
        ".config/evolution"
        ".config/geary"
        ".config/gnome-boxes"
        ".config/goa-1.0"
        ".config/google-chrome"
        ".config/libvirt"
        ".config/Microsoft"
        ".local/share/evolution"
        ".local/share/gnome-boxes"
        ".local/share/keyrings"
        ".mozilla"
      ];
      
      files =
      [
        ".git-credentials"
        ".zsh_history"
      ];
      
      allowOther = false;
    };
  };
}

Command for applying user configuration (since, I'm using home-manager as a separate function instead of conventionally importing the module)

nix build /etc/nixos#homeManagerConfigurations.$USER.activationPackage
./result/activate
rm -rf ./result

Also, if this behaviour is irregular, please point out what is being done wrong in my configuration

chroot: failed to run command 'systemd-tmpfiles': No such file or directory

Hello!

When installing with the module I get chroot: failed to run command 'systemd-tmpfiles': No such file or directory and chroot: failed to run command '/run/current-system/bin/switch-to-configuration': No such file or directory. In relation to this issue, this is when I use a smaller number of files and directories.

Thank you kindly for the help!

Live switching not working

Doing a rebuild switch, will create the dirs but not create the bindfs mounts.
Not sure if this is just a me issue because I use nixus, or if anyone else have this as well.

home-manager: race condition with certain services

I use syncthing via home-manager, so I have to bind-mount its mutable directories. The problem is that both the bind-mount and syncthing itself are started via systemd, so syncthing may start and recreate its configuration from scratch before bindfs gets a chance to do its thing.

My current solution is to turn the bindfs unit into a forking-type systemd unit and make the syncthing unit depend on it. Is there a known better solution? If not I will PR my patch.

How to persist .config directory?

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?

File created before being symlinked

When I want to add the file ~/.config/user-dirs.dirs to my persistent storage, I first delete the file; and then add it to the home.persistence."/persistent/home/a12l"/files list. After doing a simple ls -l ~/.config/user-dirs.dirs I can verify that the file gets symlinked.

But when I reboot I find a normal file at ~/.config/user-dirs.dirs. At the same time, other files in ~/.config that is listed in the home.persistence."/persistent/home/a12l"/files list is symlinked.

What should I do?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.