Merge pull request 'better backups' (#343) from better-backups into main
Reviewed-on: #343 Reviewed-by: teutat3s <teutat3s@noreply.git.pub.solar>
This commit is contained in:
commit
efe18beefb
5 changed files with 179 additions and 86 deletions
|
@ -71,6 +71,35 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
resources = mkOption {
|
||||
description = "resources required to exist before starting restic backup archive process";
|
||||
default = { };
|
||||
type = types.attrsOf (
|
||||
types.submodule (
|
||||
{ ... }:
|
||||
{
|
||||
options = {
|
||||
resourceCreateCommand = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
A script that must run successfully to create the resource. Optional.
|
||||
'';
|
||||
};
|
||||
|
||||
resourceDestroyCommand = mkOption {
|
||||
type = with types; nullOr str;
|
||||
default = null;
|
||||
description = ''
|
||||
A script that runs when the resource is destroyed. Optional.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
restic = mkOption {
|
||||
description = ''
|
||||
Periodic backups to create with Restic.
|
||||
|
@ -80,6 +109,11 @@ in
|
|||
{ name, ... }:
|
||||
{
|
||||
options = {
|
||||
resources = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
};
|
||||
|
||||
paths = mkOption {
|
||||
# This is nullable for legacy reasons only. We should consider making it a pure listOf
|
||||
# after some time has passed since this comment was added.
|
||||
|
@ -262,31 +296,88 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
services.restic.backups =
|
||||
let
|
||||
repos = config.pub-solar-os.backups.repos;
|
||||
restic = config.pub-solar-os.backups.restic;
|
||||
config =
|
||||
let
|
||||
repos = config.pub-solar-os.backups.repos;
|
||||
restic = config.pub-solar-os.backups.restic;
|
||||
resources = config.pub-solar-os.backups.resources;
|
||||
|
||||
repoNames = builtins.attrNames repos;
|
||||
backupNames = builtins.attrNames restic;
|
||||
repoNames = builtins.attrNames repos;
|
||||
resourceNames = builtins.attrNames resources;
|
||||
backupNames = builtins.attrNames restic;
|
||||
|
||||
createBackups =
|
||||
backupName:
|
||||
map (repoName: {
|
||||
name = "${backupName}-${repoName}";
|
||||
value = repos."${repoName}" // restic."${backupName}";
|
||||
}) repoNames;
|
||||
createResourceService = resourceName: {
|
||||
name = "restic-backups-resource-${resourceName}";
|
||||
value = {
|
||||
serviceConfig =
|
||||
let
|
||||
createResourceApp = pkgs.writeShellApplication {
|
||||
name = "create-resource-${resourceName}";
|
||||
text = resources."${resourceName}".resourceCreateCommand;
|
||||
};
|
||||
destroyResourceApp = pkgs.writeShellApplication {
|
||||
name = "destroy-resource-${resourceName}";
|
||||
text = resources."${resourceName}".resourceDestroyCommand;
|
||||
};
|
||||
|
||||
in
|
||||
builtins.listToAttrs (lib.lists.flatten (map createBackups backupNames));
|
||||
in
|
||||
{
|
||||
Type = "oneshot";
|
||||
ExecStart = lib.mkIf (
|
||||
resources."${resourceName}".resourceCreateCommand != null
|
||||
) "${createResourceApp}/bin/create-resource-${resourceName}";
|
||||
ExecStop = lib.mkIf (
|
||||
resources."${resourceName}".resourceDestroyCommand != null
|
||||
) "${destroyResourceApp}/bin/destroy-resource-${resourceName}";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
unitConfig.StopWhenUnneeded = true;
|
||||
};
|
||||
};
|
||||
|
||||
# Used for pub-solar-os.backups.repos.storagebox
|
||||
programs.ssh.knownHosts = {
|
||||
"u377325.your-storagebox.de".publicKey =
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA5EB5p/5Hp3hGW1oHok+PIOH9Pbn7cnUiGmUEBrCVjnAw+HrKyN8bYVV0dIGllswYXwkG/+bgiBlE6IVIBAq+JwVWu1Sss3KarHY3OvFJUXZoZyRRg/Gc/+LRCE7lyKpwWQ70dbelGRyyJFH36eNv6ySXoUYtGkwlU5IVaHPApOxe4LHPZa/qhSRbPo2hwoh0orCtgejRebNtW5nlx00DNFgsvn8Svz2cIYLxsPVzKgUxs8Zxsxgn+Q/UvR7uq4AbAhyBMLxv7DjJ1pc7PJocuTno2Rw9uMZi1gkjbnmiOh6TTXIEWbnroyIhwc8555uto9melEUmWNQ+C+PwAK+MPw==";
|
||||
"[u377325.your-storagebox.de]:23".publicKey =
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIICf9svRenC/PLKIL9nk6K/pxQgoiFC41wTNvoIncOxs";
|
||||
createResourceDependency = resourceName: backupName: repoName: {
|
||||
name = "restic-backups-${backupName}-${repoName}";
|
||||
value = {
|
||||
after = [ "restic-backups-resource-${resourceName}.service" ];
|
||||
requires = [ "restic-backups-resource-${resourceName}.service" ];
|
||||
|
||||
serviceConfig.PrivateTmp = lib.mkForce false;
|
||||
unitConfig = {
|
||||
JoinsNamespaceOf = [ "restic-backups-resource-${resourceName}.service" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
createResourceDependencies =
|
||||
backupName:
|
||||
map (
|
||||
repoName:
|
||||
map (resourceName: createResourceDependency resourceName backupName repoName)
|
||||
restic."${backupName}".resources
|
||||
) repoNames;
|
||||
|
||||
createBackups =
|
||||
backupName:
|
||||
map (repoName: {
|
||||
name = "${backupName}-${repoName}";
|
||||
value = lib.attrsets.filterAttrs (key: val: (key != "resources")) (
|
||||
repos."${repoName}" // restic."${backupName}"
|
||||
);
|
||||
}) repoNames;
|
||||
in
|
||||
{
|
||||
systemd.services =
|
||||
(builtins.listToAttrs (map createResourceService resourceNames))
|
||||
// (builtins.listToAttrs (lib.lists.flatten (map createResourceDependencies backupNames)));
|
||||
|
||||
services.restic.backups = builtins.listToAttrs (lib.lists.flatten (map createBackups backupNames));
|
||||
|
||||
# Used for pub-solar-os.backups.repos.storagebox
|
||||
programs.ssh.knownHosts = {
|
||||
"u377325.your-storagebox.de".publicKey =
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA5EB5p/5Hp3hGW1oHok+PIOH9Pbn7cnUiGmUEBrCVjnAw+HrKyN8bYVV0dIGllswYXwkG/+bgiBlE6IVIBAq+JwVWu1Sss3KarHY3OvFJUXZoZyRRg/Gc/+LRCE7lyKpwWQ70dbelGRyyJFH36eNv6ySXoUYtGkwlU5IVaHPApOxe4LHPZa/qhSRbPo2hwoh0orCtgejRebNtW5nlx00DNFgsvn8Svz2cIYLxsPVzKgUxs8Zxsxgn+Q/UvR7uq4AbAhyBMLxv7DjJ1pc7PJocuTno2Rw9uMZi1gkjbnmiOh6TTXIEWbnroyIhwc8555uto9melEUmWNQ+C+PwAK+MPw==";
|
||||
"[u377325.your-storagebox.de]:23".publicKey =
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIICf9svRenC/PLKIL9nk6K/pxQgoiFC41wTNvoIncOxs";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -59,18 +59,18 @@
|
|||
};
|
||||
};
|
||||
|
||||
pub-solar-os.backups.restic.keycloak = {
|
||||
paths = [ "/tmp/keycloak-backup.sql" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 03:00:00 Etc/UTC";
|
||||
pub-solar-os.backups = {
|
||||
resources.keycloak-db.resourceCreateCommand = ''
|
||||
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d keycloak -f /tmp/keycloak-backup.sql
|
||||
'';
|
||||
restic.keycloak = {
|
||||
resources = [ "keycloak-db" ];
|
||||
paths = [ "/tmp/keycloak-backup.sql" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 03:00:00 Etc/UTC";
|
||||
};
|
||||
initialize = true;
|
||||
};
|
||||
initialize = true;
|
||||
backupPrepareCommand = ''
|
||||
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d keycloak > /tmp/keycloak-backup.sql
|
||||
'';
|
||||
backupCleanupCommand = ''
|
||||
rm /tmp/keycloak-backup.sql
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -334,26 +334,25 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
pub-solar-os.backups.restic.matrix-synapse = {
|
||||
paths = [
|
||||
"/var/lib/matrix-synapse"
|
||||
"/var/lib/matrix-appservice-irc"
|
||||
"/var/lib/mautrix-telegram"
|
||||
"/tmp/matrix-synapse-backup.sql"
|
||||
"/tmp/matrix-authentication-service-backup.sql"
|
||||
];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 05:00:00 Etc/UTC";
|
||||
pub-solar-os.backups = {
|
||||
resources.matrix-db.resourceCreateCommand = ''
|
||||
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d matrix -f /tmp/matrix-synapse-backup.sql
|
||||
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d matrix-authentication-service -f /tmp/matrix-authentication-service-backup.sql
|
||||
'';
|
||||
restic.matrix-synapse = {
|
||||
resources = [ "matrix-db" ];
|
||||
paths = [
|
||||
"/var/lib/matrix-synapse"
|
||||
"/var/lib/matrix-appservice-irc"
|
||||
"/var/lib/mautrix-telegram"
|
||||
"/tmp/matrix-synapse-backup.sql"
|
||||
"/tmp/matrix-authentication-service-backup.sql"
|
||||
];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 05:00:00 Etc/UTC";
|
||||
};
|
||||
initialize = true;
|
||||
};
|
||||
initialize = true;
|
||||
backupPrepareCommand = ''
|
||||
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d matrix > /tmp/matrix-synapse-backup.sql
|
||||
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d matrix-authentication-service > /tmp/matrix-authentication-service-backup.sql
|
||||
'';
|
||||
backupCleanupCommand = ''
|
||||
rm /tmp/matrix-synapse-backup.sql
|
||||
rm /tmp/matrix-authentication-service-backup.sql
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -239,21 +239,24 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
pub-solar-os.backups.restic.mediawiki = {
|
||||
paths = [
|
||||
"/var/lib/mediawiki/images"
|
||||
"/var/lib/mediawiki/uploads"
|
||||
"/tmp/mediawiki-backup.sql"
|
||||
];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 00:00:00 Etc/UTC";
|
||||
pub-solar-os.backups = {
|
||||
resources.mediawiki-db = {
|
||||
resourceCreateCommand = ''
|
||||
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d mediawiki -f /tmp/mediawiki-backup.sql
|
||||
'';
|
||||
};
|
||||
|
||||
restic.mediawiki = {
|
||||
resources = [ "mediawiki-db" ];
|
||||
paths = [
|
||||
"/var/lib/mediawiki/images"
|
||||
"/var/lib/mediawiki/uploads"
|
||||
"/tmp/mediawiki-backup.sql"
|
||||
];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 00:00:00 Etc/UTC";
|
||||
};
|
||||
initialize = true;
|
||||
};
|
||||
initialize = true;
|
||||
backupPrepareCommand = ''
|
||||
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d mediawiki > /tmp/mediawiki-backup.sql
|
||||
'';
|
||||
backupCleanupCommand = ''
|
||||
rm /tmp/mediawiki-backup.sql
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
|
@ -148,25 +148,25 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
pub-solar-os.backups.restic.obs-portal = {
|
||||
paths = [
|
||||
"/var/lib/obs-portal/data"
|
||||
"/tmp/obs-portal-backup.sql"
|
||||
];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 06:30:00 Etc/UTC";
|
||||
pub-solar-os.backups = {
|
||||
resources.obs-db.resourceCreateCommand = ''
|
||||
${pkgs.docker}/bin/docker exec -i --user postgres obs-portal-db pg_dump -d obs -f /tmp/obs-portal-backup.sql
|
||||
'';
|
||||
restic.obs-portal = {
|
||||
resources = [ "obs-db" ];
|
||||
paths = [
|
||||
"/var/lib/obs-portal/data"
|
||||
"/tmp/obs-portal-backup.sql"
|
||||
];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 06:30:00 Etc/UTC";
|
||||
};
|
||||
initialize = true;
|
||||
pruneOpts = [
|
||||
"--keep-daily 7"
|
||||
"--keep-weekly 4"
|
||||
"--keep-monthly 3"
|
||||
];
|
||||
};
|
||||
initialize = true;
|
||||
backupPrepareCommand = ''
|
||||
${pkgs.docker}/bin/docker exec -i --user postgres obs-portal-db pg_dump obs > /tmp/obs-portal-backup.sql
|
||||
'';
|
||||
backupCleanupCommand = ''
|
||||
rm /tmp/obs-portal-backup.sql
|
||||
'';
|
||||
pruneOpts = [
|
||||
"--keep-daily 7"
|
||||
"--keep-weekly 4"
|
||||
"--keep-monthly 3"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue