Files
virtuality/docs/IMAGE.md
T
viktor 48ac535c3a
CI / Tests (Python 3.11) (push) Canceled after 0s
CI / Tests (Python 3.12) (push) Canceled after 0s
CI / Tests (Python 3.13) (push) Canceled after 0s
CI / Tests (Python 3.14) (push) Canceled after 0s
CI / Shell scripts (push) Canceled after 0s
Build ISO image / ISO ${{ fromJSON(github.event_name == 'workflow_dispatch' && (inputs.arch == 'both' && '["amd64","arm64"]' || format('["{0}"]', inputs.arch)) || '["amd64","arm64"]') }} (push) Canceled after 0s
Версия была обновлена до 0.12.1
2026-09-27 16:43:13 +09:00

15 KiB
Исходник Ответственный История

Установочный образ Virtuality

Загрузочный ISO ставит Virtuality на чистый сервер «с нуля», как Proxmox: записали на флешку, загрузились, ответили на три экрана — после перезагрузки панель уже открыта в браузере, а мастер настройки показывает, как ставятся остальные компоненты.

Образ собирается из официального, ничем не изменённого Ubuntu Server 26.04 LTS live-server ISO (amd64 или arm64) и дополняется:

/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 без изменений.


Где взять готовый образ

Образ собирается вручную командой make iso (см. ниже): раннер Actions в Gitea не подключён. Workflow .github/workflows/image.yml остаётся в репозитории и заработает, как только раннер появится: он собирает ISO по тегу v* и вручную, проверяет загрузочную запись UEFI, autoinstall.yaml и пункт Virtuality в grub.cfg и сохраняет .iso и .sha256 как artifacts запуска.


Сборка своими руками

Нужна Linux-машина (root не нужен), около 10 ГБ свободного места и пакеты:

sudo apt install -y xorriso git curl python3-pip

Сборка:

git clone https://git.stackworks.ru/viktor/virtuality.git
cd virtuality
make iso                 # amd64
make iso ARCH=arm64      # ARM64-серверы с UEFI

image/build-iso.sh сам находит последний Ubuntu 26.04.x live-server ISO, скачивает его (около 3 ГБ), проверяет SHA256 и кладёт результат в dist/:

dist/virtuality-0.12.1-ubuntu-26.04-amd64.iso
dist/virtuality-0.12.1-ubuntu-26.04-amd64.iso.sha256

Скачанный ISO Ubuntu кешируется в .cache/iso (или в VIRTUALITY_ISO_CACHE). Уже скачанный образ можно передать явно:

./image/build-iso.sh --ubuntu-iso ~/Downloads/ubuntu-26.04.1-live-server-amd64.iso

Параметры image/build-iso.sh

--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)
--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)

Полностью автоматический режим (вопросов нет, стирается самый большой диск):

--unattended               автоматическая установка
--username NAME            администратор (логин в панель), обязателен с --unattended
--password-hash HASH       хеш crypt(3), например от: openssl passwd -6
--hostname NAME            имя сервера (по умолчанию virtuality)

./image/build-iso.sh --help печатает тот же список. Через make параметры передаются так:

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, его читает первая загрузка.

Полностью автоматическая установка

Для массовой раскатки:

make iso ISO_ARGS="--unattended --username sysadmin --password-hash '$(openssl passwd -6)' --hostname node01"

Системные имена вроде admin, root или kvm установщик Ubuntu не принимает, и установка остановится на первом шаге. Поэтому build-iso.sh сразу отказывается собирать образ с таким --username. Полный список лежит в image/reserved-usernames, это копия списка из установщика Ubuntu.

⚠️ Такой образ сам уходит в установку через 10 секунд в меню и без подтверждения стирает самый большой диск машины. Файл получает суффикс -unattended, пункты меню — пометку «автоматически, диск будет стёрт». Не оставляйте такую флешку в серверах.


Что спрашивает установщик

Меню загрузки: Установить Virtuality 0.12.1 (выбирается сам через 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.

Смотреть ход установки с сервера:

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.


Проверка образа

Сверьте контрольную сумму скачанного или собранного образа:

sha256sum -c virtuality-0.12.1-ubuntu-26.04-amd64.iso.sha256

Убедиться, что образ загрузочный и содержит нужные файлы (то же делает CI):

xorriso -indev virtuality-0.12.1-ubuntu-26.04-amd64.iso -report_el_torito plain 2>/dev/null | grep UEFI
xorriso -osirrox on -indev virtuality-0.12.1-ubuntu-26.04-amd64.iso -extract /autoinstall.yaml autoinstall.yaml

Запись на флешку

Нужна флешка от 4 ГБ. Все данные на ней будут стёрты.

  • Windows: Rufus (режим записи DD) или balenaEtcher.

  • macOS: balenaEtcher.

  • Linux: balenaEtcher или dd, где /dev/sdX — устройство флешки (проверьте через lsblk):

    sudo dd if=dist/virtuality-0.12.1-ubuntu-26.04-amd64.iso of=/dev/sdX bs=4M status=progress conv=fsync
    

Загрузитесь с флешки (меню загрузки — обычно F8, F11, F12 или Esc при включении), выберите Установить Virtuality.


Ограничения

  • База — 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.