diff --git a/README.md b/README.md index ed72360..1db196c 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,16 @@ # Virtuality -**Virtuality** — лёгкая серверная платформа виртуализации на базе **KVM**, **QEMU**, **libvirt**, **Cockpit** и собственной web-панели. +**Virtuality** — простая замена Proxmox для дома и малого офиса. Один сервер, виртуальные машины и понятная панель в браузере на русском языке. Внутри — проверенные KVM, QEMU и libvirt, снаружи — интерфейс, в котором не нужна командная строка. -Цель проекта — собрать понятную, компактную и расширяемую систему для управления виртуальными машинами, ISO-образами, NAT/bridge-сетью, пробросом портов, диагностикой, web-console/noVNC, backup/snapshot-функциями и будущей кластеризацией. +Текущая версия: **0.11.0** (файл `VERSION`, журнал изменений — `updates/versions.json`). -> Текущий статус: версия 0.10 — код панели покрыт тестами, есть установочный ISO-образ. Уже есть one-command установка, автоопределение профиля хоста, web-панель, авторизация через Linux-пользователя, ISO-менеджер, создание VM из интерфейса, журнал операций, NAT Router для VPS/ARM edge nodes и port forwarding. +Что умеет: ---- - -## Поддерживаемые профили хоста - -Virtuality автоматически определяет профиль сборки во время установки: - -```text -x86_64 # обычный сервер, домашний сервер, VPS -raspberry-arm64 # Raspberry Pi ARM64 edge node -orangepi5-arm64 # Orange Pi 5 / RK3588 ARM64 edge node -generic-arm64 # другая ARM64-плата -``` - -Профиль сохраняется здесь: - -```text -/var/lib/virtuality/config/host_profile.json -``` - -В web-панели профиль виден на странице: - -```text -/host -``` - -Для ARM64-плат правильный сценарий — **ARM64-гости**, NAT-сеть и позже cloud-image/cloud-init шаблоны. x86_64 ISO на Raspberry/Orange Pi не являются целевым режимом. +- ставится с готового ISO-образа, как Proxmox: три экрана установщика — и через несколько минут панель открыта в браузере; +- создаёт машины из установочных ISO (в том числе Windows 11) и за минуту — из готовых облачных образов Ubuntu, Debian и Alpine; +- снимки, резервные копии, клонирование, увеличение диска, спящий режим; +- сеть машин «из коробки»: отдельная сеть NAT с постоянными адресами и пробросом портов или ваша домашняя сеть через мост; +- экран машины прямо в браузере, HTTPS для панели, автообновления со стабильным каналом. ![Обзор](docs/screenshots/dashboard.png) @@ -43,41 +22,84 @@ generic-arm64 # другая ARM64-плата |---|---| | ![Сеть](docs/screenshots/network.png) | ![Тёмная тема](docs/screenshots/dashboard-dark.png) | ---- +| Мастер настройки: установка | Мастер настройки: сеть машин | +|---|---| +| ![Мастер, установка](docs/screenshots/wizard-install.png) | ![Мастер, сеть](docs/screenshots/wizard-network.png) | -## Установка с ISO-образа +| Каталог готовых систем | Настройки | +|---|---| +| ![Каталог](docs/screenshots/catalog.png) | ![Настройки](docs/screenshots/settings.png) | -Для установки на «голое» железо собирается загрузочный ISO на базе чистого Ubuntu Server 26.04 LTS: установщик спрашивает только сеть, диск и пользователя, а при первой загрузке нода настраивается сама. +| Снимки | Резервные копии | +|---|---| +| ![Снимки](docs/screenshots/snapshots.png) | ![Резервные копии](docs/screenshots/backups.png) | -```bash -make iso # dist/virtuality-<версия>-ubuntu-26.04-amd64.iso -make iso ARCH=arm64 -``` - -Подробно: [`docs/IMAGE.md`](docs/IMAGE.md). +| Вход | На телефоне | +|---|---| +| ![Вход](docs/screenshots/login.png) | ![Мобильная версия](docs/screenshots/dashboard-mobile.png) | --- -## Быстрая установка одной командой +## Содержание -Одна команда работает и под `root`, и под обычным пользователем с `sudo`: +- [Установка](#установка) + - [Способ 1: установочный ISO](#способ-1-установочный-iso) + - [Способ 2: одна команда на готовый сервер](#способ-2-одна-команда-на-готовый-сервер) + - [Способ 3: вручную](#способ-3-вручную) +- [Первая загрузка и мастер настройки](#первая-загрузка-и-мастер-настройки) +- [Возможности](#возможности) +- [Настройки](#настройки) +- [Команда virtuality-ctl](#команда-virtuality-ctl) +- [Обновления и откат](#обновления-и-откат) +- [Удаление](#удаление) +- [Если что-то не работает](#если-что-то-не-работает) +- [Где что лежит](#где-что-лежит) +- [Разработка](#разработка) + +Подробные документы: [требования](docs/REQUIREMENTS.md) · [установочный образ](docs/IMAGE.md) · [первая машина](docs/FIRST_VM.md) · [архитектура](docs/ARCHITECTURE.md) · [планы](docs/ROADMAP.md). + +--- + +## Установка + +Перед установкой проверьте [требования](docs/REQUIREMENTS.md): процессор x86_64 с включённой виртуализацией (Intel VT-x / AMD-V), от 4 ГБ памяти, проводная сеть. + +### Способ 1: установочный ISO + +Самый простой путь для «голого» сервера или старого компьютера. Образ собирается из чистого Ubuntu Server 26.04 LTS; установщик спрашивает только сеть, диск и пользователя. + +Где взять образ: + +- **GitHub Actions.** Откройте вкладку Actions репозитория → workflow **Build ISO image** → последний успешный запуск → раздел Artifacts → `virtuality-iso-amd64` (или `virtuality-iso-arm64`). Внутри архива — `.iso` и файл `.sha256`. Артефакты хранятся 30 дней; новый образ собирается при каждом выпуске (тег `vX.Y.Z`), запустить сборку вручную можно кнопкой Run workflow. +- **Собрать самому** на любой Linux-машине (root не нужен): + + ```bash + sudo apt install -y xorriso git curl python3-pip + git clone https://github.com/viktor138irk/virtuality.git + cd virtuality + make iso # dist/virtuality-0.11.0-ubuntu-26.04-amd64.iso + ``` + +Дальше: записать образ на флешку (Rufus, balenaEtcher или `dd`), загрузиться с неё, выбрать **Установить Virtuality**, ответить на три экрана установщика и дождаться перезагрузки. Через минуту после неё панель уже открывается в браузере — адрес показан на экране сервера. Все подробности, параметры сборки и полностью автоматическая установка — в [docs/IMAGE.md](docs/IMAGE.md). + +### Способ 2: одна команда на готовый сервер + +Подходит для уже установленного Ubuntu Server 24.04 / 26.04 или Debian 13. Работает и под `root`, и под обычным пользователем с `sudo`: ```bash curl -fsSL https://raw.githubusercontent.com/viktor138irk/virtuality/main/install.sh | bash ``` -Как выбирается пользователь для входа в web-панель: +Скрипт проверит требования, поставит пакеты KVM/QEMU/libvirt, команду `vhealth` и панель, а в конце покажет адрес панели. Логин — тот пользователь, от которого запущена установка (через `sudo` — ваш пользователь, под `root` — `root`); пароль — его пароль Linux. Если пароль ещё не задан: `sudo passwd <пользователь>`. + +Переменные окружения, которые понимает `install.sh`: ```text -Если запуск под root → login: root -Если запуск через sudo → login: текущий sudo-пользователь -Если задан VIRTUALITY_USER → login: указанный Linux-пользователь -``` - -Принудительно выбрать пользователя: - -```bash -curl -fsSL https://raw.githubusercontent.com/viktor138irk/virtuality/main/install.sh | VIRTUALITY_USER= bash +VIRTUALITY_USER=admin # какой Linux-пользователь входит в панель (будет создан, если его нет) +VIRTUALITY_WEB_PORT=8089 # порт панели (по умолчанию 8088) +VIRTUALITY_AUTO_UPDATE=0 # не включать ночное автообновление +VIRTUALITY_BRANCH=main # ветка репозитория +VIRTUALITY_INSTALL_VERBOSE=1 # показывать вывод команд вместо спиннера ``` Пример: @@ -86,363 +108,227 @@ curl -fsSL https://raw.githubusercontent.com/viktor138irk/virtuality/main/instal curl -fsSL https://raw.githubusercontent.com/viktor138irk/virtuality/main/install.sh | VIRTUALITY_USER=admin bash ``` -Установка с авторизацией под `root`: - -```bash -curl -fsSL https://raw.githubusercontent.com/viktor138irk/virtuality/main/install.sh | VIRTUALITY_USER=root bash -``` - -Если пароль выбранного Linux-пользователя не задан: - -```bash -sudo passwd -``` - -Для root: - -```bash -passwd root -``` - ---- - -## Что уже есть - -- универсальная one-command установка через `install.sh`; -- автоопределение профиля хоста: x86_64, Raspberry Pi ARM64, Orange Pi 5 ARM64, generic ARM64; -- установка разных пакетных наборов под x86 и ARM64; -- красивый пошаговый installer с live-status и логами; -- preflight-проверка системных требований; -- установка KVM/QEMU/libvirt; -- установка Cockpit и Cockpit Machines; -- рабочая директория `/opt/virtuality/source`; -- libvirt storage pools `virtuality-images` и `virtuality-iso`; -- firewall-правила для SSH, Cockpit, VNC и web-панели; -- безопасная ручная настройка bridge `br0` через `netplan try`; -- NAT Router `virtuality-nat` для VPS/ARM edge nodes; -- port forwarding через nftables; -- автоматическое определение IP VM для проброса портов; -- healthcheck одной командой `vhealth`; -- консольный dashboard для физического монитора; -- web-панель Virtuality на FastAPI; -- авторизация web-панели через системного Linux-пользователя; -- `/host` — профиль хоста и проверки готовности; -- `/network` — NAT, DHCP leases, port forwarding, nftables preview; -- `/iso` — ISO-менеджер; -- `/operations` — журнал фоновых операций; -- список VM; -- управление VM: Start, Shutdown, Reboot, Power off, Autostart on/off, Delete VM with disks; -- создание VM из web-интерфейса; -- выбор сетевого режима при создании VM: `virtuality-nat` или `br0`; -- прогресс создания VM и live-лог `virt-install`; -- страница деталей VM: `dominfo`, VNC display, IP, диски, сетевые интерфейсы. - ---- - -## Системные требования - -Минимально для x86_64 тестового стенда: - -```text -CPU: 2 ядра с Intel VT-x / AMD-V -RAM: 4 GB -/: минимум 8 GB свободно -/var/lib: минимум 20 GB свободно -OS: Ubuntu Server 26.04 / 24.04 LTS или Debian 13 -Network: один проводной интерфейс -``` - -Рекомендуемо для x86_64: - -```text -CPU: 4+ ядра -RAM: 16+ GB -Storage: 100+ GB SSD/NVMe под /var/lib/virtuality -Network: 1 Gbit/s+ -OS: Ubuntu Server 26.04 LTS -``` - -ARM64 edge nodes: - -```text -Raspberry Pi 4/5 ARM64: желательно 8 GB RAM -Orange Pi 5 ARM64: желательно 8/16/32 GB RAM и NVMe -Гости: ARM64 Linux VM -Сеть: virtuality-nat по умолчанию -``` - -Подробнее: [`docs/REQUIREMENTS.md`](docs/REQUIREMENTS.md) - ---- - -## Порты - -```text -Cockpit: https://SERVER_IP:9090 -Virtuality UI: http://SERVER_IP:8088 -VNC: 5900-5999/tcp -SSH: 22/tcp -``` - -Изменить порт web-панели: - -```bash -curl -fsSL https://raw.githubusercontent.com/viktor138irk/virtuality/main/install.sh | VIRTUALITY_WEB_PORT=8089 bash -``` - -Для VPS/ARM NAT-сценария входящие сервисы VM открываются через port forwarding в разделе `/network`. - ---- - -## Директории - -```text -/opt/virtuality/source # исходники проекта из GitHub -/opt/virtuality/web # установленная web-панель -/opt/virtuality/venv # Python virtualenv web-панели -/opt/virtuality/virtuality.env # базовый env ноды -/var/lib/virtuality/config # конфиги Virtuality -/var/lib/virtuality/config/host_profile.json -/var/lib/virtuality/iso # ISO-образы -/var/lib/virtuality/images # qcow2-диски VM -/var/lib/virtuality/network # port_forwards.json -/var/lib/virtuality/backups # backups -/var/log/virtuality # логи установки и диагностики -/var/log/virtuality/operations # JSON/log фоновых операций -/var/lib/virtuality/config/web.env # настройки ноды: порт, пользователь, автообновление -/var/lib/virtuality/disk-images # загруженные образы дисков -/etc/virtuality/nftables/virtuality.nft # nftables-правила Virtuality -``` - ---- - -## Диагностика - -```bash -sudo vhealth -``` - -Дополнительно: - -```bash -cat /var/lib/virtuality/config/host_profile.json -systemctl status virtuality-web --no-pager -journalctl -u virtuality-web -n 120 --no-pager -virsh list --all -virsh pool-list --all -virsh net-list --all -virsh net-dhcp-leases virtuality-nat -ip -br a -ip route -``` - ---- - -## Web-панель - -URL: - -```text -http://SERVER_IP:8088 -``` - -Основные разделы: - -```text -/ # дашборд -/host # профиль хоста и проверки -/iso # ISO-менеджер -/network # NAT Router и проброс портов -/operations # журнал операций -/vm/create # создание VM -``` - -Переустановка web-панели: +При первом входе в панель откроется мастер настройки — тот же, что после установки с ISO. + +### Способ 3: вручную + +Если хочется видеть каждый шаг. Всё делается от `root` или через `sudo`: ```bash +sudo mkdir -p /opt/virtuality +sudo git clone https://github.com/viktor138irk/virtuality.git /opt/virtuality/source cd /opt/virtuality/source -sudo bash scripts/install_web_panel.sh +sudo bash install_virtuality_node.sh # пакеты KVM/QEMU/libvirt, пулы, firewall +sudo bash scripts/install_healthcheck_command.sh # команда sudo vhealth +sudo VIRTUALITY_AUTH_USER=admin bash scripts/install_web_panel.sh # панель и virtuality-ctl ``` -Статус: +`install_web_panel.sh` копирует панель в `/opt/virtuality/web`, создаёт virtualenv, ставит `virtuality-ctl` и через него — systemd-юниты и правила firewall. Переменные: `VIRTUALITY_AUTH_USER` (пользователь для входа), `VIRTUALITY_WEB_PORT` (порт), `VIRTUALITY_AUTO_UPDATE` (0/1). Повторный запуск скрипта обновляет панель, сохраняя настройки. -```bash -systemctl status virtuality-web --no-pager -``` +--- -Логи: +## Первая загрузка и мастер настройки -```bash -journalctl -u virtuality-web -f -``` +### Что происходит после установки с ISO -Вход: +После перезагрузки запускается `virtuality-firstboot.service` (`scripts/virtuality_firstboot.sh`). Порядок шагов выбран так, чтобы вы как можно раньше увидели, что происходит: + +1. **Панель управления** — ставится офлайн из Python-колёс, упакованных в образ, и сразу запускается. Открывайте `http://адрес-сервера:8088` — мастер покажет ход остальных шагов прямо в браузере. +2. **Подключение к интернету** — ожидание сети. Если кабель не подключён, мастер напишет об этом и продолжит сам, как только интернет появится. +3. **KVM, QEMU и libvirt** — самый долгий шаг, обычно 5–15 минут: пакеты ставятся из репозиториев Ubuntu, мастер показывает, какой пакет скачивается или настраивается. +4. **Инструменты диагностики** — команда `vhealth`. +5. **Завершение** — `virtuality-ctl reconfigure`: юниты, firewall, перезапуск панели. + +Ход установки пишется в `/var/lib/virtuality/config/setup.json` и в `/var/log/virtuality/firstboot.log`. Если какой-то шаг упал (например, отвалилась сеть), systemd перезапускает скрипт через минуту, и он продолжает с первого незавершённого шага. На экране сервера (tty) всё это время показана подсказка, а после завершения — адрес панели и логин. + +Логин в панель — пользователь, созданный в установщике Ubuntu; пароль — его пароль. + +### Мастер настройки + +Мастер (`/setup`) открывается при первом входе в панель — и после ISO, и после `install.sh`. Каждый шаг можно пропустить, а весь мастер — запустить заново из раздела «Настройки». + +| Шаг | Что делает | +|---|---| +| **Установка** | Показывает ход первой загрузки (только после ISO). | +| **Сервер** | Проверяет процессор, память, диск и доступность KVM; задаёт часовой пояс. | +| **Администратор** | Смена пароля пользователя панели (он же пароль SSH). | +| **Доступ** | HTTPS с сертификатом сервера (панель на порту 8443, с 8088 — перенаправление) или обычный HTTP; порт. | +| **Сеть машин** | **Отдельная сеть (NAT)** — машины получают адреса 192.168.100.x, работает везде. **Домашняя сеть (мост)** — машины становятся устройствами вашей сети; сервер сам перестроит сеть в мост `br0`, а если панель не ответит за 2 минуты — вернёт всё как было. | +| **Хранилище** | Отдать пустой диск (от 16 ГБ) под машины: он форматируется и монтируется в `/var/lib/virtuality`. Или оставить системный диск. | +| **Обновления** | Автоматически ночью (только выпущенные версии) или вручную; канал: стабильный или ранний доступ. | +| **Готово** | Сводка; настройки применяются, при смене адреса панель перезапускается и открывается по новому. | + +--- + +## Возможности + +Разделы панели: **Обзор**, **Создать машину**, **Образы ОС**, **Сеть и доступ**, **Резервные копии**, **Задачи**, **Журналы**, **Обновления**, **Сервер**, **Настройки**, **Помощь**. + +**Машины** + +- Создание из установочного ISO: три шага — название и система, мощность (готовые профили «Мини», «Стандарт», «Мощная» или свои значения), сеть. +- Тип системы для ISO: Linux, **Windows 11 / Server 2025** (UEFI и TPM 2.0 включаются сами), Windows 10 / Server 2019–2022, другая. Для Windows подбираются диск SATA и сетевая карта Intel — драйверы не нужны. +- Создание из готового образа за минуту: образ конвертируется в qcow2, диск увеличивается до нужного размера, а cloud-init настраивает первый вход — пользователя, пароль и/или SSH-ключ. Пароль хранится только как хеш. При первой загрузке в машину ставится гостевой агент, поэтому панель видит её адрес в любой сети и выключает её корректно. +- Запуск, выключение, перезагрузка, принудительное выключение, автозапуск, удаление вместе с дисками. +- Пауза и **спящий режим** (память сохраняется на диск сервера, после запуска машина продолжает с того же места). +- Изменение процессора и памяти, порядок загрузки, привод CD/DVD (вставить или извлечь образ). +- **Увеличение диска**, **клонирование** (точная копия с новым именем и своим адресом), заметки (название и описание), живая нагрузка процессора и памяти. +- **Экран машины в браузере** (noVNC). VNC наружу не открыт: консоль доступна только через панель. + +**Снимки и копии** + +- **Снимки** — точки восстановления внутри диска машины, до 8 на машину. У работающей машины в снимок попадает и память. Вернуться или удалить — одной кнопкой. +- **Резервные копии** — полная копия настроек и всех дисков в `/var/lib/virtuality/backups/<машина>/<дата>/`. Восстановление под тем же или новым названием; копию можно делать и по расписанию из командной строки. + +**Образы ОС** + +- Загрузка ISO и образов дисков перетаскиванием (с прогрессом и скоростью), поддержка `.qcow2`, `.img`, `.raw`, сжатых `.img.xz` и архивов. +- **Скачивание по ссылке** — сервер качает файл сам, в фоне. +- **Каталог готовых систем** — официальные облачные образы Ubuntu Server 26.04 LTS и 24.04 LTS, Debian 13, Alpine Linux 3.23 с проверкой контрольных сумм. + +**Сеть** + +- Сеть **NAT** `virtuality-nat` (192.168.100.0/24): каждая машина получает **постоянный адрес** по имени, поэтому пробросы портов не ломаются после перезагрузок. +- **Проброс портов** из списка готовых сервисов (SSH, сайт, RDP, Minecraft, VPN и другие) или любой порт и диапазон; проверка правила одной кнопкой; правила переживают перезагрузку сервера. +- **Домашняя сеть через мост** `br0` с автооткатом, если сеть пропала. + +**Сервер** + +- Мастер настройки и страница «Настройки». +- **HTTPS** для панели с сертификатом сервера и перенаправлением с HTTP. +- **Обновления** из панели или автоматически ночью, **стабильный канал** (только выпущенные версии) и ранний доступ, откат на предыдущую версию. +- Задачи с прогрессом и журналом, журналы служб, диагностика `vhealth`, отчёт для поддержки, архив настроек. +- Светлая и тёмная темы, работает на телефоне, не требует доступа в интернет для самой панели. + +Как сделать первую машину — в [docs/FIRST_VM.md](docs/FIRST_VM.md). + +--- + +## Настройки + +Страница **Настройки** (`/settings`) — всё то же, что в мастере, плюс управление сервером: + +- **Доступ к панели** — HTTPS или HTTP, порт. После применения панель перезапускается и открывается по новому адресу. +- **Пароль** — смена пароля пользователя панели (он же пароль Linux и SSH). +- **Сеть машин** — переключение между NAT и домашней сетью (мост `br0`), возврат прежней сети, проверка сети NAT. +- **Хранилище** — подключить пустой диск под машины. +- **Время** — часовой пояс сервера (по нему показываются журналы и час ночного обновления). +- **Обновления** — автообновление и канал (стабильный / ранний доступ). +- **Сервер** — скачать архив настроек, собрать отчёт для поддержки, перезагрузить или выключить сервер (машины выключаются корректно). +- **Мастер настройки** — пройти все шаги заново. + +Настройки ноды хранятся в `/var/lib/virtuality/config/web.env` и не сбрасываются обновлениями: ```text -Login: выбранный Linux-пользователь -Pass: пароль этого Linux-пользователя +VIRTUALITY_WEB_PORT=8088 # порт HTTP +VIRTUALITY_TLS=1 # 1 — HTTPS включён +VIRTUALITY_TLS_PORT=8443 # порт HTTPS +VIRTUALITY_WEB_HOST=0.0.0.0 # 127.0.0.1, если панель стоит за reverse proxy +VIRTUALITY_AUTH_USER=admin # Linux-пользователь для входа +VIRTUALITY_AUTO_UPDATE=1 # 0 — без ночного автообновления +VIRTUALITY_UPDATE_CHANNEL=stable # stable — выпущенные версии, main — все изменения +VIRTUALITY_SOURCE_DIR=/opt/virtuality/source +``` + +Менять их руками не нужно: `sudo virtuality-ctl set КЛЮЧ=ЗНАЧЕНИЕ` сохраняет значение и сразу применяет его. + +--- + +## Команда virtuality-ctl + +`virtuality-ctl` ставится в `/usr/local/bin` вместе с панелью; панель сама вызывает его для всех действий с сервером, так что из терминала можно сделать то же самое. Запускается от `root`: + +```text +sudo virtuality-ctl status # что установлено, порты, адрес панели +sudo virtuality-ctl url # адрес панели +sudo virtuality-ctl reconfigure # пересоздать systemd-юниты из web.env и перезапустить панель +sudo virtuality-ctl set KEY=VALUE ... # изменить настройку в web.env и применить (например set VIRTUALITY_TLS=1) +sudo virtuality-ctl passwd [USER] # сменить пароль пользователя панели +sudo virtuality-ctl timezone Europe/Moscow # часовой пояс сервера +sudo virtuality-ctl power reboot|poweroff # перезагрузить или выключить сервер (машины выключаются корректно) +sudo virtuality-ctl backup-config [FILE] # архив настроек ноды и описаний машин +sudo virtuality-ctl restore-config FILE # восстановить настройки из архива +sudo virtuality-ctl rollback # вернуть предыдущую версию панели +sudo virtuality-ctl maintenance # ежедневное обслуживание (запускается таймером) +sudo virtuality-ctl bridge [dhcp|static] # мост br0 с автооткатом через 2 минуты +sudo virtuality-ctl bridge-confirm # подтвердить новую сеть +sudo virtuality-ctl bridge-revert # вернуть прежнюю сеть +sudo virtuality-ctl storage-use /dev/sdX # отдать пустой диск под /var/lib/virtuality +sudo virtuality-ctl support-bundle [FILE] # отчёт для поддержки +sudo virtuality-ctl uninstall [--purge] [--yes] # удалить Virtuality ``` --- -## Сеть: Bridge и NAT Router +## Обновления и откат -### Bridge br0 - -Подходит для домашнего/офисного сервера, где VM должны получать IP из локальной сети. - -По умолчанию one-command установщик **не включает `br0` автоматически**, чтобы не уронить SSH-сессию. - -Сначала нужно посмотреть сетевой интерфейс: - -```bash -ip -br a -ip route -``` - -Затем запустить bridge setup, например для `enp2s0`: - -```bash -cd /opt/virtuality/source -sudo bash scripts/setup_bridge_br0.sh enp2s0 static -``` - -Ожидаемый результат: - -```text -enp2s0 UP -br0 UP SERVER_IP/24 -default via GATEWAY dev br0 -``` - -### Virtuality NAT Router - -Подходит для VPS, Raspberry Pi, Orange Pi 5 и других ARM64 edge nodes. - -Схема: - -```text -Интернет / LAN - ↓ -Хост Virtuality - ↓ -virtuality-nat / virbr100 - ↓ -VM 192.168.100.x -``` - -Создать или починить NAT-сеть можно в web-панели: - -```text -/network → Создать / починить NAT-сеть -``` - -Параметры по умолчанию: - -```text -Network: virtuality-nat -Bridge: virbr100 -Subnet: 192.168.100.0/24 -Gateway: 192.168.100.1 -DHCP: 192.168.100.50–192.168.100.200 -``` - -Проброс порта добавляется в `/network`. IP VM определяется автоматически через `virsh domifaddr`, а если не получилось — через DHCP leases и MAC-адрес VM. - -Пример SSH-проброса: - -```text -VM: ubuntu-test -Внешний порт сервера: 2222 -Порт внутри VM: 22 -Протокол: tcp -``` - -Подключение: - -```bash -ssh user@SERVER_IP -p 2222 -``` +- **Из панели**: раздел **Обновления** → «Проверить сейчас» → «Обновить». Машины во время обновления продолжают работать. Что изменилось — видно на той же странице. +- **Автоматически**: таймер `virtuality-auto-update.timer` проверяет обновления каждую ночь около 4:00 по времени сервера. Включается и выключается в «Настройках» или командой `sudo virtuality-ctl set VIRTUALITY_AUTO_UPDATE=0`. +- **Каналы**: `stable` — только выпущенные версии (последний тег `vX.Y.Z`; пока тегов нет, стабильный канал следует ветке `main`), `main` — все изменения ветки `main`. Нода никогда не откатывается на более старую версию сама. +- **Вручную из терминала**: `sudo bash /opt/virtuality/source/scripts/apply_github_update.sh` — тот же сценарий, что и в панели (git fetch, при недоступности git — ZIP с GitHub, затем `scripts/install_web_panel.sh` и перезапуск панели). Журнал: `/var/log/virtuality/update.log`. +- **Откат**: перед каждым обновлением предыдущая версия панели сохраняется в `/opt/virtuality/web.prev`. Если новая версия не запустилась: `sudo virtuality-ctl rollback`. --- -## ISO и создание VM - -Загрузка ISO через web-панель: - -```text -/iso -``` - -Создание VM: - -```text -/vm/create -``` - -При создании VM можно выбрать сеть: - -```text -VPS NAT Router — virtuality-nat -Bridge — br0 / локальная сеть -``` - -Для x86_64 можно использовать обычные x86_64 ISO. Для Raspberry Pi / Orange Pi 5 нужны ARM64 ISO или, в будущем, ARM64 cloud images. - -Пример загрузки Alpine x86_64 ISO: +## Удаление ```bash -sudo wget -O /var/lib/virtuality/iso/alpine-standard-x86_64.iso https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/x86_64/alpine-standard-3.20.3-x86_64.iso -sudo virsh pool-refresh virtuality-iso +sudo virtuality-ctl uninstall # убирает панель, службы и настройки; машины, образы и копии остаются +sudo virtuality-ctl uninstall --purge # удаляет ВСЁ: машины, диски, образы, резервные копии, сеть NAT ``` +Команда спрашивает подтверждение (`YES`); `--yes` пропускает вопрос. Пакеты KVM/QEMU/libvirt остаются в системе. + --- -## Обновление +## Если что-то не работает -Из web-панели: раздел `/update`. Вручную: +1. Раздел **Сервер** в панели показывает, чего не хватает (KVM, пакеты, мост). Раздел **Задачи** — журнал каждой операции. Раздел **Журналы** — панель, обновления, установка, виртуализация. +2. Полная диагностика в терминале: -```bash -cd /opt/virtuality/source -sudo git pull -sudo bash scripts/install_web_panel.sh -sudo systemctl restart virtuality-web -``` + ```bash + sudo vhealth # проверка процессора, служб, сети, firewall, libvirt, дисков + sudo virtuality-ctl status # версия, адрес панели, HTTPS, автообновление, хранилище + ``` -Порт панели, пользователь и режим автообновления сохраняются в `/var/lib/virtuality/config/web.env` и не сбрасываются при обновлениях. +3. Отчёт для поддержки — кнопка в «Настройках» или `sudo virtuality-ctl support-bundle`: архив с настройками (без секретов), журналами служб и последними задачами. +4. Журналы: -Полная повторная установка компонентов ноды: + ```bash + journalctl -u virtuality-web -f # панель + sudo journalctl -fu virtuality-firstboot # первая загрузка после ISO + cat /var/log/virtuality/firstboot.log # то же, файлом + cat /var/log/virtuality/update.log # обновления + ls /var/log/virtuality/operations/ # задачи: JSON + журнал каждой + ``` -```bash -cd /opt/virtuality/source -sudo bash install_virtuality_node.sh -sudo bash scripts/install_web_panel.sh -``` +5. Для мониторинга: `GET /healthz` без авторизации отвечает `{"ok": true, "version": "..."}`. + +Полезные команды libvirt: `virsh list --all`, `virsh net-list --all`, `virsh net-dhcp-leases virtuality-nat`, `virsh pool-list --all`. --- -## Продакшен-настройки - -Настройки ноды — `/var/lib/virtuality/config/web.env`: +## Где что лежит ```text -VIRTUALITY_WEB_PORT=8088 # порт панели -VIRTUALITY_WEB_HOST=0.0.0.0 # 127.0.0.1, если панель стоит за reverse proxy -VIRTUALITY_AUTH_USER=admin # Linux-пользователь для входа -VIRTUALITY_AUTO_UPDATE=1 # 0 — отключить ночное автообновление с GitHub -VIRTUALITY_COOKIE_SECURE=0 # 1 — cookie только по HTTPS (за reverse proxy с TLS) +/opt/virtuality/source # исходники (git), отсюда обновления +/opt/virtuality/web # установленная панель (web.prev — предыдущая версия) +/opt/virtuality/venv # Python virtualenv панели +/var/lib/virtuality/iso # установочные ISO +/var/lib/virtuality/disk-images # готовые образы систем (каталог, ссылки, загрузки) +/var/lib/virtuality/images # диски машин (qcow2) +/var/lib/virtuality/backups # резервные копии машин и архивы настроек +/var/lib/virtuality/config # web.env, setup.json, wizard.json, host_profile.json, tls/ +/var/lib/virtuality/network # port_forwards.json, virtuality-nat.xml +/var/lib/virtuality/tmp # временные файлы загрузок и cloud-init +/var/log/virtuality # firstboot.log, update.log, virtuality-ctl.log, install_*.log +/var/log/virtuality/operations # задачи панели: JSON и журнал каждой +/etc/virtuality/nftables/virtuality.nft # правила проброса портов +/usr/local/bin/virtuality-ctl # управление нодой +/usr/local/bin/vhealth # диагностика ``` -После изменения: `cd /opt/virtuality/source && sudo bash scripts/install_web_panel.sh`. Любой параметр можно передать и переменной окружения при установке, например `VIRTUALITY_AUTO_UPDATE=0`. - -Рекомендации: - -- для продакшена отключите автообновление (`VIRTUALITY_AUTO_UPDATE=0`) и обновляйтесь вручную через `/update` после проверки версии; -- открывайте панель наружу только через HTTPS reverse proxy (nginx/Caddy) с `VIRTUALITY_WEB_HOST=127.0.0.1` и `VIRTUALITY_COOKIE_SECURE=1`; -- reverse proxy должен передавать исходный `Host` (nginx: `proxy_set_header Host $host;`, для noVNC-консоли ещё `Upgrade`/`Connection`), иначе панель отклонит POST-запросы как cross-origin; -- мониторинг: `GET /healthz` без авторизации возвращает `{"ok": true, "version": "..."}`; -- после 5 неверных паролей вход с этого адреса блокируется на 5 минут; сессия живёт 12 часов; -- правила проброса портов восстанавливаются после перезагрузки сервисом `virtuality-network.service`. +Порты: панель `8088` (HTTP) и `8443` (HTTPS), SSH `22`. VNC-порты машин наружу не открываются. --- @@ -450,50 +336,27 @@ VIRTUALITY_COOKIE_SECURE=0 # 1 — cookie только по HTTPS (за rev ```bash pip install -r web/requirements.txt -r requirements-dev.txt -make check # pyflakes + shellcheck + pytest -python3 tests/dev_server.py # панель на http://127.0.0.1:8765 с имитацией virsh, вход: любой пароль +make test # pytest (virsh и systemctl имитируются в tests/conftest.py) +make lint # pyflakes + shellcheck +make check # lint + test — запускать перед коммитом +make iso # установочный ISO в dist/ (см. docs/IMAGE.md) ``` -Интерфейс: шаблоны `web/templates` (общий каркас `base.html`, компоненты `_ui.html`), стили `web/static/app.css` (светлая и тёмная темы на CSS-переменных), поведение `web/static/panel.js`. Шрифт Inter и иконки Lucide лежат в `web/static` — панель работает без доступа в интернет. - -Код панели лежит в `web/` целиком и устанавливается как есть. Патчить `app.py` во время установки больше не нужно: изменения вносятся прямо в `web/` и покрываются тестами в `tests/`. GitHub Actions запускает проверки на Python 3.11–3.13 и собирает ISO по тегу `v*`. - ---- - -## Полезные команды +Демо-панель без сервера виртуализации — с тремя машинами, задачами и загрузками: ```bash -sudo vhealth -virsh list --all -virsh pool-list --all -virsh net-list --all -virsh net-dhcp-leases virtuality-nat -ip -br a -ip route -sudo nft list ruleset -sudo ufw status -systemctl status libvirtd --no-pager -systemctl status cockpit.socket --no-pager -systemctl status virtuality-web --no-pager -journalctl -u virtuality-web -f +python3 tests/dev_server.py 8765 # http://127.0.0.1:8765, вход: tester / любой пароль +VIRTUALITY_DEV_SETUP=installing python3 tests/dev_server.py # мастер на шаге «Установка» +VIRTUALITY_DEV_SETUP=done python3 tests/dev_server.py # мастер после установки +VIRTUALITY_DEV_SETUP=finished python3 tests/dev_server.py # настроенный сервер, страница «Настройки» ``` ---- +Устройство кода описано в [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md). Интерфейс: шаблоны `web/templates` (каркас `base.html`, компоненты `_ui.html`), стили `web/static/app.css`, поведение `web/static/panel.js`; шрифт и иконки лежат в `web/static`. Скриншоты страниц: `node tests/screenshots.mjs` (нужен Playwright). -## Roadmap - -- ARM64 cloud-image templates; -- cloud-init для быстрых VM; -- управление storage pools; -- backup/snapshot manager; -- сетевой менеджер bridge/VLAN; -- роли и права пользователей; -- журнал событий; -- кластеризация; -- готовые образы для Raspberry Pi / Orange Pi 5. +GitHub Actions: `ci.yml` запускает pyflakes, shellcheck и тесты на Python 3.11–3.14; `image.yml` собирает ISO по тегу `v*` и вручную. Ветка `main` — рабочая ветка нод на канале `main`; выпуск для стабильного канала — тег `vX.Y.Z`. --- ## Лицензия -Рекомендуемая лицензия: **MIT License**. +[MIT License](LICENSE). diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index c1c4a9a..8b93a0f 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -1,122 +1,172 @@ # Архитектура Virtuality -Virtuality — это платформа виртуализации в стиле Proxmox, но с более компактной и контролируемой архитектурой. - -## Цель - -Создать собственную систему управления виртуальными машинами на базе стабильных Linux-компонентов: - -- KVM; -- QEMU; -- libvirt; -- Cockpit на раннем этапе; -- собственная веб-панель на следующих этапах. - -## Базовая схема +Virtuality — одна нода: сервер с KVM/QEMU/libvirt, поверх которого работает панель на FastAPI. Панель не хранит собственную базу данных: источник правды о машинах — libvirt (`virsh`), о ноде — файлы в `/var/lib/virtuality/config`, о задачах — файлы в `/var/log/virtuality/operations`. Всё, что меняет сам сервер (службы, firewall, сеть, диски), делает один скрипт — `virtuality-ctl`, и панель вызывает его же. ```text -Веб-интерфейс - ↓ -Backend API - ↓ -Node services - ↓ -libvirt / QEMU / KVM - ↓ -Host OS / Storage / Network +Браузер + │ HTTP 8088 / HTTPS 8443 + ▼ +virtuality-web.service — uvicorn, web/app.py (FastAPI, Jinja2) + ├── web/features/* мастер, настройки, снимки, копии, загрузки, операции с машиной + ├── web/core.py общие примитивы, хранилище задач + ├── web/nodectl.py ───────► /usr/local/bin/virtuality-ctl (systemd, TLS, ufw, br0, диск, пароль) + ├── web/network_core.py ──► virsh net-*, nft, ufw, iptables (сеть NAT и пробросы) + └── virsh / virt-install / virt-clone / qemu-img ──► libvirtd ──► QEMU/KVM ``` -## Слои системы +--- -### 1. Web UI +## Код панели: `web/` -Будущая пользовательская панель Virtuality. +| Модуль | Назначение | +|---|---| +| `app.py` | Основное приложение: вход, обзор, машины (создание, действия, ресурсы, порядок загрузки, привод), ISO и образы дисков (загрузка, конвертация, распаковка), сеть и пробросы, обновления, задачи, журналы, экран машины (WebSocket-прокси к VNC), `/healthz`. В конце подключает роутеры из `features/`. | +| `core.py` | Общие примитивы: настройки из `.env`, сессии и авторизация (`require_auth`, `require_api_auth`, защита от cross-origin POST, ограничение попыток входа), `run_cmd`, `render` и окружение шаблонов, `valid_vm_name`, хранилище задач (`new_operation`, `run_operation`, `update_operation`, `finish_operation`, `active_operations_for`, `running_operations`, `interrupt_orphaned_operations`). Импорт `core` выставляет `LC_ALL=C.UTF-8`: вывод `virsh` разбирается панелью и не должен переводиться. | +| `auth.py` | Проверка пароля Linux-пользователя по `/etc/shadow`: через `crypt`/`spwd`, а на Python 3.13+ — через `libcrypt` (ctypes). Ограничение попыток входа. | +| `features/setup.py` | Мастер первичной настройки `/setup`: шаги install → welcome → account → access → network → storage → updates → finish, страница «Применяем настройки», ожидание перестройки сети в мост. | +| `features/settings.py` | Страница «Настройки»: доступ (HTTPS/порт), пароль, часовой пояс, обновления, сеть машин, хранилище, перезагрузка/выключение, архив настроек, отчёт для поддержки. | +| `features/snapshots.py` | Снимки: внутренние снимки libvirt (`virsh snapshot-*`), до 8 на машину, создание и возврат — фоновые задачи. | +| `features/backups.py` | Резервные копии: `vm.xml` + копии дисков + `meta.json` в `backups/<машина>/<ГГГГММДД-ЧЧММ>/`; восстановление под тем же или новым именем; запуск как скрипта для расписания. | +| `features/downloads.py` | Скачивание ISO и образов по ссылке и из каталога — фоновые задачи типа `download` с прогрессом, проверкой контрольной суммы и отменой. | +| `features/vmops.py` | Увеличение диска, клонирование (`virt-clone`), пауза, спящий режим (`virsh managedsave`), заметки (title/description машины), живая нагрузка (`virsh domstats`). | +| `nodectl.py` | Факты о ноде (сеть, диски, оборудование, часовые пояса, состояние первой загрузки, выбор мастера) и действия через `virtuality-ctl`. Действия, которые перезапускают панель, запускаются отложенно через `systemd-run`. | +| `network_core.py` | Сеть NAT `virtuality-nat`, резервации DHCP, пробросы портов и их применение (nftables, ufw, iptables). | +| `catalog.py` | Каталог облачных образов (Ubuntu 26.04/24.04, Debian 13, Alpine 3.23 для x86_64 и aarch64) и типы ОС для установки с ISO (`osinfo` для `virt-install`). | +| `cloudinit.py` | Seed cloud-init для машин из готовых образов: `user-data` (пользователь, хеш пароля SHA-512, SSH-ключи, рост диска, гостевой агент) и `meta-data`; подключается к `virt-install --cloud-init`. | +| `host_profile.py` | Профиль сервера (`x86_64`, `raspberry-arm64`, `orangepi5-arm64`, `generic-arm64`), проверки готовности; хранится в `config/host_profile.json`. | +| `update_core.py` | Проверка обновлений: канал, целевой ref, список пропущенных версий из `updates/versions.json`, запуск `scripts/apply_github_update.sh` через `systemd-run`. | +| `presenters.py` | Человеческие названия состояний, профили ресурсов машин, список типовых портов, форматирование размеров. | +| `restore_network.py` | Повторное применение пробросов после загрузки (`virtuality-network.service`). | +| `redirect_http.py` | Перенаправление HTTP → HTTPS на порту 8088, когда включён TLS (`virtuality-redirect.service`). | +| `templates/`, `static/` | Jinja2-шаблоны (`base.html` — каркас, `_ui.html` — компоненты), `app.css` (светлая и тёмная темы), `panel.js`, шрифт и иконки. Панель не ходит в интернет. | -Задачи: +Правило для роутов модулей: POST-маршруты вида `/vm/{name}/<модуль>/<действие>` — минимум четыре сегмента, иначе их перехватит общий `@app.post("/vm/{name}/{action}")`. -- список виртуальных машин; -- создание VM; -- управление питанием; -- консоль; -- хранилища; -- сеть; -- бэкапы; -- пользователи и роли. +### Фоновые задачи -### 2. Backend API +Долгие операции (создание машины, конвертация образа, скачивание, снимок, копия, клон, спящий режим) выполняются в потоках и записываются в `/var/log/virtuality/operations/.json` (статус, прогресс, сообщение, метаданные) и `.log` (журнал). Раздел «Задачи» и страницы машин читают эти файлы; `active_operations_for(vm, kinds)` защищает машину от двух одновременных операций. При старте панели `interrupt_orphaned_operations()` закрывает задачи, оставшиеся в состоянии «выполняется» после перезапуска. `virtuality-ctl maintenance` удаляет задачи старше 30 дней и оставляет не больше 300. -Единая точка управления нодой. +--- -Задачи: +## Управление нодой: `scripts/virtuality-ctl` -- принимать команды от Web UI; -- валидировать действия; -- работать с libvirt; -- вести журнал событий; -- отдавать состояние VM, storage и сети. +Один bash-скрипт, устанавливается в `/usr/local/bin`. Панель (через `nodectl.py`) и администратор в терминале делают одно и то же: -### 3. Node services +- **`reconfigure`** — читает `/var/lib/virtuality/config/web.env` и пересоздаёт systemd-юниты, logrotate, `/etc/default/libvirt-guests`, правила ufw; переводит VNC старых машин на `127.0.0.1`; перезапускает панель. +- **`set KEY=VALUE`** — проверяет и сохраняет настройку в `web.env`, затем `reconfigure` (для настроек обновления — только перезапись таймера). +- **TLS** — при `VIRTUALITY_TLS=1` создаёт самоподписанный сертификат EC P-256 на 10 лет в `config/tls/panel.{key,crt}` (SAN: имя сервера, localhost, адрес), uvicorn слушает `VIRTUALITY_TLS_PORT` (8443), а `virtuality-redirect.service` перенаправляет с HTTP-порта. +- **Мост `br0`** — `bridge [dhcp|static]` делает копию `/etc/netplan`, пишет `60-virtuality-br0.yaml`, проверяет `netplan generate`, взводит таймер `virtuality-netplan-revert` на 120 секунд и применяет; `bridge-confirm` снимает таймер, `bridge-revert` возвращает копию. Панель после перестройки сети сама вызывает подтверждение, когда снова получает ответ от сервера. +- **`storage-use /dev/sdX`** — только пустой диск без разделов: `mkfs.ext4`, перенос текущего содержимого `/var/lib/virtuality`, запись в `/etc/fstab` (`nofail`), монтирование. +- **`passwd`, `timezone`, `power`, `backup-config`, `restore-config`, `rollback`, `maintenance`, `support-bundle`, `uninstall`** — см. README. -Системные сервисы Virtuality. +Журнал действий: `/var/log/virtuality/virtuality-ctl.log`. -Задачи: +--- -- диагностика ноды; -- обновления; -- резервное копирование; -- мониторинг; -- фоновые задачи. +## Службы systemd -### 4. libvirt / QEMU / KVM +Создаются `virtuality-ctl reconfigure`: -Нижний слой виртуализации. +| Юнит | Что делает | +|---|---| +| `virtuality-web.service` | Панель: `uvicorn app:app` от root из `/opt/virtuality/web` с venv `/opt/virtuality/venv`; `Restart=always`. | +| `virtuality-redirect.service` | Только при TLS: HTTP → HTTPS. | +| `virtuality-network.service` | При загрузке заново применяет пробросы портов (`restore_network.py`). | +| `virtuality-auto-update.timer` / `.service` | Ночная проверка обновлений (`scripts/auto_update_check.sh`), 04:00 ± 30 минут; включён при `VIRTUALITY_AUTO_UPDATE=1`. | +| `virtuality-maintenance.timer` / `.service` | Ежедневное обслуживание: старые задачи, временные файлы, недокачанные загрузки, `journalctl --vacuum-size=300M`, запись занятости диска в `config/health.json`. | +| `libvirt-guests.service` | При выключении сервера машины выключаются корректно (`ON_SHUTDOWN=shutdown`, до 180 секунд), при загрузке не запускаются сами — только те, у кого включён автозапуск. | -Задачи: +Отдельно, из образа: `virtuality-firstboot.service` — первая загрузка (см. [IMAGE.md](IMAGE.md)); временные юниты `virtuality-netplan-revert` (автооткат моста), `virtuality-apply-*` (отложенное применение настроек) и `virtuality-update-*` (обновление вне cgroup панели, чтобы перезапуск панели не убил сам процесс обновления). -- запуск виртуальных машин; -- управление дисками; -- управление сетевыми интерфейсами; -- снапшоты; -- консольный доступ. +--- -### 5. Host OS +## Безопасность панели -Операционная система сервера. +- Вход — по имени и паролю системного пользователя (`VIRTUALITY_AUTH_USER`); проверяется по `/etc/shadow`, поэтому панель работает от root. После 5 неверных паролей адрес блокируется на 5 минут; сессия (подписанная cookie, ключ в `config/session_secret`) живёт 12 часов. +- POST-запросы принимаются только с того же origin; за reverse proxy нужно передавать исходный `Host` (и `Upgrade`/`Connection` для экрана машины). +- Экран машины: VNC у всех машин слушает `127.0.0.1`, панель проксирует его в WebSocket по подписанному токену и только при действующей сессии. Порты 5900–5999 в ufw закрыты. +- Пароль cloud-init хранится только как хеш SHA-512; секреты не попадают в журналы и отчёт для поддержки. +- Firewall: `install_virtuality_node.sh` включает ufw и разрешает SSH; `virtuality-ctl` открывает только порт панели (и HTTPS-порт), список открытых портов хранит в `config/ports.state`. -Целевые системы: +--- -- Debian 12; -- Ubuntu Server 22.04; -- Ubuntu Server 24.04. +## Сеть машин -## Пути +### NAT: `virtuality-nat` + +libvirt-сеть с мостом `virbr100`, подсеть `192.168.100.0/24`, шлюз `192.168.100.1`, DHCP `192.168.100.50–200`. Описание сохраняется в `/var/lib/virtuality/network/virtuality-nat.xml`. Создаётся мастером, страницей «Сеть и доступ» или автоматически при создании первой машины в режиме NAT. Включается `net.ipv4.ip_forward` (`/etc/sysctl.d/99-virtuality-forward.conf`) и ослабляется rp_filter (`98-virtuality-rpfilter.conf`). + +**Постоянные адреса.** Для каждой машины MAC-адрес вычисляется из её имени (`stable_mac`), и в сети создаётся резервация DHCP (`virsh net-update add ip-dhcp-host`) — машина всегда получает один и тот же адрес, панель знает его ещё до первого запуска. При удалении машины резервация освобождается. + +**Пробросы портов** хранятся в `/var/lib/virtuality/network/port_forwards.json` и применяются тремя способами сразу, чтобы работать на любом дистрибутиве: + +1. nftables — таблица `ip virtuality` в `/etc/virtuality/nftables/virtuality.nft` (DNAT, forward, masquerade); +2. ufw — правила `route allow`, список сохранённых правил в `network/ufw_rules.json`; +3. iptables — запасной вариант, все правила помечены комментарием `virtuality-forward`, чтобы их можно было найти и удалить. + +Адрес машины определяется через гостевой агент, `virsh domifaddr`, аренды DHCP по MAC машины, либо задаётся вручную. «Проверить» рядом с правилом делает TCP-подключение к машине и показывает команды для диагностики. + +### Домашняя сеть: мост `br0` + +Сервер объединяет свой проводной интерфейс в мост `br0` (netplan), машины подключаются к нему и получают адреса от роутера. Wi-Fi в мост объединить нельзя — тогда доступен только NAT. Как устроен автооткат — выше, в разделе про `virtuality-ctl`. + +--- + +## Хранилище ```text -/opt/virtuality # код и конфигурация проекта -/var/lib/virtuality # runtime-хранилище -/var/lib/virtuality/iso # ISO-образы -/var/lib/virtuality/images # диски VM -/var/lib/virtuality/backups # резервные копии -/var/log/virtuality # логи +/var/lib/virtuality/ +├── iso/ установочные образы; libvirt-пул virtuality-iso +├── images/ диски машин <имя>.qcow2; libvirt-пул virtuality-images +├── disk-images/ готовые образы систем (каталог, ссылки, загрузки с компьютера) +├── backups/ резервные копии машин (<машина>/<ГГГГММДД-ЧЧММ>/) и архивы настроек config-*.tar.gz +├── config/ web.env, setup.json, setup_done, wizard.json, host_profile.json, +│ session_secret, ports.state, health.json, tls/, netplan-backup/ +├── network/ port_forwards.json, ufw_rules.json, virtuality-nat.xml +├── update/ state.json, last_check.json, временные файлы обновления +└── tmp/ загрузки (.<имя>.part, .<имя>.uploading), seed cloud-init; TMPDIR панели ``` -## Принципы +Мастер и «Настройки» умеют отдать под всё это отдельный пустой диск — он монтируется в `/var/lib/virtuality` целиком. Память «спящих» машин libvirt хранит в `/var/lib/libvirt/qemu/save`. -- исходный код отдельно от runtime-данных; -- диски VM и ISO не хранятся в Git; -- конфиги должны быть прозрачными; -- установщик должен быть повторяемым; -- сетевые изменения делаются осторожно, чтобы не уронить SSH; -- архитектура документируется до активной разработки. +Код и служебные файлы: -## Этап v0.1 +```text +/opt/virtuality/source git-репозиторий, из него ставится панель и берутся обновления +/opt/virtuality/web установленная панель (+ .env с пользователем и ключом сессий) +/opt/virtuality/web.prev предыдущая версия для virtuality-ctl rollback +/opt/virtuality/venv virtualenv +/opt/virtuality/virtuality.env пути ноды (пишет install_virtuality_node.sh) +/etc/virtuality/image.env параметры образа (только после установки с ISO) +/etc/virtuality/nftables/ правила пробросов +/var/log/virtuality/ firstboot.log, update.log, virtuality-ctl.log, install_*.log, operations/ +``` -На этапе v0.1 создаётся фундамент: +--- -- установщик ноды; -- установка KVM/QEMU/libvirt; -- установка Cockpit; -- storage pools; -- структура проекта; -- GitHub-синхронизация; -- базовая диагностика. +## Обновления + +1. **Канал** (`VIRTUALITY_UPDATE_CHANNEL` в `web.env`): `stable` — последний тег `vX.Y.Z` (пока тегов нет — ветка `main`); `main` — ветка `main`. Логика одна и та же в `web/update_core.py` и `scripts/update_target.sh`. +2. **Проверка** (`/update/check`, ночной `scripts/auto_update_check.sh`): `git fetch --tags`, сравнение текущего коммита с целевым; обновление предлагается, только если целевой коммит — потомок текущего (нода никогда не откатывается сама). Список изменений берётся из `updates/versions.json` целевой версии. +3. **Применение** (`scripts/apply_github_update.sh`, запускается через `systemd-run`): `git checkout -B main <цель>` и `git clean`; если git недоступен — скачивание ZIP-архива с GitHub и `rsync`; затем `scripts/install_web_panel.sh` (панель копируется в `web.new`, старая переименовывается в `web.prev`, venv обновляется) и `systemctl restart virtuality-web`. Состояние — `/var/lib/virtuality/update/state.json`, журнал — `/var/log/virtuality/update.log`. +4. **Откат**: `virtuality-ctl rollback` меняет местами `web` и `web.prev`. + +Установщики и скрипты вне `web/`: + +```text +install.sh установка одной командой (проверки, пакеты, пользователь, клон, три установщика ниже) +install_virtuality_node.sh пакеты KVM/QEMU/libvirt (x86_64 или ARM64), пулы, ufw, группы пользователя +scripts/install_web_panel.sh панель, venv (офлайн из wheels/ при наличии), virtuality-ctl, юниты +scripts/install_healthcheck_command.sh команда vhealth (scripts/virtuality_healthcheck.sh) +scripts/detect_host_profile.sh профиль сервера для установщика +scripts/virtuality_firstboot.sh первая загрузка после ISO +scripts/auto_update_check.sh, apply_github_update.sh, update_target.sh обновления +scripts/bump_patch_version.py поднять patch-версию в VERSION +image/build-iso.sh, autoinstall.yaml, files/, grub/ сборка ISO +``` + +--- + +## Тесты и CI + +`tests/conftest.py` подменяет `run_cmd`, так что `virsh`, `systemctl`, `qemu-img` и остальные команды имитируются — тесты идут на любой машине без libvirt. `tests/dev_server.py` поднимает демо-панель с теми же подменами. `make check` = pyflakes + shellcheck + pytest; `.github/workflows/ci.yml` запускает это на Python 3.11–3.14, `.github/workflows/image.yml` собирает ISO. diff --git a/docs/FIRST_VM.md b/docs/FIRST_VM.md index 8649db4..99d9ef1 100644 --- a/docs/FIRST_VM.md +++ b/docs/FIRST_VM.md @@ -1,104 +1,138 @@ -# Первая тестовая виртуальная машина +# Первая виртуальная машина -Этот документ фиксирует проверку первого рабочего сценария Virtuality: сеть `br0`, libvirt storage pools и запуск тестовой VM. +Всё в этом документе делается через панель в браузере — терминал не понадобится. Считаем, что Virtuality установлена и мастер настройки пройден (см. README). -## Требования +Сначала — самый быстрый путь: готовая Ubuntu за минуту. Потом — установка Windows 11 с ISO, экран машины, доступ снаружи, снимки и резервные копии. -Перед созданием VM должны быть готовы: +--- -- KVM/QEMU; -- libvirt; -- Cockpit; -- storage pools `virtuality-images` и `virtuality-iso`; -- bridge `br0`; -- default route через `br0`. +## 1. Быстрая машина из каталога: Ubuntu Server 26.04 -Проверка: +Готовые (облачные) образы — это уже установленная система без пароля. Панель скачивает образ, делает из него диск нужного размера и через cloud-init настраивает первый вход: пользователя, пароль, SSH-ключ. + +### Скачать образ + +1. Откройте **Образы ОС** → вкладка **Готовые системы**. +2. В карточке **Каталог готовых систем** найдите **Ubuntu Server 26.04 LTS** (помечена «Рекомендуем») и нажмите **Скачать**. Сервер скачает образ с сайта Ubuntu сам и проверит контрольную сумму; ход виден в **Задачах** и на этой же странице. +3. Когда образ отмечен «Загружен», рядом появится кнопка **Создать машину** — она открывает мастер с уже выбранным образом. + +В каталоге также Ubuntu Server 24.04 LTS, Debian 13 и Alpine Linux 3.23. Свой образ (`.qcow2`, `.img`, `.raw`, `.img.xz`) можно загрузить с компьютера перетаскиванием или скачать по ссылке в карточке **Скачать по ссылке**. + +### Создать машину + +Шаг **1. Название и система**: + +- **Название машины** — латиница, цифры, точка, дефис, подчёркивание (например, `ubuntu-1`). Это же имя станет именем компьютера внутри системы. +- Источник **Готовая система** уже выбран, образ подставлен. +- Переключатель **Настроить первый вход** должен быть включён: у готовых образов нет пароля, без этого шага в машину не войти. + - **Пользователь** — панель подставляет стандартного пользователя образа (`ubuntu`, у Debian — `debian`, у Alpine — `alpine`); можно указать свой. Он получит права администратора (`sudo`). + - **Пароль** — не короче 6 символов. + - **SSH-ключ** — необязательно; вставьте содержимое `~/.ssh/id_ed25519.pub`. Если указать только ключ без пароля, вход по SSH будет только по ключу. + +Шаг **2. Мощность**: выберите профиль — **Мини** (1 ядро, 1 ГБ, 10 ГБ), **Стандарт** (2 ядра, 4 ГБ, 40 ГБ), **Мощная** (4 ядра, 8 ГБ, 80 ГБ) — или задайте ядра, память и диск сами. Диск образа увеличивается до выбранного размера, а система при первой загрузке сама расширит файловую систему. + +Шаг **3. Сеть**: **Автоматически** — машина получит постоянный адрес `192.168.100.x` в отдельной сети и выйдет в интернет через сервер; снаружи её не видно, пока вы не откроете доступ. **В локальной сети** (если в мастере настройки выбран мост) — машина станет устройством вашей домашней сети и получит адрес от роутера. + +Справа в **Итого** проверьте сводку и нажмите **Создать машину**. Панель откроет страницу задачи с живым журналом. Обычно в пределах минуты появится «Машина создана. Вход: ubuntu по паролю. Адрес в сети машин: 192.168.100.x». + +### Войти + +Откройте страницу машины (из **Обзора**) → **Открыть экран** и войдите с указанными пользователем и паролем. В машину сразу ставится гостевой агент, поэтому её адрес виден на странице машины и в **Сети и доступе** — по нему можно зайти по SSH из локальной сети (если выбран мост) или после проброса порта (см. ниже). + +--- + +## 2. Windows 11 с установочного ISO + +### Загрузить ISO + +1. Скачайте ISO Windows 11 с сайта Microsoft на свой компьютер. +2. **Образы ОС** → вкладка **Установочные образы** → перетащите файл в окно загрузки. Или вставьте прямую ссылку на `.iso` в карточку **Скачать по ссылке** — сервер скачает его сам. + +### Создать машину + +1. **Создать машину** → шаг 1: название (например, `win11`), источник **Установить с диска**, выберите ISO. +2. **Что будете устанавливать** → **Windows 11 / Server 2025**. Панель сама включит UEFI и виртуальный TPM 2.0 (без него Windows 11 отказывается ставиться), подберёт диск SATA и сетевую карту Intel — драйверы во время установки не нужны. +3. Шаг 2: профиль **Мощная** (4 ядра, 8 ГБ, 80 ГБ) — Windows 11 требует минимум 4 ГБ памяти и 64 ГБ диска. +4. Шаг 3: сеть — как и для Linux. +5. **Создать машину**. Задача завершится за несколько секунд — машина создана и запущена с установочного диска. + +### Установить систему + +1. На странице машины нажмите **Открыть экран**. Сразу после запуска Windows показывает «Press any key to boot from CD or DVD» — нажмите любую клавишу в окне экрана, иначе загрузка с диска пропустится. Если пропустили — **Перезагрузить** на странице машины и попробовать снова. +2. Дальше установка идёт как на обычном компьютере. Диск в установщике будет пустым — выберите его целиком. +3. После установки на странице машины откройте вкладку **Диски и загрузка** → **Привод CD/DVD** и извлеките установочный образ, чтобы машина больше не предлагала загрузку с него. + +Для других систем выбирайте тип **Linux** (Ubuntu, Debian, Fedora и другие), **Windows 10 / Server 2019–2022** (классическая загрузка) или **Другая система**. + +--- + +## 3. Экран машины + +- Кнопка **Открыть экран** на странице машины открывает экран в новой вкладке браузера — это как монитор, подключённый к машине. Работает и для установки системы, и когда сеть внутри машины ещё не настроена. +- Если курсор «застрял» внутри экрана, нажмите **Ctrl + Alt**. +- Экран доступен только через панель: VNC-порты машин наружу не открываются, соединение идёт через сервер по вашей сессии. +- Для повседневной работы удобнее подключаться по SSH (Linux) или по удалённому рабочему столу (Windows) — как открыть к ним доступ, ниже. + +--- + +## 4. Доступ к машине снаружи (проброс портов) + +В сети **Автоматически (NAT)** машины не видны ни из домашней сети, ни из интернета, пока вы не откроете нужный порт на сервере. + +1. Откройте **Сеть и доступ** → карточка **Открыть доступ**. +2. **Машина** — выберите машину (рядом показан её адрес). +3. **Что открыть** — сервис из списка: **SSH — удалённый доступ к Linux**, **Сайт (HTTP)**, **Сайт (HTTPS)**, **Удалённый рабочий стол Windows (RDP)**, **Minecraft**, MySQL, PostgreSQL, OpenVPN, WireGuard и другие — или **Другой порт**. +4. **Порт в машине** заполнится сам (для SSH — `22`), **Порт на сервере** — например, `2222`. Протокол TCP или UDP подставляется по сервису. Можно указать диапазон вида `10000-20000`. +5. Нажмите **Открыть доступ**. Теперь `адрес-сервера:2222` ведёт в машину: + + ```bash + ssh ubuntu@адрес-сервера -p 2222 + ``` + + Для Windows выберите **RDP** и подключайтесь приложением «Подключение к удалённому рабочему столу» по адресу `адрес-сервера:3389` (или другому порту сервера, который вы указали). + +Кнопка **Проверить** рядом с правилом покажет, доходит ли трафик до машины и слушает ли она порт. Правила восстанавливаются после перезагрузки сервера сами. Чтобы сервис был доступен из интернета, дополнительно пробросьте тот же порт на роутере на адрес сервера. + +Адреса в сети NAT закреплены за машинами по имени, поэтому пробросы не ломаются после перезагрузок. Если адрес машины не определился (например, система внутри ещё не запущена), в карточке **Адреса машин** его можно указать вручную. + +Машинам в режиме **В локальной сети** проброс не нужен: у них свой адрес от роутера, как у ноутбука или телефона. + +--- + +## 5. Снимок перед рискованными изменениями + +Снимок — точка восстановления машины: перед обновлением системы, экспериментом с настройками или установкой сомнительной программы. + +1. Страница машины → вкладка **Снимки** → карточка **Создать снимок**, при желании впишите описание («перед обновлением») → **Создать снимок**. +2. У работающей машины в снимок попадает и память — она на несколько секунд замрёт, зато вернётся ровно в то же состояние с открытыми программами. У выключенной сохраняется только диск. +3. Если что-то пошло не так — **Вернуться** рядом с нужным снимком. Машина откатится к тому моменту; всё, что сделано после снимка, пропадёт. +4. Ненужные снимки удаляйте: они занимают место внутри диска машины. На одну машину — до 8 снимков. + +Ограничения: снимки работают только с дисками qcow2 (все машины, созданные панелью, такие). Для машин с UEFI-прошивкой (Windows 11, образы Alpine, все машины на ARM64) внутренние снимки в текущей версии libvirt недоступны — панель предупредит; для них используйте резервные копии. + +--- + +## 6. Резервная копия + +Резервная копия — полная копия настроек машины и всех её дисков в отдельной папке на сервере. В отличие от снимка, она не зависит от диска машины и переживёт его повреждение. + +1. Страница машины → вкладка **Резервные копии** → **Создать копию** (заметка по желанию). Работающая машина будет корректно выключена, скопирована и запущена снова — в списке машин в это время видно, что происходит. +2. Копии всех машин собраны в разделе **Резервные копии**; они лежат в `/var/lib/virtuality/backups/<машина>/<дата-время>/`. Ход создания виден в **Задачах**, страницу можно закрыть. +3. **Восстановить**: выберите копию → укажите название — то же (тогда текущую машину придётся заменить, панель попросит подтверждение) или новое (получите вторую машину рядом с первой). Восстановленная машина создаётся выключенной. Файлы копии остаются на месте, восстанавливать из неё можно сколько угодно раз. +4. Перед восстановлением панель проверяет, хватит ли места в `/var/lib/virtuality`. + +Копию можно делать и по расписанию из терминала сервера — например, задачей cron: ```bash -sudo vhealth -ip -br a -ip route -virsh pool-list --all +sudo /opt/virtuality/venv/bin/python /opt/virtuality/web/features/backups.py web01 "ночная копия" ``` -Нормальная сеть: +--- -```text -enp2s0 UP -br0 UP 10.0.0.200/24 -default via 10.0.0.1 dev br0 -``` +## Что дальше -## Создание тестовой VM - -```bash -cd ~/virtuality -git pull -sudo bash scripts/create_test_vm.sh -``` - -По умолчанию создаётся VM: - -```text -Name: test-alpine -RAM: 1024 MB -CPU: 1 vCPU -Disk: 8 GB qcow2 -ISO: Alpine Linux -Network: br0 -Graphics: VNC -``` - -Можно задать имя: - -```bash -sudo bash scripts/create_test_vm.sh test-alpine-2 -``` - -## Проверка - -```bash -virsh list --all -sudo virsh vncdisplay test-alpine -sudo vhealth -``` - -Если `vncdisplay` показывает `:0`, значит порт VNC — `5900`. - -Если показывает `:1`, значит порт VNC — `5901`. - -## Доступ через Cockpit - -Открыть: - -```text -https://SERVER_IP:9090 -``` - -Дальше: - -```text -Virtual machines → test-alpine → Console -``` - -## Что считается успешным результатом - -Этап считается пройденным, если: - -- VM появилась в `virsh list --all`; -- VM запущена; -- консоль открывается в Cockpit или через VNC; -- VM подключена к bridge `br0`; -- `sudo vhealth` не показывает критических ошибок по Virtuality. - -## Следующий этап - -После первой тестовой VM можно переходить к разработке собственной панели управления Virtuality: - -- список VM; -- статусы VM; -- запуск/остановка; -- просмотр storage pools; -- создание VM через UI; -- базовый журнал событий. +- **Клонировать** (меню на странице машины) — точная копия с новым именем и своим адресом, удобно для тестов. +- **Спящий режим** — сохранить память на диск и выключить; после запуска машина продолжит с того же места. +- **Автозапуск** — переключатель на странице машины: машина включится сама после перезагрузки сервера. +- **Ресурсы** — процессор и память можно поменять, когда машина выключена; диск — увеличить в любой момент во вкладке **Диски и загрузка**. +- Раздел **Помощь** в панели повторяет главное из этого документа. diff --git a/docs/IMAGE.md b/docs/IMAGE.md index 7d14b8e..2302572 100644 --- a/docs/IMAGE.md +++ b/docs/IMAGE.md @@ -1,54 +1,38 @@ # Установочный образ Virtuality -Virtuality можно поставить двумя способами: +Загрузочный ISO ставит Virtuality на чистый сервер «с нуля», как Proxmox: записали на флешку, загрузились, ответили на три экрана — после перезагрузки панель уже открыта в браузере, а мастер настройки показывает, как ставятся остальные компоненты. -1. **Скрипт на готовый сервер** — `curl ... install.sh | bash` (см. README). -2. **Установочный ISO** — загрузочный образ «с нуля», как у Proxmox: записываете на флешку, загружаетесь, отвечаете на 3 экрана, после перезагрузки получаете готовую ноду. - -Этот документ про второй способ. - ---- - -## Что внутри образа - -Образ собирается из официального, ничем не изменённого **Ubuntu Server 26.04 LTS live-server ISO** (amd64 или arm64; поддержка до 2031 года) и дополняется: +Образ собирается из официального, ничем не изменённого **Ubuntu Server 26.04 LTS live-server ISO** (amd64 или arm64) и дополняется: ```text -/autoinstall.yaml # сценарий установщика Ubuntu (subiquity autoinstall) -/virtuality/source # исходники Virtuality (git-репозиторий нужной версии) -/virtuality/source/wheels # Python-колёса web-панели для офлайн-установки -/virtuality/image.env # параметры сборки: порт панели, автообновление, пользователь -/virtuality/virtuality-firstboot.service -/boot/grub/grub.cfg # меню «Install Virtuality X.Y.Z» +/autoinstall.yaml # сценарий установщика Ubuntu (subiquity autoinstall) +/virtuality/source # исходники Virtuality нужной версии (git-репозиторий) +/virtuality/source/wheels # Python-колёса панели и pip — для установки без интернета +/virtuality/image.env # параметры сборки: версия, порт панели, автообновление +/virtuality/virtuality-firstboot.service # служба первой загрузки +/boot/grub/grub.cfg # меню «Установить Virtuality X.Y.Z» с фирменной темой +/boot/grub/themes/virtuality/ # тема GRUB ``` Загрузочные записи BIOS и UEFI берутся из оригинального ISO без изменений. -## Как проходит установка +--- -1. Загрузка с ISO → пункт **Install Virtuality**. -2. Установщик Ubuntu спрашивает только **сеть**, **диск** и **пользователя** (имя, пароль, hostname). Язык, раскладка, SSH-сервер и остальное заданы автоматически. -3. Установщик копирует Virtuality в `/opt/virtuality/source` и включает `virtuality-firstboot.service`. -4. После перезагрузки `virtuality-firstboot` (нужен интернет) ставит KVM/QEMU/libvirt, Cockpit, web-панель, `vhealth` и консольный dashboard. Обычно это 5–15 минут. Если сети нет или apt упал, попытка повторяется каждую минуту до успеха. -5. Готово: +## Где взять готовый образ -```text -Web-панель: http://SERVER_IP:8088 (логин — пользователь, созданный в установщике) -Cockpit: https://SERVER_IP:9090 -``` +Workflow `.github/workflows/image.yml` собирает ISO в GitHub Actions: -Адрес панели также показывается на экране входа консоли. Ход первой настройки: +- автоматически при выпуске — пуш тега `v*` (amd64 и arm64); +- при pull request, который меняет `image/**`, `scripts/virtuality_firstboot.sh`, `web/requirements.txt` или сам workflow; +- вручную: Actions → **Build ISO image** → Run workflow → архитектура `amd64`, `arm64` или `both`. -```bash -sudo journalctl -fu virtuality-firstboot -cat /var/log/virtuality/firstboot.log -``` +После сборки workflow проверяет, что в образе есть загрузочная запись UEFI, `autoinstall.yaml` разбирается как YAML, а в `grub.cfg` есть пункт Virtuality. Образы Ubuntu Server больше лимита GitHub Releases (2 ГБ на файл), поэтому ISO публикуются как **artifacts** запуска (`virtuality-iso-amd64`, `virtuality-iso-arm64`) и хранятся 30 дней. В артефакте — `.iso` и `.sha256`. --- -## Сборка ISO +## Сборка своими руками -Нужна Linux-машина (root не нужен), ~10 GB свободного места и пакеты: +Нужна Linux-машина (root не нужен), около 10 ГБ свободного места и пакеты: ```bash sudo apt install -y xorriso git curl python3-pip @@ -63,81 +47,154 @@ make iso # amd64 make iso ARCH=arm64 # ARM64-серверы с UEFI ``` -Скрипт сам скачает последний Ubuntu 26.04.x live-server ISO, проверит SHA256 и положит результат в `dist/`: +`image/build-iso.sh` сам находит последний Ubuntu 26.04.x live-server ISO, скачивает его (около 3 ГБ), проверяет SHA256 и кладёт результат в `dist/`: ```text -dist/virtuality-0.10.0-ubuntu-26.04-amd64.iso -dist/virtuality-0.10.0-ubuntu-26.04-amd64.iso.sha256 +dist/virtuality-0.11.0-ubuntu-26.04-amd64.iso +dist/virtuality-0.11.0-ubuntu-26.04-amd64.iso.sha256 ``` -Скачанный ISO Ubuntu кешируется в `.cache/iso`. Уже скачанный образ можно передать явно: +Скачанный ISO Ubuntu кешируется в `.cache/iso` (или в `VIRTUALITY_ISO_CACHE`). Уже скачанный образ можно передать явно: ```bash ./image/build-iso.sh --ubuntu-iso ~/Downloads/ubuntu-26.04.1-live-server-amd64.iso ``` -### Параметры +### Параметры `image/build-iso.sh` ```text ---arch amd64|arm64 архитектура +--arch amd64|arm64 архитектура (по умолчанию amd64) --ubuntu 26.04|24.04 база образа (по умолчанию 26.04 LTS) +--ubuntu-iso PATH использовать локальный live-server ISO вместо скачивания +--cache-dir DIR где хранить скачанные ISO Ubuntu (по умолчанию .cache/iso) +--output DIR куда класть результат (по умолчанию dist) --ref GIT_REF какую версию Virtuality положить в образ (по умолчанию HEAD) ---web-port PORT порт web-панели (по умолчанию 8088) ---no-auto-update не включать ночное автообновление с GitHub ---locale / --keyboard / --timezone +--repo-url URL откуда установленная нода будет получать обновления +--web-port PORT порт панели на установленной ноде (по умолчанию 8088) +--no-auto-update не включать ночное автообновление +--locale LOCALE локаль установщика и системы (по умолчанию en_US.UTF-8) +--keyboard LAYOUT раскладка (по умолчанию us) +--timezone TZ часовой пояс (по умолчанию geoip — установщик определит по сети; мастер настройки может сменить) --no-wheels не класть Python-колёса (тогда первая загрузка скачает их из PyPI) ---repo-url URL откуда нода будет получать обновления ``` -Через make параметры передаются так: +Полностью автоматический режим (вопросов нет, **стирается самый большой диск**): + +```text +--unattended автоматическая установка +--username NAME администратор (логин в панель), обязателен с --unattended +--password-hash HASH хеш crypt(3), например от: openssl passwd -6 +--hostname NAME имя сервера (по умолчанию virtuality) +``` + +`./image/build-iso.sh --help` печатает тот же список. Через `make` параметры передаются так: ```bash make iso ISO_ARGS="--web-port 8089 --no-auto-update --timezone Europe/Moscow" ``` +### Что кладётся в образ + +- **Исходники**: `git clone` репозитория на указанный `--ref`; у клона `origin` переключается на `--repo-url`, чтобы нода обновлялась оттуда. +- **Колёса**: `pip download` для Python целевого выпуска (3.14 для Ubuntu 26.04, 3.12 для 24.04) и архитектуры, только бинарные `manylinux`-колёса из `web/requirements.txt`. Сам `pip` тоже кладётся: в Ubuntu Server нет `python3-venv`, и установщик панели поднимает pip из этого колеса в virtualenv, созданный `--without-pip`. Благодаря этому панель ставится до появления сети. +- **`image.env`**: `VIRTUALITY_IMAGE_VERSION`, `VIRTUALITY_IMAGE_BUILT`, `VIRTUALITY_WEB_PORT`, `VIRTUALITY_AUTO_UPDATE` и, в автоматическом режиме, `VIRTUALITY_USER`. Установщик копирует файл в `/etc/virtuality/image.env`, его читает первая загрузка. + ### Полностью автоматическая установка -Для массовой раскатки можно собрать образ, который не задаёт вопросов: +Для массовой раскатки: ```bash make iso ISO_ARGS="--unattended --username admin --password-hash '$(openssl passwd -6)' --hostname node01" ``` -> ⚠️ Такой образ загружается в установку сам (через 10 секунд в меню) и **без подтверждения стирает самый большой диск** машины. Файл получает суффикс `-unattended`. Не оставляйте такую флешку в серверах. +> ⚠️ Такой образ сам уходит в установку через 10 секунд в меню и **без подтверждения стирает самый большой диск** машины. Файл получает суффикс `-unattended`, пункты меню — пометку «автоматически, диск будет стёрт». Не оставляйте такую флешку в серверах. + +--- + +## Что спрашивает установщик + +Меню загрузки: **Установить Virtuality 0.11.0** (выбирается сам через 10 секунд), тот же пункт с новым ядром HWE, загрузка с другого диска, настройки UEFI, проверка памяти. + +Сценарий `image/autoinstall.yaml` оставляет интерактивными только три экрана установщика Ubuntu: + +1. **Сеть** — обычно достаточно подтвердить адрес по DHCP. +2. **Диск** — какой диск использовать. Разметка: LVM на весь диск. +3. **Пользователь** — имя сервера, имя пользователя и пароль. Этот пользователь становится администратором панели (и входит по SSH). + +Язык, раскладка, часовой пояс (по умолчанию определяется по сети), SSH-сервер с входом по паролю и всё остальное заданы заранее. В конце установщик копирует исходники в `/opt/virtuality/source`, `image.env` в `/etc/virtuality/` и включает `virtuality-firstboot.service`. Затем — перезагрузка. + +--- + +## Первая загрузка + +`scripts/virtuality_firstboot.sh` запускается службой `virtuality-firstboot.service` один раз. Порядок шагов сделан так, чтобы панель появилась первой и показывала прогресс всего остального: + +| Шаг | Что происходит | Что видно | +|---|---|---| +| `panel` | `scripts/install_web_panel.sh` с `VIRTUALITY_PANEL_ONLY=1`: панель ставится офлайн из колёс и запускается. | Через минуту после загрузки панель отвечает на `http://адрес:8088`; на экране сервера — подсказка `Virtuality настраивается`. | +| `network` | Ожидание маршрута по умолчанию и DNS. | Если через 20 секунд сети нет, мастер пишет «Нет доступа в интернет. Подключите кабель или настройте сеть — установка продолжится сама». | +| `virtualization` | `install_virtuality_node.sh`: пакеты KVM/QEMU/libvirt, пулы, firewall. Самый долгий шаг, 5–15 минут. | Мастер показывает, какой пакет скачивается, распаковывается или настраивается. | +| `tools` | `scripts/install_healthcheck_command.sh`: команда `vhealth`. | | +| `finish` | `virtuality-ctl reconfigure`: юниты, firewall, перезапуск панели; на экран сервера выводится адрес панели и логин. | Мастер переходит к шагу «Сервер». | + +Прогресс пишется в `/var/lib/virtuality/config/setup.json` (`stage`, `message`, список шагов со статусами), мастер опрашивает его через `/api/setup/state`. Каждый шаг идемпотентен и отмечается флагом в `/var/lib/virtuality/.firstboot-steps/`; если что-то упало, systemd перезапускает скрипт через 60 секунд, и он продолжает с первого незавершённого шага — мастер в это время показывает ошибку и хвост журнала. По завершении создаётся `/var/lib/virtuality/.firstboot-done`, и служба больше не запускается. + +Если образ собран с `--no-wheels`, офлайн-установка панели не удастся; скрипт дождётся сети и поставит зависимости из PyPI. + +Смотреть ход установки с сервера: + +```bash +sudo journalctl -fu virtuality-firstboot +cat /var/log/virtuality/firstboot.log +``` + +Логин в панель — пользователь из установщика, пароль — его пароль. Дальше вас ведёт мастер настройки (см. README). + +--- + +## Тема загрузочного меню + +`image/grub/theme.txt` — тема GRUB (gfxmenu), `background.png` — фон 1024×768, `select_*.png` — подсветка выбранного пункта. `build-iso.sh` дописывает в `grub.cfg` подключение темы (`gfxterm`, шрифт `unicode.pf2`, `gfxmode=1024x768`); если модуль или шрифт недоступны, GRUB показывает обычное текстовое меню. Пункты меню переводятся на русский, таймаут — 10 секунд. Контрольная сумма изменённого `grub.cfg` обновляется в `md5sum.txt`, чтобы проверка целостности ISO проходила. + +Фон рендерится из `image/grub/background.html` (тот же стиль, что у страницы входа панели), как описано в `image/grub/README.md`. + +--- + +## Проверка образа + +Сверьте контрольную сумму скачанного или собранного образа: + +```bash +sha256sum -c virtuality-0.11.0-ubuntu-26.04-amd64.iso.sha256 +``` + +Убедиться, что образ загрузочный и содержит нужные файлы (то же делает CI): + +```bash +xorriso -indev virtuality-0.11.0-ubuntu-26.04-amd64.iso -report_el_torito plain 2>/dev/null | grep UEFI +xorriso -osirrox on -indev virtuality-0.11.0-ubuntu-26.04-amd64.iso -extract /autoinstall.yaml autoinstall.yaml +``` --- ## Запись на флешку -Linux / macOS: +Нужна флешка от 4 ГБ. Все данные на ней будут стёрты. -```bash -sudo dd if=dist/virtuality-0.10.0-ubuntu-26.04-amd64.iso of=/dev/sdX bs=4M status=progress conv=fsync -``` +- **Windows**: [Rufus](https://rufus.ie) (режим записи DD) или [balenaEtcher](https://etcher.balena.io). +- **macOS**: balenaEtcher. +- **Linux**: balenaEtcher или `dd`, где `/dev/sdX` — устройство флешки (проверьте через `lsblk`): -Windows: Rufus (режим DD) или balenaEtcher. + ```bash + sudo dd if=dist/virtuality-0.11.0-ubuntu-26.04-amd64.iso of=/dev/sdX bs=4M status=progress conv=fsync + ``` -Проверка целостности: - -```bash -cd dist && sha256sum -c virtuality-0.10.0-ubuntu-26.04-amd64.iso.sha256 -``` - ---- - -## Сборка в GitHub Actions - -Workflow `.github/workflows/image.yml` собирает ISO: - -- автоматически при пуше тега `v*` (amd64 и arm64); -- вручную: Actions → **Build ISO image** → Run workflow. - -Образы Ubuntu Server больше лимита GitHub Releases (2 GB на файл), поэтому ISO публикуются как **artifacts** workflow и хранятся 30 дней. +Загрузитесь с флешки (меню загрузки — обычно F8, F11, F12 или Esc при включении), выберите **Установить Virtuality**. --- ## Ограничения -- База образа — Ubuntu Server 26.04 LTS (или 24.04 LTS через `--ubuntu 24.04`). -- Для первой загрузки нужен интернет: пакеты KVM/libvirt/Cockpit ставятся из репозиториев Ubuntu. Python-зависимости панели уже лежат в образе. -- ARM64-образ рассчитан на серверы с UEFI. Raspberry Pi и Orange Pi 5 грузятся иначе — для них используйте их штатный образ Ubuntu Server и `install.sh`. +- База — Ubuntu Server 26.04 LTS или 24.04 LTS (`--ubuntu 24.04`). +- Для первой загрузки нужен интернет: пакеты KVM/libvirt ставятся из репозиториев Ubuntu. Панель и её Python-зависимости уже в образе. +- ARM64-образ рассчитан на серверы с UEFI. Raspberry Pi и Orange Pi 5 загружаются иначе — для них используйте штатный Ubuntu Server для платы и `install.sh`. diff --git a/docs/REQUIREMENTS.md b/docs/REQUIREMENTS.md index e331363..ca500f7 100644 --- a/docs/REQUIREMENTS.md +++ b/docs/REQUIREMENTS.md @@ -1,95 +1,77 @@ -# Системные требования Virtuality +# Требования -Virtuality — это серверная система управления виртуализацией на базе KVM/QEMU/libvirt/Cockpit и собственной web-панели. +## Коротко -## Минимальные требования +Подойдёт почти любой компьютер или мини-ПК не старше 10 лет с проводной сетью и включённой в BIOS/UEFI виртуализацией. Для одной-двух небольших машин достаточно 4 ГБ памяти; для Windows и нескольких машин сразу — 16 ГБ и SSD. -Подходят только для тестового стенда и одной-двух лёгких VM. +## Операционная система -```text -CPU: 2 ядра с аппаратной виртуализацией Intel VT-x / AMD-V -RAM: 4 GB -Диск /: минимум 8 GB свободно -Диск под /var/lib/virtuality: минимум 20 GB свободно -OS: Ubuntu Server 24.04 LTS / Debian-like с apt -Network: один проводной интерфейс -``` +Virtuality работает на: -## Рекомендуемые требования +- **Ubuntu Server 26.04 LTS** — основа установочного ISO, рекомендуется; +- **Ubuntu Server 24.04 LTS**; +- **Debian 13**. -Для нормальной работы нескольких VM. +Другие системы на базе Debian/Ubuntu с `apt` скорее всего заработают, но не проверяются. Нужен systemd и netplan (для режима «домашняя сеть»). Установка с ISO делает всё сама; на готовую систему Virtuality ставится скриптом `install.sh` — ставьте её на чистый сервер, а не на рабочий компьютер. -```text -CPU: 4+ ядра с Intel VT-x / AMD-V -RAM: 16+ GB -Диск: 100+ GB SSD/NVMe под /var/lib/virtuality -Network: проводной интерфейс 1 Gbit/s+ -OS: Ubuntu Server 24.04 LTS -``` +## Процессор и память -## Проверки установщика +| | Минимум | Рекомендуется | +|---|---|---| +| Процессор | 2 ядра x86_64 с Intel VT-x / AMD-V | 4+ ядер | +| Память | 4 ГБ | 16 ГБ и больше | +| Системный диск | 8 ГБ свободно на `/` | SSD | +| Диск под машины | 20 ГБ свободно в `/var/lib` | 100+ ГБ SSD/NVMe, лучше отдельный диск | +| Сеть | один проводной интерфейс | 1 Гбит/с | -`bootstrap.sh` и `install_virtuality_node.sh` проверяют: +Как считать память: сервер и панель занимают около 1 ГБ, остальное делят машины. Ubuntu Server внутри машины — от 1 ГБ, Windows 11 — от 4 ГБ (лучше 8). Диск машины занимает место постепенно, по мере заполнения, но резервные копии и снимки требуют запаса: планируйте хотя бы вдвое больше, чем суммарный размер дисков машин. -- наличие root-прав; -- наличие `apt`; -- свободное место на `/`; -- свободное место для `/var/lib`; -- объём RAM; -- количество CPU cores; -- наличие флага аппаратной виртуализации `vmx` или `svm`. +**Виртуализация должна быть включена в BIOS/UEFI** (Intel VT-x / Virtualization Technology, AMD-V / SVM Mode). Без неё машины будут работать через медленную программную эмуляцию; панель предупредит об этом в разделе «Сервер», а `sudo vhealth` покажет ошибку `/dev/kvm missing`. -## Значения по умолчанию +Внутри другой виртуальной машины или на VPS Virtuality работает, только если включена вложенная виртуализация (nested virtualization). + +## ARM64 + +Платы и серверы на ARM64 (Raspberry Pi 4/5, Orange Pi 5, серверы с UEFI) поддерживаются: панель определяет профиль, ставит `qemu-system-arm` и прошивку UEFI для ARM. Гости на таких серверах — **только ARM64** (в каталоге готовых систем есть образы aarch64 для Ubuntu, Debian и Alpine); образы x86_64 на них не запускаются. Установка Windows на ARM64 не проверялась. + +Для Raspberry Pi и Orange Pi желательно 8 ГБ памяти и загрузка с SSD/NVMe. Установочный ISO для них не подходит (они грузятся иначе) — используйте штатный Ubuntu Server для платы и `install.sh`. ARM64-ISO предназначен для серверов с UEFI. + +## Сеть + +- Проводное подключение к роутеру. По Wi-Fi сервер работать может, но режим «домашняя сеть» (мост) недоступен — только NAT. +- Доступ в интернет при установке: первая загрузка после ISO и `install.sh` скачивают пакеты из репозиториев Ubuntu/Debian (сотни мегабайт). Панель после установки в интернет не ходит, кроме проверки обновлений и скачивания образов по вашей команде. +- Порты на сервере: `8088` (панель по HTTP), `8443` (панель по HTTPS), `22` (SSH). Открывать их на роутере наружу не обязательно и без HTTPS не рекомендуется. +- Для сети NAT машинам выделяется подсеть `192.168.100.0/24` — она не должна совпадать с вашей домашней сетью. Если роутер раздаёт именно `192.168.100.x`, выбирайте режим «домашняя сеть» или смените подсеть роутера. +- Если хотите, чтобы сервисы машин были доступны из интернета, потребуется проброс портов на роутере на адрес сервера (и «белый» адрес от провайдера). + +## Что проверяет установщик + +`install.sh` и `install_virtuality_node.sh` перед установкой проверяют права root, наличие `apt`, свободное место на `/` и в `/var/lib`, память, количество ядер и флаг виртуализации `vmx`/`svm`. Пороги можно изменить переменными окружения: ```text VIRTUALITY_MIN_ROOT_FREE_MB=8192 VIRTUALITY_MIN_VAR_FREE_MB=20480 VIRTUALITY_MIN_RAM_MB=4096 VIRTUALITY_MIN_CPU_CORES=2 +VIRTUALITY_SKIP_REQUIREMENTS=1 # отключить проверки совсем — только для тестов ``` -## Переопределение требований - -Для тестового стенда можно временно уменьшить требования: +Например, для тестового стенда с маленьким диском: ```bash -curl -fsSL https://raw.githubusercontent.com/viktor138irk/virtuality/main/bootstrap.sh | sudo VIRTUALITY_MIN_VAR_FREE_MB=8192 bash +curl -fsSL https://raw.githubusercontent.com/viktor138irk/virtuality/main/install.sh | VIRTUALITY_MIN_VAR_FREE_MB=8192 bash ``` -Полностью отключить preflight-проверки можно так: +Установка с ISO эти пороги не применяет: диск и память проверяются мастером настройки, который покажет предупреждение, но не остановит установку. -```bash -curl -fsSL https://raw.githubusercontent.com/viktor138irk/virtuality/main/bootstrap.sh | sudo VIRTUALITY_SKIP_REQUIREMENTS=1 bash -``` - -Использовать отключение проверок стоит только для тестов. Для реального сервера это плохая идея: VM быстро съедают диск. - -## Как быстро проверить место +Освободить место перед установкой на существующей системе: ```bash df -h -df -i -du -xh / --max-depth=1 2>/dev/null | sort -h -``` - -## Очистка перед установкой - -```bash -sudo apt clean -sudo apt autoclean -sudo apt autoremove -y -sudo rm -rf /var/lib/apt/lists/* -sudo rm -rf /tmp/* /var/tmp/* +sudo apt clean && sudo apt autoremove -y sudo journalctl --vacuum-time=3d ``` -## Где Virtuality хранит данные +## Браузер -```text -/opt/virtuality # системные конфиги и установленная web-панель -/home//virtuality # GitHub-репозиторий проекта -/var/lib/virtuality/iso # ISO-образы -/var/lib/virtuality/images # qcow2-диски VM -/var/lib/virtuality/backups # будущие backup VM -/var/log/virtuality # логи установки и диагностики -``` +Панель работает в актуальных Chrome, Firefox, Safari и Edge, в том числе на телефоне. Экран машины (noVNC) требует поддержки WebSocket — она есть во всех перечисленных. При включённом HTTPS сертификат выпускается самим сервером, поэтому браузер один раз спросит, доверять ли ему. diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 0fc462d..1c5171f 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -1,115 +1,46 @@ -# Roadmap Virtuality +# Планы -Документ фиксирует направление разработки, чтобы проект не превратился в хаотичный комбайн. +Virtuality — панель для одного домашнего сервера. Этот документ честно фиксирует, что уже есть в версии 0.11 и что планируется дальше. Порядок в списке планов — примерный приоритет, сроков нет. Подробный журнал изменений по версиям — в `updates/versions.json` и в разделе «Обновления» панели. -## v0.1 — Фундамент ноды +## Сделано в 0.11 -Цель: получить рабочую базу для запуска виртуализации. +**Установка и настройка** -Задачи: +- Установочный ISO на базе Ubuntu Server 26.04 LTS (amd64, arm64), сборка `make iso` и в GitHub Actions, полностью автоматический режим. +- Первая загрузка: панель ставится первой и показывает ход установки в браузере, при ошибке продолжает сама. +- Мастер настройки: часовой пояс, пароль, HTTPS, сеть машин (NAT или домашняя сеть с автооткатом), отдельный диск под машины, обновления. +- Страница «Настройки», команда `virtuality-ctl`, установка одной командой на Ubuntu 24.04 / 26.04 и Debian 13. -- базовый установщик `install_virtuality_node.sh`; -- установка KVM/QEMU/libvirt; -- установка Cockpit и Cockpit Machines; -- создание директорий хранения; -- создание libvirt storage pools; -- базовая настройка firewall; -- подготовка GitHub-синхронизации; -- документация проекта. +**Машины** -## v0.2 — Сеть и диагностика +- Создание с ISO с выбором типа системы: Linux, Windows 11 / Server 2025 (UEFI + TPM), Windows 10, другая. +- Машина из готового образа за минуту: каталог (Ubuntu 26.04/24.04, Debian 13, Alpine), скачивание по ссылке, cloud-init с пользователем, паролем и SSH-ключом, гостевой агент. +- Снимки (до 8 на машину), резервные копии с восстановлением, клонирование, увеличение диска, пауза и спящий режим, заметки, живая нагрузка. +- Экран машины в браузере только через панель (VNC закрыт снаружи). -Цель: безопасно подготовить сетевую основу. +**Сеть и сервер** -Задачи: +- Сеть NAT с постоянными адресами, пробросы портов с проверкой и восстановлением после перезагрузки, домашняя сеть через мост `br0`. +- HTTPS для панели, стабильный канал обновлений и ранний доступ, откат, ежедневное обслуживание, отчёт для поддержки, архив настроек. +- Убрано: Cockpit, консольный dashboard, эмуляция ARM64 на x86, загрузка по PXE, старые вспомогательные скрипты. -- диагностический скрипт ноды; -- определение активного сетевого интерфейса; -- безопасная настройка bridge `br0`; -- резервная копия сетевых конфигов перед изменением; -- откат сетевой конфигурации; -- улучшение логов установщика. +## Планируется -## v0.3 — Прототип панели +- **Резервные копии по расписанию из панели** — сейчас копия по расписанию делается только командой в терминале; нужен график и хранение N последних копий. +- **Копии на внешний диск или сетевую папку** — сейчас копии лежат только в `/var/lib/virtuality/backups`. +- **Контейнеры LXC** — лёгкие Linux-контейнеры рядом с машинами, как в Proxmox. +- **Проброс устройств (PCI/USB passthrough)** — видеокарты, USB-ключи, диски целиком в машину. +- **Второй сервер (кластер из двух нод)** — общий список машин, перенос машины между серверами, копии на соседний сервер. +- **Пользователи и роли** — сейчас в панель входит один администратор; нужны дополнительные пользователи с ограниченными правами. +- **Уведомления** — о завершении задач, ошибках, нехватке места и доступных обновлениях (почта, Telegram). +- **Шаблоны машин** — сохранить настроенную машину как шаблон и создавать из него новые. +- **Дополнительные диски и сети у машины** — второй диск, вторая сетевая карта, изменение сети существующей машины. +- **Сертификат Let's Encrypt** — вместо самоподписанного, для доступа к панели по доменному имени. +- **История нагрузки** — графики процессора, памяти и диска за день и неделю по серверу и машинам. +- **Проверка обновлений образов каталога** — предлагать обновить скачанный облачный образ, когда вышел новый. -Цель: начать собственную панель управления. +## Не планируется -Задачи: - -- лёгкая веб-панель; -- авторизация; -- список виртуальных машин; -- статус VM; -- старт/стоп/перезагрузка VM через libvirt; -- отображение storage pools; -- базовый журнал событий. - -## v0.4 — Создание VM - -Цель: добавить мастер создания виртуальных машин. - -Задачи: - -- менеджер ISO; -- форма создания VM; -- выбор CPU/RAM/disk; -- выбор ISO; -- выбор сети; -- создание qcow2-диска; -- запуск установки ОС; -- базовая консоль. - -## v0.5 — Обновления и бэкапы - -Цель: сделать платформу обслуживаемой. - -Задачи: - -- автообновлятор; -- резервная копия конфигов перед обновлением; -- история обновлений; -- ручной backup VM; -- список бэкапов; -- восстановление из backup. - -## v0.6 — Пользователи и роли - -Цель: подготовить систему к реальному использованию несколькими пользователями. - -Задачи: - -- роли: admin, operator, viewer; -- ограничения действий по ролям; -- журнал действий пользователей; -- базовые настройки безопасности. - -## v0.7 — Мониторинг - -Цель: видеть состояние ноды без терминального шаманства. - -Задачи: - -- CPU/RAM/disk usage; -- статус libvirt; -- статус Cockpit; -- количество VM; -- состояние storage pools; -- алерты; -- Telegram/email-уведомления в будущем. - -## v1.0 — Первый стабильный релиз - -Цель: рабочая одиночная нода Virtuality. - -Минимальный состав: - -- установка одной командой; -- управление VM; -- создание VM; -- сеть bridge; -- ISO manager; -- backup/restore; -- web dashboard; -- базовая безопасность; -- документация; -- обновлятор. +- Многосерверные кластеры с общим хранилищем, Ceph, живая миграция — это уровень Proxmox для дата-центров, не для дома. +- Поддержка других гипервизоров, кроме KVM/QEMU/libvirt. +- Гости x86_64 на ARM64-серверах через эмуляцию — слишком медленно, чтобы этим пользоваться.