diff options
| -rwxr-xr-x | tools/net_services | 100 |
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 |
