aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rwxr-xr-xtools/net_services100
1 files changed, 97 insertions, 3 deletions
diff --git a/tools/net_services b/tools/net_services
index 9652948..334fb73 100755
--- a/tools/net_services
+++ b/tools/net_services
@@ -4,6 +4,10 @@ set -euo pipefail
script_dir="$(dirname "$(realpath "$0")")"
root_dir="$(realpath "$script_dir/..")"
+# Compose project name; must match `name:` in compose.yaml. Docker prefixes
+# named volumes with it (e.g. `net_services_radicale_data`).
+project="net_services"
+
# generate_self_signed_cert <domain> <crt_dst> <key_dst> [<subdomains>...]
_generate_self_signed_cert() {
local crt_dst=${1:?missing crt_dst argument}
@@ -15,8 +19,8 @@ _generate_self_signed_cert() {
mkcert -cert-file "$crt_dst" -key-file "$key_dst" "${subdomains[@]/%/.$domain}" "$domain"
}
-# _generate_ovh_cert ovh_api_creds.ini example.com www dav sftp
-_generate_ovh_cert() {
+# generate_ovh_cert ovh_api_creds.ini example.com www dav sftp
+generate_ovh_cert() {
ini="${1:?missing ini argument}"
domain="${2:?missing domain argument}"
shift 2
@@ -118,12 +122,102 @@ init() {
cp_if_absent "$root_dir/services/cgit/examples/commit-filter.sh" "$HOST__CGIT_FILTER_DIR/commit-filter.sh"
}
+# backup_dir <name> <src>
+backup_dir() {
+ local name=${1:?missing name argument}
+ local src=${2:?missing src argument}
+ if [[ -d "$src" ]]; then
+ tar --create --zstd --file "$dest/$name.tar.zst" --directory "$(dirname "$src")" "$(basename "$src")"
+ echo " ✓ $name ($src)"
+ else
+ echo " ! skip $name: $src not found" >&2
+ fi
+}
+
+# Only a backup of the git directory is needed for Radicale
+backup_radicale_repo() {
+ local vol="${project}_radicale_data"
+ if ! docker volume inspect "$vol" &>/dev/null; then
+ echo " ! skip radicale: volume $vol not found (is the stack created?)" >&2
+ return
+ fi
+
+ local owner
+ owner="$(id -u):$(id -g)"
+ docker run --rm \
+ -v "$vol":/data:ro \
+ -v "$dest":/backup \
+ --entrypoint sh \
+ alpine/git -c "git -c safe.directory='*' clone --bare /data/collections /backup/radicale-collections.git && chown -R $owner /backup/radicale-collections.git"
+ echo " ✓ radicale-collections.git"
+}
+
+# backup [dest_dir]
+backup() {
+ local backup_root=${1:-$HOME/backups/$project}
+ local timestamp
+ timestamp="$(date +%Y%m%d-%H%M%S)"
+ dest="$backup_root/$timestamp"
+ mkdir --parents "$dest"
+
+ echo "Backing up to $dest"
+
+ echo "Host directories:"
+ local -A host_dirs=(
+ ["git"]=HOST__GIT_REPO_DIR
+ ["cgit-cgitrc"]=HOST__CGITRC_DIR
+ ["cgit-filter"]=HOST__CGIT_FILTER_DIR
+ ["cgit-about"]=HOST__CGIT_ABOUT_DIR
+ ["radicale-users"]=HOST__RADICALE_USERS_DIR
+ ["syncthing"]=HOST__SYNC_DIR
+ )
+ local name envvar_name
+ for name in "${!host_dirs[@]}"; do
+ envvar_name=${host_dirs[$name]}
+ local -n dir="$envvar_name"
+ backup_dir "$name" "$dir"
+ done
+
+ echo "Radicale:"
+ if command -v docker &>/dev/null; then
+ backup_radicale_repo
+ else
+ echo " ! skip: docker not found" >&2
+ fi
+
+ echo "Stack definition:"
+ cp "$root_dir/compose.yaml" "$dest/compose.yaml"
+ cp "$root_dir/.env" "$dest/env"
+ echo " ✓ compose.yaml, env"
+}
+
+usage() {
+ cat >&2 <<-EOF
+ Manage the net_services stack.
+
+ usage: net_services <command> [args]
+
+ commands:
+ init Prepare the host, install and build everything
+ git Create a git user for user over SSH
+ backup [DIR] Do a full backup
+ EOF
+}
+
+case ${1:-} in
+-h | --help | help)
+ usage
+ exit 0
+ ;;
+esac
+
source_env
case ${1:-} in
init) init ;;
git) setup_ssh_git_user ;;
+backup) backup "${2:-}" ;;
*)
- echo "usage: net_services init|git"
+ usage
exit 1
;;
esac