lib: lift acl type into sane-lib/types

This commit is contained in:
colin 2023-01-04 00:59:52 +00:00
parent 933063115b
commit 2960b895b6
5 changed files with 80 additions and 57 deletions

View File

@ -2,6 +2,7 @@
with lib;
let
path-lib = sane-lib.path;
sane-types = sane-lib.types;
cfg = config.sane.fs;
mountNameFor = path: "${utils.escapeSystemdPath path}.mount";
@ -47,26 +48,11 @@ let
};
});
# TODO: lift this to sane-lib
acl = types.submodule {
options = {
user = mkOption {
type = types.str; # TODO: use uid?
};
group = mkOption {
type = types.str;
};
mode = mkOption {
type = types.str;
};
};
};
# sane.fs."<path>".dir sub-options
dirEntry = types.submodule {
options = {
acl = mkOption {
type = acl;
type = sane-types.acl;
};
depends = mkOption {
type = types.listOf types.str;

View File

@ -7,6 +7,7 @@
with lib;
let
path = sane-lib.path;
sane-types = sane-lib.types;
cfg = config.sane.impermanence;
storeType = types.submodule {
@ -41,18 +42,7 @@ let
directory = mkOption {
type = types.str;
};
user = mkOption {
type = types.nullOr types.str;
default = null;
};
group = mkOption {
type = types.nullOr types.str;
default = null;
};
mode = mkOption {
type = types.nullOr types.str;
default = null;
};
inherit (sane-types.aclOverrideMod.options) user group mode;
};
};
contextualizedDir = types.submodule dirEntryOptions;

View File

@ -1,31 +1,6 @@
{ lib, utils, ... }:
{ ... }@moduleArgs:
rec {
path = {
# split the string path into a list of string components.
# root directory "/" becomes the empty list [].
# implicitly performs normalization so that:
# split "a//b/" => ["a" "b"]
# split "/a/b" => ["a" "b"]
split = str: builtins.filter (seg: seg != "") (lib.splitString "/" str);
# given an array of components, returns the equivalent string path
join = comps: "/" + (builtins.concatStringsSep "/" comps);
# given an a sequence of string paths, concatenates them into one long string path
concat = paths: path.join (builtins.concatLists (builtins.map path.split paths));
# normalize the given path
norm = str: path.join (path.split str);
# return the parent directory. doesn't care about leading/trailing slashes.
# the parent of "/" is "/".
parent = str: path.norm (builtins.dirOf (path.norm str));
hasParent = str: (path.parent str) != (path.norm str);
# return the path from `from` to `to`, but keeping absolute form
# e.g. `pathFrom "/home/colin" "/home/colin/foo/bar"` -> "/foo/bar"
from = start: end: let
s = path.norm start;
e = path.norm end;
in (
assert lib.hasPrefix s e;
"/" + (lib.removePrefix s e)
);
};
{
path = import ./path.nix moduleArgs;
types = import ./types.nix moduleArgs;
}

30
modules/lib/path.nix Normal file
View File

@ -0,0 +1,30 @@
{ lib, utils, ... }:
let path = rec {
# split the string path into a list of string components.
# root directory "/" becomes the empty list [].
# implicitly performs normalization so that:
# split "a//b/" => ["a" "b"]
# split "/a/b" => ["a" "b"]
split = str: builtins.filter (seg: seg != "") (lib.splitString "/" str);
# given an array of components, returns the equivalent string path
join = comps: "/" + (builtins.concatStringsSep "/" comps);
# given an a sequence of string paths, concatenates them into one long string path
concat = paths: path.join (builtins.concatLists (builtins.map path.split paths));
# normalize the given path
norm = str: path.join (path.split str);
# return the parent directory. doesn't care about leading/trailing slashes.
# the parent of "/" is "/".
parent = str: path.norm (builtins.dirOf (path.norm str));
hasParent = str: (path.parent str) != (path.norm str);
# return the path from `from` to `to`, but keeping absolute form
# e.g. `pathFrom "/home/colin" "/home/colin/foo/bar"` -> "/foo/bar"
from = start: end: let
s = path.norm start;
e = path.norm end;
in (
assert lib.hasPrefix s e;
"/" + (lib.removePrefix s e)
);
};
in path

42
modules/lib/types.nix Normal file
View File

@ -0,0 +1,42 @@
{ lib, ... }:
with lib;
rec {
# "Access Control List", only it's just a user:group and file mode
# compatible with `chown` and `chmod`
aclMod = {
options = {
user = mkOption {
type = types.str; # TODO: use uid?
};
group = mkOption {
type = types.str;
};
mode = mkOption {
type = types.str;
};
};
};
acl = types.submodule aclMod;
# this is acl, but doesn't require to be fully specified.
# a typical use case is when there's a complete acl, and the user
# wants to override just one attribute of it.
aclOverrideMod = {
options = {
user = mkOption {
type = types.nullOr types.str;
default = null;
};
group = mkOption {
type = types.nullOr types.str;
default = null;
};
mode = mkOption {
type = types.nullOr types.str;
default = null;
};
};
};
aclOverride = types.submodule aclOverrideMod;
}