← Paleocomputing · Oberon · Русский
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.
The catalog plugs in from outside, through the Cozystack package mechanism. After that, tenants see new applications in the dashboard:
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.
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.
Documentation served next to the application it documents.
The machine, its labs and its handbook installed as one thing.
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.
The catalog is three repositories, each a single OCI artifact in
ghcr.io/tym83/paleocomputing. They are split by the trust
they ask for:
machines — OberonVM, OberonLab, Handbook, Workbench;languages — LangPack;images — boot images for ordinary KubeVirt disks. The only part that writes outside a tenant, into cozy-public; it is tagged privileged and the Cozystack validator warns about it.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.
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)
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.
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:
Sidecar feature gateIn 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.
virt-launcher image that knows RISC5It 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.
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.
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.
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.
The machine does not migrate. When a node is drained, it stops rather than moves.
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.
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.
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.