diff --git a/install_newt.sh b/install_newt.sh index ebbebc0..c8c43a7 100644 --- a/install_newt.sh +++ b/install_newt.sh @@ -1,113 +1,205 @@ #!/bin/bash + set -e +SERVICE_NAME="PVE-MGNT" +INSTALL_DIR="/opt/newt" +SYMLINK="${INSTALL_DIR}/newt_latest" +REPO="fosrl/newt" +GITHUB_API_URL="https://api.github.com/repos/${REPO}/releases/latest" + +RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' -RED='\033[0;31m' NC='\033[0m' -REPO="fosrl/newt" -INSTALL_DIR="/opt/newt" -SERVICE_NAME="PVE-MGNT" -SYMLINK="${INSTALL_DIR}/newt_latest" +FORCE_INSTALL=0 -info() { echo -e "${GREEN}[INFO]${NC} $1"; } -warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } -error() { echo -e "${RED}[ERROR]${NC} $1"; } +print_status() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +print_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# Argumente prüfen +for arg in "$@"; do + if [[ "$arg" == "--force" ]]; then + FORCE_INSTALL=1 + fi +done + +check_jq() { + if ! command -v jq >/dev/null 2>&1; then + print_status "jq wird benötigt – versuche Installation..." + if command -v apt >/dev/null 2>&1; then + sudo apt update && sudo apt install -y jq + else + print_error "Bitte installiere jq manuell." + exit 1 + fi + fi +} get_latest_version() { - curl -fsSL "https://api.github.com/repos/${REPO}/releases/latest" | grep -Po '"tag_name": *"\K[^"]+' + local latest_info + latest_info=$(curl -fsSL "$GITHUB_API_URL" 2>/dev/null) + if [ -z "$latest_info" ]; then + print_error "Failed to fetch latest version information" + exit 1 + fi + echo "$latest_info" | jq -r '.tag_name' | sed 's/^v//' +} + +detect_platform() { + local os arch + case "$(uname -s)" in + Linux*) os="linux" ;; + Darwin*) os="darwin" ;; + MINGW*|MSYS*|CYGWIN*) os="windows" ;; + FreeBSD*) os="freebsd" ;; + *) print_error "Unsupported OS: $(uname -s)"; exit 1 ;; + esac + + case "$(uname -m)" in + x86_64|amd64) arch="amd64" ;; + arm64|aarch64) arch="arm64" ;; + armv7l|armv6l) + if [ "$os" = "linux" ]; then + if [ "$(uname -m)" = "armv6l" ]; then + arch="arm32v6" + else + arch="arm32" + fi + else + arch="arm64" + fi ;; + riscv64) + if [ "$os" = "linux" ]; then + arch="riscv64" + else + print_error "RISC-V only on Linux" + exit 1 + fi ;; + *) print_error "Unsupported architecture: $(uname -m)"; exit 1 ;; + esac + + echo "${os}_${arch}" } download_newt() { - version="$1" - arch=$(uname -m) + local version="$1" + local platform="$2" + local url="https://github.com/${REPO}/releases/download/${version}/newt_${platform}" + local dest="${INSTALL_DIR}/newt_${version}" - case "$arch" in - x86_64) file="newt_linux_amd64" ;; - aarch64) file="newt_linux_arm64" ;; - armv7l) file="newt_linux_arm32" ;; - *) error "Nicht unterstützte Architektur: $arch" && exit 1 ;; - esac + print_status "⬇️ Lade $url herunter …" - url="https://github.com/${REPO}/releases/download/${version}/${file}" - target="${INSTALL_DIR}/newt_${version}" + curl -fsSL "$url" -o "$dest" || { + print_error "Download fehlgeschlagen. Prüfe Version/Architektur." + exit 1 + } - mkdir -p "$INSTALL_DIR" - info "⬇️ Lade $url herunter …" - curl -fsSL "$url" -o "$target" || { error "Download fehlgeschlagen."; exit 1; } - - chmod +x "$target" - ln -sf "$target" "$SYMLINK" - info "✅ newt ${version} installiert als ${target}" + chmod +x "$dest" + print_status "✅ newt ${version} installiert als ${dest}" } cleanup_old_versions() { - cd "$INSTALL_DIR" - keep=$(readlink -f newt_latest) - versions=($(ls -1 newt_* | grep -v latest | sort -Vr)) - count=0 - for ver in "${versions[@]}"; do - if [[ "$(readlink -f "$ver")" != "$keep" ]]; then - ((count++)) - if [ "$count" -gt 1 ]; then - info "🧹 Entferne alte Version: $ver" - rm -f "$ver" - fi + print_status "🧹 Bereinige alte Versionen (behalte nur die aktuelle und die vorherige)..." + local keep=2 + local files=($(ls -1t ${INSTALL_DIR}/newt_* 2>/dev/null | grep -v "newt_latest")) + local count=${#files[@]} + + if (( count > keep )); then + for ((i=keep; i "$svc" + cat < /dev/null [Unit] -Description=Newt Client - ${SERVICE_NAME} +Description=newt service After=network.target [Service] -ExecStart=${SYMLINK} --id ${PANGOLIN_ID} --secret ${PANGOLIN_SECRET} --endpoint ${PANGOLIN_ENDPOINT} +ExecStart=${SYMLINK} Restart=always RestartSec=5 +StartLimitIntervalSec=0 [Install] WantedBy=multi-user.target EOF - systemctl daemon-reexec - systemctl daemon-reload - systemctl enable "$SERVICE_NAME" - systemctl start "$SERVICE_NAME" - - info "🛠️ systemd-Dienst ${SERVICE_NAME} eingerichtet und gestartet." + sudo systemctl daemon-reload + sudo systemctl enable "${SERVICE_NAME}" + sudo systemctl restart "${SERVICE_NAME}" + print_status "Systemd Dienst ${SERVICE_NAME} gestartet." } main() { - info "🔧 Starte Installation/Update von newt ..." - version=$(get_latest_version) - version=${version#v} # führendes "v" entfernen, falls vorhanden + print_status "🔧 Starte Installation/Update von newt ..." - info "📦 Neueste Version: ${version}" + check_jq - if [ -f "${INSTALL_DIR}/newt_${version}" ]; then - info "✅ Version ${version} ist bereits installiert." - else - download_newt "$version" - fi + local latest_version + latest_version=$(get_latest_version) + print_status "📦 Neueste Version: v${latest_version}" - cleanup_old_versions - setup_systemd_service + local platform + platform=$(detect_platform) + print_status "Detected platform: ${platform}" - info "🚀 Fertig! newt läuft als systemd-Dienst (${SERVICE_NAME})" + # Install dir erstellen falls nicht vorhanden + sudo mkdir -p "${INSTALL_DIR}" + sudo chown "$(id -u):$(id -g)" "${INSTALL_DIR}" + + if [[ -L "$SYMLINK" ]]; then + current_version=$(readlink "$SYMLINK" | sed -E 's/.*newt_(.*)/\1/') + print_status "Aktuelle Version installiert: $current_version" + else + current_version="" + fi + + if [[ "$current_version" == "$latest_version" ]] && [[ "$FORCE_INSTALL" -eq 0 ]]; then + print_status "newt ist bereits auf dem neuesten Stand. Keine Aktion erforderlich." + exit 0 + fi + + if [[ "$FORCE_INSTALL" -eq 1 ]]; then + print_status "--force erkannt: Erzwinge Neuinstallation." + sudo systemctl stop "${SERVICE_NAME}" || true + fi + + download_newt "$latest_version" "$platform" + + # Symlink neu setzen + ln -sf "${INSTALL_DIR}/newt_${latest_version}" "$SYMLINK" + + cleanup_old_versions + + # Dienst neu einrichten (neu starten, ggf. neu anlegen) + if systemctl list-units --full -all | grep -Fq "${SERVICE_NAME}.service"; then + print_status "Dienst ${SERVICE_NAME} existiert bereits, wird neu gestartet..." + sudo systemctl restart "${SERVICE_NAME}" + else + setup_systemd_service + fi + + print_status "🚀 Fertig! newt läuft als systemd-Dienst (${SERVICE_NAME})" } main "$@"