nixos/snapraid: init
This commit is contained in:
parent
0b9a7ed217
commit
145a3d084a
@ -78,6 +78,13 @@
|
||||
<link linkend="opt-services.vikunja.enable">services.vikunja</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://www.snapraid.it/">snapraid</link>, a
|
||||
backup program for disk arrays. Available as
|
||||
<link linkend="opt-snapraid.enable">snapraid</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section xml:id="sec-release-21.11-incompatibilities">
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
230
nixos/modules/tasks/snapraid.nix
Normal file
230
nixos/modules/tasks/snapraid.nix
Normal file
@ -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 <command>snapraid touch</command> should be run before <command>snapraid sync</command>.";
|
||||
type = bool;
|
||||
};
|
||||
sync.interval = mkOption {
|
||||
default = "01:00";
|
||||
example = "daily";
|
||||
description = "How often to run <command>snapraid sync</command>.";
|
||||
type = str;
|
||||
};
|
||||
scrub = {
|
||||
interval = mkOption {
|
||||
default = "Mon *-*-* 02:00:00";
|
||||
example = "weekly";
|
||||
description = "How often to run <command>snapraid scrub</command>.";
|
||||
type = str;
|
||||
};
|
||||
plan = mkOption {
|
||||
default = 8;
|
||||
example = 5;
|
||||
description =
|
||||
"Percent of the array that should be checked by <command>snapraid scrub</command>.";
|
||||
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";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user