Страница «Настройки» была добавлена: доступ, пароль, сеть машин, хранилище, время, обновления, сервер

- web/features/settings.py + settings.html: всё, что спрашивал мастер, меняется в одном месте
- перезагрузка/выключение с ожиданием возврата панели, архив настроек и отчёт для поддержки
- сообщения после редиректов показываются на любой странице (?message=, ?error=)
- virtuality-ctl set: настройки обновлений применяются без перезапуска панели
- tests/test_settings.py

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LEUXMcdZo7b87mjkUsPgg
Этот коммит содержится в:
Claude
2026-09-25 14:55:31 +00:00
родитель 55f7d971f6
Коммит 2745a1280f
11 изменённых файлов: 497 добавлений и 8 удалений
+6 -1
Просмотреть файл
@@ -44,7 +44,7 @@ def seed(root: Path) -> None:
nodectl.WIZARD_FILE = dirs["config"] / "wizard.json"
stage = os.environ.get("VIRTUALITY_DEV_SETUP", "")
if stage:
# VIRTUALITY_DEV_SETUP=installing|done shows the setup wizard in the demo.
# VIRTUALITY_DEV_SETUP=installing|done shows the setup wizard in the demo; finished = wizard completed (Settings page).
steps = [("panel", "Панель управления", "done"), ("network-wait", "Подключение к интернету", "done"), ("virtualization", "KVM, QEMU и libvirt", "running" if stage == "installing" else "done"), ("tools", "Инструменты диагностики", "pending" if stage == "installing" else "done"), ("finish", "Завершение", "pending" if stage == "installing" else "done")]
nodectl.SETUP_STATE.write_text(json.dumps({"stage": "installing" if stage == "installing" else "done", "message": "Устанавливаем qemu-system-x86 (14 из 61)…", "steps": [{"id": i, "title": t, "status": s} for i, t, s in steps]}))
nodectl.FIRSTBOOT_LOG = dirs["config"] / "firstboot.log"
@@ -54,6 +54,11 @@ def seed(root: Path) -> None:
nodectl.network_facts = lambda: {"interface": "enp3s0", "gateway": "192.168.1.1", "address": "192.168.1.10", "prefix": 24, "mac": "aa:bb:cc:dd:ee:ff", "wireless": False, "private": True, "is_vps": False, "virt": "none", "bridge_present": False, "on_bridge": False, "recommended": "bridge", "revert_armed": False, "bridge_possible": True}
nodectl.hardware_summary = lambda: {"hostname": "home-server", "cpu_model": "Intel Core i5-12400", "cpu_count": 6, "mem_total": 32 * 1024 ** 3, "disk_total": 480 * 1024 ** 3, "disk_free": 401 * 1024 ** 3, "kvm": True}
nodectl.set_timezone = lambda tz: (True, tz)
nodectl.timezones = lambda: {"current": "Europe/Moscow", "popular": nodectl.POPULAR_TIMEZONES, "all": nodectl.POPULAR_TIMEZONES}
if stage == "finished":
nodectl.mark_wizard_done()
nodectl.NODE_ENV = dirs["config"] / "web.env"
nodectl.NODE_ENV.write_text("VIRTUALITY_WEB_PORT=8088\nVIRTUALITY_TLS=1\nVIRTUALITY_AUTO_UPDATE=1\nVIRTUALITY_UPDATE_CHANNEL=stable\n")
for name, size in (("ubuntu-26.04-live-server-amd64.iso", 3), ("debian-13.7.0-amd64-netinst.iso", 1)):
with (dirs["iso"] / name).open("wb") as handle: