workspace/arch-user/bin/backup
2025-06-08 23:08:22 +00:00

108 lines
2.9 KiB
Bash
Executable File

#!/bin/bash
set -e
source ~/.config/workspace.conf
key_vol_path="/dev/disk/by-uuid/$BACKUP_KEY_VOL_UUID"
data_vol_path="/dev/disk/by-uuid/$BACKUP_DATA_VOL_UUID"
data_mnt=
remote_open() {
data_mapper_name="$(lsblk "$data_vol_path" -no name --raw | awk 'NR==2')"
key_mnt="$(lsblk "$key_vol_path" -no mountpoint)"
if [ -z "$data_mapper_name" ]; then
echo unlocking data luks vol..
if [ -z "$key_mnt" ]; then
echo mounting key vol..
udisksctl mount -b "$key_vol_path"
key_mnt="$(lsblk "$key_vol_path" -no mountpoint)"
fi
echo decrypting key..
gpg --batch --yes --output /tmp/backup-keyfile --decrypt "$key_mnt/keyfile.gpg"
udisksctl unlock -b "$data_vol_path" --key-file /tmp/backup-keyfile
data_mapper_name="$(lsblk "$data_vol_path" -no name --raw | awk 'NR==2')"
echo unlock ok, doing key cleanup
fi
rm -f /tmp/backup-keyfile
[ -n "$key_mnt" ] && udisksctl unmount -b "$key_vol_path"
data_mnt="$(lsblk "/dev/mapper/$data_mapper_name" -no mountpoint)"
if [ -z "$data_mnt" ]; then
echo mounting data vol..
udisksctl mount -b "/dev/mapper/$data_mapper_name"
data_mnt="$(lsblk "/dev/mapper/$data_mapper_name" -no mountpoint)"
fi
echo open done
}
remote_close() {
data_mapper_name="$(lsblk "$data_vol_path" -no name --raw | awk 'NR==2')"
if [ -n "$data_mapper_name" ]; then
echo unmounting data vol..
udisksctl unmount -b "/dev/mapper/$data_mapper_name"
fi
udisksctl lock -b "$data_vol_path" # must be open here (fail if not)
echo close done
}
declare -A repos
add_repos_local() {
while IFS= read -r -d $'\0'; do
repo_path="$REPLY"
[ ! -f "$repo_path/HEAD" ] && continue
repo_path="$(realpath "$(dirname "$repo_path")")"
repos["$repo_path"]=1
done < <(find "$@" -type d -name .git -print0)
}
add_repos_remote() {
cd "$1"
while IFS= read -r -d $'\0'; do
repo_path="$REPLY"
[ ! -f "$repo_path/HEAD" ] && continue
repo_path="/$(dirname "$repo_path")"
[[ ! " $(groups) " == *" $(echo "$repo_path" | cut -d'/' -f3) "* ]] && continue
repos["$repo_path"]=1
done < <(find "home" -type d -name '*.git' -print0 2>/dev/null)
}
sync_one() {
local_path="$1"
remote_path="$2$1/$(basename "$1").git"
echo "$local_path <-> $remote_path"
remote_url="file:///$remote_path"
if [ ! -d "$local_path" ]; then
mkdir -p "$(dirname "$local_path")"
git clone "$remote_url" "$local_path"
else
cd "$local_path"
git add .
git diff-index --quiet HEAD || git commit -m autocommit || true
if [ ! -d "$remote_path" ]; then
mkdir -p "$(dirname "$remote_path")"
git clone --bare "file:///$1" "$remote_path"
else
git pull "$remote_url"
git push "$remote_url"
fi
fi
}
sync_repos() {
for i in "${!repos[@]}"; do
sync_one "$i" "$1"
sync -f "$1"
done
}
if [[ "$1" = "open" ]]; then
remote_open
exit 0
fi
remote_open
add_repos_remote "$data_mnt"
add_repos_local "/home/$(whoami)/dev" -maxdepth 2
add_repos_local "/home/$(whoami)/know" -maxdepth 2
sync_repos "$data_mnt"
remote_close
echo ALL OK