Skip to content

Conversation

@tlaurion
Copy link
Collaborator

@tlaurion tlaurion commented Dec 15, 2025

My bad: I always only tested qemu boards under QubesOS (which as of now still doesn't permit nested xen->kvm virtualization)

This change permits to run things under qemu+kvm

Tested

  • installation with media and default partition schemes
  • sealing firmware measurements + setting default boot option + TPM Disk Unlock Key when requested (to add additional LUKS key that is unsealed from TPM when coreboot+heads measurements valid + TPM DUK passphrase)

Note: TPM DUK is mitigation for any OSes not providing efifb in their initramfs, prior of specialized drm+gpu drivers being loaded (at LUKS passphrase prompt early in init/systemd).

ISO tested:

  • ubuntu-25.10-desktop-amd64.iso:
./docker_repro.sh make BOARD=qemu-coreboot-fbwhiptail-tpm2 QEMU_MEMORY_SIZE=16G QEMU_DISK_SIZE=30G INSTALL_IMG=ubuntu-25.10-desktop-amd64.iso
./docker_repro.sh make BOARD=qemu-coreboot-fbwhiptail-tpm2 PUBKEY_ASC=pubkey.asc USB_TOKEN=Nitrokey3NFC inject_gpg
./docker_repro.sh make BOARD=qemu-coreboot-fbwhiptail-tpm2 PUBKEY_ASC=pubkey.asc USB_TOKEN=Nitrokey3NFC run
  • debian-13.2.0-amd64-DVD-1.iso
./docker_repro.sh make BOARD=qemu-coreboot-fbwhiptail-tpm2 QEMU_MEMORY_SIZE=16G QEMU_DISK_SIZE=30G INSTALL_IMG=debian-13.2.0-amd64-DVD-1.iso run
./docker_repro.sh make BOARD=qemu-coreboot-fbwhiptail-tpm2 PUBKEY_ASC=pubkey.asc USB_TOKEN=Nitrokey3NFC inject_gpg
./docker_repro.sh make BOARD=qemu-coreboot-fbwhiptail-tpm2 PUBKEY_ASC=pubkey.asc USB_TOKEN=Nitrokey3NFC run
  • Fedora-Workstation-Live-43-1.6.x86_64.iso
./docker_repro.sh make BOARD=qemu-coreboot-fbwhiptail-tpm2 QEMU_MEMORY_SIZE=16G QEMU_DISK_SIZE=30G INSTALL_IMG=Fedora-Workstation-Live-43-1.6.x86_64.iso run
./docker_repro.sh make BOARD=qemu-coreboot-fbwhiptail-tpm2 PUBKEY_ASC=pubkey.asc USB_TOKEN=Nitrokey3NFC inject_gpg
./docker_repro.sh make BOARD=qemu-coreboot-fbwhiptail-tpm2 PUBKEY_ASC=pubkey.asc USB_TOKEN=Nitrokey3NFC run

Copilot AI review requested due to automatic review settings December 15, 2025 23:57
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enhances the Docker wrapper scripts to enable KVM acceleration and X11 GUI support for QEMU board testing. Previously tested only under QubesOS, these changes allow the scripts to work with standard Linux environments running KVM-accelerated QEMU with GTK windows.

Key changes:

  • Added /dev/kvm device passthrough to enable KVM hardware acceleration in containers
  • Added X11 socket and authentication mounting to support GUI applications (GTK windows)

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 18 comments.

File Description
docker_repro.sh Added KVM device passthrough and X11 authentication mounts to enable hardware-accelerated QEMU with GUI support
docker_local_dev.sh Added KVM device passthrough and X11 authentication mounts to enable hardware-accelerated QEMU with GUI support
docker_latest.sh Added KVM device passthrough and X11 authentication mounts to enable hardware-accelerated QEMU with GUI support

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 18 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@tlaurion tlaurion marked this pull request as draft December 17, 2025 22:18
@tlaurion tlaurion force-pushed the bugfix-qemu_kvm branch 4 times, most recently from 61b1ccf to 79e115f Compare February 3, 2026 18:37
@tlaurion tlaurion marked this pull request as ready for review February 3, 2026 19:45
@tlaurion tlaurion force-pushed the bugfix-qemu_kvm branch 2 times, most recently from b26b8c5 to f4c3a85 Compare February 3, 2026 20:19
@tlaurion tlaurion requested a review from Copilot February 3, 2026 21:44
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@tlaurion tlaurion force-pushed the bugfix-qemu_kvm branch 2 times, most recently from 8c27511 to c18ec25 Compare February 4, 2026 01:37
@tlaurion tlaurion requested a review from Copilot February 4, 2026 01:37
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@tlaurion tlaurion force-pushed the bugfix-qemu_kvm branch 2 times, most recently from 0509fb8 to 111c50c Compare February 4, 2026 02:15
@tlaurion tlaurion requested a review from Copilot February 4, 2026 02:15
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…ty; add pin-and-run wrapper and clarify usage; parse HEADS_NIX_EXTRA_FLAGS as shell words and document

Signed-off-by: Thierry Laurion <[email protected]>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +107 to +111
registry_api="https://auth.docker.io/token?service=registry.docker.io&scope=repository:${repo}:pull"
token=$(curl -fsSL "${registry_api}" | sed -n 's/.*"token":"\([^"]*\)".*/\1/p' || true)
if [ -n "${token}" ]; then
header=$(curl -fsSI -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -H "Authorization: Bearer ${token}" "https://registry-1.docker.io/v2/${repo}/manifests/${tag}" 2>/dev/null || true)
manifest_digest=$(printf '%s\n' "$header" | sed -n 's/Docker-Content-Digest:[[:space:]]*//Ip' | tr -d '\r' | head -n1 || true)
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

This helper unconditionally relies on curl to talk to the Docker Hub API (e.g., for registry_api and the manifest HEAD request), but there is no prerequisite check for curl (or fallback to wget). On a host without curl installed (but with Docker present), these calls will fail under set -euo pipefail and abort the script even though querying the Hub is meant to be a best-effort fallback. Consider explicitly checking for curl (and skipping the Hub API path or cleanly warning when it’s missing) or adding a wget-based fallback so the script degrades gracefully instead of exiting abruptly.

Suggested change
registry_api="https://auth.docker.io/token?service=registry.docker.io&scope=repository:${repo}:pull"
token=$(curl -fsSL "${registry_api}" | sed -n 's/.*"token":"\([^"]*\)".*/\1/p' || true)
if [ -n "${token}" ]; then
header=$(curl -fsSI -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -H "Authorization: Bearer ${token}" "https://registry-1.docker.io/v2/${repo}/manifests/${tag}" 2>/dev/null || true)
manifest_digest=$(printf '%s\n' "$header" | sed -n 's/Docker-Content-Digest:[[:space:]]*//Ip' | tr -d '\r' | head -n1 || true)
if command -v curl >/dev/null 2>&1; then
registry_api="https://auth.docker.io/token?service=registry.docker.io&scope=repository:${repo}:pull"
token=$(curl -fsSL "${registry_api}" | sed -n 's/.*\"token\":\"\([^\"]*\)\".*/\1/p' || true)
if [ -n "${token}" ]; then
header=$(curl -fsSI -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -H "Authorization: Bearer ${token}" "https://registry-1.docker.io/v2/${repo}/manifests/${tag}" 2>/dev/null || true)
manifest_digest=$(printf '%s\n' "$header" | sed -n 's/Docker-Content-Digest:[[:space:]]*//Ip' | tr -d '\r' | head -n1 || true)
fi
else
echo "Warning: 'curl' not found; skipping Docker Hub API lookup for '${image}'." >&2

Copilot uses AI. Check for mistakes.
Comment on lines +80 to +159
if [ "${HEADS_AUTO_INSTALL_NIX:-0}" = "1" ] && [ -t 1 ]; then
echo "HEADS_AUTO_INSTALL_NIX=1: attempting automatic Nix install..." >&2
local installer_url="https://nixos.org/nix/install"
local tmpf
tmpf=$(mktemp) || { echo "Failed to create temporary file for installer." >&2; return 1; }
if [ "$downloader_cmd" = "curl -L" ]; then
if ! curl -fsSL "$installer_url" -o "$tmpf"; then
echo "Failed to download Nix installer." >&2; rm -f "$tmpf"; return 1
fi
else
if ! wget -qO "$tmpf" "$installer_url"; then
echo "Failed to download Nix installer." >&2; rm -f "$tmpf"; return 1
fi
fi
local inst_sha
if command -v sha256sum >/dev/null 2>&1; then
inst_sha=$(sha256sum "$tmpf" | awk '{print $1}') || inst_sha=""
elif command -v shasum >/dev/null 2>&1; then
inst_sha=$(shasum -a 256 "$tmpf" | awk '{print $1}') || inst_sha=""
else
inst_sha=""
fi
if [ -n "$inst_sha" ]; then
echo "Downloaded Nix installer to: $tmpf" >&2
echo "Installer sha256: $inst_sha" >&2
else
echo "Downloaded Nix installer to: $tmpf (sha256 unavailable)" >&2
fi

# For supply-chain safety, do not auto-execute the downloaded installer.
if [ -t 1 ]; then
printf "Run the downloaded installer now? [y/N] " >&2
read -r _run_ans
case "${_run_ans:-N}" in
[Yy]* ) if ! sh "$tmpf" --no-daemon; then echo "Nix install failed." >&2; rm -f "$tmpf"; return 1; fi ;;
* ) echo "Installer saved to $tmpf. Verify its sha256 (printed above) and run it manually when ready: sh $tmpf --no-daemon" >&2; rm -f "$tmpf"; return 1 ;;
esac
else
echo "Non-interactive shell: automatic install suppressed. Installer saved to $tmpf; verify and run manually." >&2
return 1
fi
rm -f "$tmpf"
# Prefer adding the nix profile bin dir to PATH instead of sourcing a dynamic file
# This is easier to audit and avoids shellcheck SC1091
export PATH="$HOME/.nix-profile/bin:$PATH" || true
hash -r 2>/dev/null || true
elif [ -t 1 ]; then
echo "Note: building the Docker image and populating /nix may require ${HEADS_MIN_DISK_GB:-50}GB+ free on '/' or '/nix'." >&2
printf "Install Nix now and enable flakes (required) [Y/n]? " >&2
read -r ans
case "${ans:-Y}" in
[Yy]* )
# Download installer to temporary file and show sha256 before executing
local installer_url="https://nixos.org/nix/install"
local tmpf
tmpf=$(mktemp) || { echo "Failed to create temporary file for installer." >&2; return 1; }
if [ "$downloader_cmd" = "curl -L" ]; then
if ! curl -fsSL "$installer_url" -o "$tmpf"; then
echo "Failed to download Nix installer." >&2; rm -f "$tmpf"; return 1
fi
else
if ! wget -qO "$tmpf" "$installer_url"; then
echo "Failed to download Nix installer." >&2; rm -f "$tmpf"; return 1
fi
fi
local inst_sha
if command -v sha256sum >/dev/null 2>&1; then
inst_sha=$(sha256sum "$tmpf" | awk '{print $1}') || inst_sha=""
elif command -v shasum >/dev/null 2>&1; then
inst_sha=$(shasum -a 256 "$tmpf" | awk '{print $1}') || inst_sha=""
else
inst_sha=""
fi
if [ -n "$inst_sha" ]; then
echo "Downloaded Nix installer to: $tmpf" >&2
echo "Installer sha256: $inst_sha" >&2
else
echo "Downloaded Nix installer to: $tmpf (sha256 unavailable)" >&2
fi
if ! sh "$tmpf" --no-daemon; then echo "Nix install failed." >&2; rm -f "$tmpf"; return 1; fi
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

The ensure_nix_and_flakes helper downloads the Nix installer shell script from https://nixos.org/nix/install into a temp file and then executes it via sh "$tmpf" --no-daemon without verifying the script against a trusted checksum or signature. This means any compromise of the download path (e.g., registry compromise, TLS MITM, DNS poisoning) could result in arbitrary code execution on developer or CI hosts with access to this repository and its secrets. To reduce supply-chain risk, avoid auto-executing network-fetched installer scripts and instead require a pinned installer artifact with a hard-coded expected hash or signature verification step, or abort after download and instruct the user to verify and run the installer manually outside the script.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@copilot this is not useful. The dev environment is for developers which should otherwise follow the same steps from global README.md manually, not for Circleci nor docker_repro.sh.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant