Skip to content

RunR 0.6.7

Choose a tag to compare

@brkfun brkfun released this 06 Nov 22:28
· 3 commits to main since this release
v0.6.7

RunR is an open-source, self-hosted serverless platform on Kubernetes and Knative: functions, containers, sandboxes, WebAssembly and durable workflows, with an API, a web console, the runr CLI, SDKs, a Terraform provider and a GitHub Action. You install it on infrastructure you operate, connected or air-gapped. It is developed by BRF Teknoloji and released under the MIT License.

0.6.7 is a maintenance release of 0.6.6. It fixes sandbox commands on Kata Containers 4.3.1 and gVisor, whose runtimes lost a command's input or output while the command still exited 0: on Cloud Hypervisor, QEMU and Firecracker a command's output stopped once its input ended, on Dragonball input over 64 KiB ended at 64 KiB, and on gVisor a write over 64 KiB could lose its end. Input that arrives short now fails with a message on every class. kube-prometheus-stack 92.21.2 (Prometheus v3.16.0) comes to new regions, and to existing ones by a command of the operator, and a sandbox command starts one process less.

Nothing needs a step: there is no database migration, Kata is not reinstalled, and running sandboxes keep running. Two things to know: a command on gVisor takes about 100 ms more, and a custom sandbox image needs cat and mkfifo.

