at 23.11-pre 4.0 kB view raw
1{ config, lib, ... }: 2 3let 4 5 inherit (lib.attrsets) hasAttr; 6 inherit (lib.modules) mkDefault mkIf; 7 inherit (lib.options) mkEnableOption mkOption; 8 inherit (lib.types) nonEmptyStr nullOr; 9 10 options.services.tsmBackup = { 11 enable = mkEnableOption (lib.mdDoc '' 12 automatic backups with the 13 IBM Spectrum Protect (Tivoli Storage Manager, TSM) client. 14 This also enables 15 {option}`programs.tsmClient.enable` 16 ''); 17 command = mkOption { 18 type = nonEmptyStr; 19 default = "backup"; 20 example = "incr"; 21 description = lib.mdDoc '' 22 The actual command passed to the 23 `dsmc` executable to start the backup. 24 ''; 25 }; 26 servername = mkOption { 27 type = nonEmptyStr; 28 example = "mainTsmServer"; 29 description = lib.mdDoc '' 30 Create a systemd system service 31 `tsm-backup.service` that starts 32 a backup based on the given servername's stanza. 33 Note that this server's 34 {option}`passwdDir` will default to 35 {file}`/var/lib/tsm-backup/password` 36 (but may be overridden); 37 also, the service will use 38 {file}`/var/lib/tsm-backup` as 39 `HOME` when calling 40 `dsmc`. 41 ''; 42 }; 43 autoTime = mkOption { 44 type = nullOr nonEmptyStr; 45 default = null; 46 example = "12:00"; 47 description = lib.mdDoc '' 48 The backup service will be invoked 49 automatically at the given date/time, 50 which must be in the format described in 51 {manpage}`systemd.time(5)`. 52 The default `null` 53 disables automatic backups. 54 ''; 55 }; 56 }; 57 58 cfg = config.services.tsmBackup; 59 cfgPrg = config.programs.tsmClient; 60 61 assertions = [ 62 { 63 assertion = hasAttr cfg.servername cfgPrg.servers; 64 message = "TSM service servername not found in list of servers"; 65 } 66 { 67 assertion = cfgPrg.servers.${cfg.servername}.genPasswd; 68 message = "TSM service requires automatic password generation"; 69 } 70 ]; 71 72in 73 74{ 75 76 inherit options; 77 78 config = mkIf cfg.enable { 79 inherit assertions; 80 programs.tsmClient.enable = true; 81 programs.tsmClient.servers.${cfg.servername}.passwdDir = 82 mkDefault "/var/lib/tsm-backup/password"; 83 systemd.services.tsm-backup = { 84 description = "IBM Spectrum Protect (Tivoli Storage Manager) Backup"; 85 # DSM_LOG needs a trailing slash to have it treated as a directory. 86 # `/var/log` would be littered with TSM log files otherwise. 87 environment.DSM_LOG = "/var/log/tsm-backup/"; 88 # TSM needs a HOME dir to store certificates. 89 environment.HOME = "/var/lib/tsm-backup"; 90 serviceConfig = { 91 # for exit status description see 92 # https://www.ibm.com/docs/en/spectrum-protect/8.1.13?topic=clients-client-return-codes 93 SuccessExitStatus = "4 8"; 94 # The `-se` option must come after the command. 95 # The `-optfile` option suppresses a `dsm.opt`-not-found warning. 96 ExecStart = 97 "${cfgPrg.wrappedPackage}/bin/dsmc ${cfg.command} -se='${cfg.servername}' -optfile=/dev/null"; 98 LogsDirectory = "tsm-backup"; 99 StateDirectory = "tsm-backup"; 100 StateDirectoryMode = "0750"; 101 # systemd sandboxing 102 LockPersonality = true; 103 NoNewPrivileges = true; 104 PrivateDevices = true; 105 #PrivateTmp = true; # would break backup of {/var,}/tmp 106 #PrivateUsers = true; # would block backup of /home/* 107 ProtectClock = true; 108 ProtectControlGroups = true; 109 ProtectHome = "read-only"; 110 ProtectHostname = true; 111 ProtectKernelLogs = true; 112 ProtectKernelModules = true; 113 ProtectKernelTunables = true; 114 ProtectProc = "noaccess"; 115 ProtectSystem = "strict"; 116 RestrictNamespaces = true; 117 RestrictSUIDSGID = true; 118 }; 119 startAt = mkIf (cfg.autoTime!=null) cfg.autoTime; 120 }; 121 }; 122 123 meta.maintainers = [ lib.maintainers.yarny ]; 124 125}