← Палеокомпьютинг · Оберон · English

Каталог для Cozystack

Всё из проекта про Оберон ставится в кластер Cozystack так же, как Postgres или Kubernetes: форма в дашборде и кнопка. В том числе — виртуальная машина с архитектурой, которой в платформе нет.

Что вы получаете

Каталог подключается снаружи, штатным механизмом пакетов Cozystack. После этого у тенантов в дашборде появляются новые приложения:

  1. OberonVM

    Машина Вирта RISC5 как настоящая виртуальная машина в KubeVirt, в ней загружается система Оберон 1986 года. Поля: memory и hardware — base или chk, процессор с аппаратной проверкой границ массива; та же машина, на которую переключает страница о цене проверки.

  2. OberonLab

    Тринадцать лабораторных и методичка, раздаются изнутри кластера. По желанию — разовый прогон заданий, которым нужно пересобрать схему или компилятор: task — isa, compiler или check.

  3. Handbook

    Документация, которая раздаётся рядом с приложением, которое она описывает.

  4. Workbench

    Машина, лабораторные и методичка одной установкой.

  5. LangPack

    Окружение для языка: компилятор Оберона без операционной системы — разовый прогон программы или постоянная служба.

Как это устроено

Каталог — три репозитория, каждый один OCI-артефакт в ghcr.io/tym83/paleocomputing. Разделены по тому, какого доверия просят:

Тег репозитория — это его версия: обновление — переход на другой тег, откат — на прежний. Всё собирает, подписывает и выкладывает CI; подпись без ключа — её личность сам процесс сборки, проверить её может кто угодно.

Подключение

Делается один раз администратором кластера, утилитой cozypkg из репозитория Cozystack:

cozypkg tap oci://ghcr.io/tym83/paleocomputing/machines:v0.1.17
cozypkg tap oci://ghcr.io/tym83/paleocomputing/languages:v0.1.17
# tap подключает репозиторий, add ставит из него приложения
cozypkg add paleocomputing.machines
cozypkg add paleocomputing.languages

Проверяйте, что источник прочитал все компоненты, а не только что он готов:

kubectl get packagesource paleocomputing.machines
# reconciliation succeeded, generated 5 artifact(s)
Обновлять повторным подключением, а не правкой тега. Тег живёт в OCIRepository, а список компонентов — в PackageSource, и за тегом он не следует. Приложение, добавленное в новой версии, появится в дашборде и не развернётся. cozypkg tap с новым тегом обновляет оба места.

Что OberonVM нужно от кластера

Всё остальное в каталоге — обычные приложения. OberonVM — нет: KubeVirt знает четыре архитектуры, и RISC5 среди них нет. Форков KubeVirt и Cozystack здесь нет — описание домена переписывает перехватчик OnDefineDomain, штатная точка расширения. Но две вещи задаются один раз на уровне кластера, и тенант задать их не может:

  1. Признак Sidecar

    В ресурсе KubeVirt. Без него перехватчик не запускается. Он включается на весь кластер: любой, кто может создавать виртуалки напрямую, сможет подключить к ним свой перехватчик — на общем кластере это стоит взвесить.

  2. Образ virt-launcher, который знает RISC5

    В нём наша цель QEMU и libvirt с вкомпилированной архитектурой — libvirt спрашивает эмулятор, что он такое, а не верит описанию домена. Образ публикуется в каждом релизе каталога как ghcr.io/tym83/paleocomputing/virt-launcher:<kubevirt>-paleo-<релиз> для KubeVirt 1.8.4 и 1.9.0, на узлах amd64 и arm64. Launcher обязан совпадать с версией KubeVirt.

Смена launcher перевозит все виртуалки кластера. Новый образ launcher KubeVirt считает обновлением нагрузки. При workloadUpdateMethods: [LiveMigrate, Evict] — а в Cozystack так по умолчанию — он живьём мигрирует каждую виртуалку на новый образ, а те, что мигрировать не могут, перезапускает. Это происходит при включении launcher, при возврате штатного и при каждом обновлении KubeVirt. Проверьте заранее:
kubectl -n cozy-kubevirt get kubevirt kubevirt \
  -o jsonpath='{.spec.workloadUpdateStrategy}'
Мы узнали это на себе: через 16 секунд после первой подмены KubeVirt начал переносить весь кластер.

