nix fmt
This commit is contained in:
@@ -3,11 +3,25 @@
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
cfg = config.zfs-root.boot;
|
||||
inherit (lib) mkIf types mkDefault mkOption mkMerge strings;
|
||||
inherit (builtins) head toString map tail;
|
||||
in {
|
||||
inherit (lib)
|
||||
mkIf
|
||||
types
|
||||
mkDefault
|
||||
mkOption
|
||||
mkMerge
|
||||
strings
|
||||
;
|
||||
inherit (builtins)
|
||||
head
|
||||
toString
|
||||
map
|
||||
tail
|
||||
;
|
||||
in
|
||||
{
|
||||
options.zfs-root.boot = {
|
||||
enable = mkOption {
|
||||
description = "Enable root on ZFS support";
|
||||
@@ -17,9 +31,10 @@ in {
|
||||
devNodes = mkOption {
|
||||
description = "Specify where to discover ZFS pools";
|
||||
type = types.str;
|
||||
apply = x:
|
||||
assert (strings.hasSuffix "/" x
|
||||
|| abort "devNodes '${x}' must have trailing slash!"); x;
|
||||
apply =
|
||||
x:
|
||||
assert (strings.hasSuffix "/" x || abort "devNodes '${x}' must have trailing slash!");
|
||||
x;
|
||||
default = "/dev/disk/by-id/";
|
||||
};
|
||||
bootDevices = mkOption {
|
||||
@@ -28,11 +43,15 @@ in {
|
||||
};
|
||||
availableKernelModules = mkOption {
|
||||
type = types.nonEmptyListOf types.str;
|
||||
default = ["uas" "nvme" "ahci"];
|
||||
default = [
|
||||
"uas"
|
||||
"nvme"
|
||||
"ahci"
|
||||
];
|
||||
};
|
||||
kernelParams = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
default = [ ];
|
||||
};
|
||||
immutable = mkOption {
|
||||
description = "Enable root on ZFS immutable root support";
|
||||
@@ -62,7 +81,7 @@ in {
|
||||
};
|
||||
authorizedKeys = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -77,7 +96,9 @@ in {
|
||||
};
|
||||
}
|
||||
(mkIf (!cfg.immutable) {
|
||||
zfs-root.fileSystems.datasets = {"rpool/nixos/root" = "/";};
|
||||
zfs-root.fileSystems.datasets = {
|
||||
"rpool/nixos/root" = "/";
|
||||
};
|
||||
})
|
||||
(mkIf cfg.immutable {
|
||||
zfs-root.fileSystems = {
|
||||
@@ -100,32 +121,25 @@ in {
|
||||
})
|
||||
{
|
||||
zfs-root.fileSystems = {
|
||||
efiSystemPartitions =
|
||||
map (diskName: diskName + cfg.partitionScheme.efiBoot)
|
||||
cfg.bootDevices;
|
||||
efiSystemPartitions = map (diskName: diskName + cfg.partitionScheme.efiBoot) cfg.bootDevices;
|
||||
swapPartitions =
|
||||
if cfg.partitionScheme ? swap
|
||||
then map (diskName: diskName + cfg.partitionScheme.swap) cfg.bootDevices
|
||||
else [];
|
||||
if cfg.partitionScheme ? swap then
|
||||
map (diskName: diskName + cfg.partitionScheme.swap) cfg.bootDevices
|
||||
else
|
||||
[ ];
|
||||
};
|
||||
boot = {
|
||||
initrd.availableKernelModules = cfg.availableKernelModules;
|
||||
kernelParams = cfg.kernelParams;
|
||||
supportedFilesystems = ["zfs"];
|
||||
supportedFilesystems = [ "zfs" ];
|
||||
zfs = {
|
||||
devNodes = cfg.devNodes;
|
||||
forceImportRoot = mkDefault false;
|
||||
};
|
||||
loader = {
|
||||
efi = {
|
||||
canTouchEfiVariables =
|
||||
if cfg.removableEfi
|
||||
then false
|
||||
else true;
|
||||
efiSysMountPoint =
|
||||
"/boot/efis/"
|
||||
+ (head cfg.bootDevices)
|
||||
+ cfg.partitionScheme.efiBoot;
|
||||
canTouchEfiVariables = if cfg.removableEfi then false else true;
|
||||
efiSysMountPoint = "/boot/efis/" + (head cfg.bootDevices) + cfg.partitionScheme.efiBoot;
|
||||
};
|
||||
generationsDir.copyKernels = true;
|
||||
grub = {
|
||||
@@ -135,11 +149,13 @@ in {
|
||||
copyKernels = true;
|
||||
efiSupport = true;
|
||||
zfsSupport = true;
|
||||
extraInstallCommands = toString (map (diskName: ''
|
||||
set -x
|
||||
${pkgs.coreutils-full}/bin/cp -r ${config.boot.loader.efi.efiSysMountPoint}/EFI /boot/efis/${diskName}${cfg.partitionScheme.efiBoot}
|
||||
set +x
|
||||
'') (tail cfg.bootDevices));
|
||||
extraInstallCommands = toString (
|
||||
map (diskName: ''
|
||||
set -x
|
||||
${pkgs.coreutils-full}/bin/cp -r ${config.boot.loader.efi.efiSysMountPoint}/EFI /boot/efis/${diskName}${cfg.partitionScheme.efiBoot}
|
||||
set +x
|
||||
'') (tail cfg.bootDevices)
|
||||
);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -3,20 +3,23 @@
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
cfg = config.mj.base.btrfssnapshot;
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.mj.base.btrfssnapshot = {
|
||||
enable = lib.mkEnableOption "Enable btrfs snapshots";
|
||||
|
||||
subvolumes = lib.mkOption {
|
||||
default = {};
|
||||
type = with lib.types;
|
||||
default = { };
|
||||
type =
|
||||
with lib.types;
|
||||
attrsOf (submodule {
|
||||
options = {
|
||||
label = lib.mkOption {type = str;};
|
||||
keep = lib.mkOption {type = int;};
|
||||
refreshInterval = lib.mkOption {type = str;};
|
||||
label = lib.mkOption { type = str; };
|
||||
keep = lib.mkOption { type = int; };
|
||||
refreshInterval = lib.mkOption { type = str; };
|
||||
};
|
||||
});
|
||||
};
|
||||
@@ -24,30 +27,22 @@ in {
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd = {
|
||||
services =
|
||||
lib.mapAttrs'
|
||||
(
|
||||
subvolume: params:
|
||||
lib.nameValuePair
|
||||
"btrfs-snapshot-${lib.strings.sanitizeDerivationName subvolume}"
|
||||
{
|
||||
description = "${params.label} btrfs snapshot for ${subvolume} (keep ${params.keep}";
|
||||
serviceConfig.ExecStart = "${pkgs.btrfs-auto-snapshot} --verbose --label=${params.label} --keep=${params.keep} ${subvolume}";
|
||||
}
|
||||
);
|
||||
services = lib.mapAttrs' (
|
||||
subvolume: params:
|
||||
lib.nameValuePair "btrfs-snapshot-${lib.strings.sanitizeDerivationName subvolume}" {
|
||||
description = "${params.label} btrfs snapshot for ${subvolume} (keep ${params.keep}";
|
||||
serviceConfig.ExecStart = "${pkgs.btrfs-auto-snapshot} --verbose --label=${params.label} --keep=${params.keep} ${subvolume}";
|
||||
}
|
||||
);
|
||||
|
||||
timers =
|
||||
lib.mapAttrs'
|
||||
(
|
||||
subvolume: params:
|
||||
lib.nameValuePair
|
||||
"btrfs-snapshot-${lib.strings.sanitizeDerivationName subvolume}"
|
||||
{
|
||||
description = "${params.label} btrfs snapshot for ${subvolume}";
|
||||
wantedBy = ["timers.target"];
|
||||
timerConfig.OnCalendar = params.refreshInterval;
|
||||
}
|
||||
);
|
||||
timers = lib.mapAttrs' (
|
||||
subvolume: params:
|
||||
lib.nameValuePair "btrfs-snapshot-${lib.strings.sanitizeDerivationName subvolume}" {
|
||||
description = "${params.label} btrfs snapshot for ${subvolume}";
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig.OnCalendar = params.refreshInterval;
|
||||
}
|
||||
);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
pkgs,
|
||||
myData,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
cfg = config.mj;
|
||||
in {
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./boot
|
||||
./btrfssnapshot
|
||||
@@ -32,7 +34,7 @@ in {
|
||||
description = "Time zone for this system";
|
||||
};
|
||||
|
||||
username = lib.mkOption {type = str;};
|
||||
username = lib.mkOption { type = str; };
|
||||
|
||||
skipPerf = lib.mkOption {
|
||||
type = bool;
|
||||
@@ -51,7 +53,7 @@ in {
|
||||
|
||||
kernelPackages = lib.mkDefault pkgs.linuxPackages;
|
||||
|
||||
supportedFilesystems = ["btrfs"];
|
||||
supportedFilesystems = [ "btrfs" ];
|
||||
};
|
||||
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
@@ -62,15 +64,15 @@ in {
|
||||
|
||||
mj.services.friendlyport.ports = [
|
||||
{
|
||||
subnets = [myData.subnets.tailscale.cidr];
|
||||
tcp = [config.services.iperf3.port];
|
||||
udp = [config.services.iperf3.port];
|
||||
subnets = [ myData.subnets.tailscale.cidr ];
|
||||
tcp = [ config.services.iperf3.port ];
|
||||
udp = [ config.services.iperf3.port ];
|
||||
}
|
||||
];
|
||||
|
||||
i18n = {
|
||||
defaultLocale = "en_US.UTF-8";
|
||||
supportedLocales = ["all"];
|
||||
supportedLocales = [ "all" ];
|
||||
};
|
||||
|
||||
nix = {
|
||||
@@ -80,8 +82,11 @@ in {
|
||||
options = "--delete-older-than 14d";
|
||||
};
|
||||
settings = {
|
||||
experimental-features = ["nix-command" "flakes"];
|
||||
trusted-users = [cfg.username];
|
||||
experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
trusted-users = [ cfg.username ];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -95,7 +100,8 @@ in {
|
||||
};
|
||||
|
||||
environment = {
|
||||
systemPackages = with pkgs;
|
||||
systemPackages =
|
||||
with pkgs;
|
||||
lib.mkMerge [
|
||||
[
|
||||
bc
|
||||
@@ -165,7 +171,6 @@ in {
|
||||
smartmontools
|
||||
unixtools.xxd
|
||||
bcachefs-tools
|
||||
nixfmt-rfc-style
|
||||
sqlite-interactive
|
||||
|
||||
# networking
|
||||
@@ -204,7 +209,7 @@ in {
|
||||
config.boot.kernelPackages.cpupower
|
||||
config.boot.kernelPackages.vm-tools
|
||||
]
|
||||
(lib.mkIf (!cfg.skipPerf) [config.boot.kernelPackages.perf])
|
||||
(lib.mkIf (!cfg.skipPerf) [ config.boot.kernelPackages.perf ])
|
||||
];
|
||||
};
|
||||
|
||||
@@ -233,7 +238,7 @@ in {
|
||||
|
||||
chrony = {
|
||||
enable = true;
|
||||
servers = ["time.cloudflare.com"];
|
||||
servers = [ "time.cloudflare.com" ];
|
||||
};
|
||||
|
||||
locate = {
|
||||
|
||||
@@ -1,50 +1,60 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.zfs-root.fileSystems;
|
||||
inherit (lib) types mkDefault mkOption mkMerge mapAttrsToList;
|
||||
in {
|
||||
inherit (lib)
|
||||
types
|
||||
mkDefault
|
||||
mkOption
|
||||
mkMerge
|
||||
mapAttrsToList
|
||||
;
|
||||
in
|
||||
{
|
||||
options.zfs-root.fileSystems = {
|
||||
datasets = mkOption {
|
||||
description = "Set mountpoint for datasets";
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
default = { };
|
||||
};
|
||||
bindmounts = mkOption {
|
||||
description = "Set mountpoint for bindmounts";
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
default = { };
|
||||
};
|
||||
efiSystemPartitions = mkOption {
|
||||
description = "Set mountpoint for efi system partitions";
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
default = [ ];
|
||||
};
|
||||
swapPartitions = mkOption {
|
||||
description = "Set swap partitions";
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
config.fileSystems = mkMerge (mapAttrsToList (dataset: mountpoint: {
|
||||
config.fileSystems = mkMerge (
|
||||
mapAttrsToList (dataset: mountpoint: {
|
||||
"${mountpoint}" = {
|
||||
device = "${dataset}";
|
||||
fsType = "zfs";
|
||||
options = ["X-mount.mkdir" "noatime"];
|
||||
options = [
|
||||
"X-mount.mkdir"
|
||||
"noatime"
|
||||
];
|
||||
neededForBoot = true;
|
||||
};
|
||||
})
|
||||
cfg.datasets
|
||||
}) cfg.datasets
|
||||
++ mapAttrsToList (bindsrc: mountpoint: {
|
||||
"${mountpoint}" = {
|
||||
device = "${bindsrc}";
|
||||
fsType = "none";
|
||||
options = ["bind" "X-mount.mkdir" "noatime"];
|
||||
options = [
|
||||
"bind"
|
||||
"X-mount.mkdir"
|
||||
"noatime"
|
||||
];
|
||||
};
|
||||
})
|
||||
cfg.bindmounts
|
||||
}) cfg.bindmounts
|
||||
++ map (esp: {
|
||||
"/boot/efis/${esp}" = {
|
||||
device = "${config.zfs-root.boot.devNodes}${esp}";
|
||||
@@ -58,15 +68,16 @@ in {
|
||||
"X-mount.mkdir"
|
||||
];
|
||||
};
|
||||
})
|
||||
cfg.efiSystemPartitions);
|
||||
config.swapDevices = mkDefault (map (swap: {
|
||||
}) cfg.efiSystemPartitions
|
||||
);
|
||||
config.swapDevices = mkDefault (
|
||||
map (swap: {
|
||||
device = "${config.zfs-root.boot.devNodes}${swap}";
|
||||
discardPolicy = mkDefault "both";
|
||||
randomEncryption = {
|
||||
enable = true;
|
||||
allowDiscards = mkDefault true;
|
||||
};
|
||||
})
|
||||
cfg.swapPartitions);
|
||||
}) cfg.swapPartitions
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
options.mj.base.snapshot = {
|
||||
enable = lib.mkEnableOption "Enable zfs snapshots";
|
||||
|
||||
mountpoints = lib.mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
type = with lib.types; listOf str;
|
||||
};
|
||||
};
|
||||
@@ -21,23 +18,23 @@
|
||||
autosnap = true;
|
||||
autoprune = true;
|
||||
};
|
||||
extraArgs = ["--verbose"];
|
||||
datasets = let
|
||||
fs_zfs = lib.filterAttrs (_: v: v.fsType == "zfs") config.fileSystems;
|
||||
mountpoint2fs =
|
||||
builtins.listToAttrs
|
||||
(map (mountpoint: {
|
||||
extraArgs = [ "--verbose" ];
|
||||
datasets =
|
||||
let
|
||||
fs_zfs = lib.filterAttrs (_: v: v.fsType == "zfs") config.fileSystems;
|
||||
mountpoint2fs = builtins.listToAttrs (
|
||||
map (mountpoint: {
|
||||
name = mountpoint;
|
||||
value = builtins.getAttr mountpoint fs_zfs;
|
||||
})
|
||||
config.mj.base.snapshot.mountpoints);
|
||||
s_datasets =
|
||||
lib.mapAttrs' (_mountpoint: fs: {
|
||||
}) config.mj.base.snapshot.mountpoints
|
||||
);
|
||||
s_datasets = lib.mapAttrs' (_mountpoint: fs: {
|
||||
name = fs.device;
|
||||
value = {use_template = ["prod"];};
|
||||
})
|
||||
mountpoint2fs;
|
||||
in
|
||||
value = {
|
||||
use_template = [ "prod" ];
|
||||
};
|
||||
}) mountpoint2fs;
|
||||
in
|
||||
s_datasets;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
lib,
|
||||
myData,
|
||||
...
|
||||
}: {
|
||||
}:
|
||||
{
|
||||
config = {
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
@@ -13,9 +14,13 @@
|
||||
};
|
||||
};
|
||||
programs.mosh.enable = true;
|
||||
programs.ssh.knownHosts = let
|
||||
sshAttrs = lib.genAttrs ["extraHostNames" "publicKey"] (_: null);
|
||||
in
|
||||
programs.ssh.knownHosts =
|
||||
let
|
||||
sshAttrs = lib.genAttrs [
|
||||
"extraHostNames"
|
||||
"publicKey"
|
||||
] (_: null);
|
||||
in
|
||||
lib.mapAttrs (_name: builtins.intersectAttrs sshAttrs) myData.hosts;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,55 +3,58 @@
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
}:
|
||||
{
|
||||
# TODO:
|
||||
# - assert postfix is configured
|
||||
options.mj.base.unitstatus = with lib.types; {
|
||||
enable = lib.mkEnableOption "alert by email on unit failure";
|
||||
email = lib.mkOption {type = str;};
|
||||
email = lib.mkOption { type = str; };
|
||||
units = lib.mkOption {
|
||||
type = listOf str;
|
||||
default = [];
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.mj.base.unitstatus.enable {
|
||||
systemd.services =
|
||||
{
|
||||
"unit-status-mail@" = let
|
||||
# https://northernlightlabs.se/2014-07-05/systemd-status-mail-on-unit-failure.html
|
||||
script = pkgs.writeShellScript "unit-status-mail" ''
|
||||
set -e
|
||||
MAILTO="${config.mj.base.unitstatus.email}"
|
||||
UNIT=$1
|
||||
EXTRA=""
|
||||
for e in "''${@:2}"; do
|
||||
EXTRA+="$e"$'\n'
|
||||
done
|
||||
UNITSTATUS=$(${pkgs.systemd}/bin/systemctl status "$UNIT" || :)
|
||||
${pkgs.postfix}/bin/sendmail $MAILTO <<EOF
|
||||
Subject:Status mail for unit: $UNIT
|
||||
"unit-status-mail@" =
|
||||
let
|
||||
# https://northernlightlabs.se/2014-07-05/systemd-status-mail-on-unit-failure.html
|
||||
script = pkgs.writeShellScript "unit-status-mail" ''
|
||||
set -e
|
||||
MAILTO="${config.mj.base.unitstatus.email}"
|
||||
UNIT=$1
|
||||
EXTRA=""
|
||||
for e in "''${@:2}"; do
|
||||
EXTRA+="$e"$'\n'
|
||||
done
|
||||
UNITSTATUS=$(${pkgs.systemd}/bin/systemctl status "$UNIT" || :)
|
||||
${pkgs.postfix}/bin/sendmail $MAILTO <<EOF
|
||||
Subject:Status mail for unit: $UNIT
|
||||
|
||||
Status report for unit: $UNIT
|
||||
$EXTRA
|
||||
Status report for unit: $UNIT
|
||||
$EXTRA
|
||||
|
||||
$UNITSTATUS
|
||||
EOF
|
||||
$UNITSTATUS
|
||||
EOF
|
||||
|
||||
echo -e "Status mail sent to: $MAILTO for unit: $UNIT"
|
||||
'';
|
||||
in {
|
||||
description = "Send an email on unit failure";
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = ''${script} "%i" "Hostname: %H" "Machine ID: %m" "Boot ID: %b" '';
|
||||
echo -e "Status mail sent to: $MAILTO for unit: $UNIT"
|
||||
'';
|
||||
in
|
||||
{
|
||||
description = "Send an email on unit failure";
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = ''${script} "%i" "Hostname: %H" "Machine ID: %m" "Boot ID: %b" '';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
// lib.genAttrs config.mj.base.unitstatus.units (
|
||||
unit: {
|
||||
unitConfig = {OnFailure = "unit-status-mail@${unit}.service";};
|
||||
}
|
||||
);
|
||||
// lib.genAttrs config.mj.base.unitstatus.units (unit: {
|
||||
unitConfig = {
|
||||
OnFailure = "unit-status-mail@${unit}.service";
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
lib,
|
||||
myData,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
cfg = config.mj.base.users;
|
||||
props = with lib.types; {
|
||||
hashedPasswordFile = lib.mkOption {
|
||||
@@ -21,10 +22,11 @@
|
||||
|
||||
extraGroups = lib.mkOption {
|
||||
type = listOf str;
|
||||
default = [];
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.mj.base.users = with lib.types; {
|
||||
enable = lib.mkEnableOption "enable motiejus and root";
|
||||
devTools = lib.mkOption {
|
||||
@@ -44,33 +46,37 @@ in {
|
||||
mutableUsers = false;
|
||||
|
||||
users = {
|
||||
${config.mj.username} =
|
||||
{
|
||||
isNormalUser = true;
|
||||
extraGroups = ["wheel" "dialout" "video"] ++ cfg.user.extraGroups;
|
||||
uid = myData.uidgid.motiejus;
|
||||
openssh.authorizedKeys.keys = let
|
||||
${config.mj.username} = {
|
||||
isNormalUser = true;
|
||||
extraGroups = [
|
||||
"wheel"
|
||||
"dialout"
|
||||
"video"
|
||||
] ++ cfg.user.extraGroups;
|
||||
uid = myData.uidgid.motiejus;
|
||||
openssh.authorizedKeys.keys =
|
||||
let
|
||||
fqdn = "${config.networking.hostName}.${config.networking.domain}";
|
||||
in
|
||||
lib.mkMerge [
|
||||
[
|
||||
myData.people_pubkeys.motiejus
|
||||
myData.people_pubkeys.motiejus_work
|
||||
]
|
||||
lib.mkMerge [
|
||||
[
|
||||
myData.people_pubkeys.motiejus
|
||||
myData.people_pubkeys.motiejus_work
|
||||
]
|
||||
|
||||
(lib.mkIf (builtins.hasAttr fqdn myData.hosts) [
|
||||
("from=\"127.0.0.1,::1\" " + myData.hosts.${fqdn}.publicKey)
|
||||
])
|
||||
];
|
||||
}
|
||||
// lib.filterAttrs (n: v: n != "extraGroups" && v != null) cfg.user or {};
|
||||
(lib.mkIf (builtins.hasAttr fqdn myData.hosts) [
|
||||
(''from="127.0.0.1,::1" '' + myData.hosts.${fqdn}.publicKey)
|
||||
])
|
||||
];
|
||||
} // lib.filterAttrs (n: v: n != "extraGroups" && v != null) cfg.user or { };
|
||||
|
||||
root = lib.filterAttrs (_: v: v != null) cfg.root;
|
||||
};
|
||||
};
|
||||
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.users.${config.mj.username} = {pkgs, ...}:
|
||||
home-manager.users.${config.mj.username} =
|
||||
{ pkgs, ... }:
|
||||
import ../../../shared/home {
|
||||
inherit lib;
|
||||
inherit pkgs;
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
options.mj.base.zfs = with lib.types; {
|
||||
enable = lib.mkEnableOption "Enable common zfs options";
|
||||
};
|
||||
@@ -16,6 +13,6 @@
|
||||
expandOnBoot = "all";
|
||||
};
|
||||
|
||||
mj.base.unitstatus.units = ["zfs-scrub"];
|
||||
mj.base.unitstatus.units = [ "zfs-scrub" ];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
mkPreHook = zfs_name: i: ''
|
||||
set -x
|
||||
sleep ${toString i}
|
||||
@@ -15,99 +16,103 @@
|
||||
"$RUNTIME_DIRECTORY/snapshot"
|
||||
cd "$RUNTIME_DIRECTORY/snapshot"
|
||||
'';
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.mj.base.zfsborg = with lib.types; {
|
||||
enable = lib.mkEnableOption "backup zfs snapshots with borg";
|
||||
|
||||
passwordPath = lib.mkOption {type = str;};
|
||||
passwordPath = lib.mkOption { type = str; };
|
||||
sshKeyPath = lib.mkOption {
|
||||
type = nullOr path;
|
||||
default = null;
|
||||
};
|
||||
|
||||
dirs = lib.mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
type = listOf (submodule {
|
||||
options = {
|
||||
mountpoint = lib.mkOption {type = path;};
|
||||
repo = lib.mkOption {type = str;};
|
||||
paths = lib.mkOption {type = listOf str;};
|
||||
mountpoint = lib.mkOption { type = path; };
|
||||
repo = lib.mkOption { type = str; };
|
||||
paths = lib.mkOption { type = listOf str; };
|
||||
patterns = lib.mkOption {
|
||||
type = listOf str;
|
||||
default = [];
|
||||
default = [ ];
|
||||
};
|
||||
prune = lib.mkOption {
|
||||
type = anything;
|
||||
default = {};
|
||||
default = { };
|
||||
};
|
||||
backup_at = lib.mkOption {type = str;};
|
||||
backup_at = lib.mkOption { type = str; };
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
config = with config.mj.base.zfsborg;
|
||||
config =
|
||||
with config.mj.base.zfsborg;
|
||||
lib.mkIf enable {
|
||||
systemd.services = lib.listToAttrs (lib.imap0 (
|
||||
i: attr: let
|
||||
systemd.services = lib.listToAttrs (
|
||||
lib.imap0 (
|
||||
i: attr:
|
||||
let
|
||||
svcName = "borgbackup-job-${lib.strings.sanitizeDerivationName attr.mountpoint}-${toString i}";
|
||||
in
|
||||
lib.nameValuePair svcName {
|
||||
serviceConfig.RuntimeDirectory = svcName;
|
||||
}
|
||||
)
|
||||
dirs);
|
||||
lib.nameValuePair svcName { serviceConfig.RuntimeDirectory = svcName; }
|
||||
) dirs
|
||||
);
|
||||
|
||||
services.borgbackup.jobs = builtins.listToAttrs (
|
||||
lib.imap0 (
|
||||
i: attrs: let
|
||||
i: attrs:
|
||||
let
|
||||
mountpoint = builtins.getAttr "mountpoint" attrs;
|
||||
fs = builtins.getAttr mountpoint config.fileSystems;
|
||||
in
|
||||
assert fs.fsType == "zfs";
|
||||
assert lib.assertMsg
|
||||
config.mj.base.unitstatus.enable
|
||||
assert fs.fsType == "zfs";
|
||||
assert lib.assertMsg config.mj.base.unitstatus.enable
|
||||
"config.mj.base.unitstatus.enable must be true";
|
||||
lib.nameValuePair
|
||||
"${lib.strings.sanitizeDerivationName mountpoint}-${toString i}"
|
||||
({
|
||||
inherit (attrs) repo paths;
|
||||
lib.nameValuePair "${lib.strings.sanitizeDerivationName mountpoint}-${toString i}" (
|
||||
{
|
||||
inherit (attrs) repo paths;
|
||||
|
||||
doInit = true;
|
||||
encryption = {
|
||||
mode = "repokey-blake2";
|
||||
passCommand = "cat ${config.mj.base.zfsborg.passwordPath}";
|
||||
};
|
||||
extraArgs = "--remote-path=borg1";
|
||||
compression = "auto,zstd,10";
|
||||
extraCreateArgs = "--chunker-params buzhash,10,23,16,4095";
|
||||
startAt = attrs.backup_at;
|
||||
preHook = mkPreHook fs.device i;
|
||||
prune.keep = {
|
||||
within = "1d";
|
||||
daily = 7;
|
||||
weekly = 4;
|
||||
monthly = 3;
|
||||
};
|
||||
environment =
|
||||
{
|
||||
BORG_HOST_ID = let
|
||||
h = config.networking;
|
||||
in "${h.hostName}.${h.domain}@${h.hostId}";
|
||||
}
|
||||
// lib.optionalAttrs (sshKeyPath != null) {
|
||||
BORG_RSH = ''ssh -i "${config.mj.base.zfsborg.sshKeyPath}"'';
|
||||
};
|
||||
doInit = true;
|
||||
encryption = {
|
||||
mode = "repokey-blake2";
|
||||
passCommand = "cat ${config.mj.base.zfsborg.passwordPath}";
|
||||
};
|
||||
extraArgs = "--remote-path=borg1";
|
||||
compression = "auto,zstd,10";
|
||||
extraCreateArgs = "--chunker-params buzhash,10,23,16,4095";
|
||||
startAt = attrs.backup_at;
|
||||
preHook = mkPreHook fs.device i;
|
||||
prune.keep = {
|
||||
within = "1d";
|
||||
daily = 7;
|
||||
weekly = 4;
|
||||
monthly = 3;
|
||||
};
|
||||
environment =
|
||||
{
|
||||
BORG_HOST_ID =
|
||||
let
|
||||
h = config.networking;
|
||||
in
|
||||
"${h.hostName}.${h.domain}@${h.hostId}";
|
||||
}
|
||||
// lib.optionalAttrs (attrs ? patterns) {inherit (attrs) patterns;}
|
||||
// lib.optionalAttrs (attrs ? prune) {inherit (attrs) prune;})
|
||||
)
|
||||
dirs
|
||||
// lib.optionalAttrs (sshKeyPath != null) {
|
||||
BORG_RSH = ''ssh -i "${config.mj.base.zfsborg.sshKeyPath}"'';
|
||||
};
|
||||
}
|
||||
// lib.optionalAttrs (attrs ? patterns) { inherit (attrs) patterns; }
|
||||
// lib.optionalAttrs (attrs ? prune) { inherit (attrs) prune; }
|
||||
)
|
||||
) dirs
|
||||
);
|
||||
|
||||
mj.base.unitstatus.units = let
|
||||
sanitized = map lib.strings.sanitizeDerivationName (lib.catAttrs "mountpoint" dirs);
|
||||
in
|
||||
mj.base.unitstatus.units =
|
||||
let
|
||||
sanitized = map lib.strings.sanitizeDerivationName (lib.catAttrs "mountpoint" dirs);
|
||||
in
|
||||
lib.imap0 (i: name: "borgbackup-job-${name}-${toString i}") sanitized;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user