Install

  • Kubernetes (Helm): the chart comes from BRF's public Helm repository, without credentials:
    helm repo add brf-tech https://helm.brf.sh
    helm upgrade --install runr brf-tech/runr --namespace runr --create-namespace --set domain=runr.example.com
    See the README and docs/install.md; helm show values brf-tech/runr lists every value. A pinned install adds --version 0.6.7; the API and UI images, the region agent and the event gateway follow the chart version.
  • Single host (Docker Compose, also air-gapped): compose/README.md, from a checkout of the release tag (git clone -b v0.6.7 https://github.com/BRF-Tech/runr.git).
  • CLI: curl -fsSL https://runr.sh/install.sh | sh on Linux and macOS. The archives of every platform are at runr.sh/dl (https://runr.sh/dl/cli/v0.6.7/) and attached below; check them against checksums.txt (docs/cli.md#install).
  • Terraform / OpenTofu: source = "brf-tech/runr", version = "~> 0.6", from the Terraform Registry; terraform init checks the archive against SHA256SUMS, signed with the RunR release key (key ID 2588846B241BC095). runr.sh serves the same archives under runr.sh/brf-tech/runr, for OpenTofu and for configurations that use that address (docs/terraform.md#install).
  • GitHub Action: uses: brf-tech/runr/actions/deploy@v0.6.7; it downloads the CLI from runr.sh (docs/github-action.md).
  • Images: every image is published under ghcr.io/brf-tech/runr by release-images.yml, for linux/amd64 and linux/arm64, and pulls anonymously.

The documentation is at runr.sh/docs and in the documentation index here.

Upgrading from 0.6.6

Upgrade in place with helm upgrade of the running release; never uninstall and install again, and back up the database first (Procedure in docs/upgrade.md). From 0.6.6 there is no database migration, the images keep their names, and nothing has to be set (0.6.6 → 0.6.7).

helm repo update brf-tech
helm upgrade runr brf-tech/runr --version 0.6.7 -n runr --reuse-values
  • Sandbox commands on Kata and gVisor travel differently. On Kata's Go runtime (Cloud Hypervisor, QEMU, Firecracker) a command's stdin is no longer closed while it runs: an /exec with stdin takes one exec more, as the input is written into the sandbox first and the command reads it from there. On Dragonball, input goes in acknowledged frames of 48 KiB, the next once the sandbox read the last: a 10 MiB upload took 6.6 s on the single-node test VM. On gVisor, a user command writes through pipes inside the sandbox, which costs about 100 ms per command on that VM; terminal sessions are unchanged. Running sandboxes, those started by 0.6.6 included, run their next command the new way (Sandbox input and output).
  • Input that arrives short fails. On every class, an upload, an archive, the stdin of /exec and the code of a code run are checked once written: one that arrived short fails with runr: the input ended after N of M bytes (the upload, the archive for those) instead of being stored short. An archive is written to /tmp/.runr/exec and checked before it is extracted, so while it is extracted it takes its size on the sandbox's disk twice.
  • A custom sandbox image (sandbox.allow_custom_images) now needs cat for /exec with stdin, mkfifo for the exec WebSocket without a terminal, and on Dragonball head or dd for any input. coreutils and busybox have them all.
  • The region agent and the event gateway move to 0.6.7. As in 0.6.0 to 0.6.6, they run at the installed version: after helm upgrade returned, the Job runr-region-reconcile-<revision> moves the regions' agents, queue consumers and topic publishers from agent:0.6.6 / queue-consumer:0.6.6 to ghcr.io/brf-tech/runr/agent:0.6.7 and queue-consumer:0.6.7; each rolls once. A region that pulls through a mirror of your own needs these two images there before the upgrade (Order of operations).
  • kube-prometheus-stack does not move by itself, because the move restarts Prometheus. php artisan cluster:patch-observability moves a region to 92.21.2 when it suits the region: Prometheus and its operator restart once, and no CRD step is needed. A region whose nodes pull through a mirror of their own needs quay.io/prometheus/prometheus:v3.16.0-distroless and ghcr.io/jkroepke/kube-webhook-certgen:1.11.1 there first (kube-prometheus-stack 92.21.2).
  • While the API and reverb pods roll, an exec WebSocket without a terminal that reaches a reverb pod of 0.6.6 runs as it did in 0.6.6.
  • Back to 0.6.6: a plain helm rollback (or helm upgrade with the 0.6.6 chart where only one package version is kept) on the same database; there is no migration to undo. The region Job of the 0.6.6 chart moves the region images back to 0.6.6, and Kata is not reinstalled either way. Sandbox commands then run the 0.6.6 way again, with the runtime bugs above. A region moved to kube-prometheus-stack 92.21.2 keeps it.
  • Terraform provider 0.6.7: its resources and data sources are the ones of 0.6.6.

From 0.6.5, upgrade straight to 0.6.7 and read 0.6.5 → 0.6.6 as well: 0.6.6 re-runs kata-deploy with Kata Containers 4.3.1, which stops the running Kata pods of every region with Kata, the region Traefik moves to chart 42.3.0 and deletes request headers with _ or . in their names, and Reverb refuses client events. From 0.6.4, also read 0.6.4 → 0.6.5: 0.6.5 adds the notification_user_states migration, the Helm value notifications.retentionDays, and its daily task deletes notifications older than 90 days. From 0.6.3, also read 0.6.3 → 0.6.4: 0.6.4 adds the captcha_settings migration and the Helm values captcha.*, and its first upgrade rolls the pods once. From 0.6.2, also read 0.6.2 → 0.6.3; from 0.6.1, also 0.6.1 → 0.6.2. From 0.6.0, also read 0.6.0 → 0.6.1 first: before a rollback to 0.6.0, let the running deploys finish (Rolling back to 0.6.0). From 0.5.10, read 0.5.10 → 0.6.0 in docs/upgrade.md first — in particular what to decide before the upgrade — and the notes of 0.6.0 to 0.6.6 in CHANGELOG.md; everything said there applies. From 0.5.9 or earlier, read the notes of the releases in between as well; from 0.5.8 or earlier, add --set api.image.tag= --set ui.image.tag= to that upgrade once (step 3 of the Procedure).

Changes in 0.6.7 (2026-11-06)

Upgrade notes

  • Nothing needs a step. There is no database migration, Kata is not reinstalled, and running
    sandboxes keep running: their next command runs the new way. See
    docs/upgrade.md.
  • A sandbox command on gVisor takes about 100 ms more on the single-node test VM: it
    writes through pipes inside the sandbox, so that a large write no longer loses its end. On
    Dragonball, input goes in acknowledged frames of 48 KiB (a 10 MiB upload took 6.6 s on the same
    VM). See docs/upgrade.md.
  • A custom sandbox image (sandbox.allow_custom_images) now needs cat for /exec with
    stdin, mkfifo for the exec WebSocket without a terminal, and on Dragonball head or dd for
    any input. coreutils and busybox have them all.
  • kube-prometheus-stack 92.21.2 does not reach an installed region by itself:
    php artisan cluster:patch-observability moves it and restarts Prometheus once. See
    docs/upgrade.md.

Changed

  • A sandbox command starts one process less. Every command ran mkdir -p /tmp/.runr/exec
    before it wrote its PID file; the sandbox pod now creates that directory (and
    /tmp/.runr/code) when it starts, and a command writes its PID file with the shell alone. On
    the single-node test VM (nested KVM, Kata 4.3.1) a command took 22–37 ms less at the median on
    Cloud Hypervisor, QEMU, Dragonball and gVisor (kubectl exec of the command's wrapper, n=60 per
    class; Firecracker unchanged). The code interpreter and the files of a create or of a claimed
    warm pod start no mkdir when their directories exist. Sandboxes started by 0.6.6 or earlier
    create the directory on their first command.
  • kube-prometheus-stack 92.21.2 (Prometheus v3.16.0, kube-webhook-certgen 1.11.1; the Prometheus
    Operator stays at v0.94.2). Regions installed from now on run it; an installed region keeps its
    chart until php artisan cluster:patch-observability, a change back to RunR's own monitoring or a
    new Serving install moves it. The move restarts Prometheus and its operator once and needs no step
    of its own: the operator's CRDs are the same. The chart no longer puts its version in the labels of
    the operator's pod, so a later chart upgrade restarts the operator only when the operator changes
    (upgrade.md).

Fixed

  • On Kata, a sandbox command's output no longer stops when its input ends. With Kata
    Containers 4.3.1 (RunR 0.6.6), the Go runtime behind Cloud Hypervisor, QEMU and Firecracker
    stops passing a command's stdout once the exec's stdin is closed: /run with more than 32 KiB
    of output timed out with 32 KiB, /exec with stdin lost what the command wrote after its
    input ended (and more than 32 KiB of it hung until the timeout), and the exec WebSocket lost the
    output after stdin_close. RunR no longer closes an exec's stdin while a command runs: the
    input of /exec and the code of /run are written into the sandbox by an exec of their own and
    read from there (an input whose command never started is removed after an hour), uploads and the
    env file of a claimed warm pod take exactly their bytes, and the exec WebSocket passes its input
    on in frames that end in-band, with the exit code from a marker the command's wrapper writes; a
    kill reaches the command through its PID file as before. Dragonball (runtime-rs) and gVisor were
    not affected. A custom image now needs cat for /exec with stdin and mkfifo for the exec
    WebSocket without a terminal (upgrade.md).
  • On Dragonball, input over 64 KiB no longer ends at 64 KiB. Kata 4.3.1's Rust runtime with the
    Dragonball VMM ends an exec's stdin once 64 KiB of it wait unread in the guest, and the command
    still exits 0: an upload over 64 KiB was stored short (100000 bytes written, 65536 read back), and
    /exec with stdin, a code run's code and the files of a create over 64 KiB were cut. Input to a
    Dragonball sandbox now goes in acknowledged frames of 48 KiB, the next once the sandbox read the
    last (on the single-node test VM a 10 MiB upload took 6.6 s). On every class, input that arrives
    short now fails with a message instead of being stored, and an archive is checked before it is
    extracted: tar takes an archive cut between two files without a word.
  • On gVisor, a large write of a command no longer loses its end. gVisor returns a short write
    when a program writes more than 64 KiB at once to an exec's stdout or stderr, and programs that do
    not write the rest lose it: Python's print("y" * 100000) came back with 65537 bytes (RunR's Python
    runtime runs unbuffered). A user command on gVisor now writes through pipes inside the sandbox,
    whose cat writes everything, with its exit code, kill and timeout as before; this costs about
    100 ms per command on the single-node test VM. Kata and runc were not affected.
  • kubectl's "command terminated with exit code N" no longer ends a command's stderr when that
    stderr did not end in a newline and the trailer came in the same piece of output.