Files
Halloween/tools/upload_to_pi.sh
T

108 lines
3.3 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
project_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd -P)
source_dir=$project_dir
pi_user=
pi_host=
remote_dir=
apply=false
install_service=false
usage() {
cat <<'EOF'
Projektdateien per SSH/rsync auf einen Raspberry Pi kopieren.
Aufruf:
bash tools/upload_to_pi.sh --user BENUTZER --host HOST \
--remote-dir /home/BENUTZER/halloween [--source ORDNER] [--install-service] [--apply]
Ohne --apply wird nur der geplante Aufruf angezeigt; es gibt keine Verbindung
zum Pi. --apply legt den Zielordner an und kopiert die Dateien. Alte Dateien
auf dem Pi werden nicht gelöscht.
--install-service richtet nach dem Upload einen systemd-Autostart ein. Dazu
muss die Python-Umgebung auf dem Pi bereits vorbereitet sein; sudo wird dort
benötigt. Ohne --apply wird auch der Dienst nicht installiert.
EOF
}
die() {
printf 'Fehler: %s\n' "$*" >&2
exit 2
}
while (($#)); do
case $1 in
--user|--host|--remote-dir|--source)
(($# >= 2)) || die "Wert für $1 fehlt"
case $1 in
--user) pi_user=$2 ;;
--host) pi_host=$2 ;;
--remote-dir) remote_dir=$2 ;;
--source) source_dir=$2 ;;
esac
shift 2
;;
--apply) apply=true; shift ;;
--install-service) install_service=true; shift ;;
-h|--help) usage; exit 0 ;;
*) die "Unbekanntes Argument: $1" ;;
esac
done
[[ $pi_user =~ ^[a-zA-Z_][a-zA-Z0-9_-]*$ ]] || die 'Gültigen --user angeben'
[[ $pi_host =~ ^[a-zA-Z0-9][a-zA-Z0-9._-]*$ ]] || die 'Gültigen --host angeben (Name oder IPv4-Adresse)'
[[ $remote_dir =~ ^/[a-zA-Z0-9_./-]+$ && $remote_dir != / ]] || die 'Sicheren absoluten --remote-dir angeben'
[[ /$remote_dir/ != *'/../'* && /$remote_dir/ != *'/./'* ]] || die 'Zielpfad darf keine . oder .. Segmente enthalten'
[[ -d $source_dir ]] || die "Quellordner fehlt: $source_dir"
source_dir=$(cd -- "$source_dir" && pwd -P)
if $install_service; then
[[ -f "$source_dir/tools/install_pi_service.sh" ]] || die 'tools/install_pi_service.sh fehlt in der Quelle'
fi
command -v ssh >/dev/null || die 'ssh fehlt lokal'
command -v rsync >/dev/null || die 'rsync fehlt lokal'
target="$pi_user@$pi_host"
excludes=(
--exclude=.git/
--exclude=.venv/
--exclude=__pycache__/
--exclude=data/
--exclude=preview/
--exclude=references/
--exclude=.env
--exclude='*.pem'
--exclude='*.key'
--exclude='*.p12'
--exclude='*.pfx'
)
ssh_cmd=(ssh -o StrictHostKeyChecking=ask "$target" "mkdir -p -- '$remote_dir'")
rsync_cmd=(
rsync -a --delay-updates --human-readable --info=stats2
"${excludes[@]}"
-e 'ssh -o StrictHostKeyChecking=ask'
-- "$source_dir/" "$target:$remote_dir/"
)
service_cmd=(ssh -tt -o StrictHostKeyChecking=ask "$target" "cd -- '$remote_dir' && bash tools/install_pi_service.sh --apply")
printf 'Quelle: %s\nZiel: %s:%s/\n' "$source_dir" "$target" "$remote_dir"
printf 'Ausgelassen: .git, .venv, data, preview, references, __pycache__, .env, Schlüsseldateien\n'
if ! $apply; then
printf '\nVorschau, noch keine Verbindung und keine Übertragung:\n'
printf ' %q' "${ssh_cmd[@]}"; printf '\n'
printf ' %q' "${rsync_cmd[@]}"; printf '\n'
if $install_service; then
printf ' %q' "${service_cmd[@]}"; printf '\n'
fi
printf '\nMit --apply ausführen.\n'
exit 0
fi
"${ssh_cmd[@]}"
"${rsync_cmd[@]}"
printf 'Übertragung abgeschlossen.\n'
if $install_service; then
"${service_cmd[@]}"
fi