at v192 12 kB view raw
1{ config, lib, pkgs, ... }: 2 3# TODO: test configuration when building nixexpr (use -t parameter) 4# TODO: support sqlite3 (it's deprecate?) and mysql 5 6with lib; 7 8let 9 libDir = "/var/lib/bacula"; 10 11 fd_cfg = config.services.bacula-fd; 12 fd_conf = pkgs.writeText "bacula-fd.conf" 13 '' 14 Client { 15 Name = "${fd_cfg.name}"; 16 FDPort = ${toString fd_cfg.port}; 17 WorkingDirectory = "${libDir}"; 18 Pid Directory = "/var/run"; 19 ${fd_cfg.extraClientConfig} 20 } 21 22 ${concatStringsSep "\n" (mapAttrsToList (name: value: '' 23 Director { 24 Name = "${name}"; 25 Password = "${value.password}"; 26 Monitor = "${value.monitor}"; 27 } 28 '') fd_cfg.director)} 29 30 Messages { 31 Name = Standard; 32 syslog = all, !skipped, !restored 33 ${fd_cfg.extraMessagesConfig} 34 } 35 ''; 36 37 sd_cfg = config.services.bacula-sd; 38 sd_conf = pkgs.writeText "bacula-sd.conf" 39 '' 40 Storage { 41 Name = "${sd_cfg.name}"; 42 SDPort = ${toString sd_cfg.port}; 43 WorkingDirectory = "${libDir}"; 44 Pid Directory = "/var/run"; 45 ${sd_cfg.extraStorageConfig} 46 } 47 48 ${concatStringsSep "\n" (mapAttrsToList (name: value: '' 49 Device { 50 Name = "${name}"; 51 Archive Device = "${value.archiveDevice}"; 52 Media Type = "${value.mediaType}"; 53 ${value.extraDeviceConfig} 54 } 55 '') sd_cfg.device)} 56 57 ${concatStringsSep "\n" (mapAttrsToList (name: value: '' 58 Director { 59 Name = "${name}"; 60 Password = "${value.password}"; 61 Monitor = "${value.monitor}"; 62 } 63 '') sd_cfg.director)} 64 65 Messages { 66 Name = Standard; 67 syslog = all, !skipped, !restored 68 ${sd_cfg.extraMessagesConfig} 69 } 70 ''; 71 72 dir_cfg = config.services.bacula-dir; 73 dir_conf = pkgs.writeText "bacula-dir.conf" 74 '' 75 Director { 76 Name = "${dir_cfg.name}"; 77 Password = "${dir_cfg.password}"; 78 DirPort = ${toString dir_cfg.port}; 79 Working Directory = "${libDir}"; 80 Pid Directory = "/var/run/"; 81 QueryFile = "${pkgs.bacula}/etc/query.sql"; 82 ${dir_cfg.extraDirectorConfig} 83 } 84 85 Catalog { 86 Name = "PostgreSQL"; 87 dbname = "bacula"; 88 user = "bacula"; 89 } 90 91 Messages { 92 Name = Standard; 93 syslog = all, !skipped, !restored 94 ${dir_cfg.extraMessagesConfig} 95 } 96 97 ${dir_cfg.extraConfig} 98 ''; 99 100 # TODO: by default use this config 101 bconsole_conf = pkgs.writeText "bconsole.conf" 102 '' 103 Director { 104 Name = ${dir_cfg.name}; 105 Address = "localhost"; 106 DirPort = ${toString dir_cfg.port}; 107 Password = "${dir_cfg.password}"; 108 } 109 ''; 110 111 directorOptions = {name, config, ...}: 112 { 113 options = { 114 password = mkOption { 115 # TODO: required? 116 description = '' 117 Specifies the password that must be supplied for a Director to b 118 ''; 119 }; 120 121 monitor = mkOption { 122 default = "no"; 123 example = "yes"; 124 description = '' 125 If Monitor is set to no (default), this director will have full 126 ''; 127 }; 128 }; 129 }; 130 131 deviceOptions = {name, config, ...}: 132 { 133 options = { 134 archiveDevice = mkOption { 135 # TODO: required? 136 description = '' 137 The specified name-string gives the system file name of the storage device managed by this storage daemon. This will usually be the device file name of a removable storage device (tape drive), for example " /dev/nst0" or "/dev/rmt/0mbn". For a DVD-writer, it will be for example /dev/hdc. It may also be a directory name if you are archiving to disk storage. 138 ''; 139 }; 140 141 mediaType = mkOption { 142 # TODO: required? 143 description = '' 144 The specified name-string names the type of media supported by this device, for example, "DLT7000". Media type names are arbitrary in that you set them to anything you want, but they must be known to the volume database to keep track of which storage daemons can read which volumes. In general, each different storage type should have a unique Media Type associated with it. The same name-string must appear in the appropriate Storage resource definition in the Director's configuration file. 145 ''; 146 }; 147 148 extraDeviceConfig = mkOption { 149 default = ""; 150 description = '' 151 Extra configuration to be passed in Device directive. 152 ''; 153 example = '' 154 LabelMedia = yes 155 Random Access = no 156 AutomaticMount = no 157 RemovableMedia = no 158 MaximumOpenWait = 60 159 AlwaysOpen = no 160 ''; 161 }; 162 }; 163 }; 164 165in { 166 options = { 167 services.bacula-fd = { 168 enable = mkOption { 169 type = types.bool; 170 default = false; 171 description = '' 172 Whether to enable the Bacula File Daemon. 173 ''; 174 }; 175 176 name = mkOption { 177 default = "${config.networking.hostName}-fd"; 178 description = '' 179 The client name that must be used by the Director when connecting. 180 Generally, it is a good idea to use a name related to the machine 181 so that error messages can be easily identified if you have multiple 182 Clients. This directive is required. 183 ''; 184 }; 185 186 port = mkOption { 187 default = 9102; 188 type = types.int; 189 description = '' 190 This specifies the port number on which the Client listens for 191 Director connections. It must agree with the FDPort specified in 192 the Client resource of the Director's configuration file. 193 ''; 194 }; 195 196 director = mkOption { 197 default = {}; 198 description = '' 199 This option defines director resources in Bacula File Daemon. 200 ''; 201 type = types.attrsOf types.optionSet; 202 options = [ directorOptions ]; 203 }; 204 205 extraClientConfig = mkOption { 206 default = ""; 207 description = '' 208 Extra configuration to be passed in Client directive. 209 ''; 210 example = literalExample '' 211 Maximum Concurrent Jobs = 20; 212 Heartbeat Interval = 30; 213 ''; 214 }; 215 216 extraMessagesConfig = mkOption { 217 default = ""; 218 description = '' 219 Extra configuration to be passed in Messages directive. 220 ''; 221 example = literalExample '' 222 console = all 223 ''; 224 }; 225 }; 226 227 services.bacula-sd = { 228 enable = mkOption { 229 type = types.bool; 230 default = false; 231 description = '' 232 Whether to enable Bacula Storage Daemon. 233 ''; 234 }; 235 236 name = mkOption { 237 default = "${config.networking.hostName}-sd"; 238 description = '' 239 Specifies the Name of the Storage daemon. 240 ''; 241 }; 242 243 port = mkOption { 244 default = 9103; 245 type = types.int; 246 description = '' 247 Specifies port number on which the Storage daemon listens for Director connections. The default is 9103. 248 ''; 249 }; 250 251 director = mkOption { 252 default = {}; 253 description = '' 254 This option defines Director resources in Bacula Storage Daemon. 255 ''; 256 type = types.attrsOf types.optionSet; 257 options = [ directorOptions ]; 258 }; 259 260 device = mkOption { 261 default = {}; 262 description = '' 263 This option defines Device resources in Bacula Storage Daemon. 264 ''; 265 type = types.attrsOf types.optionSet; 266 options = [ deviceOptions ]; 267 }; 268 269 extraStorageConfig = mkOption { 270 default = ""; 271 description = '' 272 Extra configuration to be passed in Storage directive. 273 ''; 274 example = '' 275 Maximum Concurrent Jobs = 20; 276 Heartbeat Interval = 30; 277 ''; 278 }; 279 280 extraMessagesConfig = mkOption { 281 default = ""; 282 description = '' 283 Extra configuration to be passed in Messages directive. 284 ''; 285 example = '' 286 console = all 287 ''; 288 }; 289 290 }; 291 292 services.bacula-dir = { 293 enable = mkOption { 294 type = types.bool; 295 default = false; 296 description = '' 297 Whether to enable Bacula Director Daemon. 298 ''; 299 }; 300 301 name = mkOption { 302 default = "${config.networking.hostName}-dir"; 303 description = '' 304 The director name used by the system administrator. This directive is required. 305 ''; 306 }; 307 308 port = mkOption { 309 default = 9101; 310 type = types.int; 311 description = '' 312 Specify the port (a positive integer) on which the Director daemon will listen for Bacula Console connections. This same port number must be specified in the Director resource of the Console configuration file. The default is 9101, so normally this directive need not be specified. This directive should not be used if you specify DirAddresses (N.B plural) directive. 313 ''; 314 }; 315 316 password = mkOption { 317 # TODO: required? 318 description = '' 319 Specifies the password that must be supplied for a Director. 320 ''; 321 }; 322 323 extraMessagesConfig = mkOption { 324 default = ""; 325 description = '' 326 Extra configuration to be passed in Messages directive. 327 ''; 328 example = '' 329 console = all 330 ''; 331 }; 332 333 extraDirectorConfig = mkOption { 334 default = ""; 335 description = '' 336 Extra configuration to be passed in Director directive. 337 ''; 338 example = '' 339 Maximum Concurrent Jobs = 20; 340 Heartbeat Interval = 30; 341 ''; 342 }; 343 344 extraConfig = mkOption { 345 default = ""; 346 description = '' 347 Extra configuration for Bacula Director Daemon. 348 ''; 349 example = '' 350 TODO 351 ''; 352 }; 353 }; 354 }; 355 356 config = mkIf (fd_cfg.enable || sd_cfg.enable || dir_cfg.enable) { 357 systemd.services.bacula-fd = mkIf fd_cfg.enable { 358 after = [ "network.target" ]; 359 description = "Bacula File Daemon"; 360 wantedBy = [ "multi-user.target" ]; 361 path = [ pkgs.bacula ]; 362 serviceConfig.ExecStart = "${pkgs.bacula}/sbin/bacula-fd -f -u root -g bacula -c ${fd_conf}"; 363 serviceConfig.ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 364 }; 365 366 systemd.services.bacula-sd = mkIf sd_cfg.enable { 367 after = [ "network.target" ]; 368 description = "Bacula Storage Daemon"; 369 wantedBy = [ "multi-user.target" ]; 370 path = [ pkgs.bacula ]; 371 serviceConfig.ExecStart = "${pkgs.bacula}/sbin/bacula-sd -f -u bacula -g bacula -c ${sd_conf}"; 372 serviceConfig.ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 373 }; 374 375 services.postgresql.enable = dir_cfg.enable == true; 376 377 systemd.services.bacula-dir = mkIf dir_cfg.enable { 378 after = [ "network.target" "postgresql.service" ]; 379 description = "Bacula Director Daemon"; 380 wantedBy = [ "multi-user.target" ]; 381 path = [ pkgs.bacula ]; 382 serviceConfig.ExecStart = "${pkgs.bacula}/sbin/bacula-dir -f -u bacula -g bacula -c ${dir_conf}"; 383 serviceConfig.ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 384 preStart = '' 385 if ! test -e "${libDir}/db-created"; then 386 ${pkgs.postgresql}/bin/createuser --no-superuser --no-createdb --no-createrole bacula 387 #${pkgs.postgresql}/bin/createdb --owner bacula bacula 388 389 # populate DB 390 ${pkgs.bacula}/etc/create_bacula_database postgresql 391 ${pkgs.bacula}/etc/make_bacula_tables postgresql 392 ${pkgs.bacula}/etc/grant_bacula_privileges postgresql 393 touch "${libDir}/db-created" 394 else 395 ${pkgs.bacula}/etc/update_bacula_tables postgresql || true 396 fi 397 ''; 398 }; 399 400 environment.systemPackages = [ pkgs.bacula ]; 401 402 users.extraUsers.bacula = { 403 group = "bacula"; 404 uid = config.ids.uids.bacula; 405 home = "${libDir}"; 406 createHome = true; 407 description = "Bacula Daemons user"; 408 shell = "${pkgs.bash}/bin/bash"; 409 }; 410 411 users.extraGroups.bacula.gid = config.ids.gids.bacula; 412 }; 413}