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
4 changes: 2 additions & 2 deletions .github/workflows/build-devcontainer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [debian, c10s]
os: [debian, ubuntu, c10s]
arch: [amd64, arm64]
include:
- arch: amd64
Expand Down Expand Up @@ -90,7 +90,7 @@ jobs:
if: github.event_name != 'pull_request'
strategy:
matrix:
os: [debian, c10s]
os: [debian, ubuntu, c10s]
steps:
- name: Download digests
uses: actions/download-artifact@v8
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-devcontainer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [debian]
os: [debian, ubuntu]
# TODO: c10s has PAM/sudo issues with devcontainer CLI's --userns=keep-id
# include:
# - os: c10s
Expand Down
11 changes: 7 additions & 4 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ devcontainer-validate:
devenv-build-debian:
cd devenv && podman build --jobs=4 -f Containerfile.debian -t localhost/bootc-devenv-debian .

# Build devenv Ubuntu 24.04 image with local tag
devenv-build-ubuntu:
cd devenv && podman build --jobs=4 -f Containerfile.ubuntu -t localhost/bootc-devenv-ubuntu .

# Build devenv CentOS Stream 10 image with local tag
devenv-build-c10s:
cd devenv && podman build --jobs=4 -f Containerfile.c10s -t localhost/bootc-devenv-c10s .
Expand All @@ -19,17 +23,16 @@ devenv-build: devenv-build-debian
devcontainer-test os:
#!/bin/bash
set -euo pipefail
config=common/.devcontainer/{{os}}/devcontainer.json
# Tag local image to match what devcontainer.json expects
# (devcontainer CLI's --override-config replaces rather than merges, so we
# work around by tagging the image to the expected name)
podman tag localhost/bootc-devenv-{{os}}:latest ghcr.io/bootc-dev/devenv-{{os}}:latest
npx --yes @devcontainers/cli up \
--workspace-folder . \
--docker-path podman \
--config common/.devcontainer/devcontainer.json \
--config "$config" \
--remove-existing-container
npx @devcontainers/cli exec \
--workspace-folder . \
--docker-path podman \
--config common/.devcontainer/devcontainer.json \
--config "$config" \
/usr/libexec/devenv-selftest.sh
30 changes: 30 additions & 0 deletions common/.devcontainer/debian/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "bootc-devenv-debian",
"image": "ghcr.io/bootc-dev/devenv-debian",
"customizations": {
"vscode": {
// Arbitrary, but most of our code is in one of these two
"extensions": [
"rust-lang.rust-analyzer",
"golang.Go"
]
},
"devaipod": {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also here we may need to go to generating these or at least validating they're in sync

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in my later PR.

// When running under devaipod, use minimal capabilities
// (SYS_ADMIN, NET_ADMIN, etc.) instead of full --privileged.
"nestedContainers": true
}
},
"features": {},
// Use privileged mode for broad compatibility (Codespaces, Docker,
// stock devcontainer CLI). devaipod overrides this with tighter
// security via the nestedContainers customization above.
"privileged": true,
"postCreateCommand": {
// Our init script
"devenv-init": "sudo /usr/local/bin/devenv-init.sh"
},
"remoteEnv": {
"PATH": "${containerEnv:PATH}:/usr/local/cargo/bin"
}
}
30 changes: 30 additions & 0 deletions common/.devcontainer/ubuntu/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "bootc-devenv-ubuntu",
"image": "ghcr.io/bootc-dev/devenv-ubuntu",
"customizations": {
"vscode": {
// Arbitrary, but most of our code is in one of these two
"extensions": [
"rust-lang.rust-analyzer",
"golang.Go"
]
},
"devaipod": {
// When running under devaipod, use minimal capabilities
// (SYS_ADMIN, NET_ADMIN, etc.) instead of full --privileged.
"nestedContainers": true
}
},
"features": {},
// Use privileged mode for broad compatibility (Codespaces, Docker,
// stock devcontainer CLI). devaipod overrides this with tighter
// security via the nestedContainers customization above.
"privileged": true,
"postCreateCommand": {
// Our init script
"devenv-init": "sudo /usr/local/bin/devenv-init.sh"
},
"remoteEnv": {
"PATH": "${containerEnv:PATH}:/usr/local/cargo/bin"
}
}
2 changes: 2 additions & 0 deletions devenv/.dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
!packages-common.txt
!packages-debian.txt
!packages-c10s.txt
!packages-ubuntu.txt
!npm.txt
!build-deps.txt
!build-deps-debian.txt
!build-deps-c10s.txt
!build-deps-ubuntu.txt
!devenv-init.sh
!fetch-tools.py
!tool-versions.txt
Expand Down
117 changes: 117 additions & 0 deletions devenv/Containerfile.ubuntu
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# These aren't packages, just low-dependency binaries dropped in /usr/local/bin
# so we can fetch them independently in a separate build.
ARG base=docker.io/library/ubuntu:24.04
FROM $base AS base
# Life is too short to care about dash
RUN ln -sfr /bin/bash /bin/sh
RUN <<EORUN
set -xeuo pipefail