Рекомендуемый путь — компонент платформы. Подключите репозиторий platform и поставьте kubevirt-paleo-launcher — он привилегированный, поэтому нужно явное согласие оператора:

cozypkg tap oci://ghcr.io/tym83/paleocomputing/platform:v0.1.17
cozypkg add paleocomputing.platform --allow-privileged

Он следит за версией KubeVirt в кластере и держит launcher в паре с ней. Меняет он ровно один аргумент — образ после --launcher-image, JSON-патчем с двумя проверками перед заменой, — и не трогает остальные аргументы и чужие настройки. На версии KubeVirt, под которую образа нет, на узлах архитектуры, под которую образа нет, и при любом сомнении он свою правку снимает: чужие машины останавливаются, все остальные работают. Удаление компонента правку тоже снимает.

Если автоперевод машин включён, компонент ждёт согласия. Свою правку он не поставит и не поменяет, пока переезд не разрешён явно; состояние у него тогда NeedsConsent, с событием на ресурсе KubeVirt. Разрешить можно значением компонента allowWorkloadUpdate: true или аннотацией на ресурсе KubeVirt:

kubectl -n cozy-kubevirt annotate kubevirt kubevirt \
  paleocomputing.io/allow-workload-update=true
kubectl -n cozy-kubevirt get cm kubevirt-paleo-launcher-status \
  -o jsonpath='{.data.state} {.data.reason}'

Снятие правки согласия не ждёт: это безопасное направление. Чтобы сделать то же руками, без компонента, положите ту же единственную замену в customizeComponents; точный патч и откат — в инструкции для KubeVirt. Не заменяйте весь список аргументов: заодно замёрзнут образ экспорта, порт и уровень журнала virt-controller.

Это касается всех виртуалок кластера, а не только Оберона. Образ — штатный virt-launcher, в который добавлены библиотеки libvirt и один эмулятор; обычные машины на нём работают, и каждый релиз проверяется загрузкой Ubuntu на нём. Выставленная руками правка обязана следовать за обновлениями KubeVirt — launcher другой версии ломает все машины. Компонент делает это за вас.

Установка машины

Из дашборда — форма OberonVM — или ресурсом:

apiVersion: apps.cozystack.io/v1alpha1
kind: OberonVM
metadata:
  name: wirth
spec:
  memory: 128Mi
  hardware: chk     # или base

Самой машине хватает шестнадцати мегабайт, остальное уходит на обвязку KubeVirt. ПЗУ и системный диск приходят на томе, который наполняется один раз, при установке.

Экран открывается через virtctl vnc oberon-vm-oberon-vm-wirth с правами самого тенанта (без локального VNC-клиента — с --proxy-only). Дашборд показывает машину, её состояние и поды, но вкладка VNC-консоли в текущих версиях дашборда есть только у VMInstance. Оберону нужны три кнопки мыши; средняя, которой запускаются команды, — Alt и левый щелчок, и первые полминуты машина сама пишет это на своём экране. В дашборде у каталога свой раздел — Paleocomputing. Дашборды, которые рисуют в меню только IaaS, PaaS и NaaS (1.6 и раньше), показывают его в конце списка «Show all apps».

Машина — обычная VirtualMachine KubeVirt: тенант с обычной ролью use останавливает, запускает и перезапускает её из дашборда или virtctl restart. Системный диск хранит файлы пользователя между перезапусками и обновлениями — из выпуска обновляется только прошивка.

Известные ограничения

  1. Машина не мигрирует. При выводе узла на обслуживание она останавливается, а не переезжает.

  2. Машины, поставленные версией v0.1.10 и раньше, перед обновлением нужно переустановить. Их том создан хуком установки и в релиз не входит; обновление до любого более позднего выпуска падает на нём («already exists»). Удалите такую машину и поставьте заново.

  3. Версии до v0.1.9 включительно оставляют том после удаления машины. Он создаётся один раз при установке, и такие ресурсы Helm при удалении не убирает. В следующих версиях его убирает задача, которая запускается при удалении; машина, удалённая ещё на v0.1.9 или раньше, оставляет oberon-vm-<имя>-payload — его удалите вручную.

  4. Версии до v0.1.7 включительно нельзя обновить под работающей машиной. Обновление пересоздавало том машины, и он зависал в Terminating. Исправлено в v0.1.8; при переходе с более ранней версии такие машины удалите и поставьте заново.