This is a good idea in itself.
Additionally, it avoids issues if users want to use mkDefault in their
fileSystems config and have no persistent directories.
This includes the options of all modules used in the evaluation, not
just the ones from `<nixpkgs/nixos>` in the local manual.
Right now this breaks with
error: attribute '"‹name›"' missing
because the submodule `environment.persistence` doesn't have
actual declarations when building the manual, but a dummy only to evaluate
the sub-options (including their defaults which is the cause of the
error) and generate documentation from that.
Using `defaultText` prevents that because there's no need anymore to
evaluate the `default` values of the options.
The fstrim service, when enabled, by default trims all mounts listed in
fstab (as long as the underlying device supports discard), including
bind mounts. With impermanence, this can lead to a significant number of
redundant trim operations, since the persistent volume is trimmed once
for itself and then again once per persistent directory each. On my
system, this leads to fstrim.service taking about 10 minutes, during
which the system usability is somewhat degraded. In addition, it may be
desired to disable trim for a certain filesystem entirely, for example
when using btrfs with discard=async.
Mark our bind mounts with the X-fstrim.notrim option, which is ignored
by mount, but instructs fstrim to skip the mount point in question. The
persistent filesystem is still trimmed properly, since it has to be
listed in fstab itself as well.
This allows the path to persistent storage to be defined through an
option in the submodule, not just by the submodule name, i.e. instead
of
```nix
environment.persistence."/persistent" = {
files = [ ... ]
directories = [ ... ]
};
```
you could specify
```nix
environment.persistence.main = {
persistentStoragePath = "/persistent";
files = [ ... ]
directories = [ ... ]
};
```
which is good for readability and when you want to split the config
between multiple files.
Fixes#117.
The logic for detecting whether a file or directory is specified
multiple times was not updated to account for the recent
file/filePath and directory/dirPath changes. This can lead to spurious
failures like the following if the same home-relative path is persisted
for different users:
Failed assertions:
- environment.persistence:
The following directories were specified two or more
times:
.cache
.config
.local/share
.local/state
.gnupg
.ssh
In addition, the assertion may falsely not trigger in the contrived
situation where the same entity is persisted both in a per-user
configuration (using the relative path) and the global configuration
(using the absolute path).
Fix these situations by checking the absolute paths again using
filePath and dirPath.
Construct directory items for all parent directories of the user
specified files and directories, assigning better default permissions
and ownership to each and removing this responsibility from the
create-directories script.
This means that all parent directories of root directories will now
have the default permissions and ownership, not inherit them from the
child. User directories are assigned default user ownership. The home
directory itself is handled specially to make sure it is owned by the
user, not readable by anyone else and its parent gets default root
ownership.
To illustrate this with an example, here is a directory specification
and the ownership and permissions that could potentially be assigned
to the parent directories, given none of them yet exist in persistent
storage:
environment.persistence."/persistent" = {
users.talyz = {
directories = [
{ directory = ".local/share/secret"; mode = "0500"; }
];
};
};
Before:
/home talyz:talyz 0500
/home/talyz talyz:talyz 0500
/home/talyz/.local talyz:talyz 0500
/home/talyz/.local/share talyz:talyz 0500
/home/talyz/.local/share/secret talyz:talyz 0500
After:
/home root:root 0755
/home/talyz talyz:talyz 0700
/home/talyz/.local talyz:talyz 0755
/home/talyz/.local/share talyz:talyz 0755
/home/talyz/.local/share/secret talyz:talyz 0500
This adds the new internal options `home`, `filePath` and
`dirPath`. Whereas previously `file` and `directory` would be
rewritten to the full path for user files and directories, they now
keep the value specified by the user. The new `filePath` and `dirPath`
options fill their previous use where the full path is required. In
addition, the new `home` option can be used to get the path to the
user's home directory for a specific file or directory item; for root
items it's set to `null`.
The `/var/lib/nixos` directory contains the uid and gid map for entities
without a static id. Not persisting them means your user and group ids
could change between reboots, which is likely undesirable.
When cross-compiling, `patchShebangs` requires the host platform's bash
to be present in the HOST_PATH environment variable. However, by default
when using `pkgs.runCommand`, only the build platform's bash is
implicitly added to the PATH. The result is that the shebang is not
replaced, and the script fails to run because the activation scripts
don't have `bash` in their environment.
By explicitly adding `pkgs.bash` to the build inputs, this ensures the
HOST_PATH is populated and makes `patchShebangs` work as expected.