# Disable apt sandboxing for nested container environments
echo 'APT::Sandbox::User "root";' > /etc/apt/apt.conf.d/99sandbox-disable

# Initialize some basic packages
apt -y update && apt -y install ca-certificates curl time bzip2 software-properties-common

# Enable deb-src repositories for build-dep
sed -i 's/^Types: deb$/Types: deb deb-src/' /etc/apt/sources.list.d/ubuntu.sources

# Enable universe repository (needed for some packages like just, fsverity)
add-apt-repository -y universe

# Cherry-pick newer container stack from plucky (Ubuntu 25.04).
# Keep in sync with actions/bootc-ubuntu-setup.
# The main archive only carries amd64; arm64 uses ports.ubuntu.com.
if [ "$(dpkg --print-architecture)" = "amd64" ]; then
mirror="http://archive.ubuntu.com/ubuntu"
else
mirror="http://ports.ubuntu.com/ubuntu-ports"
fi
echo "deb ${mirror} plucky universe main" > /etc/apt/sources.list.d/plucky.list

# Enable gh CLI repository
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should share this one with the other images too

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debian and C10S have gh CLI repo added.

mkdir -p -m 755 /etc/apt/keyrings
curl -fLo /etc/apt/keyrings/githubcli-archive-keyring.gpg https://cli.github.com/packages/githubcli-archive-keyring.gpg
chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg
mkdir -p -m 755 /etc/apt/sources.list.d
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" > /etc/apt/sources.list.d/github-cli.list

# And re-update after we've fetched repos
apt -y update
EORUN

FROM base AS tools
# renovate: datasource=github-releases depName=astral-sh/uv
ARG uvversion=0.10.9
COPY fetch-tools.py tool-versions.txt install-uv.sh /run/src/
RUN apt -y install python3 && /run/src/fetch-tools.py && apt -y purge python3 && apt -y autoremove
RUN uvversion=$uvversion /run/src/install-uv.sh

FROM base AS rust
# renovate: datasource=custom.rust-nightly depName=rust-nightly versioning=rust-release-channel
ARG rust_nightly=nightly-2026-03-08
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The default value for rust_nightly is set to a future date (nightly-2026-03-08). This will likely cause the build to fail when install-rust.sh tries to install this non-existent nightly toolchain via rustup. While this pattern is copied from other Containerfiles, it seems problematic. Could you confirm if this is intentional or a placeholder that should be updated to a valid, recent nightly version?

COPY install-rust.sh /run/src/
RUN rust_nightly=$rust_nightly /run/src/install-rust.sh

# Kani formal verification tool - requires rustup for toolchain management
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've gone from 2 to 3 copies of this stuff...which is a baseline rule I have where deduplication is probably wanted.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in my later PR.

