programs: simplify sandbox symlink closure code
This commit is contained in:
@@ -9,11 +9,9 @@ in rec {
|
|||||||
wantedSymlinkTo = target: wantedSymlink { inherit target; };
|
wantedSymlinkTo = target: wantedSymlink { inherit target; };
|
||||||
wantedText = text: wantedSymlink { inherit text; };
|
wantedText = text: wantedSymlink { inherit text; };
|
||||||
|
|
||||||
# Type: derefSymlinkOrNul :: config.sane.fs.type -> str -> (str|null)
|
# Type: derefSymlinkOrNull :: config.sane.fs.type -> str -> (str|null)
|
||||||
# N.B.: the returned path, even though absolute, might not be "canonical".
|
# the returned path is always absolute (even if the original symlink was relative),
|
||||||
# for example, if the symlink is relative, to "../Pictures", this function
|
# and in canonical form.
|
||||||
# could return "/home/colin/Music/../Pictures".
|
|
||||||
# consider feeding the output into `sane-lib.path.realpath` to correct this.
|
|
||||||
derefSymlinkOrNull = fs: logical: let
|
derefSymlinkOrNull = fs: logical: let
|
||||||
symlinkedPrefixes = lib.filter
|
symlinkedPrefixes = lib.filter
|
||||||
(p: ((fs."${p}" or {}).symlink or null) != null)
|
(p: ((fs."${p}" or {}).symlink or null) != null)
|
||||||
@@ -27,7 +25,7 @@ in rec {
|
|||||||
sane-path.join [ firstSymlinkParent firstSymlinkDest ];
|
sane-path.join [ firstSymlinkParent firstSymlinkDest ];
|
||||||
in
|
in
|
||||||
if symlinkedPrefixes != [] then
|
if symlinkedPrefixes != [] then
|
||||||
firstSymlinkDestAbs
|
sane-path.realpath firstSymlinkDestAbs
|
||||||
else
|
else
|
||||||
null
|
null
|
||||||
;
|
;
|
||||||
|
@@ -43,25 +43,23 @@ let
|
|||||||
makeProfile = pkgs.callPackage ./make-sandbox-profile.nix { };
|
makeProfile = pkgs.callPackage ./make-sandbox-profile.nix { };
|
||||||
makeSandboxed = pkgs.callPackage ./make-sandboxed.nix { sane-sandboxed = config.sane.programs.sane-sandboxed.package; };
|
makeSandboxed = pkgs.callPackage ./make-sandboxed.nix { sane-sandboxed = config.sane.programs.sane-sandboxed.package; };
|
||||||
|
|
||||||
# TODO: much of this can be simplified now that the sandbox helper uses a symlink cache
|
# derefSymlinks: [ str ] -> [ str ]: for each path which is a symlink (or a child of a symlink'd dir), dereference one layer of symlink. else, return the path unchanged.
|
||||||
# removeStorePaths: [ str ] -> [ str ], but remove store paths, because nix evals aren't allowed to contain any (for purity reasons?)
|
derefSymlinks = paths: builtins.map (fs-lib.derefSymlink config.sane.fs) paths;
|
||||||
removeStorePaths = paths: lib.filter (p: !(lib.hasPrefix "/nix/store" p)) paths;
|
|
||||||
|
|
||||||
makeCanonical = paths: builtins.map path-lib.realpath paths;
|
|
||||||
# derefSymlinks: [ str ] -> [ str ]: for each path which is a symlink (or a child of a symlink'd dir), dereference one layer of symlink. else, drop it from the list.
|
|
||||||
derefSymlinks' = paths: builtins.map (fs-lib.derefSymlinkOrNull config.sane.fs) paths;
|
|
||||||
derefSymlinks = paths: lib.filter (p: p != null) (derefSymlinks' paths);
|
|
||||||
# expandSymlinksOnce: [ str ] -> [ str ], returning all the original paths plus dereferencing any symlinks and adding their targets to this list.
|
|
||||||
expandSymlinksOnce = paths: lib.unique (paths ++ removeStorePaths (makeCanonical (derefSymlinks paths)));
|
|
||||||
expandSymlinks = paths: lib.converge expandSymlinksOnce paths;
|
|
||||||
|
|
||||||
# given some paths, walk all of these and keep only the paths/ancestors which are symlinks
|
# given some paths, walk all of these and keep only the paths/ancestors which are symlinks
|
||||||
keepOnlySymlinks = paths: lib.filter
|
keepOnlySymlinks = paths: lib.filter
|
||||||
(p: ((config.sane.fs."${p}" or {}).symlink or null) != null)
|
(p: ((config.sane.fs."${builtins.unsafeDiscardStringContext p}" or {}).symlink or null) != null)
|
||||||
(lib.concatMap (p: path-lib.walk "/" p) paths)
|
(lib.concatMap (p: path-lib.walk "/" p) paths)
|
||||||
;
|
;
|
||||||
|
# expandSymlinksOnce: [ str ] -> [ str ]
|
||||||
|
# dereference all the paths once, union with the original path set, and then filter out everything that's not a symlink.
|
||||||
|
expandSymlinksOnce = paths: keepOnlySymlinks (lib.unique (paths ++ derefSymlinks paths));
|
||||||
|
symlinksClosure = paths: lib.converge expandSymlinksOnce paths;
|
||||||
|
|
||||||
# symlinkToAttrs: [ str ] -> Attrs such that `attrs."${symlink}" = symlinkTarget`.
|
# symlinkToAttrs: [ str ] -> Attrs such that `attrs."${symlink}" = symlinkTarget`.
|
||||||
symlinksToAttrs = paths: lib.genAttrs paths (p: config.sane.fs."${p}".symlink.target);
|
symlinksToAttrs = paths: lib.genAttrs
|
||||||
|
paths
|
||||||
|
(p: config.sane.fs."${p}".symlink.target)
|
||||||
|
;
|
||||||
|
|
||||||
vpn = lib.findSingle (v: v.default) null null (builtins.attrValues config.sane.vpn);
|
vpn = lib.findSingle (v: v.default) null null (builtins.attrValues config.sane.vpn);
|
||||||
|
|
||||||
@@ -141,7 +139,7 @@ let
|
|||||||
};
|
};
|
||||||
in "${package}";
|
in "${package}";
|
||||||
} // (
|
} // (
|
||||||
symlinksToAttrs (keepOnlySymlinks (expandSymlinks allowedPaths))
|
symlinksToAttrs (symlinksClosure allowedPaths)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
defaultProfile = sandboxProfilesFor config.sane.defaultUser;
|
defaultProfile = sandboxProfilesFor config.sane.defaultUser;
|
||||||
|
Reference in New Issue
Block a user