Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Create Linux OCI runtime roots across reboot
  • Loading branch information
gitcommit90 committed Jul 30, 2026
commit d2829c12116dcf825e09d904a863b0cb1eea3752
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Repeat Linux installation preserves the root-owned OCI runtime and existing
channel storage permissions instead of recursively rewriting the new state
namespace as the application service user.
- Linux installs declare Podman's ephemeral runtime roots through systemd
tmpfiles, so the hardened service starts on a fresh host and after reboot
before any container has happened to create those directories.
- Windows packaging builds the app and Squirrel staging tree beneath one fresh
drive-root scratch directory, keeping deeply nested runtime dependencies
inside Squirrel's legacy 260-character path limit.
Expand Down
1 change: 1 addition & 0 deletions site/public/apply-linux-release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ HOST_CONTRACT_PATHS=(
/usr/libexec/1helm-oci-runtime
/etc/1helm/oci-runtime-v1.conf
/etc/sudoers.d/1helm-oci-runtime
/etc/tmpfiles.d/1helm-oci.conf
/usr/lib/1helm-oci/Containerfile.oci
/etc/systemd/system/1helm.service
/etc/systemd/system/1helm-update.service
Expand Down
13 changes: 13 additions & 0 deletions site/public/install-linux-units.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ id "$SERVICE_USER" >/dev/null 2>&1 || { echo "The 1Helm service account does not
install -o root -g root -m 0755 "$RELEASE_ROOT/site/public/update-host.sh" "$INSTALL_ROOT/update-host.sh"
install -o root -g root -m 0755 "$RELEASE_ROOT/site/public/uninstall-host.sh" "$INSTALL_ROOT/uninstall-host.sh"

# ProtectSystem=strict resolves ReadWritePaths before it runs the service. Keep
# Podman's host-only scratch roots present both now and after every reboot so a
# completely fresh machine never fails mount-namespace setup before 1Helm can
# invoke its root-owned runtime helper.
install -m 0644 /dev/stdin /etc/tmpfiles.d/1helm-oci.conf <<'EOF'
d /run/1helm-oci 0755 root root -
d /run/containers 0755 root root -
d /run/crun 0755 root root -
d /run/libpod 0700 root root -
d /run/netns 0755 root root -
EOF
systemd-tmpfiles --create /etc/tmpfiles.d/1helm-oci.conf

install -m 0644 /dev/stdin /etc/systemd/system/1helm.service <<EOF
[Unit]
Description=1Helm durable agent workspace
Expand Down
1 change: 1 addition & 0 deletions site/public/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ HOST_CONTRACT_PATHS=(
/usr/libexec/1helm-oci-runtime
/etc/1helm/oci-runtime-v1.conf
/etc/sudoers.d/1helm-oci-runtime
/etc/tmpfiles.d/1helm-oci.conf
/usr/lib/1helm-oci/Containerfile.oci
/etc/systemd/system/1helm.service
/etc/systemd/system/1helm-update.service
Expand Down
1 change: 1 addition & 0 deletions site/public/update-host.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ HOST_CONTRACT_PATHS=(
/usr/libexec/1helm-oci-runtime
/etc/1helm/oci-runtime-v1.conf
/etc/sudoers.d/1helm-oci-runtime
/etc/tmpfiles.d/1helm-oci.conf
/usr/lib/1helm-oci/Containerfile.oci
/etc/systemd/system/1helm.service
/etc/systemd/system/1helm-update.service
Expand Down
4 changes: 4 additions & 0 deletions test/site.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ test("installer assets are explicit and syntax-valid", () => {
assert.match(linuxUnits, /HELM_INSTALL_KIND=linux-systemd/, "standard Linux installs identify their host-owned update mechanism");
assert.match(readFileSync(`${root}/src/server/channel-computers.ts`, "utf8"), /HELM_INSTALL_KIND === "linux-systemd"[\s\S]*source-tree fallback is disabled/, "installed Linux services cannot silently execute a helper from a mutable source checkout");
assert.match(linuxUnits, /Delegate=yes/, "systemd delegates the service cgroup required for nested channel containers");
assert.match(linuxUnits, /\/etc\/tmpfiles\.d\/1helm-oci\.conf[\s\S]*systemd-tmpfiles --create/, "fresh installs and boot recreate Podman's ephemeral runtime roots before the hardened service namespace is assembled");
for (const path of ["/run/1helm-oci", "/run/containers", "/run/crun", "/run/libpod", "/run/netns"]) {
assert.match(linuxUnits, new RegExp(`^d ${path.replaceAll("/", "\\/")} [0-7]{4} root root -$`, "m"), `tmpfiles owns the ephemeral ${path} runtime tree across reboot`);
}
for (const path of ["/run/containers", "/run/crun", "/run/libpod", "/run/lock", "/run/netns"]) {
assert.match(linuxUnits, new RegExp(`ReadWritePaths=[^\\n]*${path.replaceAll("/", "\\/")}(?:\\s|$)`), `the sandbox permits Podman's ephemeral ${path} runtime tree`);
}
Expand Down