From 145a3d084af985c7c39d4de8fc5630f8c0b9da1c Mon Sep 17 00:00:00 2001 From: lunik1 Date: Wed, 14 Jul 2021 17:40:05 +0100 Subject: nixos/snapraid: init --- .../from_md/release-notes/rl-2111.section.xml | 7 + nixos/doc/manual/release-notes/rl-2111.section.md | 4 + nixos/modules/module-list.nix | 1 + nixos/modules/tasks/snapraid.nix | 230 +++++++++++++++++++++ 4 files changed, 242 insertions(+) create mode 100644 nixos/modules/tasks/snapraid.nix (limited to 'nixos') diff --git a/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml index 53c1a18a507..6f2a7fd8dd5 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml @@ -78,6 +78,13 @@ services.vikunja. + + + snapraid, a + backup program for disk arrays. Available as + snapraid. + +
diff --git a/nixos/doc/manual/release-notes/rl-2111.section.md b/nixos/doc/manual/release-notes/rl-2111.section.md index ad56b5cd7d7..5a1a29c270a 100644 --- a/nixos/doc/manual/release-notes/rl-2111.section.md +++ b/nixos/doc/manual/release-notes/rl-2111.section.md @@ -23,6 +23,10 @@ In addition to numerous new and upgraded packages, this release has the followin - [vikunja](https://vikunja.io), a to-do list app. Available as [services.vikunja](#opt-services.vikunja.enable). +- [snapraid](https://www.snapraid.it/), a backup program for disk arrays. + Available as [snapraid](#opt-snapraid.enable). + + ## Backward Incompatibilities {#sec-release-21.11-incompatibilities} - The `staticjinja` package has been upgraded from 1.0.4 to 3.0.1 diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 69616716c92..3474c6e99d2 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1104,6 +1104,7 @@ ./tasks/network-interfaces-systemd.nix ./tasks/network-interfaces-scripted.nix ./tasks/scsi-link-power-management.nix + ./tasks/snapraid.nix ./tasks/swraid.nix ./tasks/trackpoint.nix ./tasks/powertop.nix diff --git a/nixos/modules/tasks/snapraid.nix b/nixos/modules/tasks/snapraid.nix new file mode 100644 index 00000000000..4529009930f --- /dev/null +++ b/nixos/modules/tasks/snapraid.nix @@ -0,0 +1,230 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.snapraid; +in +{ + options.snapraid = with types; { + enable = mkEnableOption "SnapRAID"; + dataDisks = mkOption { + default = { }; + example = { + d1 = "/mnt/disk1/"; + d2 = "/mnt/disk2/"; + d3 = "/mnt/disk3/"; + }; + description = "SnapRAID data disks."; + type = attrsOf str; + }; + parityFiles = mkOption { + default = [ ]; + example = [ + "/mnt/diskp/snapraid.parity" + "/mnt/diskq/snapraid.2-parity" + "/mnt/diskr/snapraid.3-parity" + "/mnt/disks/snapraid.4-parity" + "/mnt/diskt/snapraid.5-parity" + "/mnt/disku/snapraid.6-parity" + ]; + description = "SnapRAID parity files."; + type = listOf str; + }; + contentFiles = mkOption { + default = [ ]; + example = [ + "/var/snapraid.content" + "/mnt/disk1/snapraid.content" + "/mnt/disk2/snapraid.content" + ]; + description = "SnapRAID content list files."; + type = listOf str; + }; + exclude = mkOption { + default = [ ]; + example = [ "*.unrecoverable" "/tmp/" "/lost+found/" ]; + description = "SnapRAID exclude directives."; + type = listOf str; + }; + touchBeforeSync = mkOption { + default = true; + example = false; + description = + "Whether snapraid touch should be run before snapraid sync."; + type = bool; + }; + sync.interval = mkOption { + default = "01:00"; + example = "daily"; + description = "How often to run snapraid sync."; + type = str; + }; + scrub = { + interval = mkOption { + default = "Mon *-*-* 02:00:00"; + example = "weekly"; + description = "How often to run snapraid scrub."; + type = str; + }; + plan = mkOption { + default = 8; + example = 5; + description = + "Percent of the array that should be checked by snapraid scrub."; + type = int; + }; + olderThan = mkOption { + default = 10; + example = 20; + description = + "Number of days since data was last scrubbed before it can be scrubbed again."; + type = int; + }; + }; + extraConfig = mkOption { + default = ""; + example = '' + nohidden + blocksize 256 + hashsize 16 + autosave 500 + pool /pool + ''; + description = "Extra config options for SnapRAID."; + type = lines; + }; + }; + + config = + let + nParity = builtins.length cfg.parityFiles; + mkPrepend = pre: s: pre + s; + in + mkIf cfg.enable { + assertions = [ + { + assertion = nParity <= 6; + message = "You can have no more than six SnapRAID parity files."; + } + { + assertion = builtins.length cfg.contentFiles >= nParity + 1; + message = + "There must be at least one SnapRAID content file for each SnapRAID parity file plus one."; + } + ]; + + environment = { + systemPackages = with pkgs; [ snapraid ]; + + etc."snapraid.conf" = { + text = with cfg; + let + prependData = mkPrepend "data "; + prependContent = mkPrepend "content "; + prependExclude = mkPrepend "exclude "; + in + concatStringsSep "\n" + (map prependData + ((mapAttrsToList (name: value: name + " " + value)) dataDisks) + ++ zipListsWith (a: b: a + b) + ([ "parity " ] ++ map (i: toString i + "-parity ") (range 2 6)) + parityFiles ++ map prependContent contentFiles + ++ map prependExclude exclude) + "\n" + extraConfig; + }; + }; + + systemd.services = with cfg; { + snapraid-scrub = { + description = "Scrub the SnapRAID array"; + startAt = scrub.interval; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${pkgs.snapraid}/bin/snapraid scrub -p ${ + toString scrub.plan + } -o ${toString scrub.olderThan}"; + Nice = 19; + IOSchedulingPriority = 7; + CPUSchedulingPolicy = "batch"; + + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateTmp = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + RestrictAddressFamilies = "none"; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = "@system-service"; + SystemCallErrorNumber = "EPERM"; + CapabilityBoundingSet = "CAP_DAC_OVERRIDE"; + + ProtectSystem = "strict"; + ProtectHome = "read-only"; + ReadWritePaths = + # scrub requires access to directories containing content files + # to remove them if they are stale + let + contentDirs = map dirOf contentFiles; + in + unique ( + attrValues dataDisks ++ contentDirs + ); + }; + unitConfig.After = "snapraid-sync.service"; + }; + snapraid-sync = { + description = "Synchronize the state of the SnapRAID array"; + startAt = sync.interval; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${pkgs.snapraid}/bin/snapraid sync"; + Nice = 19; + IOSchedulingPriority = 7; + CPUSchedulingPolicy = "batch"; + + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateTmp = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + RestrictAddressFamilies = "none"; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = "@system-service"; + SystemCallErrorNumber = "EPERM"; + CapabilityBoundingSet = "CAP_DAC_OVERRIDE"; + + ProtectSystem = "strict"; + ProtectHome = "read-only"; + ReadWritePaths = + # sync requires access to directories containing content files + # to remove them if they are stale + let + contentDirs = map dirOf contentFiles; + in + unique ( + attrValues dataDisks ++ parityFiles ++ contentDirs + ); + } // optionalAttrs touchBeforeSync { + ExecStartPre = "${pkgs.snapraid}/bin/snapraid touch"; + }; + }; + }; + }; +} -- cgit 1.4.1 From 2463620fc2bad6eeb8f0c0e837e4d6affd2c22a9 Mon Sep 17 00:00:00 2001 From: Antoine Martin Date: Wed, 14 Jul 2021 23:20:10 +0200 Subject: nixos/vaultwarden: make package configurable (#113216) This allows the user to override the version of Vaultwarden used by the service, if using an overlay to keep up to date with releases for example. --- .../modules/services/security/vaultwarden/default.nix | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'nixos') diff --git a/nixos/modules/services/security/vaultwarden/default.nix b/nixos/modules/services/security/vaultwarden/default.nix index 940ac7832da..d28ea61e66a 100644 --- a/nixos/modules/services/security/vaultwarden/default.nix +++ b/nixos/modules/services/security/vaultwarden/default.nix @@ -26,12 +26,12 @@ let if value != null then [ (nameValuePair (nameToEnvVar name) (if isBool value then boolToString value else toString value)) ] else [] ) cfg.config)); in { DATA_FOLDER = "/var/lib/bitwarden_rs"; } // optionalAttrs (!(configEnv ? WEB_VAULT_ENABLED) || configEnv.WEB_VAULT_ENABLED == "true") { - WEB_VAULT_FOLDER = "${pkgs.vaultwarden-vault}/share/vaultwarden/vault"; + WEB_VAULT_FOLDER = "${cfg.webVaultPackage}/share/vaultwarden/vault"; } // configEnv; configFile = pkgs.writeText "vaultwarden.env" (concatStrings (mapAttrsToList (name: value: "${name}=${value}\n") configEnv)); - vaultwarden = pkgs.vaultwarden.override { inherit (cfg) dbBackend; }; + vaultwarden = cfg.package.override { inherit (cfg) dbBackend; }; in { imports = [ @@ -102,6 +102,20 @@ in { vaultwarden is running. ''; }; + + package = mkOption { + type = package; + default = pkgs.vaultwarden; + defaultText = "pkgs.vaultwarden"; + description = "Vaultwarden package to use."; + }; + + webVaultPackage = mkOption { + type = package; + default = pkgs.vaultwarden-vault; + defaultText = "pkgs.vaultwarden-vault"; + description = "Web vault package to use."; + }; }; config = mkIf cfg.enable { -- cgit 1.4.1