ooknet/modules/nixos/server/services/ookflix/lib.nix
2024-12-02 12:30:30 +11:00

128 lines
3.6 KiB
Nix

{
lib,
config,
self,
...
}: let
inherit (lib) mkOption mkEnableOption elem assertMsg;
inherit (builtins) attrValues;
inherit (lib.types) int path port str;
inherit (config.ooknet) server;
cfg = server.ookflix;
mkSubdomainOption = name: description: example:
mkOption {
type = str;
default = "${name}.${server.domain}";
inherit description example;
};
# check config.ids for static uid/gid based on service name, if available use that, if not, use fallback.
# check fallback doesnt conflict with existing static id
getId = idType: name: fallback: let
allNixosIds = attrValues config.ids.${idType};
fallbackConflict = elem fallback allNixosIds;
in
mkOption {
type = int;
default =
config.ids.${idType}.${name}
or (
assert assertMsg (!fallbackConflict)
"Fallback ${idType} ${toString fallback} for ${name} conflicts with NixOS static allocation"; fallback
);
description = "${idType} of ${name} container";
example = 224;
};
mkUserOption = name: fallback: {
name = mkOption {
type = str;
default = name;
description = "Name of ${name} container user";
example = "${name}";
};
id = getId "uids" name fallback;
};
mkGroupOption = name: fallback: {
name = mkOption {
type = str;
default = name;
};
id = getId "gids" name fallback;
};
mkPortOption = value: description: example:
mkOption {
type = port;
default = value;
inherit description example;
};
mkVolumeOption = type: pathValue:
mkOption {
type = path;
default =
if type == "state"
then "${cfg.volumes.state.root}/${pathValue}"
else if type == "media"
then "${cfg.volumes.media.root}/${pathValue}"
else if type == "downloads"
then "${cfg.volumes.downloads.root}/${pathValue}"
else if type == "root"
then pathValue
else throw "Invalid VolumeOption type: ${type}. Must be one of 'state' 'media' 'downloads' 'root'";
};
mkServiceOptions = name: {
port,
gid,
uid,
...
} @ args: {
enable = mkEnableOption "Enable ${name} container";
port = mkPortOption args.port "Port for ${name} container." 80;
domain = mkSubdomainOption name "Domain for ${name} container." "${name}.mydomain.com";
stateDir = mkVolumeOption "state" name;
user = mkUserOption name args.uid;
group = mkGroupOption name args.gid;
};
mkBasicServiceOptions = name: {
gid,
uid,
...
} @ args: {
enable = mkEnableOption "Enable ${name} container";
user = mkUserOption name args.uid;
group = mkGroupOption name args.gid;
};
mkServiceUser = service: {
users.${service} = {
isSystemUser = true;
uid = cfg.services.${service}.user.id;
name = service;
group = service;
};
groups.${service} = {
gid = cfg.services.${service}.group.id;
name = service;
};
};
mkServiceStateDir = service: dir: {
settings."${service}StateDir".${dir}."d" = {
mode = "0700";
user = cfg.services.${service}.user.name;
group = cfg.services.${service}.group.name;
};
};
mkServiceSecret = name: service: {
${name} = {
file = "${self}/secrets/container/${name}.age";
owner = cfg.services.${service}.user.name;
group = cfg.services.${service}.group.name;
};
};
in {
inherit mkServiceSecret mkBasicServiceOptions mkServiceOptions mkServiceStateDir mkServiceUser mkUserOption mkPortOption mkGroupOption mkVolumeOption mkSubdomainOption;
}