Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/reproducibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ jobs:
oci/nvidia-container-toolkit-sysext.bst
bluefin-server/os-sd-boot-signed.bst
homelab/homelab-templates.bst
runtimes/podman-sysext.bst
runtimes/docker-sysext.bst
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down
2 changes: 1 addition & 1 deletion Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ validate: gen-dev-keys
python3 .github/scripts/check-release-version.py
python3 .github/scripts/check-k0s-version.py
python3 .github/scripts/check-renovate-series.py
just bst show --deps all oci/bluefin-server-image.bst oci/k0s-sysext.bst oci/zfs-sysext.bst oci/kubeadm-sysext.bst oci/homelab-sysext.bst oci/argo-workflows-sysext.bst oci/mcp-sysext.bst oci/kubestellar-sysext.bst oci/nvidia-open-595-sysext.bst oci/nvidia-container-toolkit-sysext.bst
just bst show --deps all oci/bluefin-server-image.bst oci/k0s-sysext.bst oci/zfs-sysext.bst oci/kubeadm-sysext.bst oci/homelab-sysext.bst oci/argo-workflows-sysext.bst oci/mcp-sysext.bst oci/kubestellar-sysext.bst oci/nvidia-open-595-sysext.bst oci/nvidia-container-toolkit-sysext.bst runtimes/podman-sysext.bst runtimes/docker-sysext.bst

# Run the unit test suite (pytest + bats; bats from a container if not installed).
[group('dev')]
Expand Down
16 changes: 15 additions & 1 deletion docs/skills/systemd-sysext-extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Extensibility via systemd-sysext and systemd-confext for Bluefin Se
metadata:
type: reference
status: stable
last_updated: "2026-10-05"
last_updated: "2026-10-16"
context7-sources:
- /systemd/systemd
---
Expand Down Expand Up @@ -113,6 +113,20 @@ update and a rollback. Their units skip themselves on a node without an
NVIDIA GPU, and `nvidia-flavour-guard.service` fails when two flavours are
merged.

The optional **Podman** and **Docker** host engines use the same version-locked
scheme (`runtimes/{podman,docker}-sysext.bst`, features `podman` and `docker`).
Both features and their user units default off; no rootful socket is created.
Their private `/usr/lib/bluefin/{podman,docker}` binaries and separate state do
not replace Kubernetes' containerd or CNI. Podman is composed from FSDK; Docker
uses digest-pinned upstream static binaries plus the FSDK rootless support closure.
An administrator must provision non-overlapping subordinate UID/GID ranges and
enable lingering for the intended nonroot user. After enabling/fetching the
chosen feature and merging its sysext, that user runs `systemctl --user daemon-reload`
then `systemctl --user enable --now bluefin-podman.socket` or
`systemctl --user enable --now bluefin-docker.service`. The private endpoints are
`$XDG_RUNTIME_DIR/bluefin-podman/api.sock` and
`$XDG_RUNTIME_DIR/bluefin-docker/api.sock`; no client or engine enters base `/usr`.

The **homelab** sysext (`oci/homelab-sysext.bst`, `homelab_<image-version>.raw`,
sysupdate feature `homelab`) is version-locked the same way and carries no
binaries: the default homelab component set as plain YAML under
Expand Down
10 changes: 10 additions & 0 deletions elements/oci/bluefin-server-image.bst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ description: |
zfs_<ver>.raw.zst, kubestellar_<ver>.raw.zst, kubeadm_<ver>.raw.zst,
homelab_<ver>.raw.zst, argo-workflows_<ver>.raw.zst, mcp_<ver>.raw.zst,
nvidia-open-595_<ver>.raw.zst opt-in sysexts locked to this image version
podman_<ver>.raw.zst, docker_<ver>.raw.zst
opt-in rootless host engine sysexts
k0s-<k0s-ver>.raw.zst opt-in k0s sysext (own version axis)
nvidia-container-toolkit-<ctk-ver>.raw.zst
opt-in NVIDIA Container Toolkit sysext
Expand Down Expand Up @@ -104,6 +106,12 @@ build-depends:
- filename: homelab/homelab-templates.bst
config:
location: /homelab-templates
- filename: runtimes/podman-sysext.bst
config:
location: /sysext/podman
- filename: runtimes/docker-sysext.bst
config:
location: /sysext/docker

