← Paleocomputing · Oberon · Русский

The catalog for Cozystack

Everything from the Oberon project, installable in a Cozystack cluster the way Postgres or Kubernetes is: a form in the dashboard and a button. Among it — a virtual machine with an architecture the platform does not have.

What you get

The catalog plugs in from outside, through the Cozystack package mechanism. After that, tenants see new applications in the dashboard:

  1. OberonVM

    Wirth's RISC5 as a real virtual machine in KubeVirt, booting the Oberon system of 1986. Fields: memory and hardware — base, or chk for the processor with the hardware array bounds check, the same machine the bounds-check page switches to.

  2. OberonLab

    The thirteen labs and the handbook, served inside the cluster. Optionally a batch run of the labs that need the circuit or the compiler rebuilt: task is isa, compiler or check.

  3. Handbook

    Documentation served next to the application it documents.

  4. Workbench

    The machine, its labs and its handbook installed as one thing.

  5. LangPack

    An environment for a language: the Oberon compiler without an operating system, for a one-off run of a program or as a standing service.

How it is put together

The catalog is three repositories, each a single OCI artifact in ghcr.io/tym83/paleocomputing. They are split by the trust they ask for:

A repository's tag is its version: upgrading is moving to another tag, rolling back is moving to the previous one. Everything is built, signed and published by CI; the signature is keyless — its identity is the build workflow itself, and anyone can verify it.

Plugging it in

Done once, by the cluster administrator, with cozypkg from the Cozystack repository:

cozypkg tap oci://ghcr.io/tym83/paleocomputing/machines:v0.1.17
cozypkg tap oci://ghcr.io/tym83/paleocomputing/languages:v0.1.17
# tap makes the repository known; add installs its applications
cozypkg add paleocomputing.machines
cozypkg add paleocomputing.languages

Check that the source has read every component, not just that it is ready:

kubectl get packagesource paleocomputing.machines
# reconciliation succeeded, generated 5 artifact(s)
Upgrade by tapping again, not by editing the tag. The tag lives in the OCIRepository, but the list of components lives in the PackageSource and does not follow it. A new application added in a newer version shows up in the dashboard and then fails to deploy. cozypkg tap with the new tag updates both.

What OberonVM needs from the cluster

Everything else in the catalog is an ordinary application. OberonVM is not: KubeVirt knows four architectures and RISC5 is not one of them. No fork of KubeVirt or Cozystack is involved — the domain is rewritten by an OnDefineDomain hook, a supported extension point. But two things are set once, at the cluster level, and a tenant cannot set them:

  1. The Sidecar feature gate

    In the KubeVirt resource. Without it the hook never runs. It is cluster-wide: anyone who can create VMs directly can then attach a hook of their own — weigh that on a shared cluster.

  2. A virt-launcher image that knows RISC5

    It carries our QEMU target and a libvirt with the architecture compiled in — libvirt asks the emulator what it is rather than trusting the domain. The image is published per catalog release as ghcr.io/tym83/paleocomputing/virt-launcher:<kubevirt>-paleo-<release> for KubeVirt 1.8.4 and 1.9.0, on amd64 and arm64 nodes. The launcher must match the KubeVirt version.

Switching the launcher moves every virtual machine in the cluster. KubeVirt treats a new launcher image as a workload update. With workloadUpdateMethods: [LiveMigrate, Evict] — the Cozystack default — it live-migrates every VM to the new image and restarts the ones that cannot migrate. That happens when the launcher is switched on, when it is switched back, and on every KubeVirt upgrade. Check it first:
kubectl -n cozy-kubevirt get kubevirt kubevirt \
  -o jsonpath='{.spec.workloadUpdateStrategy}'
We learned it the hard way: 16 seconds after the first switch, KubeVirt started migrating the whole cluster.

The recommended way is the platform component. Tap the platform repository and install kubevirt-paleo-launcher — it is privileged, so it needs the operator's explicit consent:

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

It watches the cluster's KubeVirt version and keeps the launcher matched to it. It changes one argument only — the image after --launcher-image, as a JSON patch with two tests before the replace — and leaves every other argument and customization alone. On a KubeVirt version it has no image for, on nodes of an architecture it has no image for, or on any doubt, it removes its change: foreign machines stop, every other VM keeps working. Uninstalling it removes the change as well.

If automatic workload updates are on, the component waits for consent. It will not put in or change its launcher until you allow the migration explicitly; its state is then NeedsConsent, with an event on the KubeVirt resource. Allow it with the component value allowWorkloadUpdate: true or with an annotation on the KubeVirt resource:

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}'

Removing its change never waits for consent: that is the safe direction. To do the same by hand, without the component, put the same single replacement into customizeComponents; the exact patch and the removal are in the KubeVirt guide. Do not replace the whole argument list: it would freeze the exporter image, port and log level of virt-controller too.

This affects every virtual machine in the cluster, not only Oberon. The image is the stock virt-launcher with the libvirt libraries and one emulator added; ordinary machines keep working on it, and every release is checked by booting an Ubuntu VM on it. Set by hand, the patch must follow KubeVirt upgrades — a launcher from a different version breaks every machine. The component does this for you.

Installing a machine

From the dashboard — the OberonVM form — or as a resource:

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

The machine needs sixteen megabytes; the rest goes to the KubeVirt scaffolding. Its read-only memory and system disk arrive on a volume that is filled once, at install time.

The screen is reached with virtctl vnc oberon-vm-oberon-vm-wirth, with the tenant's own rights (add --proxy-only if there is no local VNC viewer). The dashboard shows the machine, its status and pods, but in current dashboard versions the VNC console tab exists only for VMInstance. Oberon wants three mouse buttons; the middle one, which runs commands, is Alt with a left click, and the machine says so on its own screen for the first half minute. In the dashboard the catalog has its own section, Paleocomputing. Dashboards that render only IaaS, PaaS and NaaS in the sidebar (1.6 and earlier) show it at the end of “Show all apps”.

The machine is an ordinary KubeVirt VirtualMachine: a tenant with the usual use role can stop, start and restart it from the dashboard or with virtctl restart. The system disk keeps the user's files across restarts and upgrades — only the firmware is refreshed from the release.

Known limits

  1. The machine does not migrate. When a node is drained, it stops rather than moves.

  2. Machines installed with v0.1.10 or earlier must be reinstalled before upgrading. Their volume was created by an install hook and is not part of the release; upgrading them to any later release fails on that volume ("already exists"). Delete such a machine and install it again.

  3. Versions up to v0.1.9 leave the machine's volume behind when it is deleted. The volume is created once, at install time, and Helm does not remove such resources on uninstall. Later versions clean it up with a job that runs on deletion; a machine deleted while still on v0.1.9 or earlier leaves oberon-vm-<name>-payload to be removed by hand.

  4. Versions up to v0.1.7 cannot be upgraded under a running machine. Upgrading recreated the machine's volume, which hung in Terminating. Fixed in v0.1.8; when coming from an earlier version, delete such machines and install them again.