modules/persist: support nested persistence

especially, support persisting 'parent' and 'parent/child' to the same backing store

this is mechanically the same as persisting parent, and ensuring parent/child gets created, but explicit support will allow for automating the persistence of more things which *might* be subdirs of other persisted items (e.g. ~/.cache/my-program/mesa_shader_db)
This commit is contained in:
2024-12-14 12:08:40 +00:00
parent c00ebddb85
commit db4e79fde8

View File

@@ -192,9 +192,26 @@ in
method = (sane-lib.withDefault store.defaultMethod) opt.method;
fsPathToStoreRelPath = fspath: path.from store.prefix fspath;
fsPathToBackingPath = fspath: path.concat [ store.origin (fsPathToStoreRelPath fspath) ];
getPersistedAncestor = fspath: let
parent = path.parent fspath;
in
if parent != path.norm fspath then
cfg.sys.byPath."${parent}" or (getPersistedAncestor parent)
else
# root path; no ancestor of `fspath` is persisted
null
;
persistedAncestor = getPersistedAncestor fspath;
persistedAncestorStore = if persistedAncestor == null then
null
else
persistedAncestor.store
;
in lib.mkMerge [
{
(lib.optionalAttrs (persistedAncestorStore == null || persistedAncestorStore != store) {
# create destination dir, with correct perms
# but skip this if an ancestor is persisted to the same store,
# else this would be a self-symlink/bind
sane.fs."${fspath}" = (lib.optionalAttrs (method == "bind") {
# inherit perms & make sure we don't mount until after the mount point is setup correctly.
dir.acl = opt.acl;
@@ -203,7 +220,7 @@ in
symlink.acl = opt.acl;
symlink.target = fsPathToBackingPath fspath;
});
}
})
(lib.optionalAttrs (opt.type == "dir") {
# create the backing path as a dir
sane.fs."${fsPathToBackingPath fspath}" = {