- защита от удаления проверяет все незавершённые восстановления этой копии (под любым именем машины)
- наблюдатель, который запускает машину после позднего выключения, снимается при «Выключить»/«Удалить»
в панели и при новой копии, и не мешает другим задачам с этой машиной
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LEUXMcdZo7b87mjkUsPgg
Найдено полной установкой ISO в QEMU: панель ставится первой, и virtuality-ctl заранее создавал
/etc/default/libvirt-guests; при установке libvirt dpkg спрашивал, какую версию оставить, и падал.
- virtuality-ctl пишет этот файл только после установки libvirt
- apt ставит пакеты с --force-confdef/--force-confold, перед установкой доделывает прерванную (dpkg --configure -a)
- спиннер установщика не засоряет журнал первой загрузки
- проверка ISO в CI ищет русский пункт меню
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LEUXMcdZo7b87mjkUsPgg
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
- Проверка «уже скачивается» идёт по всем операциям каталога (glob), а не по последним 50;
скачивания без живого потока закрываются при старте (reap_stale_downloads), их .part удаляются,
а отмена такой операции завершает её сразу, не дожидаясь потока.
- Два запуска одного файла больше не пишут в один .part: проверки и создание операции под замком,
файл создаётся монопольно (O_EXCL), вторая копия завершается ошибкой, не трогая чужой файл;
осиротевший .part без владельца убирается перед новым запуском.
- Отмена во время проверки контрольной суммы и распаковки .img.xz останавливает работу:
операция завершается как отменённая, недокачанный файл, архив и недораспакованный образ удаляются.
- Битый .img.xz после неудачной распаковки удаляется с понятным сообщением, повторное скачивание разрешено;
проверка «файл уже есть» учитывает распакованный .img и qcow2 после конвертации.
- Ссылки с кириллицей (домен IDNA, путь и параметры в процентах) открываются, некорректный порт
и непонятные символы отклоняются сразу; ошибки сети описаны словами, исходный текст — в журнале.
- Прогресс раз в секунду перечитывает JSON операции, чтобы не затирать cancel_requested и замечать
отмену из другого процесса; операции читаются один раз на страницу; отмена в карточке — не ошибка.
- Формулировки карточек и сообщения о недоступной архитектуре упрощены; добавлены тесты на каждое поведение.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LEUXMcdZo7b87mjkUsPgg
- Папка копии занимается атомарно ещё в create_backup; вторая копия в ту же
минуту получает суффикс -2, поэтому неудачная задача удаляет только свою папку.
- qemu-img info вызывается с -U (диск работающей машины занят QEMU), а ошибка
теперь поднимается пользователю вместо тихих нулей в расчёте места.
- Проверки «с машиной уже идёт задача» переведены на core.active_operations_for;
удаление копии, которую читает восстановление под другим именем, блокирует
метка .restoring с id задачи (устаревшая метка после перезапуска игнорируется).
- Зависший qemu-img убивается по общему таймауту stream_cmd.
- Восстановление с заменой сначала распаковывает все диски во временные файлы
и только потом удаляет старую машину; при ошибке она остаётся на месте.
Освобождаемое место старой машины больше не учитывается в проверке.
- Отклонённая команда выключения сообщается как есть, машина на паузе
сохраняется через managedsave и продолжает с того же места, а если машина
выключилась уже после отказа задачи — панель запускает её снова.
- rewrite_xml при замене сохраняет uuid и mac, убирает <backingStore> и
вынимает из привода образ, которого больше нет на сервере.
- Имена дисков из meta.json проверяются, процент занятого места считается от
всего диска, убран двойной отклик при удалении, сообщения об ошибках
копирования без жаргона, путь запуска из расписания указан через venv панели.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LEUXMcdZo7b87mjkUsPgg
- stable (по умолчанию): обновление до последнего тега vX.Y.Z; пока релизов нет — ветка main
- main: ранний доступ, все изменения; канал берётся из web.env (Настройки → Обновления)
- scripts/update_target.sh общий для автообновления и ручного обновления, ZIP-запасной путь для тегов
- страница «Обновления» показывает канал и целевую версию
- клонирование и увеличение диска недоступны, пока машина в спящем режиме
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LEUXMcdZo7b87mjkUsPgg
- все команды запускаются с LC_ALL=C.UTF-8: русский перевод virsh ломал разбор состояния машин
- имя машины не может быть числом или UUID (virsh принял бы его за ID другой машины)
- IP без MAC машины не угадывается по чужой аренде DHCP; у выключенных машин нет устаревшего IP
- вставленный ISO определяется по устройству CD-ROM, а не по «.iso» в пути
- ISO, вставленный в привод машины, нельзя удалить — машина перестала бы запускаться
- на ARM-платах нет ложного предупреждения про флаги vmx/svm
- проверка машины в консоли не блокирует остальные запросы
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LEUXMcdZo7b87mjkUsPgg
- готовые образы: пользователь, пароль (хеш SHA-512) и SSH-ключ через virt-install --cloud-init,
диск увеличивается до выбранного размера, osinfo из каталога
- установка с ISO: выбор Linux / Windows 11 (UEFI + TPM) / Windows 10 / другая;
Windows получает SATA-диск и сетевую карту e1000e
- каждая машина в NAT получает фиксированный MAC и резервацию DHCP — адрес не меняется,
пробросы портов не ломаются; при удалении резервация снимается
- xorriso в пакетах ноды (для seed-образа cloud-init)
- tests/test_quickvm.py; тест каталога скачиваний сделан детерминированным
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LEUXMcdZo7b87mjkUsPgg
- core.interrupt_orphaned_operations() при запуске панели, active_operations_for() по всем задачам
- снимки: имена с пробелами, снимки вне панели без кнопок, --force только на «revert requires force»,
память на паузе учитывается, защита от двойного нажатия, надпись «Создаём снимок…»
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LEUXMcdZo7b87mjkUsPgg
- формат образа диска определяется через qemu-img info (облачные .img — это qcow2)
- ISO подключается/извлекается через virsh change-media, без угадывания устройств
- действия start/shutdown/delete сообщают об ошибке virsh; удаление UEFI-машин (--nvram)
- правила iptables/ufw для удалённых пробросов портов теперь удаляются
- VNC машин слушает только 127.0.0.1; virtuality-ctl reconfigure чинит старые машины
- зелёное уведомление не показывается, если действие вернуло ошибку
- убраны смена архитектуры машины, эмуляция ARM64 на x86 и загрузка по PXE
- tests/test_audit_fixes.py
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LEUXMcdZo7b87mjkUsPgg