Документация была переписана под версию 0.11: README, образ, первая машина, архитектура, требования, планы

README описывает продукт как простую замену Proxmox для дома: три способа установки
(ISO из GitHub Actions или make iso, одна команда, вручную), первую загрузку и мастер
настройки, возможности, страницу «Настройки», команды virtuality-ctl, обновления и откат,
удаление, диагностику и разработку. Упоминания Cockpit, консольного dashboard, тестовых
скриптов, эмуляции ARM64 на x86 и PXE убраны; таблица скриншотов сохранена и дополнена
существующими снимками.

docs/IMAGE.md — сборка ISO и все параметры image/build-iso.sh, вопросы установщика,
этапы первой загрузки, тема GRUB, артефакты CI, проверка и запись на флешку.
docs/FIRST_VM.md — первая машина только через панель: Ubuntu 26.04 из каталога
с cloud-init, Windows 11 с ISO, экран, проброс портов, снимки, резервные копии.
docs/ARCHITECTURE.md — текущее устройство: модули web/, virtuality-ctl, задачи,
службы systemd, TLS, firewall, сеть NAT с резервациями, хранилище, обновления.
docs/REQUIREMENTS.md — оборудование, ОС, ARM64, сеть, браузер.
docs/ROADMAP.md — что сделано в 0.11 и что планируется.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LEUXMcdZo7b87mjkUsPgg
Этот коммит содержится в:
Claude
2026-09-25 15:41:03 +00:00
родитель 1d39029472
Коммит 5465000f42
6 изменённых файлов: 740 добавлений и 823 удалений
+261 -398
Просмотреть файл
@@ -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) |
| Каталог готовых систем | Настройки |
|---|---|
| ![Каталог](docs/screenshots/catalog.png) | ![Настройки](docs/screenshots/settings.png) |
| Снимки | Резервные копии |
|---|---|
| ![Снимки](docs/screenshots/snapshots.png) | ![Резервные копии](docs/screenshots/backups.png) |
| Вход | На телефоне |
|---|---|
| ![Вход](docs/screenshots/login.png) | ![Мобильная версия](docs/screenshots/dashboard-mobile.png) |
---
## Установка с ISO-образа
## Содержание
Для установки на «голое» железо собирается загрузочный ISO на базе чистого Ubuntu Server 26.04 LTS: установщик спрашивает только сеть, диск и пользователя, а при первой загрузке нода настраивается сама.
- [Установка](#установка)
- [Способ 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
make iso # dist/virtuality-<версия>-ubuntu-26.04-amd64.iso
make iso ARCH=arm64
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
```
Подробно: [`docs/IMAGE.md`](docs/IMAGE.md).
Дальше: записать образ на флешку (Rufus, balenaEtcher или `dd`), загрузиться с неё, выбрать **Установить Virtuality**, ответить на три экрана установщика и дождаться перезагрузки. Через минуту после неё панель уже открывается в браузере — адрес показан на экране сервера. Все подробности, параметры сборки и полностью автоматическая установка — в [docs/IMAGE.md](docs/IMAGE.md).
---
### Способ 2: одна команда на готовый сервер
## Быстрая установка одной командой
Одна команда работает и под `root`, и под обычным пользователем с `sudo`:
Подходит для уже установленного 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=<linux_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 <linux_user>
```
Для 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
```
Статус:
```bash
systemctl status virtuality-web --no-pager
```
Логи:
```bash
journalctl -u virtuality-web -f
```
Вход:
```text
Login: выбранный Linux-пользователь
Pass: пароль этого Linux-пользователя
```
`install_web_panel.sh` копирует панель в `/opt/virtuality/web`, создаёт virtualenv, ставит `virtuality-ctl` и через него — systemd-юниты и правила firewall. Переменные: `VIRTUALITY_AUTH_USER` (пользователь для входа), `VIRTUALITY_WEB_PORT` (порт), `VIRTUALITY_AUTO_UPDATE` (0/1). Повторный запуск скрипта обновляет панель, сохраняя настройки.
---
## Сеть: Bridge и NAT Router
## Первая загрузка и мастер настройки
### Bridge br0
### Что происходит после установки с ISO
Подходит для домашнего/офисного сервера, где VM должны получать IP из локальной сети.
После перезагрузки запускается `virtuality-firstboot.service` (`scripts/virtuality_firstboot.sh`). Порядок шагов выбран так, чтобы вы как можно раньше увидели, что происходит:
По умолчанию one-command установщик **не включает `br0` автоматически**, чтобы не уронить SSH-сессию.
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) всё это время показана подсказка, а после завершения — адрес панели и логин.
```bash
ip -br a
ip route
```
Логин в панель — пользователь, созданный в установщике Ubuntu; пароль — его пароль.
Затем запустить bridge setup, например для `enp2s0`:
### Мастер настройки
```bash
cd /opt/virtuality/source
sudo bash scripts/setup_bridge_br0.sh enp2s0 static
```
Мастер (`/setup`) открывается при первом входе в панель — и после ISO, и после `install.sh`. Каждый шаг можно пропустить, а весь мастер — запустить заново из раздела «Настройки».
Ожидаемый результат:
```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
```
| Шаг | Что делает |
|---|---|
| **Установка** | Показывает ход первой загрузки (только после ISO). |
| **Сервер** | Проверяет процессор, память, диск и доступность KVM; задаёт часовой пояс. |
| **Администратор** | Смена пароля пользователя панели (он же пароль SSH). |
| **Доступ** | HTTPS с сертификатом сервера (панель на порту 8443, с 8088 — перенаправление) или обычный HTTP; порт. |
| **Сеть машин** | **Отдельная сеть (NAT)** — машины получают адреса 192.168.100.x, работает везде. **Домашняя сеть (мост)** — машины становятся устройствами вашей сети; сервер сам перестроит сеть в мост `br0`, а если панель не ответит за 2 минуты — вернёт всё как было. |
| **Хранилище** | Отдать пустой диск (от 16 ГБ) под машины: он форматируется и монтируется в `/var/lib/virtuality`. Или оставить системный диск. |
| **Обновления** | Автоматически ночью (только выпущенные версии) или вручную; канал: стабильный или ранний доступ. |
| **Готово** | Сводка; настройки применяются, при смене адреса панель перезапускается и открывается по новому. |
---
## ISO и создание VM
## Возможности
Загрузка ISO через web-панель:
Разделы панели: **Обзор**, **Создать машину**, **Образы ОС**, **Сеть и доступ**, **Резервные копии**, **Задачи**, **Журналы**, **Обновления**, **Сервер**, **Настройки**, **Помощь**.
```text
/iso
```
**Машины**
Создание VM:
- Создание из установочного 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 наружу не открыт: консоль доступна только через панель.
```text
/vm/create
```
**Снимки и копии**
При создании VM можно выбрать сеть:
- **Снимки** — точки восстановления внутри диска машины, до 8 на машину. У работающей машины в снимок попадает и память. Вернуться или удалить — одной кнопкой.
- **Резервные копии** — полная копия настроек и всех дисков в `/var/lib/virtuality/backups/<машина>/<дата>/`. Восстановление под тем же или новым названием; копию можно делать и по расписанию из командной строки.
```text
VPS NAT Router — virtuality-nat
Bridge — br0 / локальная сеть
```
**Образы ОС**
Для x86_64 можно использовать обычные x86_64 ISO. Для Raspberry Pi / Orange Pi 5 нужны ARM64 ISO или, в будущем, ARM64 cloud images.
- Загрузка ISO и образов дисков перетаскиванием (с прогрессом и скоростью), поддержка `.qcow2`, `.img`, `.raw`, сжатых `.img.xz` и архивов.
- **Скачивание по ссылке** — сервер качает файл сам, в фоне.
- **Каталог готовых систем** — официальные облачные образы Ubuntu Server 26.04 LTS и 24.04 LTS, Debian 13, Alpine Linux 3.23 с проверкой контрольных сумм.
Пример загрузки 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
```
- Сеть **NAT** `virtuality-nat` (192.168.100.0/24): каждая машина получает **постоянный адрес** по имени, поэтому пробросы портов не ломаются после перезагрузок.
- **Проброс портов** из списка готовых сервисов (SSH, сайт, RDP, Minecraft, VPN и другие) или любой порт и диапазон; проверка правила одной кнопкой; правила переживают перезагрузку сервера.
- **Домашняя сеть через мост** `br0` с автооткатом, если сеть пропала.
**Сервер**
- Мастер настройки и страница «Настройки».
- **HTTPS** для панели с сертификатом сервера и перенаправлением с HTTP.
- **Обновления** из панели или автоматически ночью, **стабильный канал** (только выпущенные версии) и ранний доступ, откат на предыдущую версию.
- Задачи с прогрессом и журналом, журналы служб, диагностика `vhealth`, отчёт для поддержки, архив настроек.
- Светлая и тёмная темы, работает на телефоне, не требует доступа в интернет для самой панели.
Как сделать первую машину — в [docs/FIRST_VM.md](docs/FIRST_VM.md).
---
## Обновление
## Настройки
Из web-панели: раздел `/update`. Вручную:
Страница **Настройки** (`/settings`) — всё то же, что в мастере, плюс управление сервером:
```bash
cd /opt/virtuality/source
sudo git pull
sudo bash scripts/install_web_panel.sh
sudo systemctl restart virtuality-web
```
- **Доступ к панели** — HTTPS или HTTP, порт. После применения панель перезапускается и открывается по новому адресу.
- **Пароль** — смена пароля пользователя панели (он же пароль Linux и SSH).
- **Сеть машин** — переключение между NAT и домашней сетью (мост `br0`), возврат прежней сети, проверка сети NAT.
- **Хранилище** — подключить пустой диск под машины.
- **Время** — часовой пояс сервера (по нему показываются журналы и час ночного обновления).
- **Обновления** — автообновление и канал (стабильный / ранний доступ).
- **Сервер** — скачать архив настроек, собрать отчёт для поддержки, перезагрузить или выключить сервер (машины выключаются корректно).
- **Мастер настройки** — пройти все шаги заново.
Порт панели, пользователь и режим автообновления сохраняются в `/var/lib/virtuality/config/web.env` и не сбрасываются при обновлениях.
Полная повторная установка компонентов ноды:
```bash
cd /opt/virtuality/source
sudo bash install_virtuality_node.sh
sudo bash scripts/install_web_panel.sh
```
---
## Продакшен-настройки
Настройки ноды — `/var/lib/virtuality/config/web.env`:
Настройки ноды хранятся в `/var/lib/virtuality/config/web.env` и не сбрасываются обновлениями:
```text
VIRTUALITY_WEB_PORT=8088 # порт панели
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 — отключить ночное автообновление с GitHub
VIRTUALITY_COOKIE_SECURE=0 # 1 — cookie только по HTTPS (за reverse proxy с TLS)
VIRTUALITY_AUTO_UPDATE=1 # 0 — без ночного автообновления
VIRTUALITY_UPDATE_CHANNEL=stable # stable — выпущенные версии, main — все изменения
VIRTUALITY_SOURCE_DIR=/opt/virtuality/source
```
После изменения: `cd /opt/virtuality/source && sudo bash scripts/install_web_panel.sh`. Любой параметр можно передать и переменной окружения при установке, например `VIRTUALITY_AUTO_UPDATE=0`.
Менять их руками не нужно: `sudo virtuality-ctl set КЛЮЧ=ЗНАЧЕНИЕ` сохраняет значение и сразу применяет его.
Рекомендации:
---
- для продакшена отключите автообновление (`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`.
## Команда 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 <iface> [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
```
---
## Обновления и откат
- **Из панели**: раздел **Обновления** → «Проверить сейчас» → «Обновить». Машины во время обновления продолжают работать. Что изменилось — видно на той же странице.
- **Автоматически**: таймер `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`.
---
## Удаление
```bash
sudo virtuality-ctl uninstall # убирает панель, службы и настройки; машины, образы и копии остаются
sudo virtuality-ctl uninstall --purge # удаляет ВСЁ: машины, диски, образы, резервные копии, сеть NAT
```
Команда спрашивает подтверждение (`YES`); `--yes` пропускает вопрос. Пакеты KVM/QEMU/libvirt остаются в системе.
---
## Если что-то не работает
1. Раздел **Сервер** в панели показывает, чего не хватает (KVM, пакеты, мост). Раздел **Задачи** — журнал каждой операции. Раздел **Журналы** — панель, обновления, установка, виртуализация.
2. Полная диагностика в терминале:
```bash
sudo vhealth # проверка процессора, служб, сети, firewall, libvirt, дисков
sudo virtuality-ctl status # версия, адрес панели, HTTPS, автообновление, хранилище
```
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 + журнал каждой
```
5. Для мониторинга: `GET /healthz` без авторизации отвечает `{"ok": true, "version": "..."}`.
Полезные команды libvirt: `virsh list --all`, `virsh net-list --all`, `virsh net-dhcp-leases virtuality-nat`, `virsh pool-list --all`.
---
## Где что лежит
```text
/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 # диагностика
```
Порты: панель `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).
+137 -87
Просмотреть файл
@@ -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/<id>.json` (статус, прогресс, сообщение, метаданные) и `<id>.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 <iface> [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.
+121 -87
Просмотреть файл
@@ -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
sudo vhealth
ip -br a
ip route
virsh pool-list --all
ssh ubuntu@адрес-сервера -p 2222
```
Нормальная сеть:
Для Windows выберите **RDP** и подключайтесь приложением «Подключение к удалённому рабочему столу» по адресу `адрес-сервера:3389` (или другому порту сервера, который вы указали).
```text
enp2s0 UP
br0 UP 10.0.0.200/24
default via 10.0.0.1 dev br0
```
Кнопка **Проверить** рядом с правилом покажет, доходит ли трафик до машины и слушает ли она порт. Правила восстанавливаются после перезагрузки сервера сами. Чтобы сервис был доступен из интернета, дополнительно пробросьте тот же порт на роутере на адрес сервера.
## Создание тестовой VM
Адреса в сети 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
cd ~/virtuality
git pull
sudo bash scripts/create_test_vm.sh
sudo /opt/virtuality/venv/bin/python /opt/virtuality/web/features/backups.py web01 "ночная копия"
```
По умолчанию создаётся 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;
- базовый журнал событий.
- **Клонировать** (меню на странице машины) — точная копия с новым именем и своим адресом, удобно для тестов.
- **Спящий режим** — сохранить память на диск и выключить; после запуска машина продолжит с того же места.
- **Автозапуск** — переключатель на странице машины: машина включится сама после перезагрузки сервера.
- **Ресурсы** — процессор и память можно поменять, когда машина выключена; диск — увеличить в любой момент во вкладке **Диски и загрузка**.
- Раздел **Помощь** в панели повторяет главное из этого документа.
+126 -69
Просмотреть файл
@@ -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»
/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 ГБ. Все данные на ней будут стёрты.
- **Windows**: [Rufus](https://rufus.ie) (режим записи DD) или [balenaEtcher](https://etcher.balena.io).
- **macOS**: balenaEtcher.
- **Linux**: balenaEtcher или `dd`, где `/dev/sdX` — устройство флешки (проверьте через `lsblk`):
```bash
sudo dd if=dist/virtuality-0.10.0-ubuntu-26.04-amd64.iso of=/dev/sdX bs=4M status=progress conv=fsync
sudo dd if=dist/virtuality-0.11.0-ubuntu-26.04-amd64.iso of=/dev/sdX bs=4M status=progress conv=fsync
```
Windows: Rufus (режим DD) или balenaEtcher.
Проверка целостности:
```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`.
+46 -64
Просмотреть файл
@@ -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/<user>/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 сертификат выпускается самим сервером, поэтому браузер один раз спросит, доверять ли ему.
+34 -103
Просмотреть файл
@@ -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-серверах через эмуляцию — слишком медленно, чтобы этим пользоваться.