nix-files/modules/ids.nix

90 lines
2.0 KiB
Nix

{ lib, config, ... }:
with lib;
let
cfg = config.sane.ids;
id = types.submodule {
options = {
uid = mkOption {
type = types.nullOr types.int;
default = null;
};
gid = mkOption {
type = types.nullOr types.int;
default = null;
};
};
};
userOpts = { name, ... }: {
config =
let
ent-ids = cfg."${name}" or {};
uid = ent-ids.uid or null;
in
{
uid = lib.mkIf (uid != null) uid;
};
};
groupOpts = { name, ... }: {
config =
let
ent-ids = cfg."${name}" or {};
gid = ent-ids.gid or null;
in
{
gid = lib.mkIf (gid != null) gid;
};
};
in
{
options = {
sane.ids = mkOption {
type = types.attrsOf id;
default = {};
description = ''
mapping from user/group name to gids/uids you expect that entity to have.
for users/groups created elsewhere *without* an id, this is used to provide them a fixed/stable id.
'';
};
# these get merged with the nixpkgs options.
users.users = mkOption {
type = types.attrsOf (types.submodule userOpts);
};
users.groups = mkOption {
type = types.attrsOf (types.submodule groupOpts);
};
};
config = {
# guarantee determinism in uid/gid generation for users:
assertions = lib.mkMerge [
(
lib.mapAttrsToList
(name: user: {
assertion = user.uid != null;
message = "non-deterministic uid detected for: ${name}";
})
config.users.users
)
(
lib.mapAttrsToList
(name: group: {
assertion = group.gid != null;
message = "non-deterministic gid detected for: ${name}";
})
config.users.groups
)
(
lib.mapAttrsToList
(name: user: {
assertion = !user.autoSubUidGidRange;
message = "non-deterministic subUids/Guids detected for: ${name}";
})
config.users.users
)
];
};
}