Merge remote-tracking branch 'origin/main'

This commit is contained in:
Geoffrey Frogeye 2023-12-18 14:40:41 +01:00
commit ab7a8f73e6
Signed by: geoffrey
GPG key ID: C72403E7F82E6AD8
23 changed files with 255 additions and 127 deletions

83
curacao/backup/backup.sh Executable file
View file

@ -0,0 +1,83 @@
#!/usr/bin/env bash
set -euxo pipefail
# Parse arguments
function help {
echo "Usage: $0 [-h|-i] volume"
echo "Backup BTRFS subvolume on rapido to razmo."
echo
echo "Arguments:"
echo " volume: Name of the subvolume to backup"
echo
echo "Options:"
echo " -h: Display this help message."
echo " -i: Don't fail if the receiving subvolume doesn't exist."
}
init=false
while getopts "hi" OPTION
do
case "$OPTION" in
h)
help
exit 0
;;
i)
init=true
;;
?)
help
exit 2
;;
esac
done
shift "$((OPTIND - 1))"
if [ "$#" -ne 1 ]
then
help
exit 2
fi
volume="$1"
# Assertions
[ -d "/mnt/rapido/${volume}" ]
[ -d "/mnt/rapido/${volume}.bkp" ] || "$init"
[ ! -d "/mnt/rapido/${volume}.new" ]
[ -d "/mnt/razmo/${volume}.bkp" ] || "$init"
[ -d "/mnt/razmo/${volume}" ] || "$init"
[ ! -d "/mnt/razmo/${volume}.new" ]
[ ! -d "/mnt/razmo/${volume}.snapshots" ]
# Taking a snapshot of the running subvolume
btrfs subvolume snapshot -r "/mnt/rapido/${volume}" "/mnt/rapido/${volume}.new"
# Sending (the difference with) the last backup to the backup disk
function error_handler() {
btrfs subvolume delete "/mnt/rapido/${volume}.new" || true
btrfs subvolume delete "/mnt/razmo/${volume}.new" || true
}
trap error_handler ERR
if [ -d "/mnt/rapido/${volume}.bkp" ]
then
btrfs send -p "/mnt/rapido/${volume}.bkp" "/mnt/rapido/${volume}.new" | btrfs receive /mnt/razmo
else
btrfs send "/mnt/rapido/${volume}.new" | btrfs receive /mnt/razmo
fi
trap - ERR
# Removing old backups and putting the new one in place
[ ! -d "/mnt/rapido/${volume}.bkp" ] || btrfs subvolume delete "/mnt/rapido/${volume}.bkp"
mv "/mnt/rapido/${volume}.new" "/mnt/rapido/${volume}.bkp"
[ ! -d "/mnt/razmo/${volume}.bkp" ] || btrfs subvolume delete "/mnt/razmo/${volume}.bkp"
mv "/mnt/razmo/${volume}.new" "/mnt/razmo/${volume}.bkp"
# Create a writeable clone in case we need to boot on the HDD
# Needs to move away then back the .snapshots folder
[ ! -d "/mnt/razmo/${volume}/.snapshots" ] || mv "/mnt/razmo/${volume}/.snapshots" "/mnt/razmo/${volume}.snapshots"
[ ! -d "/mnt/razmo/${volume}" ] || btrfs subvolume delete "/mnt/razmo/${volume}"
btrfs subvolume snapshot "/mnt/razmo/${volume}.bkp" "/mnt/razmo/${volume}"
[ ! -d "/mnt/razmo/${volume}.snapshots" ] || mv "/mnt/razmo/${volume}.snapshots" "/mnt/razmo/${volume}/.snapshots"
sync

View file

@ -0,0 +1,64 @@
{ pkgs, lib, ... }:
# MANU Snapper is not able to create the snapshot directory, so you'll need to do this after eventually running the backup script:
# sudo btrfs subvol create /mnt/razmo/$subvolume/.snapshots
let
backup_subvolumes = [ "nixos" "home.rapido" ];
backup_app = pkgs.writeShellApplication {
name = "backup-subvolume";
runtimeInputs = with pkgs; [ coreutils btrfs-progs ];
text = builtins.readFile ./backup.sh;
};
snapper_subvolumes = [ "nixos" "home.rapido" "home.razmo" ];
in
{
services =
let
default = {
# filesystem type
FSTYPE = "btrfs";
# run daily number cleanup
NUMBER_CLEANUP = true;
NUMBER_MIN_AGE = 1800;
NUMBER_LIMIT = 25;
# create hourly snapshots
TIMELINE_CREATE = true;
# cleanup hourly snapshots after some time
TIMELINE_CLEANUP = true;
TIMELINE_MIN_AGE = 1800;
TIMELINE_LIMIT_HOURLY = 24;
TIMELINE_LIMIT_DAILY = 31;
TIMELINE_LIMIT_WEEKLY = 8;
TIMELINE_LIMIT_MONTHLY = 0;
TIMELINE_LIMIT_YEARLY = 0;
# cleanup empty pre-post-pairs
EMPTY_PRE_POST_CLEANUP = true;
};
in
{
snapper.configs = lib.attrsets.mergeAttrsList (map (s: { "${s}" = default // { SUBVOLUME = "/mnt/razmo/${s}"; }; }) snapper_subvolumes);
};
systemd = {
services.bkp_rapido = {
description = "Make a snapshot of the SSD to the HDD";
before = [ "snapper-timeline.service" ];
serviceConfig = {
Type = "oneshot";
ExecStart = map (s: "${backup_app}/bin/backup-subvolume ${s}") backup_subvolumes;
};
# TODO Harden
};
timers.bkp_rapido = {
description = "Regular snapshot of SSD to HDD";
timerConfig = {
OnCalendar = "hourly";
};
wantedBy = [ "timers.target" ];
};
};
}

View file

@ -1,6 +1,4 @@
{ passwordFile ? "/should_not_be_needed_in_this_context", ... }:
# FIXME Subvolumes for backup. If they're not created with the script. Add the script btw.
# Doesn't seem like it's possible to decrypt luks partition at stage2, hence why everything is with a password now
# TODO Find a way to use keys in filesystem
# TODO Not relatime everywhere, thank you
# TODO Default options
@ -86,7 +84,7 @@ in
mountOptions = [
"rw"
"relatime"
"stripe=4"
# "stripe=4" # For some reason doesn't work on NixOS
];
};
};

View file

@ -3,15 +3,14 @@
frogeye = {
desktop = {
xorg = true;
x11_screens = [ "HDMI-1-0" "eDP1" ];
x11_screens = [ "HDMI-1-0" "eDP-1" ];
maxVideoHeight = 1440;
numlock = true;
phasesBrightness = {
enable = true;
backlight = "intel_backlight";
jour = 40000;
crepuscule = 10000;
nuit = 1;
jour = "40000";
crepuscule = "10000";
nuit = "1";
};
};
dev = {

View file

@ -5,6 +5,7 @@
./options.nix
./hardware.nix
./dk.nix
./backup
];
networking.hostName = "curacao";