diff --git a/scripts/freqtrade-lxc-install.sh b/scripts/freqtrade-lxc-install.sh index 4034b18..6bf470e 100644 --- a/scripts/freqtrade-lxc-install.sh +++ b/scripts/freqtrade-lxc-install.sh @@ -76,124 +76,151 @@ detect_resources() { DEFAULT_BRIDGE=$(ip link show 2>/dev/null | grep -oP '(?<=: )vmbr\d+' | head -1 || echo "vmbr0") } -# ── Template auswählen ──────────────────────────────────────────────────────── +# ── Debian 12 Template ──────────────────────────────────────────────────────── prepare_template() { - step "LXC Template auswählen" + step "Debian 12 Template prüfen" + TEMPLATE_FILE=$(pveam list local 2>/dev/null | grep -oP 'debian-12-standard_\S+' | sort -V | tail -1 || true) - # Lokal vorhandene Templates auflisten - local available_local - available_local=$(pveam list local 2>/dev/null | awk 'NR>1{print $1}' | grep -oP '[^/]+\.tar\.(gz|zst|xz)' | sort || true) - - # Default: neuestes Debian 12 - local default_tpl - default_tpl=$(echo "$available_local" | grep -oP 'debian-12-standard_\S+' | sort -V | tail -1 || true) - - if [[ -z "$default_tpl" ]]; then - # Noch nicht heruntergeladen – aus verfügbaren holen + if [[ -z "$TEMPLATE_FILE" ]]; then + info "Nicht lokal vorhanden – lade herunter..." pveam update &>/dev/null || warn "pveam update fehlgeschlagen" - default_tpl=$(pveam available --section system 2>/dev/null | grep -oP 'debian-12-standard_\S+' | sort -V | tail -1 || echo "debian-12-standard_12.7-1_amd64.tar.zst") - fi - - if [[ -n "$available_local" ]]; then - echo -e " ${CYAN}Lokal verfügbare Templates:${NC}" - local i=1 - while IFS= read -r tpl; do - [[ -z "$tpl" ]] && continue - local marker="" - [[ "$tpl" == "$default_tpl" ]] && marker=" ${GREEN}← Standard${NC}" - printf " ${CYAN}%-3s${NC} %s%b -" "$i" "$tpl" "$marker" - ((i++)) - done <<< "$available_local" - echo - echo -ne "${YELLOW} ➜ ${NC}Template (Enter = Standard ${CYAN}${default_tpl}${NC}): " - read -r sel_tpl - if [[ -z "$sel_tpl" ]]; then - TEMPLATE_FILE="$default_tpl" - elif [[ "$sel_tpl" =~ ^[0-9]+$ ]]; then - TEMPLATE_FILE=$(echo "$available_local" | sed -n "${sel_tpl}p") - [[ -z "$TEMPLATE_FILE" ]] && { warn "Ungültige Auswahl, nehme Standard."; TEMPLATE_FILE="$default_tpl"; } - else - TEMPLATE_FILE="$sel_tpl" - fi - else - TEMPLATE_FILE="$default_tpl" - fi - - # Herunterladen falls nicht lokal vorhanden - if ! pveam list local 2>/dev/null | grep -q "$TEMPLATE_FILE"; then - info "Lade Template herunter: $TEMPLATE_FILE" + TEMPLATE_FILE=$(pveam available --section system 2>/dev/null \ + | grep -oP 'debian-12-standard_\S+' | sort -V | tail -1 \ + || echo "debian-12-standard_12.7-1_amd64.tar.zst") + info "Lade: $TEMPLATE_FILE" pveam download local "$TEMPLATE_FILE" || error "Template-Download fehlgeschlagen!" fi TEMPLATE_PATH="local:vztmpl/${TEMPLATE_FILE}" - success "Template: $TEMPLATE_FILE" + success "Template bereit: $TEMPLATE_FILE" } # ── Konfiguration abfragen ───────────────────────────────────────────────────── collect_config() { - step "LXC Konfiguration" - echo -e " ${CYAN}Storages (rootdir-fähig):${NC} ${BOLD}${STORAGES}${NC}" - echo -e " ${YELLOW} ↑ 'local' reicht nicht – braucht z.B. local-lvm${NC}" - echo -e " ${CYAN}Bridges:${NC} ${BRIDGES}\n" - - ask "LXC Container-ID" "$NEXT_ID" - CT_ID="$REPLY" - [[ "$CT_ID" =~ ^[0-9]+$ ]] || error "Muss eine Zahl sein!" - pct status "$CT_ID" &>/dev/null && error "CT-ID $CT_ID existiert bereits!" - - ask "Hostname" "freqtrade" ; CT_HOST="$REPLY" - ask "CPU Kerne" "2" ; CT_CORES="$REPLY" - ask "RAM in MB" "2048" ; CT_RAM="$REPLY" - ask "Swap in MB" "512" ; CT_SWAP="$REPLY" - ask "Disk in GB" "10" ; CT_DISK="$REPLY" - ask "Storage Pool" "$DEFAULT_STORAGE" ; CT_STORAGE="$REPLY" - ask "Bridge" "$DEFAULT_BRIDGE" ; CT_BRIDGE="$REPLY" - ask "Netzwerk (dhcp oder 192.168.1.100/24)" "dhcp" ; CT_IP="$REPLY" + # ── Modus wählen ── + echo -e " +${BOLD}${BLUE} Installationsmodus:${NC}" + echo -e " ${CYAN}1)${NC} ${BOLD}Schnellinstallation${NC} – Standardwerte, nur Passwörter eingeben" + echo -e " ${CYAN}2)${NC} ${BOLD}Erweitert${NC} – alle Einstellungen manuell festlegen" + ask "Modus [1/2]" "1" + local mode="$REPLY" + # Defaults + CT_ID="$NEXT_ID" + CT_HOST="freqtrade" + CT_CORES="2" + CT_RAM="2048" + CT_SWAP="512" + CT_DISK="10" + CT_STORAGE="$DEFAULT_STORAGE" + CT_BRIDGE="$DEFAULT_BRIDGE" + CT_IP="dhcp" CT_GW="" - if [[ "$CT_IP" != "dhcp" ]]; then - ask "Gateway"; CT_GW="$REPLY" + FT_PORT="8080" + PT_PORT="9000" + FB_PORT="8081" + FT_EXCHANGE="binance" + FT_STAKE="USDC" + FT_MAX_TRADES="3" + FT_TIMEFRAME="5m" + FT_API_USER="freqtrader" + FT_TELEGRAM=false + TG_TOKEN="" + TG_CHATID="" + + if [[ "$mode" == "2" ]]; then + # ── Erweitert: alle Fragen ── + step "LXC Konfiguration" + echo -e " ${CYAN}Storages (rootdir-fähig):${NC} ${BOLD}${STORAGES}${NC}" + echo -e " ${YELLOW} ↑ 'local' reicht nicht – braucht z.B. local-lvm${NC}" + echo -e " ${CYAN}Bridges:${NC} ${BRIDGES}\n" + + ask "LXC Container-ID" "$CT_ID" ; CT_ID="$REPLY" + ask "Hostname" "$CT_HOST" ; CT_HOST="$REPLY" + ask "CPU Kerne" "$CT_CORES" ; CT_CORES="$REPLY" + ask "RAM in MB" "$CT_RAM" ; CT_RAM="$REPLY" + ask "Swap in MB" "$CT_SWAP" ; CT_SWAP="$REPLY" + ask "Disk in GB" "$CT_DISK" ; CT_DISK="$REPLY" + ask "Storage Pool" "$CT_STORAGE" ; CT_STORAGE="$REPLY" + ask "Bridge" "$CT_BRIDGE" ; CT_BRIDGE="$REPLY" + ask "Netzwerk (dhcp oder 192.168.1.100/24)" "$CT_IP" ; CT_IP="$REPLY" + if [[ "$CT_IP" != "dhcp" ]]; then + ask "Gateway"; CT_GW="$REPLY" + fi + + step "Freqtrade Konfiguration" + ask "FreqUI Port" "$FT_PORT" ; FT_PORT="$REPLY" + ask "Portainer Port" "$PT_PORT" ; PT_PORT="$REPLY" + ask "Filebrowser Port" "$FB_PORT" ; FB_PORT="$REPLY" + ask "Börse" "$FT_EXCHANGE" ; FT_EXCHANGE="$REPLY" + + echo -e " + ${CYAN}Stake-Währung:${NC} ${BOLD}1)${NC} USDC ${BOLD}2)${NC} USDT ${BOLD}3)${NC} EUR ${BOLD}4)${NC} Eigene" + ask "Auswahl [1-4]" "1" + case "$REPLY" in + 2) FT_STAKE="USDT" ;; + 3) FT_STAKE="EUR" ;; + 4) ask "Stake-Währung eingeben"; FT_STAKE="$REPLY" ;; + *) FT_STAKE="USDC" ;; + esac + + ask "Max. offene Trades" "$FT_MAX_TRADES" ; FT_MAX_TRADES="$REPLY" + ask "Timeframe" "$FT_TIMEFRAME" ; FT_TIMEFRAME="$REPLY" + ask "FreqUI Benutzername" "$FT_API_USER" ; FT_API_USER="$REPLY" + else + # ── Schnellinstallation: CT-ID prüfen ── + step "Schnellinstallation" + echo -e " Alle Standardwerte werden verwendet:\n" + echo -e " CT-ID: ${CYAN}${CT_ID}${NC} | Host: ${CYAN}${CT_HOST}${NC} | ${CYAN}${CT_CORES}${NC} CPU | ${CYAN}${CT_RAM}${NC}MB RAM | ${CYAN}${CT_DISK}${NC}GB" + echo -e " Storage: ${CYAN}${CT_STORAGE}${NC} | Bridge: ${CYAN}${CT_BRIDGE}${NC} | IP: ${CYAN}dhcp${NC}" + echo -e " FreqUI: ${CYAN}:${FT_PORT}${NC} | Stake: ${CYAN}${FT_STAKE}${NC} | Börse: ${CYAN}${FT_EXCHANGE}${NC}\n" + + # Stake-Währung auch im Schnellmodus wählbar + echo -e " ${CYAN}Stake-Währung:${NC} ${BOLD}1)${NC} USDC (Standard) ${BOLD}2)${NC} USDT ${BOLD}3)${NC} EUR" + ask "Auswahl [1-3]" "1" + case "$REPLY" in + 2) FT_STAKE="USDT" ;; + 3) FT_STAKE="EUR" ;; + *) FT_STAKE="USDC" ;; + esac + echo fi - ask_secret "Root-Passwort für den LXC" + # Passwörter – immer abfragen + step "Passwörter" + ask_secret "Root-Passwort für den LXC (mind. 8 Zeichen)" CT_PASS="$REPLY" [[ ${#CT_PASS} -lt 8 ]] && error "Passwort mind. 8 Zeichen!" - step "Freqtrade Konfiguration" - ask "FreqUI Port" "8080" ; FT_PORT="$REPLY" - ask "Portainer Port" "9000" ; PT_PORT="$REPLY" - ask "Filebrowser Port" "8081" ; FB_PORT="$REPLY" - ask "Börse" "binance" ; FT_EXCHANGE="$REPLY" - ask "Stake-Währung" "USDC" ; FT_STAKE="$REPLY" - ask "Max. offene Trades" "3" ; FT_MAX_TRADES="$REPLY" - ask "Timeframe" "5m" ; FT_TIMEFRAME="$REPLY" - ask "FreqUI Benutzername" "freqtrader" ; FT_API_USER="$REPLY" - ask_secret "FreqUI Passwort (mind. 8 Zeichen)" FT_API_PASS="$REPLY" [[ ${#FT_API_PASS} -lt 8 ]] && error "Passwort mind. 8 Zeichen!" - FT_TELEGRAM=false; TG_TOKEN=""; TG_CHATID="" - if confirm "Telegram-Benachrichtigungen?"; then - FT_TELEGRAM=true - ask "Telegram Bot-Token" ; TG_TOKEN="$REPLY" - ask "Telegram Chat-ID" ; TG_CHATID="$REPLY" + # Telegram nur im erweiterten Modus + if [[ "$mode" == "2" ]]; then + if confirm "Telegram-Benachrichtigungen?"; then + FT_TELEGRAM=true + ask "Telegram Bot-Token" ; TG_TOKEN="$REPLY" + ask "Telegram Chat-ID" ; TG_CHATID="$REPLY" + fi fi - # Passwörter base64-kodiert weitergeben (sicher für Heredoc-Transport) + # CT-ID validieren + [[ "$CT_ID" =~ ^[0-9]+$ ]] || error "CT-ID muss eine Zahl sein!" + pct status "$CT_ID" &>/dev/null && error "CT-ID $CT_ID existiert bereits!" + + # Passwörter base64-kodiert weitergeben CT_PASS_B64=$(printf '%s' "$CT_PASS" | base64 -w0) FT_API_PASS_B64=$(printf '%s' "$FT_API_PASS" | base64 -w0) TG_TOKEN_B64=$(printf '%s' "$TG_TOKEN" | base64 -w0) - # Zufällige Secrets JWT_SECRET=$(openssl rand -hex 32) WS_TOKEN=$(openssl rand -hex 16) echo -e "\n${BOLD}${BLUE}══════════════ Zusammenfassung ══════════════${NC}" echo -e " CT ${CYAN}${CT_ID}${NC} | ${CYAN}${CT_HOST}${NC} | ${CYAN}${CT_CORES}${NC}x CPU | ${CYAN}${CT_RAM}${NC}MB RAM | ${CYAN}${CT_DISK}${NC}GB | ${CYAN}${CT_STORAGE}${NC}" echo -e " Netz: ${CYAN}${CT_IP}${NC} via ${CYAN}${CT_BRIDGE}${NC}" - echo -e " FreqUI: ${CYAN}:${FT_PORT}${NC} | Portainer: ${CYAN}:${PT_PORT}${NC} | Filebrowser: ${CYAN}:${FB_PORT}${NC}" + echo -e " FreqUI: ${CYAN}:${FT_PORT}${NC} | Portainer: ${CYAN}:${PT_PORT}${NC} | Filebrowser: ${CYAN}:${FB_PORT}${NC}" echo -e " Börse: ${CYAN}${FT_EXCHANGE}${NC} | Stake: ${CYAN}${FT_STAKE}${NC} | Telegram: ${CYAN}${FT_TELEGRAM}${NC}" echo -e "${BOLD}${BLUE}════════════════════════════════════════════${NC}\n" confirm "Installation starten?" || { info "Abgebrochen."; exit 0; }