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) nullOr strMatching;
9
10 options.services.tsmBackup = {
11 enable = mkEnableOption ''
12 automatic backups with the
13 IBM Spectrum Protect (Tivoli Storage Manager, TSM) client.
14 This also enables
15 <option>programs.tsmClient.enable</option>
16 '';
17 command = mkOption {
18 type = strMatching ".+";
19 default = "backup";
20 example = "incr";
21 description = ''
22 The actual command passed to the
23 <literal>dsmc</literal> executable to start the backup.
24 '';
25 };
26 servername = mkOption {
27 type = strMatching ".+";
28 example = "mainTsmServer";
29 description = ''
30 Create a systemd system service
31 <literal>tsm-backup.service</literal> that starts
32 a backup based on the given servername's stanza.
33 Note that this server's
34 <option>passwdDir</option> will default to
35 <filename>/var/lib/tsm-backup/password</filename>
36 (but may be overridden);
37 also, the service will use
38 <filename>/var/lib/tsm-backup</filename> as
39 <literal>HOME</literal> when calling
40 <literal>dsmc</literal>.
41 '';
42 };
43 autoTime = mkOption {
44 type = nullOr (strMatching ".+");
45 default = null;
46 example = "12:00";
47 description = ''
48 The backup service will be invoked
49 automatically at the given date/time,
50 which must be in the format described in
51 <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
52 The default <literal>null</literal>
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 # for exit status description see
91 # https://www.ibm.com/support/knowledgecenter/en/SSEQVQ_8.1.8/client/c_sched_rtncode.html
92 serviceConfig.SuccessExitStatus = "4 8";
93 # The `-se` option must come after the command.
94 # The `-optfile` option suppresses a `dsm.opt`-not-found warning.
95 serviceConfig.ExecStart =
96 "${cfgPrg.wrappedPackage}/bin/dsmc ${cfg.command} -se='${cfg.servername}' -optfile=/dev/null";
97 serviceConfig.LogsDirectory = "tsm-backup";
98 serviceConfig.StateDirectory = "tsm-backup";
99 serviceConfig.StateDirectoryMode = "0750";
100 startAt = mkIf (cfg.autoTime!=null) cfg.autoTime;
101 };
102 };
103
104 meta.maintainers = [ lib.maintainers.yarny ];
105
106}