From 7caca1b18505d7ba78d7f32fea8ac4ee15e37821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6gler?= Date: Tue, 2 Jan 2024 23:17:46 +0100 Subject: [PATCH] nixos/vdr: add option user/group and more admin control - Add option to set user and group name - Set users home to runtime directory, to avoid mixing of temporal files like caches - Allow admin to control LIRC service by avoiding LIRC enabling - Allow admin to set libDir, by removing setting argument config to default - Add package to environment, to allow easy access for admins to helper tools like svdrpsend and vdr -h - Cleanup Nix code by avoiding with statement --- nixos/modules/services/hardware/vdr.nix | 96 +++++++++++++++---------- 1 file changed, 59 insertions(+), 37 deletions(-) diff --git a/nixos/modules/services/hardware/vdr.nix b/nixos/modules/services/hardware/vdr.nix index 5feb379b50d1..689d83f7eedc 100644 --- a/nixos/modules/services/hardware/vdr.nix +++ b/nixos/modules/services/hardware/vdr.nix @@ -1,18 +1,15 @@ { config, lib, pkgs, ... }: - -with lib; - let cfg = config.services.vdr; - libDir = "/var/lib/vdr"; -in { - - ###### interface + inherit (lib) + mkEnableOption mkPackageOption mkOption types mkIf optional mdDoc; +in +{ options = { services.vdr = { - enable = mkEnableOption (lib.mdDoc "VDR. Please put config into ${libDir}"); + enable = mkEnableOption (mdDoc "Start VDR"); package = mkPackageOption pkgs "vdr" { example = "wrapVdr.override { plugins = with pkgs.vdrPlugins; [ hello ]; }"; @@ -21,59 +18,84 @@ in { videoDir = mkOption { type = types.path; default = "/srv/vdr/video"; - description = lib.mdDoc "Recording directory"; + description = mdDoc "Recording directory"; }; extraArguments = mkOption { type = types.listOf types.str; - default = []; - description = lib.mdDoc "Additional command line arguments to pass to VDR."; + default = [ ]; + description = mdDoc "Additional command line arguments to pass to VDR."; }; - enableLirc = mkEnableOption (lib.mdDoc "LIRC"); + enableLirc = mkEnableOption (mdDoc "LIRC"); + + user = mkOption { + type = types.str; + default = "vdr"; + description = mdDoc '' + User under which the VDR service runs. + ''; + }; + + group = mkOption { + type = types.str; + default = "vdr"; + description = mdDoc '' + Group under which the VDRvdr service runs. + ''; + }; }; + }; - ###### implementation + config = mkIf cfg.enable { - config = mkIf cfg.enable (mkMerge [{ systemd.tmpfiles.rules = [ - "d ${cfg.videoDir} 0755 vdr vdr -" - "Z ${cfg.videoDir} - vdr vdr -" + "d ${cfg.videoDir} 0755 ${cfg.user} ${cfg.group} -" + "Z ${cfg.videoDir} - ${cfg.user} ${cfg.group} -" ]; systemd.services.vdr = { description = "VDR"; wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; + wants = optional cfg.enableLirc "lircd.service"; + after = [ "network.target" ] + ++ optional cfg.enableLirc "lircd.service"; serviceConfig = { - ExecStart = '' - ${cfg.package}/bin/vdr \ - --video="${cfg.videoDir}" \ - --config="${libDir}" \ - ${escapeShellArgs cfg.extraArguments} - ''; - User = "vdr"; + ExecStart = + let + args = [ + "--video=${cfg.videoDir}" + ] + ++ optional cfg.enableLirc "--lirc=${config.passthru.lirc.socket}" + ++ cfg.extraArguments; + in + "${cfg.package}/bin/vdr ${lib.escapeShellArgs args}"; + User = cfg.user; + Group = cfg.group; CacheDirectory = "vdr"; StateDirectory = "vdr"; + RuntimeDirectory = "vdr"; Restart = "on-failure"; }; }; - users.users.vdr = { - group = "vdr"; - home = libDir; - isSystemUser = true; + environment.systemPackages = [ cfg.package ]; + + users.users = mkIf (cfg.user == "vdr") { + vdr = { + inherit (cfg) group; + home = "/run/vdr"; + isSystemUser = true; + extraGroups = [ + "video" + "audio" + ] + ++ optional cfg.enableLirc "lirc"; + }; }; - users.groups.vdr = {}; - } + users.groups = mkIf (cfg.group == "vdr") { vdr = { }; }; - (mkIf cfg.enableLirc { - services.lirc.enable = true; - users.users.vdr.extraGroups = [ "lirc" ]; - services.vdr.extraArguments = [ - "--lirc=${config.passthru.lirc.socket}" - ]; - })]); + }; }