variables:
image-name: bluefin-server_%{image-version}
Expand Down Expand Up @@ -271,6 +279,8 @@ config:
/sysext/mcp/mcp_%{image-version}.raw.zst \
/sysext/nvidia-open-595/nvidia-open-595_%{image-version}.raw.zst \
/sysext/nvidia-container-toolkit/nvidia-container-toolkit-*.raw.zst "%{install-root}/"
cp /sysext/podman/podman_%{image-version}.raw.zst \
/sysext/docker/docker_%{image-version}.raw.zst "%{install-root}/"
install -m644 -t "%{install-root}" /homelab-templates/*.bu /homelab-templates/*.ign

- |
Expand Down
4 changes: 4 additions & 0 deletions elements/oci/bluefin-server-sbom.bst
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ build-depends:
- nvidia/nvidia-open-595.bst
- oci/nvidia-container-toolkit-sysext.bst
- nvidia/nvidia-container-toolkit.bst
- runtimes/podman-sysext.bst
- runtimes/podman-runtime.bst
- runtimes/docker-sysext.bst
- runtimes/docker-bin.bst

config:
path: /bluefin-server.spdx.json
Expand Down
88 changes: 88 additions & 0 deletions elements/runtimes/docker-bin.bst
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
kind: manual
description: |
Maintained upstream static Docker engine and real CLI, private containerd/runc,
RootlessKit, slirp4netns, Compose and Buildx. All release assets are sha256-pinned
for each architecture. The inspected bakery docker image uses /usr/bin/containerd
and global rootful units, so cannot merge beside kubeadm; reuse its upstream
artifact chain with a private /usr/lib/bluefin tree. Nothing is installed in the base.

(@):
- include/arch.yml
- include/runtimes.yml

build-depends:
- base/base-stack.bst

variables:
strip-binaries: ""

sources:
- kind: tar
url: https://download.docker.com/linux/static/stable/x86_64/docker-%{docker-version}.tgz
ref: 33e1ab8b63d14bca449f7a3d30d7f6aa669daa544e60a86b17fec87f61afe2b4
base-dir: docker
directory: docker
- kind: tar
url: https://download.docker.com/linux/static/stable/x86_64/docker-rootless-extras-%{docker-version}.tgz
ref: 6b4a2e085a1e4ade5ba3de99fd770a0a9b53c719e6bf6b1632242bf4b068adb6
base-dir: docker-rootless-extras
directory: docker-rootless-extras
- kind: remote
url: github:rootless-containers/slirp4netns/releases/download/v%{slirp4netns-version}/slirp4netns-x86_64
ref: 411167abceff1fc8a7c562f53ed9f26d3ec8a17df4e2fe6eaa3bd53f1c1e1d48
directory: slirp4netns
filename: slirp4netns
- kind: remote
url: github:docker/compose/releases/download/v%{docker-compose-version}/docker-compose-linux-x86_64
ref: 40343e21ca777173e69cff5dbafeb37c6f81f3b0d57d9e597f036e95eb63e76a
directory: plugins
filename: docker-compose
- kind: remote
url: github:docker/buildx/releases/download/v%{docker-buildx-version}/buildx-v%{docker-buildx-version}.linux-amd64
ref: 4fe4cc38adf48169132749b6ca22a990928db0118e3407584ee553723115d287
directory: plugins
filename: docker-buildx

(?):
- arch == "aarch64":
sources:
- kind: tar
url: https://download.docker.com/linux/static/stable/aarch64/docker-%{docker-version}.tgz
ref: 811f6eee271678fc98dbe5c4d896c00fc5fe2daa4f7a37069c17abc036eab85b
base-dir: docker
directory: docker
- kind: tar
url: https://download.docker.com/linux/static/stable/aarch64/docker-rootless-extras-%{docker-version}.tgz
ref: f1b76a0721101e15c1eabeccf08751c0d42206defe06422de2e4b8897fc0f129
base-dir: docker-rootless-extras
directory: docker-rootless-extras
- kind: remote
url: github:rootless-containers/slirp4netns/releases/download/v%{slirp4netns-version}/slirp4netns-aarch64
ref: 045f85dd0bc51a61b99cdfe6bd22282cbc308b73caa64fc8859c11d3775c5817
directory: slirp4netns
filename: slirp4netns
- kind: remote
url: github:docker/compose/releases/download/v%{docker-compose-version}/docker-compose-linux-aarch64
ref: 733ec76717ceb59052a9609b9dadfb523b2df8eab57a54212872d10a58078ea2
directory: plugins
filename: docker-compose
- kind: remote
url: github:docker/buildx/releases/download/v%{docker-buildx-version}/buildx-v%{docker-buildx-version}.linux-arm64
ref: 38e890e1a162bfdbf32fbe91404991dc4fc28e55b0de901b34374a061bab4d2c
directory: plugins
filename: docker-buildx

config:
install-commands:
- |
set -eu
root="%{install-root}/usr/lib/bluefin/docker"
install -d "$root/bin" "$root/lib/docker/cli-plugins"
for b in docker dockerd docker-init docker-proxy containerd containerd-shim-runc-v2 ctr runc; do
install -m0755 "docker/$b" "$root/bin/$b"
done
for b in rootlesskit dockerd-rootless.sh; do
install -m0755 "docker-rootless-extras/$b" "$root/bin/$b"
done
install -m0755 slirp4netns/slirp4netns "$root/bin/slirp4netns"
install -m0755 plugins/docker-compose plugins/docker-buildx "$root/lib/docker/cli-plugins/"
34 changes: 34 additions & 0 deletions elements/runtimes/docker-runtime.bst
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
kind: manual
description: |
Static Docker plus FSDK-built nft-compatible iptables and its library/plugin
closure under a private prefix. Never installs a shared containerd, runc,
iptables, system unit or root socket from another runtime provider.

build-depends:
- base/base-stack.bst
- freedesktop-sdk.bst:components/findutils.bst
- filename: runtimes/docker-bin.bst
config:
location: /docker
- filename: freedesktop-sdk.bst:components/iptables.bst
config:
location: /firewall

variables:
strip-binaries: ""

config:
install-commands:
- |
set -eu
root="%{install-root}/usr/lib/bluefin/docker"
mkdir -p "$root"
cp -a /docker/usr/lib/bluefin/docker/. "$root/"
install -d "$root/lib" "$root/lib/xtables"
install -m0755 /firewall%{bindir}/xtables-nft-multi "$root/bin/xtables-nft-multi"
for b in iptables iptables-save iptables-restore ip6tables ip6tables-save ip6tables-restore; do
ln -s xtables-nft-multi "$root/bin/$b"
done
find /firewall%{libdir} -maxdepth 1 \( -type f -o -type l \) -name '*.so*' \
-exec cp -L -t "$root/lib" {} +
cp -a /firewall%{libdir}/xtables/. "$root/lib/xtables/"
45 changes: 45 additions & 0 deletions elements/runtimes/docker-sysext.bst
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
kind: manual
description: |
Optional real host docker system extension, image-locked and delivered through
the signed Bluefin release. Rootless owner units are opt-in; rootful API sockets
are never created or exposed by this integration.
Private /usr/lib/bluefin binaries and independent state coexist with kubeadm.

(@):
- include/arch.yml
- include/image.yml
- include/runtimes.yml
- include/sysext.yml

build-depends:
- base/base-stack.bst
- freedesktop-sdk.bst:components/erofs-utils.bst
- freedesktop-sdk.bst:components/zstd.bst
- filename: runtimes/docker-runtime.bst
config:
location: /runtime

sources:
- kind: local
path: files/runtimes/docker
directory: sysext-src

variables:
strip-binaries: ""
sysext-name: "docker"
sysext-image: "docker_%{image-version}"
sysext-release: "docker_%{image-version}"
sysext-version: "%{image-version}"
sysext-architecture: "%{systemd-arch}"

config:
install-commands:
- |
set -eu
mkdir -p sysext/usr/lib/bluefin
cp -a /runtime/usr/lib/bluefin/docker sysext/usr/lib/bluefin/
lib="sysext%{indep-libdir}"
install -d "$lib/systemd/user"
install -m0644 sysext-src/bluefin-docker.service "$lib/systemd/user/"
install -D -m0644 sysext-src/80-bluefin-docker.preset "$lib/systemd/user-preset/80-bluefin-docker.preset"
- "%{sysext-pack}"
57 changes: 57 additions & 0 deletions elements/runtimes/podman-runtime.bst
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
kind: manual
description: |
FSDK-native Podman with its complete runtime closure, never a nested engine in
Homebrew. The junction pins Podman 6.1, conmon, crun, netavark, aardvark-dns,
passt, fuse-overlayfs and containers-common. Private paths keep kubeadm's runc
and containerd untouched. Only shared libraries and engine helpers are copied;
no second systemd, shell, account database or host /usr/bin provider ships.

build-depends:
- base/base-stack.bst
- freedesktop-sdk.bst:components/findutils.bst
- freedesktop-sdk.bst:components/patchelf.bst
- filename: freedesktop-sdk.bst:components/podman.bst
config:
location: /podman
- filename: freedesktop-sdk.bst:components/aardvark-dns.bst
config:
location: /podman

sources:
- kind: local
path: files/runtimes/podman
directory: runtime-src

variables:
strip-binaries: ""

config:
install-commands:
- |
set -eu
root="%{install-root}/usr/lib/bluefin/podman"
install -d "$root/bin" "$root/lib" "$root/libexec/podman" "$root/share/containers"
for b in podman crun pasta passt fuse-overlayfs catatonit nft; do
install -m0755 "/podman%{bindir}/$b" "$root/bin/$b"
done
install -m0755 "/podman%{bindir}/conmon" "$root/libexec/podman/conmon"
for b in netavark aardvark-dns rootlessport; do
install -m0755 "/podman%{libexecdir}/podman/$b" "$root/libexec/podman/$b"
done
# Dereference soname links into this private library directory. Host ABI is
# exactly the same pinned FSDK; no foreign loader or shared /usr libs merge.
find "/podman%{libdir}" -maxdepth 1 \( -type f -o -type l \) -name '*.so*' \
-exec cp -L -t "$root/lib" {} +
# OCI runtimes must work without the wrapper's loader environment.
# Give crun and its private library independent, relative loader paths.
patchelf --set-rpath '$ORIGIN/../lib' "$root/bin/crun"
for library in "$root"/lib/libcrun.so*; do
patchelf --set-rpath '$ORIGIN' "$library"
done
cp -a "/podman%{datadir}/containers/." "$root/share/containers/"
install -d "$root/etc/containers"
cp -a /podman/etc/containers/. "$root/etc/containers/"
install -m0644 runtime-src/containers.conf "$root/containers.conf"
install -m0644 runtime-src/storage.conf "$root/storage.conf"
install -m0644 runtime-src/tmpfiles.conf "$root/tmpfiles.conf"
install -m0755 runtime-src/podman "$root/podman"
45 changes: 45 additions & 0 deletions elements/runtimes/podman-sysext.bst
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
kind: manual
description: |
Optional real host podman system extension, image-locked and delivered through
the signed Bluefin release. Rootless owner units are opt-in; rootful API sockets
are never created or exposed by this integration.
Private /usr/lib/bluefin binaries and independent state coexist with kubeadm.

(@):
- include/arch.yml
- include/image.yml
- include/runtimes.yml
- include/sysext.yml

build-depends:
- base/base-stack.bst
- freedesktop-sdk.bst:components/erofs-utils.bst
- freedesktop-sdk.bst:components/zstd.bst
- filename: runtimes/podman-runtime.bst
config:
location: /runtime

sources:
- kind: local
path: files/runtimes/podman
directory: sysext-src

variables:
strip-binaries: ""
sysext-name: "podman"
sysext-image: "podman_%{image-version}"
sysext-release: "podman_%{image-version}"
sysext-version: "%{image-version}"
sysext-architecture: "%{systemd-arch}"

config:
install-commands:
- |
set -eu
mkdir -p sysext/usr/lib/bluefin
cp -a /runtime/usr/lib/bluefin/podman sysext/usr/lib/bluefin/
lib="sysext%{indep-libdir}"
install -d "$lib/systemd/user"
install -m0644 sysext-src/bluefin-podman.service sysext-src/bluefin-podman.socket "$lib/systemd/user/"
install -D -m0644 sysext-src/80-bluefin-podman.preset "$lib/systemd/user-preset/80-bluefin-podman.preset"
- "%{sysext-pack}"
15 changes: 15 additions & 0 deletions files/os/sysupdate.d/41-podman.transfer
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[Transfer]
Features=podman
ProtectVersion=%A

[Source]
Type=url-file
Path=https://github.com/projectbluefin/server/releases/latest/download/
MatchPattern=podman_@v.raw.zst

[Target]
Type=regular-file
Path=/var/lib/extensions
MatchPattern=podman_@v.raw
Mode=0444
InstancesMax=2
15 changes: 15 additions & 0 deletions files/os/sysupdate.d/42-docker.transfer
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[Transfer]
Features=docker
ProtectVersion=%A

[Source]
Type=url-file
Path=https://github.com/projectbluefin/server/releases/latest/download/
MatchPattern=docker_@v.raw.zst

[Target]
Type=regular-file
Path=/var/lib/extensions
MatchPattern=docker_@v.raw
Mode=0444
InstancesMax=2
2 changes: 2 additions & 0 deletions files/os/sysupdate.d/docker.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[Feature]
Description=Opt-in rootless host Docker engine, locked to the image version
Loading
Loading