Документация была переписана под версию 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 удалений
+128 -71
Просмотреть файл
@@ -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`.