Configure web panel auth from Linux install user
Этот коммит содержится в:
@@ -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
|
||||
ok "Исходники web найдены: $WEB_DIR"
|
||||
[[ -d "$WEB_DIR" ]] || fail "Не найдена директория web: $WEB_DIR"
|
||||
ok "Исходники web найдены: $WEB_DIR"
|
||||
[[ -f "$WEB_DIR/app.py" ]] || fail "Не найден web/app.py"
|
||||
ok "FastAPI entrypoint найден: web/app.py"
|
||||
[[ -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: $WEB_DIR"
|
||||
fail "Пользователь $AUTH_USER не найден. Создай его или передай VIRTUALITY_AUTH_USER=username"
|
||||
fi
|
||||
if [[ -f "$WEB_DIR/app.py" ]]; then
|
||||
ok "FastAPI entrypoint найден: web/app.py"
|
||||
if getent shadow "$AUTH_USER" | cut -d: -f2 | grep -Eq '^(!|\*|!!)?$'; then
|
||||
warn "У пользователя $AUTH_USER может быть заблокирован пароль. Установи пароль: sudo passwd $AUTH_USER"
|
||||
else
|
||||
fail "Не найден web/app.py"
|
||||
fi
|
||||
if [[ -f "$WEB_DIR/requirements.txt" ]]; then
|
||||
ok "requirements.txt найден"
|
||||
else
|
||||
fail "Не найден web/requirements.txt"
|
||||
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
|
||||
|
||||
Ссылка в новой задаче
Block a user