diff --git a/scripts/install_web_panel.sh b/scripts/install_web_panel.sh index 2a30e00..fb373d3 100644 --- a/scripts/install_web_panel.sh +++ b/scripts/install_web_panel.sh @@ -2,7 +2,7 @@ set -euo pipefail # Virtuality Web Panel Installer -# Clean step-by-step installer with readable statuses, Linux-user auth and log file. +# Auto-detects x86_64 / Raspberry Pi ARM64 / Orange Pi 5 ARM64 / generic ARM64 profile. REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" WEB_DIR="${REPO_DIR}/web" @@ -13,7 +13,9 @@ PORT="${VIRTUALITY_WEB_PORT:-8088}" AUTH_USER="${VIRTUALITY_AUTH_USER:-${SUDO_USER:-viktor}}" LOG_DIR="/var/log/virtuality" LOG_FILE="${LOG_DIR}/install_web_panel_$(date +%Y%m%d_%H%M%S).log" -TOTAL_STEPS=11 +PROFILE_DIR="/var/lib/virtuality/config" +PROFILE_FILE="${PROFILE_DIR}/host_profile.json" +TOTAL_STEPS=12 CURRENT_STEP=0 ESC="\033" @@ -27,7 +29,7 @@ CYAN="${ESC}[36m" BLUE="${ESC}[34m" GRAY="${ESC}[90m" -mkdir -p "$LOG_DIR" +mkdir -p "$LOG_DIR" "$PROFILE_DIR" timestamp() { date '+%Y-%m-%d %H:%M:%S'; } line() { printf '%*s\n' 72 '' | tr ' ' '─'; } @@ -37,7 +39,7 @@ print_header() { clear 2>/dev/null || true echo -e "${CYAN}${BOLD}╭────────────────────────────────────────────────────────────╮${RESET}" echo -e "${CYAN}${BOLD}│${RESET} ${BOLD}Virtuality Web Panel Installer${RESET} ${CYAN}${BOLD}│${RESET}" - echo -e "${CYAN}${BOLD}│${RESET} Панель управления VM, сервисами, сетью и storage pools ${CYAN}${BOLD}│${RESET}" + echo -e "${CYAN}${BOLD}│${RESET} Auto profile: x86 / VPS / Raspberry / Orange Pi 5 ${CYAN}${BOLD}│${RESET}" echo -e "${CYAN}${BOLD}╰────────────────────────────────────────────────────────────╯${RESET}" echo echo -e "${GRAY}Лог установки:${RESET} ${LOG_FILE}" @@ -70,6 +72,7 @@ run_logged() { service_state() { systemctl is-active "$1" 2>/dev/null || echo "inactive"; } require_root() { [[ "$EUID" -eq 0 ]] || fail "Запусти через sudo: sudo bash scripts/install_web_panel.sh"; } +json_value() { python3 -c 'import json,sys; print(json.load(open(sys.argv[1])).get(sys.argv[2], ""))' "$PROFILE_FILE" "$1" 2>/dev/null || true; } print_header @@ -83,6 +86,23 @@ ok "FastAPI entrypoint найден: web/app.py" [[ -f "$WEB_DIR/requirements.txt" ]] || fail "Не найден web/requirements.txt" ok "requirements.txt найден" +step "Автоматически определяем профиль сборки" +if [[ -x "${REPO_DIR}/scripts/detect_host_profile.sh" ]]; then + PROFILE="$(${REPO_DIR}/scripts/detect_host_profile.sh 2>>"$LOG_FILE" | tail -n1)" +else + bash "${REPO_DIR}/scripts/detect_host_profile.sh" >>"$LOG_FILE" 2>&1 || true + PROFILE="$(json_value profile)" +fi +[[ -n "$PROFILE" ]] || PROFILE="x86_64" +ARCH="$(json_value arch)" +MODEL="$(json_value model)" +LABEL="$(json_value label)" +PACKAGE_PROFILE="$(json_value package_profile)" +ok "Профиль: ${LABEL:-$PROFILE}" +ok "Архитектура: ${ARCH:-unknown}" +ok "Модель: ${MODEL:-unknown}" +ok "Конфиг профиля: $PROFILE_FILE" + step "Проверяем Linux-пользователя для входа" if id "$AUTH_USER" >/dev/null 2>&1; then ok "Пользователь найден: $AUTH_USER" @@ -107,12 +127,30 @@ done step "Обновляем apt cache" run_logged "apt update выполнен" apt update -step "Устанавливаем системные зависимости" -run_logged "Пакеты Python/venv/pip/rsync/nftables установлены" apt install -y python3 python3-venv python3-pip rsync openssl nftables +step "Устанавливаем системные зависимости под выбранную сборку" +COMMON_PACKAGES=(python3 python3-venv python3-pip rsync openssl nftables) +X86_PACKAGES=(qemu-system-x86 virtinst libvirt-daemon-system libvirt-clients bridge-utils) +ARM_PACKAGES=(qemu-system-arm qemu-efi-aarch64 virtinst libvirt-daemon-system libvirt-clients bridge-utils cloud-image-utils) +PACKAGES=("${COMMON_PACKAGES[@]}") +case "$PACKAGE_PROFILE" in + raspberry|orangepi5|arm64) + PACKAGES+=("${ARM_PACKAGES[@]}") + ;; + *) + PACKAGES+=("${X86_PACKAGES[@]}") + ;; +esac +run_logged "Системные пакеты установлены для профиля ${PACKAGE_PROFILE:-x86}" apt install -y "${PACKAGES[@]}" step "Копируем web-панель в /opt/virtuality" run_logged "Создана директория /opt/virtuality" mkdir -p /opt/virtuality run_logged "Файлы панели синхронизированы в $APP_DIR" rsync -a --delete "$WEB_DIR/" "$APP_DIR/" +run_logged "Конфиг профиля доступен web-панели" mkdir -p "$PROFILE_DIR" +if [[ -f "$PROFILE_FILE" ]]; then + ok "Профиль уже сохранён: $PROFILE_FILE" +else + warn "Профиль не найден после детекта, будет создан web-панелью при старте" +fi step "Создаём конфиг авторизации" SESSION_SECRET="$(openssl rand -hex 32)" @@ -192,11 +230,13 @@ echo -e "${GREEN}${BOLD}╰───────────────── echo echo -e "${BOLD}URL:${RESET} http://${SERVER_IP}:${PORT}" echo -e "${BOLD}Login:${RESET} ${AUTH_USER} / пароль Linux-пользователя" +echo -e "${BOLD}Profile:${RESET} ${LABEL:-$PROFILE}" +echo -e "${BOLD}Arch:${RESET} ${ARCH:-unknown}" echo -e "${BOLD}Service:${RESET} virtuality-web.service" echo -e "${BOLD}Status:${RESET} systemctl status virtuality-web --no-pager" echo -e "${BOLD}Logs:${RESET} journalctl -u virtuality-web -f" echo -e "${BOLD}Install log:${RESET} ${LOG_FILE}" echo line -echo -e "${DIM}Следующий шаг: настройка сети /network и создание VM.${RESET}" +echo -e "${DIM}Следующий шаг: /host для проверки профиля, /network для NAT, /vm/create для VM.${RESET}" line