normcap: fix on GNOME wayland when used via keybind or alt-f2 (#351763)
[NixPkgs.git] / nixos / modules / services / backup / bacula.nix
bloba35350646c9be2d318743a0ee3d89fc9a7a028f6
2   config,
3   lib,
4   pkgs,
5   ...
6 }:
8 # TODO: test configuration when building nixexpr (use -t parameter)
9 # TODO: support sqlite3 (it's deprecate?) and mysql
11 let
12   inherit (lib)
13     concatStringsSep
14     literalExpression
15     mapAttrsToList
16     mkIf
17     mkOption
18     optional
19     optionalString
20     types
21     ;
22   libDir = "/var/lib/bacula";
24   yes_no = bool: if bool then "yes" else "no";
25   tls_conf =
26     tls_cfg:
27     optionalString tls_cfg.enable (
28       concatStringsSep "\n" (
29         [ "TLS Enable = yes;" ]
30         ++ optional (tls_cfg.require != null) "TLS Require = ${yes_no tls_cfg.require};"
31         ++ optional (tls_cfg.certificate != null) ''TLS Certificate = "${tls_cfg.certificate}";''
32         ++ [ ''TLS Key = "${tls_cfg.key}";'' ]
33         ++ optional (tls_cfg.verifyPeer != null) "TLS Verify Peer = ${yes_no tls_cfg.verifyPeer};"
34         ++ optional (
35           tls_cfg.allowedCN != [ ]
36         ) "TLS Allowed CN = ${concatStringsSep " " (tls_cfg.allowedCN)};"
37         ++ optional (
38           tls_cfg.caCertificateFile != null
39         ) ''TLS CA Certificate File = "${tls_cfg.caCertificateFile}";''
40       )
41     );
43   fd_cfg = config.services.bacula-fd;
44   fd_conf = pkgs.writeText "bacula-fd.conf" ''
45     Client {
46       Name = "${fd_cfg.name}";
47       FDPort = ${toString fd_cfg.port};
48       WorkingDirectory = ${libDir};
49       Pid Directory = /run;
50       ${fd_cfg.extraClientConfig}
51       ${tls_conf fd_cfg.tls}
52     }
54     ${concatStringsSep "\n" (
55       mapAttrsToList (name: value: ''
56         Director {
57           Name = "${name}";
58           Password = ${value.password};
59           Monitor = ${value.monitor};
60           ${tls_conf value.tls}
61         }
62       '') fd_cfg.director
63     )}
65     Messages {
66       Name = Standard;
67       syslog = all, !skipped, !restored
68       ${fd_cfg.extraMessagesConfig}
69     }
70   '';
72   sd_cfg = config.services.bacula-sd;
73   sd_conf = pkgs.writeText "bacula-sd.conf" ''
74     Storage {
75       Name = "${sd_cfg.name}";
76       SDPort = ${toString sd_cfg.port};
77       WorkingDirectory = ${libDir};
78       Pid Directory = /run;
79       ${sd_cfg.extraStorageConfig}
80       ${tls_conf sd_cfg.tls}
81     }
83     ${concatStringsSep "\n" (
84       mapAttrsToList (name: value: ''
85         Autochanger {
86           Name = "${name}";
87           Device = ${concatStringsSep ", " (map (a: "\"${a}\"") value.devices)};
88           Changer Device =  ${value.changerDevice};
89           Changer Command = ${value.changerCommand};
90           ${value.extraAutochangerConfig}
91         }
92       '') sd_cfg.autochanger
93     )}
95     ${concatStringsSep "\n" (
96       mapAttrsToList (name: value: ''
97         Device {
98           Name = "${name}";
99           Archive Device = ${value.archiveDevice};
100           Media Type = ${value.mediaType};
101           ${value.extraDeviceConfig}
102         }
103       '') sd_cfg.device
104     )}
106     ${concatStringsSep "\n" (
107       mapAttrsToList (name: value: ''
108         Director {
109           Name = "${name}";
110           Password = ${value.password};
111           Monitor = ${value.monitor};
112           ${tls_conf value.tls}
113         }
114       '') sd_cfg.director
115     )}
117     Messages {
118       Name = Standard;
119       syslog = all, !skipped, !restored
120       ${sd_cfg.extraMessagesConfig}
121     }
122   '';
124   dir_cfg = config.services.bacula-dir;
125   dir_conf = pkgs.writeText "bacula-dir.conf" ''
126     Director {
127       Name = "${dir_cfg.name}";
128       Password = ${dir_cfg.password};
129       DirPort = ${toString dir_cfg.port};
130       Working Directory = ${libDir};
131       Pid Directory = /run/;
132       QueryFile = ${pkgs.bacula}/etc/query.sql;
133       ${tls_conf dir_cfg.tls}
134       ${dir_cfg.extraDirectorConfig}
135     }
137     Catalog {
138       Name = PostgreSQL;
139       dbname = bacula;
140       user = bacula;
141     }
143     Messages {
144       Name = Standard;
145       syslog = all, !skipped, !restored
146       ${dir_cfg.extraMessagesConfig}
147     }
149     ${dir_cfg.extraConfig}
150   '';
152   linkOption =
153     name: destination: "[${name}](#opt-${builtins.replaceStrings [ "<" ">" ] [ "_" "_" ] destination})";
154   tlsLink =
155     destination: submodulePath:
156     linkOption "${submodulePath}.${destination}" "${submodulePath}.${destination}";
158   tlsOptions =
159     submodulePath:
160     { ... }:
161     {
162       options = {
163         enable = mkOption {
164           type = types.bool;
165           default = false;
166           description = ''
167             Specifies if TLS should be enabled.
168             If this set to `false` TLS will be completely disabled, even if ${tlsLink "tls.require" submodulePath} is true.
169           '';
170         };
171         require = mkOption {
172           type = types.nullOr types.bool;
173           default = null;
174           description = ''
175             Require TLS or TLS-PSK encryption.
176             This directive is ignored unless one of ${tlsLink "tls.enable" submodulePath} is true or TLS PSK Enable is set to `yes`.
177             If TLS is not required while TLS or TLS-PSK are enabled, then the Bacula component
178             will connect with other components either with or without TLS or TLS-PSK
180             If ${tlsLink "tls.enable" submodulePath} or TLS-PSK is enabled and TLS is required, then the Bacula
181             component will refuse any connection request that does not use TLS.
182           '';
183         };
184         certificate = mkOption {
185           type = types.nullOr types.path;
186           default = null;
187           description = ''
188             The full path to the PEM encoded TLS certificate.
189             It will be used as either a client or server certificate,
190             depending on the connection direction.
191             This directive is required in a server context, but it may
192             not be specified in a client context if ${tlsLink "tls.verifyPeer" submodulePath} is
193             `false` in the corresponding server context.
194           '';
195         };
196         key = mkOption {
197           type = types.path;
198           description = ''
199             The path of a PEM encoded TLS private key.
200             It must correspond to the TLS certificate.
201           '';
202         };
203         verifyPeer = mkOption {
204           type = types.nullOr types.bool;
205           default = null;
206           description = ''
207             Verify peer certificate.
208             Instructs server to request and verify the client's X.509 certificate.
209             Any client certificate signed by a known-CA will be accepted.
210             Additionally, the client's X509 certificate Common Name must meet the value of the Address directive.
211             If ${tlsLink "tls.allowedCN" submodulePath} is used,
212             the client's x509 certificate Common Name must also correspond to
213             one of the CN specified in the ${tlsLink "tls.allowedCN" submodulePath} directive.
214             This directive is valid only for a server and not in client context.
216             Standard from Bacula is `true`.
217           '';
218         };
219         allowedCN = mkOption {
220           type = types.listOf types.str;
221           default = [ ];
222           description = ''
223             Common name attribute of allowed peer certificates.
224             This directive is valid for a server and in a client context.
225             If this directive is specified, the peer certificate will be verified against this list.
226             In the case this directive is configured on a server side, the allowed
227             CN list will not be checked if ${tlsLink "tls.verifyPeer" submodulePath} is false.
228           '';
229         };
230         caCertificateFile = mkOption {
231           type = types.nullOr types.path;
232           default = null;
233           description = ''
234             The path specifying a PEM encoded TLS CA certificate(s).
235             Multiple certificates are permitted in the file.
236             One of TLS CA Certificate File or TLS CA Certificate Dir are required in a server context, unless
237             ${tlsLink "tls.verifyPeer" submodulePath} is false, and are always required in a client context.
238           '';
239         };
240       };
241     };
243   directorOptions =
244     submodulePath:
245     { ... }:
246     {
247       options = {
248         password = mkOption {
249           type = types.str;
250           # TODO: required?
251           description = ''
252             Specifies the password that must be supplied for the default Bacula
253             Console to be authorized. The same password must appear in the
254             Director resource of the Console configuration file. For added
255             security, the password is never passed across the network but instead
256             a challenge response hash code created with the password. This
257             directive is required. If you have either /dev/random or bc on your
258             machine, Bacula will generate a random password during the
259             configuration process, otherwise it will be left blank and you must
260             manually supply it.
262             The password is plain text. It is not generated through any special
263             process but as noted above, it is better to use random text for
264             security reasons.
265           '';
266         };
268         monitor = mkOption {
269           type = types.enum [
270             "no"
271             "yes"
272           ];
273           default = "no";
274           example = "yes";
275           description = ''
276             If Monitor is set to `no`, this director will have
277             full access to this Storage daemon. If Monitor is set to
278             `yes`, this director will only be able to fetch the
279             current status of this Storage daemon.
281             Please note that if this director is being used by a Monitor, we
282             highly recommend to set this directive to yes to avoid serious
283             security problems.
284           '';
285         };
287         tls = mkOption {
288           type = types.submodule (tlsOptions "${submodulePath}.director.<name>");
289           description = ''
290             TLS Options for the Director in this Configuration.
291           '';
292         };
293       };
294     };
296   autochangerOptions =
297     { ... }:
298     {
299       options = {
300         changerDevice = mkOption {
301           type = types.str;
302           description = ''
303             The specified name-string must be the generic SCSI device name of the
304             autochanger that corresponds to the normal read/write Archive Device
305             specified in the Device resource. This generic SCSI device name
306             should be specified if you have an autochanger or if you have a
307             standard tape drive and want to use the Alert Command (see below).
308             For example, on Linux systems, for an Archive Device name of
309             `/dev/nst0`, you would specify
310             `/dev/sg0` for the Changer Device name.  Depending
311             on your exact configuration, and the number of autochangers or the
312             type of autochanger, what you specify here can vary. This directive
313             is optional. See the Using AutochangersAutochangersChapter chapter of
314             this manual for more details of using this and the following
315             autochanger directives.
316           '';
317         };
319         changerCommand = mkOption {
320           type = types.str;
321           description = ''
322             The name-string specifies an external program to be called that will
323             automatically change volumes as required by Bacula. Normally, this
324             directive will be specified only in the AutoChanger resource, which
325             is then used for all devices. However, you may also specify the
326             different Changer Command in each Device resource. Most frequently,
327             you will specify the Bacula supplied mtx-changer script as follows:
329             `"/path/mtx-changer %c %o %S %a %d"`
331             and you will install the mtx on your system (found in the depkgs
332             release). An example of this command is in the default bacula-sd.conf
333             file. For more details on the substitution characters that may be
334             specified to configure your autochanger please see the
335             AutochangersAutochangersChapter chapter of this manual. For FreeBSD
336             users, you might want to see one of the several chio scripts in
337             examples/autochangers.
338           '';
339           default = "/etc/bacula/mtx-changer %c %o %S %a %d";
340         };
342         devices = mkOption {
343           description = "";
344           type = types.listOf types.str;
345         };
347         extraAutochangerConfig = mkOption {
348           default = "";
349           type = types.lines;
350           description = ''
351             Extra configuration to be passed in Autochanger directive.
352           '';
353           example = ''
355           '';
356         };
357       };
358     };
360   deviceOptions =
361     { ... }:
362     {
363       options = {
364         archiveDevice = mkOption {
365           # TODO: required?
366           type = types.str;
367           description = ''
368             The specified name-string gives the system file name of the storage
369             device managed by this storage daemon. This will usually be the
370             device file name of a removable storage device (tape drive), for
371             example `/dev/nst0` or
372             `/dev/rmt/0mbn`. For a DVD-writer, it will be for
373             example `/dev/hdc`. It may also be a directory name
374             if you are archiving to disk storage. In this case, you must supply
375             the full absolute path to the directory. When specifying a tape
376             device, it is preferable that the "non-rewind" variant of the device
377             file name be given.
378           '';
379         };
381         mediaType = mkOption {
382           # TODO: required?
383           type = types.str;
384           description = ''
385             The specified name-string names the type of media supported by this
386             device, for example, `DLT7000`. Media type names are
387             arbitrary in that you set them to anything you want, but they must be
388             known to the volume database to keep track of which storage daemons
389             can read which volumes. In general, each different storage type
390             should have a unique Media Type associated with it. The same
391             name-string must appear in the appropriate Storage resource
392             definition in the Director's configuration file.
394             Even though the names you assign are arbitrary (i.e. you choose the
395             name you want), you should take care in specifying them because the
396             Media Type is used to determine which storage device Bacula will
397             select during restore. Thus you should probably use the same Media
398             Type specification for all drives where the Media can be freely
399             interchanged. This is not generally an issue if you have a single
400             Storage daemon, but it is with multiple Storage daemons, especially
401             if they have incompatible media.
403             For example, if you specify a Media Type of `DDS-4`
404             then during the restore, Bacula will be able to choose any Storage
405             Daemon that handles `DDS-4`. If you have an
406             autochanger, you might want to name the Media Type in a way that is
407             unique to the autochanger, unless you wish to possibly use the
408             Volumes in other drives. You should also ensure to have unique Media
409             Type names if the Media is not compatible between drives. This
410             specification is required for all devices.
412             In addition, if you are using disk storage, each Device resource will
413             generally have a different mount point or directory. In order for
414             Bacula to select the correct Device resource, each one must have a
415             unique Media Type.
416           '';
417         };
419         extraDeviceConfig = mkOption {
420           default = "";
421           type = types.lines;
422           description = ''
423             Extra configuration to be passed in Device directive.
424           '';
425           example = ''
426             LabelMedia = yes
427             Random Access = no
428             AutomaticMount = no
429             RemovableMedia = no
430             MaximumOpenWait = 60
431             AlwaysOpen = no
432           '';
433         };
434       };
435     };
439   options = {
440     services.bacula-fd = {
441       enable = mkOption {
442         type = types.bool;
443         default = false;
444         description = ''
445           Whether to enable the Bacula File Daemon.
446         '';
447       };
449       name = mkOption {
450         default = "${config.networking.hostName}-fd";
451         defaultText = literalExpression ''"''${config.networking.hostName}-fd"'';
452         type = types.str;
453         description = ''
454           The client name that must be used by the Director when connecting.
455           Generally, it is a good idea to use a name related to the machine so
456           that error messages can be easily identified if you have multiple
457           Clients. This directive is required.
458         '';
459       };
461       port = mkOption {
462         default = 9102;
463         type = types.port;
464         description = ''
465           This specifies the port number on which the Client listens for
466           Director connections. It must agree with the FDPort specified in
467           the Client resource of the Director's configuration file.
468         '';
469       };
471       director = mkOption {
472         default = { };
473         description = ''
474           This option defines director resources in Bacula File Daemon.
475         '';
476         type = types.attrsOf (types.submodule (directorOptions "services.bacula-fd"));
477       };
479       tls = mkOption {
480         type = types.submodule (tlsOptions "services.bacula-fd");
481         default = { };
482         description = ''
483           TLS Options for the File Daemon.
484           Important notice: The backup won't be encrypted.
485         '';
486       };
488       extraClientConfig = mkOption {
489         default = "";
490         type = types.lines;
491         description = ''
492           Extra configuration to be passed in Client directive.
493         '';
494         example = ''
495           Maximum Concurrent Jobs = 20;
496           Heartbeat Interval = 30;
497         '';
498       };
500       extraMessagesConfig = mkOption {
501         default = "";
502         type = types.lines;
503         description = ''
504           Extra configuration to be passed in Messages directive.
505         '';
506         example = ''
507           console = all
508         '';
509       };
510     };
512     services.bacula-sd = {
513       enable = mkOption {
514         type = types.bool;
515         default = false;
516         description = ''
517           Whether to enable Bacula Storage Daemon.
518         '';
519       };
521       name = mkOption {
522         default = "${config.networking.hostName}-sd";
523         defaultText = literalExpression ''"''${config.networking.hostName}-sd"'';
524         type = types.str;
525         description = ''
526           Specifies the Name of the Storage daemon.
527         '';
528       };
530       port = mkOption {
531         default = 9103;
532         type = types.port;
533         description = ''
534           Specifies port number on which the Storage daemon listens for
535           Director connections.
536         '';
537       };
539       director = mkOption {
540         default = { };
541         description = ''
542           This option defines Director resources in Bacula Storage Daemon.
543         '';
544         type = types.attrsOf (types.submodule (directorOptions "services.bacula-sd"));
545       };
547       device = mkOption {
548         default = { };
549         description = ''
550           This option defines Device resources in Bacula Storage Daemon.
551         '';
552         type = types.attrsOf (types.submodule deviceOptions);
553       };
555       autochanger = mkOption {
556         default = { };
557         description = ''
558           This option defines Autochanger resources in Bacula Storage Daemon.
559         '';
560         type = types.attrsOf (types.submodule autochangerOptions);
561       };
563       extraStorageConfig = mkOption {
564         default = "";
565         type = types.lines;
566         description = ''
567           Extra configuration to be passed in Storage directive.
568         '';
569         example = ''
570           Maximum Concurrent Jobs = 20;
571           Heartbeat Interval = 30;
572         '';
573       };
575       extraMessagesConfig = mkOption {
576         default = "";
577         type = types.lines;
578         description = ''
579           Extra configuration to be passed in Messages directive.
580         '';
581         example = ''
582           console = all
583         '';
584       };
585       tls = mkOption {
586         type = types.submodule (tlsOptions "services.bacula-sd");
587         default = { };
588         description = ''
589           TLS Options for the Storage Daemon.
590           Important notice: The backup won't be encrypted.
591         '';
592       };
594     };
596     services.bacula-dir = {
597       enable = mkOption {
598         type = types.bool;
599         default = false;
600         description = ''
601           Whether to enable Bacula Director Daemon.
602         '';
603       };
605       name = mkOption {
606         default = "${config.networking.hostName}-dir";
607         defaultText = literalExpression ''"''${config.networking.hostName}-dir"'';
608         type = types.str;
609         description = ''
610           The director name used by the system administrator. This directive is
611           required.
612         '';
613       };
615       port = mkOption {
616         default = 9101;
617         type = types.port;
618         description = ''
619           Specify the port (a positive integer) on which the Director daemon
620           will listen for Bacula Console connections. This same port number
621           must be specified in the Director resource of the Console
622           configuration file. The default is 9101, so normally this directive
623           need not be specified. This directive should not be used if you
624           specify DirAddresses (N.B plural) directive.
625         '';
626       };
628       password = mkOption {
629         # TODO: required?
630         type = types.str;
631         description = ''
632           Specifies the password that must be supplied for a Director.
633         '';
634       };
636       extraMessagesConfig = mkOption {
637         default = "";
638         type = types.lines;
639         description = ''
640           Extra configuration to be passed in Messages directive.
641         '';
642         example = ''
643           console = all
644         '';
645       };
647       extraDirectorConfig = mkOption {
648         default = "";
649         type = types.lines;
650         description = ''
651           Extra configuration to be passed in Director directive.
652         '';
653         example = ''
654           Maximum Concurrent Jobs = 20;
655           Heartbeat Interval = 30;
656         '';
657       };
659       extraConfig = mkOption {
660         default = "";
661         type = types.lines;
662         description = ''
663           Extra configuration for Bacula Director Daemon.
664         '';
665         example = ''
666           TODO
667         '';
668       };
670       tls = mkOption {
671         type = types.submodule (tlsOptions "services.bacula-dir");
672         default = { };
673         description = ''
674           TLS Options for the Director.
675           Important notice: The backup won't be encrypted.
676         '';
677       };
678     };
679   };
681   config = mkIf (fd_cfg.enable || sd_cfg.enable || dir_cfg.enable) {
682     systemd.slices.system-bacula = {
683       description = "Bacula Backup System Slice";
684       documentation = [
685         "man:bacula(8)"
686         "https://www.bacula.org/"
687       ];
688     };
690     systemd.services.bacula-fd = mkIf fd_cfg.enable {
691       after = [ "network.target" ];
692       description = "Bacula File Daemon";
693       wantedBy = [ "multi-user.target" ];
694       path = [ pkgs.bacula ];
695       serviceConfig = {
696         ExecStart = "${pkgs.bacula}/sbin/bacula-fd -f -u root -g bacula -c ${fd_conf}";
697         ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
698         LogsDirectory = "bacula";
699         StateDirectory = "bacula";
700         Slice = "system-bacula.slice";
701       };
702     };
704     systemd.services.bacula-sd = mkIf sd_cfg.enable {
705       after = [ "network.target" ];
706       description = "Bacula Storage Daemon";
707       wantedBy = [ "multi-user.target" ];
708       path = [ pkgs.bacula ];
709       serviceConfig = {
710         ExecStart = "${pkgs.bacula}/sbin/bacula-sd -f -u bacula -g bacula -c ${sd_conf}";
711         ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
712         LogsDirectory = "bacula";
713         StateDirectory = "bacula";
714         Slice = "system-bacula.slice";
715       };
716     };
718     services.postgresql.enable = lib.mkIf dir_cfg.enable true;
720     systemd.services.bacula-dir = mkIf dir_cfg.enable {
721       after = [
722         "network.target"
723         "postgresql.service"
724       ];
725       description = "Bacula Director Daemon";
726       wantedBy = [ "multi-user.target" ];
727       path = [ pkgs.bacula ];
728       serviceConfig = {
729         ExecStart = "${pkgs.bacula}/sbin/bacula-dir -f -u bacula -g bacula -c ${dir_conf}";
730         ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
731         LogsDirectory = "bacula";
732         StateDirectory = "bacula";
733         Slice = "system-bacula.slice";
734       };
735       preStart = ''
736         if ! test -e "${libDir}/db-created"; then
737             ${pkgs.postgresql}/bin/createuser --no-superuser --no-createdb --no-createrole bacula
738             #${pkgs.postgresql}/bin/createdb --owner bacula bacula
740             # populate DB
741             ${pkgs.bacula}/etc/create_bacula_database postgresql
742             ${pkgs.bacula}/etc/make_bacula_tables postgresql
743             ${pkgs.bacula}/etc/grant_bacula_privileges postgresql
744             touch "${libDir}/db-created"
745         else
746             ${pkgs.bacula}/etc/update_bacula_tables postgresql || true
747         fi
748       '';
749     };
751     environment.systemPackages = [ pkgs.bacula ];
753     users.users.bacula = {
754       group = "bacula";
755       uid = config.ids.uids.bacula;
756       home = "${libDir}";
757       createHome = true;
758       description = "Bacula Daemons user";
759       shell = "${pkgs.bash}/bin/bash";
760     };
762     users.groups.bacula.gid = config.ids.gids.bacula;
763   };