mirror of
https://github.com/nix-community/impermanence
synced 2024-09-20 05:51:58 +00:00
b4160ba71d
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
91 lines
1.8 KiB
Nix
91 lines
1.8 KiB
Nix
{ lib }:
|
|
let
|
|
inherit (lib)
|
|
filter
|
|
concatMap
|
|
concatStringsSep
|
|
hasPrefix
|
|
head
|
|
replaceStrings
|
|
optionalString
|
|
removePrefix
|
|
foldl'
|
|
elem
|
|
take
|
|
length
|
|
last
|
|
;
|
|
inherit (lib.strings)
|
|
sanitizeDerivationName
|
|
;
|
|
|
|
# ["/home/user/" "/.screenrc"] -> ["home" "user" ".screenrc"]
|
|
splitPath = paths:
|
|
(filter
|
|
(s: builtins.typeOf s == "string" && s != "")
|
|
(concatMap (builtins.split "/") paths)
|
|
);
|
|
|
|
# ["home" "user" ".screenrc"] -> "home/user/.screenrc"
|
|
dirListToPath = dirList: (concatStringsSep "/" dirList);
|
|
|
|
# ["/home/user/" "/.screenrc"] -> "/home/user/.screenrc"
|
|
concatPaths = paths:
|
|
let
|
|
prefix = optionalString (hasPrefix "/" (head paths)) "/";
|
|
path = dirListToPath (splitPath paths);
|
|
in
|
|
prefix + path;
|
|
|
|
|
|
parentsOf = path:
|
|
let
|
|
prefix = optionalString (hasPrefix "/" path) "/";
|
|
split = splitPath [ path ];
|
|
parents = take ((length split) - 1) split;
|
|
in
|
|
foldl'
|
|
(state: item:
|
|
state ++ [
|
|
(concatPaths [
|
|
(if state != [ ] then last state else prefix)
|
|
item
|
|
])
|
|
])
|
|
[ ]
|
|
parents;
|
|
|
|
sanitizeName = name:
|
|
replaceStrings
|
|
[ "." ] [ "" ]
|
|
(sanitizeDerivationName (removePrefix "/" name));
|
|
|
|
duplicates = list:
|
|
let
|
|
result =
|
|
foldl'
|
|
(state: item:
|
|
if elem item state.items then
|
|
{
|
|
items = state.items ++ [ item ];
|
|
duplicates = state.duplicates ++ [ item ];
|
|
}
|
|
else
|
|
state // {
|
|
items = state.items ++ [ item ];
|
|
})
|
|
{ items = [ ]; duplicates = [ ]; }
|
|
list;
|
|
in
|
|
result.duplicates;
|
|
in
|
|
{
|
|
inherit
|
|
splitPath
|
|
dirListToPath
|
|
concatPaths
|
|
parentsOf
|
|
sanitizeName
|
|
duplicates
|
|
;
|
|
}
|