backup: init as a reusable module
This commit is contained in:
parent
691c180ac1
commit
fefc7bd20d
15
flake.nix
15
flake.nix
|
@ -102,6 +102,21 @@
|
|||
"qenya@shaw".imports = [ ./hosts/shaw/home.nix ];
|
||||
};
|
||||
|
||||
fountain.backup = {
|
||||
keys = {
|
||||
elucredassa = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOFa3hjej6KGmS2aQ4s46Y7U8pN4yyR2FuMofpHRwXNk syncoid@elucredassa" ];
|
||||
};
|
||||
sync = {
|
||||
"orm-state" = {
|
||||
dataset = "state";
|
||||
sourceHost = "orm";
|
||||
targetHost = "elucredassa";
|
||||
source = "rpool_orm";
|
||||
target = "rpool_elucredassa/backup/orm";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
flake.colmena = {
|
||||
meta = {
|
||||
nixpkgs = import nixpkgs-unstable {
|
||||
|
|
126
flake/backup.nix
Normal file
126
flake/backup.nix
Normal file
|
@ -0,0 +1,126 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.fountain.backup;
|
||||
|
||||
syncOptions = {
|
||||
dataset = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The name of the dataset to be synced (not including its parent
|
||||
datasets, if any). This will be the same on the source and target.
|
||||
It must already exist on the source, defined with the
|
||||
{option}`randomcat.services.zfs` module, and not exist on the target.
|
||||
'';
|
||||
};
|
||||
sourceHost = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The host from which the dataset should be synced. Must be an entry in
|
||||
{option}`flake.colmena`.
|
||||
'';
|
||||
};
|
||||
targetHost = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The host to which the dataset should be synced. Must be an entry in
|
||||
{option}`flake.colmena`.
|
||||
'';
|
||||
};
|
||||
source = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The path to the synced dataset in the ZFS namespace on the source host,
|
||||
excluding the component that is the name of the dataset itself.
|
||||
'';
|
||||
};
|
||||
target = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The path to the synced dataset in the ZFS namespace on the target host,
|
||||
excluding the component that is the name of the dataset itself. It must
|
||||
already exist, defined with the {option}`randomcat.services.zfs`
|
||||
module.
|
||||
'';
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
options.fountain.backup = {
|
||||
keys = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.listOf lib.types.singleLineStr);
|
||||
default = { };
|
||||
description = ''
|
||||
Lists of verbatim OpenSSH public keys that may be used to identify the
|
||||
syncoid user on each target host. The key to each list must be the
|
||||
host's hostname, as listed in {option}`flake.colmena`.
|
||||
'';
|
||||
example = {
|
||||
host = [ "ssh-rsa AAAAB3NzaC1yc2etc/etc/etcjwrsh8e596z6J0l7 example@host" ];
|
||||
bar = [ "ssh-ed25519 AAAAC3NzaCetcetera/etceteraJZMfk3QPfQ foo@bar" ];
|
||||
};
|
||||
};
|
||||
|
||||
sync = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule { options = syncOptions; });
|
||||
default = { };
|
||||
description = ''
|
||||
Details of ZFS datasets whose snapshots should be synced from machine
|
||||
to machine using syncoid. Syncoid will run hourly at 15 past the hour
|
||||
and copy all ZFS snapshots from the source dataset to the target
|
||||
dataset (recursing into child datasets).
|
||||
|
||||
See descriptions for the individual options for more details. The name
|
||||
of each attribute in this set is arbitrary and used to generate systemd
|
||||
unit names.
|
||||
|
||||
This module does not actually cause snapshots to be taken; sanoid must
|
||||
be configured separately to do this.
|
||||
'';
|
||||
example = {
|
||||
"orm-state" = {
|
||||
dataset = "state";
|
||||
sourceHost = "orm";
|
||||
targetHost = "elucredassa";
|
||||
source = "rpool_orm";
|
||||
target = "rpool_elucredassa/backup/orm";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# TODO: add some assertions to verify the options
|
||||
|
||||
config.flake.colmena = lib.mkMerge (lib.mapAttrsToList
|
||||
(name: sync: {
|
||||
${sync.sourceHost} = { pkgs, ... }: {
|
||||
randomcat.services.zfs.datasets."${sync.source}/${sync.dataset}".zfsPermissions.users.backup = [ "hold" "send" ];
|
||||
users.users.backup = {
|
||||
group = "backup";
|
||||
isSystemUser = true;
|
||||
useDefaultShell = true;
|
||||
openssh.authorizedKeys.keys = cfg.keys.${sync.targetHost};
|
||||
packages = with pkgs; [ mbuffer lzop ]; # syncoid uses these if available but doesn't pull them in automatically
|
||||
};
|
||||
users.groups.backup = { };
|
||||
};
|
||||
|
||||
${sync.targetHost} = {
|
||||
randomcat.services.zfs.datasets."${sync.target}".zfsPermissions.users.syncoid = [ "mount" "create" "receive" "recordsize" ];
|
||||
services.syncoid = {
|
||||
enable = true;
|
||||
interval = "*-*-* *:15:00";
|
||||
commonArgs = [ "--no-sync-snap" ];
|
||||
commands = {
|
||||
${name} = {
|
||||
source = "backup@${config.flake.nixosConfigurations.${sync.sourceHost}.config.networking.fqdn}:${sync.source}/${sync.dataset}";
|
||||
target = "${sync.target}/${sync.dataset}";
|
||||
recursive = true;
|
||||
recvOptions = "ux recordsize o compression=lz4";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
})
|
||||
cfg.sync
|
||||
);
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
imports = [
|
||||
./backup.nix
|
||||
./colmena.nix
|
||||
];
|
||||
}
|
||||
|
|
|
@ -23,26 +23,10 @@ in
|
|||
console.keyMap = "uk";
|
||||
services.xserver.xkb.layout = "gb";
|
||||
|
||||
# TODO: modularise this
|
||||
# These are populated by fountain.backup
|
||||
randomcat.services.zfs.datasets = {
|
||||
"rpool_elucredassa/backup" = { mountpoint = "none"; };
|
||||
"rpool_elucredassa/backup/orm" = {
|
||||
mountpoint = "none";
|
||||
zfsPermissions.users.syncoid = [ "mount" "create" "receive" "recordsize" ];
|
||||
};
|
||||
};
|
||||
services.syncoid = {
|
||||
enable = true;
|
||||
interval = "*-*-* *:15:00";
|
||||
commonArgs = [ "--no-sync-snap" ];
|
||||
commands = {
|
||||
"testing1" = {
|
||||
source = "backup@10.127.1.2:rpool_orm/state";
|
||||
target = "rpool_elucredassa/backup/orm/state";
|
||||
recursive = true;
|
||||
recvOptions = "ux recordsize o compression=lz4";
|
||||
};
|
||||
};
|
||||
"rpool_elucredassa/backup/orm" = { mountpoint = "none"; };
|
||||
};
|
||||
|
||||
qenya.services.distributed-builds = {
|
||||
|
|
|
@ -31,19 +31,6 @@
|
|||
useTemplate = [ "production" ];
|
||||
recursive = "zfs";
|
||||
};
|
||||
|
||||
# TODO: modularise this
|
||||
randomcat.services.zfs.datasets."rpool_orm/state".zfsPermissions.users.backup = [ "hold" "send" ];
|
||||
users.users.backup = {
|
||||
group = "backup";
|
||||
isSystemUser = true;
|
||||
useDefaultShell = true;
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOFa3hjej6KGmS2aQ4s46Y7U8pN4yyR2FuMofpHRwXNk syncoid@elucredassa"
|
||||
];
|
||||
packages = with pkgs; [ mbuffer lzop ]; # syncoid uses these if available but doesn't pull them in automatically
|
||||
};
|
||||
users.groups.backup = { };
|
||||
|
||||
qenya.services.actual = {
|
||||
enable = true;
|
||||
|
|
Loading…
Reference in a new issue