restic,florp: add backup
This commit is contained in:
parent
2388e80dd9
commit
e297f0afeb
8 changed files with 122 additions and 4 deletions
|
@ -59,3 +59,9 @@ creation_rules:
|
||||||
- *emily
|
- *emily
|
||||||
age:
|
age:
|
||||||
- *florp
|
- *florp
|
||||||
|
- path_regex: secrets/restic/zh3485s1.yaml
|
||||||
|
key_groups:
|
||||||
|
- pgp:
|
||||||
|
- *emily
|
||||||
|
age:
|
||||||
|
- *florp
|
||||||
|
|
|
@ -12,6 +12,15 @@
|
||||||
domain = lib.mkForce "social";
|
domain = lib.mkForce "social";
|
||||||
};
|
};
|
||||||
kyouma.nginx.defaultForbidden = "florp.social";
|
kyouma.nginx.defaultForbidden = "florp.social";
|
||||||
|
|
||||||
|
kyouma.restic = {
|
||||||
|
enable = true;
|
||||||
|
remoteUser = "zh3485s1";
|
||||||
|
paths = [
|
||||||
|
"/var/lib/akkoma"
|
||||||
|
"/var/lib/postgresql"
|
||||||
|
];
|
||||||
|
};
|
||||||
systemd.network.networks."98-eth-default" = {
|
systemd.network.networks."98-eth-default" = {
|
||||||
address = [
|
address = [
|
||||||
"2a0f:be01:0:100::171/128"
|
"2a0f:be01:0:100::171/128"
|
||||||
|
@ -19,7 +28,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
services.postgresql.settings = {
|
services.postgresql.settings = {
|
||||||
max_connections = 30;
|
max_connections = 128;
|
||||||
shared_buffers = "4GB";
|
shared_buffers = "4GB";
|
||||||
effective_cache_size = "12GB";
|
effective_cache_size = "12GB";
|
||||||
maintenance_work_mem = "1GB";
|
maintenance_work_mem = "1GB";
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{ lib, inputs, ... }: {
|
{ lib, inputs, ... }: {
|
||||||
imports = [
|
imports = [
|
||||||
|
inputs.sops-nix.nixosModules.sops
|
||||||
"${inputs.nixpkgs}/nixos/modules/installer/sd-card/sd-image-aarch64.nix"
|
"${inputs.nixpkgs}/nixos/modules/installer/sd-card/sd-image-aarch64.nix"
|
||||||
./configuration.nix
|
./configuration.nix
|
||||||
];
|
];
|
||||||
|
|
|
@ -243,7 +243,7 @@
|
||||||
clientMaxBodySize = "256m";
|
clientMaxBodySize = "256m";
|
||||||
commonHttpConfig = ''
|
commonHttpConfig = ''
|
||||||
proxy_cache_path /var/cache/nginx/akkoma-media-cache
|
proxy_cache_path /var/cache/nginx/akkoma-media-cache
|
||||||
levels= keys_zone=akkoma_media_cache:32m max_size=32g
|
levels= keys_zone=akkoma_media_cache:32m max_size=64g
|
||||||
inactive=1y use_temp_path=off;
|
inactive=1y use_temp_path=off;
|
||||||
|
|
||||||
access_log off;
|
access_log off;
|
||||||
|
|
65
modules/restic/default.nix
Normal file
65
modules/restic/default.nix
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
{ config, lib, pkgs, ... }: let
|
||||||
|
cfg = config.kyouma.restic;
|
||||||
|
in {
|
||||||
|
options.kyouma.restic = let
|
||||||
|
inherit (lib) mkOption types;
|
||||||
|
in {
|
||||||
|
enable = lib.mkEnableOption "Enable restic backup";
|
||||||
|
paths = mkOption {
|
||||||
|
description = "paths to backup";
|
||||||
|
type = with types; listOf path;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
pruneOpts = mkOption {
|
||||||
|
description = "paths to backup";
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [
|
||||||
|
"--keep-hourly 24"
|
||||||
|
"--keep-daily 14"
|
||||||
|
"--keep-weekly 8"
|
||||||
|
"--keep-monthly 12"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
remote = mkOption {
|
||||||
|
description = "restic remote to use";
|
||||||
|
type = types.nonEmptyStr;
|
||||||
|
default = "zh3485.rsync.net";
|
||||||
|
};
|
||||||
|
remoteUser = mkOption {
|
||||||
|
description = "remote ssh user";
|
||||||
|
type = types.nonEmptyStr;
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
user = mkOption {
|
||||||
|
description = "user who runs the backup job";
|
||||||
|
type = types.nonEmptyStr;
|
||||||
|
default = "root";
|
||||||
|
};
|
||||||
|
repo = mkOption {
|
||||||
|
description = "restic repo";
|
||||||
|
type = types.nonEmptyStr;
|
||||||
|
default = "${config.networking.hostName}-backup";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
sops.secrets."restic/${cfg.remoteUser}/password" = {
|
||||||
|
sopsFile = ../../secrets/restic/${cfg.remoteUser}.yaml;
|
||||||
|
};
|
||||||
|
sops.secrets."restic/${cfg.remoteUser}/id_ed25519" = {
|
||||||
|
sopsFile = ../../secrets/restic/${cfg.remoteUser}.yaml;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.restic.backups."${config.networking.hostName}-${cfg.remote}" = {
|
||||||
|
inherit (cfg) paths user pruneOpts;
|
||||||
|
initialize = true;
|
||||||
|
repository = "sftp:${cfg.remoteUser}@${cfg.remote}:${cfg.repo}";
|
||||||
|
passwordFile = config.sops.secrets."restic/${cfg.remoteUser}/password".path;
|
||||||
|
extraOptions = let
|
||||||
|
knownHost = pkgs.writeText "${cfg.remote}-known-host" (builtins.readFile ./${cfg.remote}/ssh_host_ed25519_key.pub);
|
||||||
|
sshKey = config.sops.secrets."restic/${cfg.remoteUser}/id_ed25519".path;
|
||||||
|
in [
|
||||||
|
"sftp.command='ssh ${cfg.remoteUser}@${cfg.remote} -i ${sshKey} -o UserKnownHostsFile=${knownHost} -s sftp'"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
1
modules/restic/zh3485.rsync.net/ssh_host_ed25519_key.pub
Normal file
1
modules/restic/zh3485.rsync.net/ssh_host_ed25519_key.pub
Normal file
|
@ -0,0 +1 @@
|
||||||
|
zh3485.rsync.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJtclizeBy1Uo3D86HpgD3LONGVH0CJ0NT+YfZlldAJd
|
|
@ -6,7 +6,6 @@ BRANCH="update-inputs-$(date +%Y-%m-%d-%H-%M)"
|
||||||
HYDRA_URL="https://hydra.kyouma.net"
|
HYDRA_URL="https://hydra.kyouma.net"
|
||||||
JOBSET_URL="${HYDRA_URL}/jobset/nixfiles/update-inputs"
|
JOBSET_URL="${HYDRA_URL}/jobset/nixfiles/update-inputs"
|
||||||
ROOT="$(mktemp -d)"
|
ROOT="$(mktemp -d)"
|
||||||
START_TIME="$(date +%s)"
|
|
||||||
|
|
||||||
gitin () {
|
gitin () {
|
||||||
git -C "${ROOT}/nixfiles" "$@"
|
git -C "${ROOT}/nixfiles" "$@"
|
||||||
|
@ -24,6 +23,8 @@ merge_theirs () {
|
||||||
test_build () {
|
test_build () {
|
||||||
local last_error
|
local last_error
|
||||||
local build_jobs
|
local build_jobs
|
||||||
|
local start_time
|
||||||
|
start_time="$(date +%s)"
|
||||||
|
|
||||||
build_jobs="$(curl --fail -s -L -H "Accept: application/json" "${JOBSET_URL}/latest-eval" | jq -r ".builds | .[]")"
|
build_jobs="$(curl --fail -s -L -H "Accept: application/json" "${JOBSET_URL}/latest-eval" | jq -r ".builds | .[]")"
|
||||||
for build in ${build_jobs}; do
|
for build in ${build_jobs}; do
|
||||||
|
@ -44,7 +45,7 @@ test_build () {
|
||||||
done
|
done
|
||||||
|
|
||||||
last_error="$(curl --fail -s -L -H "Accept: application/json" "${JOBSET_URL}" | jq -r ".errortime")"
|
last_error="$(curl --fail -s -L -H "Accept: application/json" "${JOBSET_URL}" | jq -r ".errortime")"
|
||||||
[[ $last_error -gt $START_TIME ]] &&
|
[[ $last_error -gt $start_time ]] &&
|
||||||
echo "Evaluation error encountered at $(date +%Y-%m-%d-%H:%M:%S --date="@${last_error}")" &&
|
echo "Evaluation error encountered at $(date +%Y-%m-%d-%H:%M:%S --date="@${last_error}")" &&
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
35
secrets/restic/zh3485s1.yaml
Normal file
35
secrets/restic/zh3485s1.yaml
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
restic:
|
||||||
|
zh3485s1:
|
||||||
|
password: ENC[AES256_GCM,data:lDDSSqUH3pewpMA+6SNwGwRz95MBjeaD6I3RWUQNBFXsw/W9RoIY85AcRXxCl7CW,iv:NFF6uCs2FolMe9cgPkoAFmbWdXG2SuVRtoOyQXouEAU=,tag:UeC49xFwFkMh0Wi8p9reFw==,type:str]
|
||||||
|
id_ed25519: ENC[AES256_GCM,data:fe2CAKWSrEOvEPZgGhbigw+DEnDUGtTXEj7nuGaH5enMGDvd7QtRlDYLkM+g9zKrRJ46e2nM6btUZVqqx4rJiUbjJ5B/cBzb259CTxKGgHeMj/cYXPypamIEKFwUrloxzrgxH5JIOoUvj9Ny1P1UPIB//B5Z1Uunqmdqd2XoiAtDwZ/hvyuOfdFyUkKmOnCdF4pheMRXZ6Z51N4f09OIwuZ/xC4LQYAVB2lyycOgrvefPA5YYabMd23yEXn6v/BiP1TWbSInTHvz6Rii2WYqYO3ORCfi1pvWe15kSrTsT9zYRzLvZi5TD+4FMhLmIttZB2OXK7X+h6cHtej7X+v6HKhMKHNJhukRUP7DpcZ0+ArBEdw2j+H7C4q8NdR9rk4we7WpdQlY7tGpJvEzSis+P/Jph/tkzx6xXpKiOeOAXgQUS41qcAy7gmZj7CdsulerUHcfDy4a0y1OEuDmoYW420cGGYOCB9BlvYQbaDhyv5AMSL8sMZfm7mX5qXliE7ZQc20ggKoY2MKH6RjnT8pQhMBWo/NW13PPBDIL,iv:1+aopW183ir5XHMKcDons24A/E61mLuyJGrQTRpPXdE=,tag:s1w+HZdktM0H9FUrz097Cw==,type:str]
|
||||||
|
sops:
|
||||||
|
kms: []
|
||||||
|
gcp_kms: []
|
||||||
|
azure_kv: []
|
||||||
|
hc_vault: []
|
||||||
|
age:
|
||||||
|
- recipient: age18vc8rcmczlt3r0ee7jr9s8l3yrkthu8wtypt08eh0eskpkw3dg6qxs7t3t
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQeWpKYktzVE1tMkpGU1c5
|
||||||
|
akZZdlBkeFQyUmUrOHZxTGE2V1FUVmV3cG5VCmZvTG1JTS9SUTk1aVl6TnBPQ1Fh
|
||||||
|
clRDTmQzQUJxWlYyV2dmVXNyTDJ2K0kKLS0tIHA3S0dsQzRxRWF4RFdSSzh1aXI5
|
||||||
|
ZFQvWFhZTndubkxaRVh3YXl0V25ZcUEK0/wV9i01kRkphrseSBqAL9f8tUlUtJDO
|
||||||
|
PUZL2Em/QjNEnXJaxxR612ONA94ptK9bsqzRJV5RtGqDwd+oAnr13Q==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2024-11-08T13:41:02Z"
|
||||||
|
mac: ENC[AES256_GCM,data:tMatUcv/jbvQ1URp6DrUyuiB9+rgCCdOxEVcM0NBiV5P9DGWE1hWytky4yPE9nFUOWLI7m4nTSEXHuT4yT3LkBd1Ndzhm5wQ0NEAVnZ6Sj7YOQI5CS1q95sviJBv57PBkaajHDNeSJX2hEQeR4qJFUR4fu0hIwadyzeunP/kfKE=,iv:gXRAg4cN43ocQMZm0lL8AnrbDtK+TKGchWpd/TYhnjA=,tag:+HqYuDWjoTdv+CWrJmuwxA==,type:str]
|
||||||
|
pgp:
|
||||||
|
- created_at: "2024-11-08T13:31:55Z"
|
||||||
|
enc: |-
|
||||||
|
-----BEGIN PGP MESSAGE-----
|
||||||
|
|
||||||
|
hF4D1GtNSlou/HkSAQdALVqRZ2qzjR86mEE/MHAR5H3gmIukchY/NSvGg1Ggfmsw
|
||||||
|
uZhnl5puGOO579ItHXbk+BYwBS2koL7jyhnX8E9zmM3d3SZHwzx0mk79fr2jLFj6
|
||||||
|
0l4BLrhhcpUtzfje4/SeTgWFRIA68ON/PUTmW2Lgclh9OpQfbbousFS/JMvvdHaT
|
||||||
|
/3uJEww5MKMPlqWqK7w7z6iwIITRKH0vzQoIZ3hVcDKtKOJrJ/1bWcJorFsazxvT
|
||||||
|
=KZPf
|
||||||
|
-----END PGP MESSAGE-----
|
||||||
|
fp: B04F01A7A98A13020C39B4A68AB7B773A214ACE5
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.9.1
|
Loading…
Reference in a new issue