157 lines
7.8 KiB
Bash
157 lines
7.8 KiB
Bash
#!/usr/bin/env bash
|
||
# ============================================================
|
||
# PiCopy – Installer
|
||
# https://git.leuschner.dev/Tobias/PiCopy
|
||
#
|
||
# Usage:
|
||
# sudo bash install.sh
|
||
# or one-line:
|
||
# curl -sSL https://git.leuschner.dev/Tobias/PiCopy/raw/branch/main/install.sh | sudo bash
|
||
# ============================================================
|
||
set -euo pipefail
|
||
|
||
INSTALL_DIR="/opt/picopy"
|
||
SERVICE_NAME="picopy"
|
||
PORT=8080
|
||
REPO_RAW="https://git.leuschner.dev/Tobias/PiCopy/raw/branch/main"
|
||
|
||
# ── Farben ───────────────────────────────────────────────────────────────────
|
||
R='\033[0;31m'; G='\033[0;32m'; Y='\033[1;33m'; B='\033[0;34m'; N='\033[0m'
|
||
info() { echo -e "${B}[PiCopy]${N} $1"; }
|
||
ok() { echo -e "${G}[ OK ]${N} $1"; }
|
||
warn() { echo -e "${Y}[ WARN ]${N} $1"; }
|
||
fail() { echo -e "${R}[ FAIL ]${N} $1"; exit 1; }
|
||
|
||
# ── Voraussetzungen ───────────────────────────────────────────────────────────
|
||
[ "$EUID" -eq 0 ] || fail "Bitte als root ausführen: sudo bash install.sh"
|
||
command -v apt-get &>/dev/null || fail "apt-get nicht gefunden (nur Debian/Raspberry Pi OS unterstützt)"
|
||
|
||
echo ""
|
||
echo -e "${B}╔══════════════════════════════════════════╗${N}"
|
||
echo -e "${B}║ PiCopy – Installation ║${N}"
|
||
echo -e "${B}╚══════════════════════════════════════════╝${N}"
|
||
echo ""
|
||
|
||
# ── System-Pakete ─────────────────────────────────────────────────────────────
|
||
info "Systemabhängigkeiten werden installiert..."
|
||
apt-get update -q
|
||
apt-get install -y -q python3 python3-venv python3-pip util-linux rclone \
|
||
exfatprogs dosfstools ntfs-3g
|
||
ok "Systemabhängigkeiten installiert"
|
||
|
||
# ── Verzeichnisse anlegen ─────────────────────────────────────────────────────
|
||
info "Installationsverzeichnis: $INSTALL_DIR"
|
||
mkdir -p "$INSTALL_DIR/logs"
|
||
mkdir -p "$INSTALL_DIR/picopy"
|
||
mkdir -p "$INSTALL_DIR/routes"
|
||
mkdir -p "$INSTALL_DIR/templates"
|
||
|
||
# ── Hilfsfunktion: Datei kopieren oder herunterladen ──────────────────────────
|
||
install_file() {
|
||
local src="$1" # relativer Pfad im Repo / im lokalen Verzeichnis
|
||
local dst="$2" # absoluter Zielpfad
|
||
|
||
if [ -f "./$src" ]; then
|
||
info "Lokale Datei wird verwendet: $src"
|
||
cp "./$src" "$dst"
|
||
else
|
||
info "Datei wird heruntergeladen: $src"
|
||
curl -sSfL "$REPO_RAW/$src" -o "$dst" \
|
||
|| warn "Download fehlgeschlagen: $src (nicht kritisch wenn optional)"
|
||
fi
|
||
}
|
||
|
||
# ── Hauptdateien ──────────────────────────────────────────────────────────────
|
||
install_file "app.py" "$INSTALL_DIR/app.py"
|
||
ok "app.py installiert"
|
||
|
||
install_file "version.txt" "$INSTALL_DIR/version.txt"
|
||
ok "version.txt installiert"
|
||
|
||
install_file "PiCopy_Logo.png" "$INSTALL_DIR/PiCopy_Logo.png"
|
||
ok "Logo installiert"
|
||
|
||
# ── picopy/ Paket ─────────────────────────────────────────────────────────────
|
||
install_file "picopy/__init__.py" "$INSTALL_DIR/picopy/__init__.py"
|
||
install_file "picopy/config.py" "$INSTALL_DIR/picopy/config.py"
|
||
install_file "picopy/state.py" "$INSTALL_DIR/picopy/state.py"
|
||
install_file "picopy/usb.py" "$INSTALL_DIR/picopy/usb.py"
|
||
install_file "picopy/copy_engine.py" "$INSTALL_DIR/picopy/copy_engine.py"
|
||
install_file "picopy/wifi.py" "$INSTALL_DIR/picopy/wifi.py"
|
||
install_file "picopy/wireguard.py" "$INSTALL_DIR/picopy/wireguard.py"
|
||
install_file "picopy/samba.py" "$INSTALL_DIR/picopy/samba.py"
|
||
install_file "picopy/upload.py" "$INSTALL_DIR/picopy/upload.py"
|
||
install_file "picopy/system.py" "$INSTALL_DIR/picopy/system.py"
|
||
ok "picopy/-Paket installiert"
|
||
|
||
# ── routes/ Paket ─────────────────────────────────────────────────────────────
|
||
install_file "routes/__init__.py" "$INSTALL_DIR/routes/__init__.py"
|
||
install_file "routes/copy_routes.py" "$INSTALL_DIR/routes/copy_routes.py"
|
||
install_file "routes/wifi_routes.py" "$INSTALL_DIR/routes/wifi_routes.py"
|
||
install_file "routes/wireguard_routes.py" "$INSTALL_DIR/routes/wireguard_routes.py"
|
||
install_file "routes/upload_routes.py" "$INSTALL_DIR/routes/upload_routes.py"
|
||
install_file "routes/system_routes.py" "$INSTALL_DIR/routes/system_routes.py"
|
||
install_file "routes/browse_routes.py" "$INSTALL_DIR/routes/browse_routes.py"
|
||
ok "routes/-Paket installiert"
|
||
|
||
# ── templates/ ────────────────────────────────────────────────────────────────
|
||
install_file "templates/index.html" "$INSTALL_DIR/templates/index.html"
|
||
ok "Template installiert"
|
||
|
||
# ── Python-Umgebung ───────────────────────────────────────────────────────────
|
||
info "Python venv wird erstellt..."
|
||
python3 -m venv "$INSTALL_DIR/venv"
|
||
"$INSTALL_DIR/venv/bin/pip" install --quiet --upgrade pip
|
||
"$INSTALL_DIR/venv/bin/pip" install --quiet flask pyudev
|
||
ok "Python-Umgebung erstellt"
|
||
|
||
# ── Systemd-Service ───────────────────────────────────────────────────────────
|
||
info "Systemd-Service wird eingerichtet..."
|
||
|
||
if [ -f "./picopy.service" ]; then
|
||
cp picopy.service /etc/systemd/system/picopy.service
|
||
else
|
||
cat > /etc/systemd/system/picopy.service << 'EOF'
|
||
[Unit]
|
||
Description=PiCopy – Automatischer USB-Kopierdienst
|
||
After=network.target
|
||
|
||
[Service]
|
||
Type=simple
|
||
User=root
|
||
WorkingDirectory=/opt/picopy
|
||
ExecStart=/opt/picopy/venv/bin/python /opt/picopy/app.py
|
||
Restart=always
|
||
RestartSec=5
|
||
StandardOutput=journal
|
||
StandardError=journal
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
fi
|
||
|
||
systemctl daemon-reload
|
||
systemctl enable "$SERVICE_NAME"
|
||
systemctl restart "$SERVICE_NAME"
|
||
|
||
# ── Ergebnis ─────────────────────────────────────────────────────────────────
|
||
sleep 3
|
||
if systemctl is-active --quiet "$SERVICE_NAME"; then
|
||
IP=$(hostname -I | awk '{print $1}')
|
||
echo ""
|
||
echo -e "${G}╔══════════════════════════════════════════╗${N}"
|
||
echo -e "${G}║ PiCopy ist bereit! ║${N}"
|
||
echo -e "${G}╚══════════════════════════════════════════╝${N}"
|
||
echo ""
|
||
echo -e " Web-Interface: ${B}http://$IP:$PORT${N}"
|
||
echo ""
|
||
echo " Nützliche Befehle:"
|
||
echo " sudo systemctl status $SERVICE_NAME # Status"
|
||
echo " journalctl -u $SERVICE_NAME -f # Live-Logs"
|
||
echo " sudo systemctl restart $SERVICE_NAME # Neustart"
|
||
echo ""
|
||
else
|
||
fail "PiCopy konnte nicht gestartet werden."$'\n'"Logs: journalctl -u $SERVICE_NAME -n 50"
|
||
fi
|