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
Implement support for a submodule representation for files and
directories. Strings are automatically converted to appropriate
submodule representations and each file and directory is handled based
only on their respective submodule's attributes. This means that for
most files, a string will suffice, but if more advanced options need
to be set for the specific files or directories, a submodule can be
used instead. It also, arguably, simplifies the implementation a bit.
Use bindfs to create bind mounts for directories instead of symlinking
them. This should be less problematic for many applications, since
bind mounts are much more transparent.
This sets up the bind mounts in the activation script, before any
writes are done by home-manager, then tears them down again
afterwards. The bind mounts are then handled by individual systemd
services, since they're long-running fuse processes and need to be
managed as such. This also means we leverage home-manager's mechanism
for deciding which user services should be active after a switch to a
new generation, and don't have to bother with cleaning up old leftover
fuse processes.
NOTE: All unmounts done in the activation script are put into a
function which is run either on error, or right before home-manager
starts / reloads systemd units. This will conflict with other attempts
to add traps on ERR, but this isn't currently done upstream.