Browse Source

New `phoebe.backup.scripts' module for scheduling backup scripts

master
Peter J. Jones 1 month ago
parent
commit
755cc2a84b
Signed by: Peter Jones <pjones@devalot.com> GPG Key ID: 9DAFAA8D01941E49
3 changed files with 141 additions and 0 deletions
  1. 1
    0
      modules/backup/default.nix
  2. 111
    0
      modules/backup/script.nix
  3. 29
    0
      test/backup/script/default.nix

+ 1
- 0
modules/backup/default.nix View File

@@ -8,6 +8,7 @@ in
imports = [
./postgresql.nix
./rsync.nix
./script.nix
];

#### Interface

+ 111
- 0
modules/backup/script.nix View File

@@ -0,0 +1,111 @@
# Run any script to perform a backup.
{ config, lib, pkgs, ...}: with lib;

let
cfg = config.phoebe.backup;
plib = config.phoebe.lib;

##############################################################################
scriptOpts = { name, ... }: {
options = {
name = mkOption {
type = types.str;
description = "Unique name for this backup script.";
};

path = mkOption {
type = types.listOf types.package;
default = [ ];
description = "List of packages to put in PATH.";
};

script = mkOption {
type = types.lines;
description = "Script to run.";
};

schedule = mkOption {
type = types.str;
default = "*-*-* 02:00:00";
example = "*-*-* *:00/30:00";
description = ''
A systemd calendar specification to designate the frequency
of the backup. You can use the "systemd-analyze calendar"
command to validate your calendar specification.
'';
};

user = mkOption {
type = types.str;
default = "backup";
example = "root";
description = "User to execute the script as.";
};

key = mkOption {
type = types.nullOr types.path;
default = null;
example = "/run/keys/mykey";
description = ''
Optional key file to wait for. If the key is provided by
NixOps then this backup will wait until the key is
available.
'';
};
};

config = {
name = mkDefault name;
};
};

##############################################################################
# Generate a systemd service for a backup.
service = opts: rec {
description = "${opts.name} backup";
path = [ pkgs.coreutils ] ++ opts.path;
wants = plib.keyService opts.key;
after = wants;
script = opts.script;
serviceConfig.Type = "simple";
serviceConfig.User = opts.user;
};

##############################################################################
# Generate a systemd timer for a backup.
timer = opts: {
description = "Scheduled ${opts.name} backup";
wantedBy = [ "timers.target" ];
timerConfig.OnCalendar = opts.schedule;
timerConfig.RandomizedDelaySec = "5m";
timerConfig.Unit = "backup-${opts.name}.service";
};

##############################################################################
# Generate systemd services and timers.
toSystemd = f:
foldr (a: b: b // {"backup-${a.name}" = f a;}) {}
(attrValues cfg.scripts);

in
{
#### Interface
options.phoebe.backup.scripts = mkOption {
type = types.attrsOf (types.submodule scriptOpts);
default = { };

example = {
copy-files = {
script = "cp ~/.config ~/.config.bk";
};
};

description = "Set of backup scripts to run.";
};

#### Implementation
config = {
systemd.services = toSystemd service;
systemd.timers = toSystemd timer;
};
}

+ 29
- 0
test/backup/script/default.nix View File

@@ -0,0 +1,29 @@
{ pkgs ? import <nixpkgs> {}
}:

let
service = "backup-test.service";

in
pkgs.nixosTest {
name = "backup-script-test";

nodes = {
simple = {config, pkgs, ...}: {
imports = [ ../../../modules ];
phoebe.security.enable = false;

phoebe.backup.scripts.test = {
user = "root";
script = "cp /etc/issue /tmp/issue";
};
};
};

testScript = ''
$simple->start;
$simple->systemctl("start ${service}");
$simple->waitUntilFails("systemctl status ${service} | grep -q 'Active: active'");
$simple->succeed("cat /tmp/issue") =~ /NixOS/ or die;
'';
}

Loading…
Cancel
Save