mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-10 04:49:19 -08:00
170 lines
4.4 KiB
Nix
170 lines
4.4 KiB
Nix
let
|
|
cameraModule = {
|
|
pkgs,
|
|
config,
|
|
gensokyo-zone,
|
|
name,
|
|
lib,
|
|
lib'motion,
|
|
...
|
|
}: let
|
|
inherit (lib.options) mkOption mkEnableOption;
|
|
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
|
|
inherit (lib.strings) hasPrefix;
|
|
in {
|
|
options = with lib.types; {
|
|
enable =
|
|
mkEnableOption "camera"
|
|
// {
|
|
default = true;
|
|
};
|
|
settings = mkOption {
|
|
type = attrsOf (oneOf [str int bool]);
|
|
description = "https://motion-project.github.io/motion_config.html";
|
|
};
|
|
extraConfig = mkOption {
|
|
type = lines;
|
|
default = "";
|
|
};
|
|
configText = mkOption {
|
|
type = lines;
|
|
internal = true;
|
|
};
|
|
configFile = mkOption {
|
|
type = path;
|
|
};
|
|
};
|
|
config = let
|
|
configFile = pkgs.writeText "motion.conf" config.configText;
|
|
in {
|
|
settings = {
|
|
videodevice = mkIf (hasPrefix "/" name) (mkOptionDefault name);
|
|
};
|
|
configFile = mkOptionDefault "${configFile}";
|
|
configText = mkMerge (
|
|
(lib'motion.mkMotionSettings config.settings)
|
|
++ [config.extraConfig]
|
|
);
|
|
};
|
|
};
|
|
in
|
|
{
|
|
pkgs,
|
|
config,
|
|
gensokyo-zone,
|
|
utils,
|
|
lib,
|
|
...
|
|
}: let
|
|
inherit (lib.options) mkOption mkPackageOption mkEnableOption;
|
|
inherit (lib.modules) mkIf mkMerge mkAfter mkOptionDefault;
|
|
inherit (lib.attrsets) attrValues mapAttrsToList;
|
|
inherit (lib.lists) filter;
|
|
inherit (lib.meta) getExe;
|
|
cfg = config.services.motion;
|
|
lib'motion = config.lib.motion;
|
|
in {
|
|
options.services.motion = with lib.types; {
|
|
enable = mkEnableOption "motion";
|
|
package = mkPackageOption pkgs "motion" {};
|
|
cameras = mkOption {
|
|
type = attrsOf (submoduleWith {
|
|
modules = [cameraModule];
|
|
specialArgs = {
|
|
inherit pkgs gensokyo-zone lib'motion;
|
|
nixosConfig = config;
|
|
};
|
|
});
|
|
};
|
|
dataDir = mkOption {
|
|
type = path;
|
|
default = "/var/lib/motion";
|
|
};
|
|
user = mkOption {
|
|
type = str;
|
|
default = "motion";
|
|
};
|
|
group = mkOption {
|
|
type = str;
|
|
default = "motion";
|
|
};
|
|
settings = mkOption {
|
|
type = attrsOf (oneOf [str int bool]);
|
|
description = "https://motion-project.github.io/motion_config.html";
|
|
};
|
|
extraArgs = mkOption {
|
|
type = listOf str;
|
|
default = [];
|
|
};
|
|
extraConfig = mkOption {
|
|
type = lines;
|
|
default = "";
|
|
};
|
|
configText = mkOption {
|
|
type = lines;
|
|
internal = true;
|
|
};
|
|
configFile = mkOption {
|
|
type = path;
|
|
};
|
|
};
|
|
config.services.motion = let
|
|
configFile = pkgs.writeText "motion.conf" cfg.configText;
|
|
enabledCameras = filter (camera: camera.enable) (attrValues cfg.cameras);
|
|
in {
|
|
settings = {
|
|
target_dir = mkOptionDefault cfg.dataDir;
|
|
webcontrol_ipv6 = mkIf config.networking.enableIPv6 (mkOptionDefault true);
|
|
};
|
|
configFile = mkOptionDefault "${configFile}";
|
|
configText = mkMerge (
|
|
(lib'motion.mkMotionSettings cfg.settings)
|
|
++ [cfg.extraConfig]
|
|
++ map (camera: mkAfter "camera ${camera.configFile}") enabledCameras
|
|
);
|
|
};
|
|
config.users = mkIf cfg.enable {
|
|
users.motion = {
|
|
uid = 916;
|
|
group = "motion";
|
|
home = cfg.dataDir;
|
|
extraGroups = ["video"];
|
|
};
|
|
groups.motion = {
|
|
gid = config.users.users.motion.uid;
|
|
};
|
|
};
|
|
config.systemd.services.motion = let
|
|
cliArgs =
|
|
[
|
|
(getExe cfg.package)
|
|
"-n"
|
|
"-c"
|
|
cfg.configFile
|
|
]
|
|
++ cfg.extraArgs;
|
|
in
|
|
mkIf cfg.enable {
|
|
wantedBy = ["multi-user.target"];
|
|
after = ["network.target"];
|
|
serviceConfig = {
|
|
Type = mkOptionDefault "exec";
|
|
Restart = mkOptionDefault "on-failure";
|
|
User = mkOptionDefault cfg.user;
|
|
Group = mkOptionDefault cfg.group;
|
|
ExecStart = [
|
|
(utils.escapeSystemdExecArgs cliArgs)
|
|
];
|
|
};
|
|
};
|
|
config.lib.motion = {
|
|
mkMotionValue = value:
|
|
if value == true
|
|
then "on"
|
|
else if value == false
|
|
then "off"
|
|
else toString value;
|
|
mkMotionSetting = key: value: "${key} ${lib'motion.mkMotionValue value}";
|
|
mkMotionSettings = mapAttrsToList lib'motion.mkMotionSetting;
|
|
};
|
|
}
|