Configure web panel auth from Linux install user

Этот коммит содержится в:
Виктор
2026-05-06 19:46:35 +09:00
родитель 42a26e09b6
Коммит 7205174924
+38 -45
Просмотреть файл
@@ -2,7 +2,7 @@
set -euo pipefail
# Virtuality Web Panel Installer
# Clean step-by-step installer with readable statuses and log file.
# Clean step-by-step installer with readable statuses, Linux-user auth and log file.
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
WEB_DIR="${REPO_DIR}/web"
@@ -10,9 +10,10 @@ APP_DIR="/opt/virtuality/web"
VENV_DIR="/opt/virtuality/venv"
SERVICE_FILE="/etc/systemd/system/virtuality-web.service"
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=10
TOTAL_STEPS=11
CURRENT_STEP=0
ESC="\033"
@@ -30,10 +31,7 @@ mkdir -p "$LOG_DIR"
timestamp() { date '+%Y-%m-%d %H:%M:%S'; }
line() { printf '%*s\n' 72 '' | tr ' ' '─'; }
log() {
echo "[$(timestamp)] $*" >> "$LOG_FILE"
}
log() { echo "[$(timestamp)] $*" >> "$LOG_FILE"; }
print_header() {
clear 2>/dev/null || true
@@ -44,6 +42,7 @@ print_header() {
echo
echo -e "${GRAY}Лог установки:${RESET} ${LOG_FILE}"
echo -e "${GRAY}Порт панели:${RESET} ${PORT}"
echo -e "${GRAY}Linux auth user:${RESET} ${AUTH_USER}"
echo
}
@@ -54,23 +53,9 @@ step() {
log "STEP ${CURRENT_STEP}/${TOTAL_STEPS}: $*"
}
ok() {
echo -e " ${GREEN}${RESET} $*"
log "OK: $*"
}
warn() {
echo -e " ${YELLOW}!${RESET} $*"
log "WARN: $*"
}
fail() {
echo -e " ${RED}${RESET} $*"
log "ERROR: $*"
echo
echo -e "${RED}${BOLD}Установка остановлена.${RESET} Подробности в логе: ${LOG_FILE}"
exit 1
}
ok() { echo -e " ${GREEN}${RESET} $*"; log "OK: $*"; }
warn() { echo -e " ${YELLOW}!${RESET} $*"; log "WARN: $*"; }
fail() { echo -e " ${RED}${RESET} $*"; log "ERROR: $*"; echo; echo -e "${RED}${BOLD}Установка остановлена.${RESET} Подробности в логе: ${LOG_FILE}"; exit 1; }
run_logged() {
local description="$1"
@@ -83,39 +68,35 @@ run_logged() {
fi
}
service_state() {
systemctl is-active "$1" 2>/dev/null || echo "inactive"
}
require_root() {
if [[ "$EUID" -ne 0 ]]; then
fail "Запусти через sudo: sudo bash scripts/install_web_panel.sh"
fi
}
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"; }
print_header
step "Проверяем права и структуру проекта"
require_root
ok "Права root подтверждены"
if [[ -d "$WEB_DIR" ]]; then
[[ -d "$WEB_DIR" ]] || fail "Не найдена директория web: $WEB_DIR"
ok "Исходники web найдены: $WEB_DIR"
else
fail "Не найдена директория web: $WEB_DIR"
fi
if [[ -f "$WEB_DIR/app.py" ]]; then
[[ -f "$WEB_DIR/app.py" ]] || fail "Не найден web/app.py"
ok "FastAPI entrypoint найден: web/app.py"
else
fail "Не найден web/app.py"
fi
if [[ -f "$WEB_DIR/requirements.txt" ]]; then
[[ -f "$WEB_DIR/requirements.txt" ]] || fail "Не найден web/requirements.txt"
ok "requirements.txt найден"
step "Проверяем Linux-пользователя для входа"
if id "$AUTH_USER" >/dev/null 2>&1; then
ok "Пользователь найден: $AUTH_USER"
else
fail "Не найден web/requirements.txt"
fail "Пользователь $AUTH_USER не найден. Создай его или передай VIRTUALITY_AUTH_USER=username"
fi
if getent shadow "$AUTH_USER" | cut -d: -f2 | grep -Eq '^(!|\*|!!)?$'; then
warn "У пользователя $AUTH_USER может быть заблокирован пароль. Установи пароль: sudo passwd $AUTH_USER"
else
ok "У пользователя $AUTH_USER есть пароль для Linux-auth"
fi
step "Проверяем базовые команды"
for cmd in apt systemctl rsync python3 hostname; do
for cmd in apt systemctl rsync python3 hostname openssl; do
if command -v "$cmd" >/dev/null 2>&1; then
ok "$cmd найден: $(command -v "$cmd")"
else
@@ -127,12 +108,22 @@ step "Обновляем apt cache"
run_logged "apt update выполнен" apt update
step "Устанавливаем системные зависимости"
run_logged "Пакеты Python/venv/pip/rsync установлены" apt install -y python3 python3-venv python3-pip rsync
run_logged "Пакеты Python/venv/pip/rsync установлены" apt install -y python3 python3-venv python3-pip rsync openssl
step "Копируем web-панель в /opt/virtuality"
run_logged "Создана директория /opt/virtuality" mkdir -p /opt/virtuality
run_logged "Файлы панели синхронизированы в $APP_DIR" rsync -a --delete "$WEB_DIR/" "$APP_DIR/"
step "Создаём конфиг авторизации"
SESSION_SECRET="$(openssl rand -hex 32)"
cat > "${APP_DIR}/.env" <<EOF
VIRTUALITY_AUTH_USER=${AUTH_USER}
VIRTUALITY_SESSION_SECRET=${SESSION_SECRET}
EOF
chmod 600 "${APP_DIR}/.env"
ok "Создан ${APP_DIR}/.env"
ok "Вход будет по Linux-пользователю: ${AUTH_USER}"
step "Создаём Python virtualenv"
if [[ -d "$VENV_DIR" ]]; then
warn "Virtualenv уже существует, будет переиспользован: $VENV_DIR"
@@ -160,6 +151,7 @@ RestartSec=3
User=root
Group=root
Environment=PYTHONUNBUFFERED=1
Environment=VIRTUALITY_AUTH_USER=${AUTH_USER}
[Install]
WantedBy=multi-user.target
@@ -199,11 +191,12 @@ echo -e "${GREEN}${BOLD}│${RESET} ${BOLD}Установка Virtuality Web Pan
echo -e "${GREEN}${BOLD}╰────────────────────────────────────────────────────────────╯${RESET}"
echo
echo -e "${BOLD}URL:${RESET} http://${SERVER_IP}:${PORT}"
echo -e "${BOLD}Login:${RESET} ${AUTH_USER} / пароль Linux-пользователя"
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}Следующий шаг: добавить авторизацию и страницу создания VM.${RESET}"
echo -e "${DIM}Следующий шаг: страница создания VM из интерфейса.${RESET}"
line