FROM rust AS kani
# renovate: datasource=crate depName=kani-verifier
ARG kaniversion=0.67.0
RUN apt-get update && apt-get install -y --no-install-recommends gcc libc6-dev && rm -rf /var/lib/apt/lists/*
COPY install-kani.sh /run/src/
RUN kaniversion=$kaniversion /run/src/install-kani.sh

# This builds the image.
# Build this using `just devenv-build-ubuntu` from the root of the repository.
FROM base
COPY packages-common.txt packages-ubuntu.txt build-deps-ubuntu.txt /run/src/
WORKDIR /run/src
RUN <<EORUN
set -xeuo pipefail
# Install newer container stack from plucky (keep in sync with actions/bootc-ubuntu-setup)
# skopeo is currently older in plucky for some reason hence --allow-downgrades
/bin/time -f '%E %C' apt -y install --allow-downgrades crun/plucky podman/plucky skopeo/plucky just
grep -hEve '^#' packages-common.txt packages-ubuntu.txt | /bin/time -f '%E %C' xargs apt -y install
grep -vEe '^#' build-deps-ubuntu.txt | /bin/time -f '%E %C' xargs apt -y build-dep
apt clean && rm -rf /var/lib/apt/lists/*
EORUN
COPY npm.txt /run/src
RUN grep -vEe '^#' npm.txt | /bin/time -f '%E %C' xargs npm i -g

# Install tmt via uv tool install for isolated environment
# UV_TOOL_DIR and UV_TOOL_BIN_DIR set to system-wide locations like rustup
COPY --from=tools /usr/local/bin/uv /usr/local/bin/uv
COPY --from=tools /usr/local/bin/uvx /usr/local/bin/uvx
ENV UV_TOOL_DIR=/usr/local/uv-tools
ENV UV_TOOL_BIN_DIR=/usr/local/bin
RUN uv tool install 'tmt[provision-virtual]'

# Copy in the binaries from our tools container image
COPY --from=tools /usr/local/bin/* /usr/local/bin/
Comment on lines +83 to +90
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The uv and uvx binaries are copied from the tools stage, then used, and then all binaries from the tools stage (including uv and uvx again) are copied over. This can be simplified by copying all binaries from the tools stage at once before using uv, which removes redundant COPY instructions.

COPY --from=tools /usr/local/bin/* /usr/local/bin/
ENV UV_TOOL_DIR=/usr/local/uv-tools
ENV UV_TOOL_BIN_DIR=/usr/local/bin
RUN uv tool install 'tmt[provision-virtual]'

COPY --from=kani /usr/local/bin/* /usr/local/bin/
COPY --from=kani /usr/local/rustup /usr/local/rustup
# Kani bundle (compiler, libraries, CBMC) installed via KANI_HOME during setup
COPY --from=kani /usr/local/kani /usr/local/kani
# Point rustup at the system-wide installation, but let CARGO_HOME default to ~/.cargo
ENV RUSTUP_HOME=/usr/local/rustup
# Point Kani at the system-wide installation
ENV KANI_HOME=/usr/local/kani
# Setup for codespaces
COPY devenv-init.sh /usr/local/bin/
COPY userns-setup /usr/lib/devenv/userns-setup
COPY devenv-selftest.sh /usr/libexec/
RUN chmod 755 /usr/libexec/devenv-selftest.sh /usr/lib/devenv/userns-setup

WORKDIR /
# Create user before declaring volumes so home directory has correct ownership
RUN <<EORUN
set -xeuo pipefail
useradd -m devenv -s /bin/bash
# This needs to be precreated and owned by the devenv user
mkdir -p ~devenv/.local/share/containers
chown -R -h devenv: ~devenv/.local
echo 'devenv ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/devenv && chmod 0440 /etc/sudoers.d/devenv
EORUN
# To avoid overlay-on-overlay with nested containers
VOLUME [ "/var/lib/containers", "/home/devenv/.local/share/containers/" ]
USER devenv
1 change: 1 addition & 0 deletions devenv/build-deps-ubuntu.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ostree
17 changes: 11 additions & 6 deletions devenv/devenv-selftest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,22 @@ podman run --rm "$image" echo "Hello from nested podman!"

echo "=== Nested container test passed ==="

# Test bcvk (VM) if available and /dev/kvm exists
# Test bcvk (VM) if available and /dev/kvm exists.
# This is best-effort: in nested containers /dev/kvm can appear accessible
# but fail at runtime due to namespace restrictions, so we don't fail the
# overall selftest if bcvk fails.
if command -v bcvk >/dev/null 2>&1 && [ -e /dev/kvm ]; then
echo ""
echo "=== Testing bcvk VM ==="
echo "=== Testing bcvk VM (best-effort) ==="
echo "bcvk version:"
bcvk --version

echo "Running bcvk ephemeral VM with SSH..."
bcvk ephemeral run-ssh "$image" -- echo "Hello from bcvk VM!"

echo "=== bcvk VM test passed ==="
if bcvk ephemeral run-ssh "$image" -- echo "Hello from bcvk VM!"; then
echo "=== bcvk VM test passed ==="
else
echo "=== bcvk VM test failed (KVM may not be functional in this environment) ==="
fi
else
echo ""
echo "=== Skipping bcvk VM test (bcvk not available or /dev/kvm missing) ==="
Expand Down
22 changes: 22 additions & 0 deletions devenv/packages-ubuntu.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Ubuntu-specific package names
# Common packages are in packages-common.txt

# General build env
clang-format
libkrb5-dev
libvirt-dev
libostree-dev

# Python dev headers (needed for uv to build libvirt-python from source for tmt)
python3-dev

# Runtime virt
genisoimage
qemu-utils
libvirt-daemon-system

# Filesystem verity utilities (composefs testing)
fsverity

# TUI editors
vim
Loading