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
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ jobs:
curl -sfL "https://github.com/gitleaks/gitleaks/releases/download/${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION#v}_linux_x64.tar.gz" \
| tar -xz -C /usr/local/bin gitleaks

- name: Verify extension pins and paths
run: ./hack/verify.sh

- name: Gitleaks secret scan
run: gitleaks detect --source . --redact

Expand Down
21 changes: 21 additions & 0 deletions .github/workflows/export-cosign-public-key.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Export Cosign public key

on:
workflow_dispatch:

jobs:
export:
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Install Cosign
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v3.8.1

- name: Export public key
env:
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
run: |
cosign public-key --key env://COSIGN_PRIVATE_KEY
22 changes: 18 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,46 @@
ARG FIRECRACKER_VERSION=v1.15.0
ARG FIRECRACKER_SHA256_X86_64=00cadf7f21e709e939dc0c8d16e2d2ce7b975a62bec6c50f74b421cc8ab3cab4
ARG FIRECRACKER_SHA256_AARCH64=58325e6c3c539482a412ec0b60e6f539c3320adebcf8179c7629d06736aee0bd
ARG FIRECRACKER_CI_PREFIX=https://s3.amazonaws.com/spec.ccfc.min/firecracker-ci/v1.15
ARG KERNEL_VERSION=6.1.155
ARG KERNEL_SHA256_X86_64=e20e46d0c36c55c0d1014eb20576171b3f3d922260d9f792017aeff53af3d4f2
ARG KERNEL_SHA256_AARCH64=e3544b10603acbf3db492cb52e000d22ba202cb4b63b9add027565683e11c591

# -- download stage -----------------------------------------------------------
FROM --platform=${BUILDPLATFORM} alpine:3.21 AS download
ARG FIRECRACKER_VERSION
ARG FIRECRACKER_SHA256_X86_64
ARG FIRECRACKER_SHA256_AARCH64
ARG FIRECRACKER_CI_PREFIX
ARG KERNEL_VERSION
ARG KERNEL_SHA256_X86_64
ARG KERNEL_SHA256_AARCH64
ARG TARGETARCH

# hadolint ignore=DL3018
RUN apk add --no-cache curl && \
case "${TARGETARCH}" in \
amd64) ARCH="x86_64"; SHA256="${FIRECRACKER_SHA256_X86_64}" ;; \
arm64) ARCH="aarch64"; SHA256="${FIRECRACKER_SHA256_AARCH64}" ;; \
amd64) ARCH="x86_64"; FIRECRACKER_SHA256="${FIRECRACKER_SHA256_X86_64}"; KERNEL_SHA256="${KERNEL_SHA256_X86_64}" ;; \
arm64) ARCH="aarch64"; FIRECRACKER_SHA256="${FIRECRACKER_SHA256_AARCH64}"; KERNEL_SHA256="${KERNEL_SHA256_AARCH64}" ;; \
*) echo "Unsupported architecture: ${TARGETARCH}" >&2 && exit 1 ;; \
esac && \
URL="https://github.com/firecracker-microvm/firecracker/releases/download/${FIRECRACKER_VERSION}/firecracker-${FIRECRACKER_VERSION}-${ARCH}.tgz" && \
curl -fsSL "${URL}" -o /tmp/firecracker.tgz && \
printf '%s %s\n' "${SHA256}" "/tmp/firecracker.tgz" > /tmp/firecracker.sha256 && \
printf '%s %s\n' "${FIRECRACKER_SHA256}" "/tmp/firecracker.tgz" > /tmp/firecracker.sha256 && \
sha256sum -c /tmp/firecracker.sha256 && \
tar -xzf /tmp/firecracker.tgz -C /tmp && \
install -Dm755 \
"/tmp/release-${FIRECRACKER_VERSION}-${ARCH}/firecracker-${FIRECRACKER_VERSION}-${ARCH}" \
/out/rootfs/usr/local/bin/firecracker && \
install -Dm755 \
"/tmp/release-${FIRECRACKER_VERSION}-${ARCH}/jailer-${FIRECRACKER_VERSION}-${ARCH}" \
/out/rootfs/usr/local/bin/jailer
/out/rootfs/usr/local/bin/jailer && \
KERNEL_URL="${FIRECRACKER_CI_PREFIX}/${ARCH}/vmlinux-${KERNEL_VERSION}" && \
curl -fsSL "${KERNEL_URL}" -o /tmp/vmlinux && \
printf '%s %s\n' "${KERNEL_SHA256}" /tmp/vmlinux > /tmp/vmlinux.sha256 && \
sha256sum -c /tmp/vmlinux.sha256 && \
test -s /tmp/vmlinux && \
install -Dm0644 /tmp/vmlinux /out/rootfs/usr/local/share/imp/vmlinux

# -- extension image ----------------------------------------------------------
# Files under /rootfs/ are overlaid onto the Talos node filesystem at boot.
Expand Down
26 changes: 21 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,23 @@
[![Publish](https://github.com/syscode-labs/talos-ext-firecracker/actions/workflows/release.yml/badge.svg)](https://github.com/syscode-labs/talos-ext-firecracker/actions/workflows/release.yml)
[![GHCR](https://img.shields.io/badge/registry-ghcr.io-blue)](https://ghcr.io/syscode-labs/talos-ext-firecracker)
[![Talos](https://img.shields.io/badge/talos-%3E%3D1.7-0f62fe)](https://www.talos.dev/)
[![Firecracker](https://img.shields.io/badge/firecracker-v1.9.0-orange)](https://github.com/firecracker-microvm/firecracker/releases/tag/v1.9.0)
[![Firecracker](https://img.shields.io/badge/firecracker-v1.15.0-orange)](https://github.com/firecracker-microvm/firecracker/releases/tag/v1.15.0)
[![Platforms](https://img.shields.io/badge/platforms-amd64%20%7C%20arm64-brightgreen)](#)
[![License](https://img.shields.io/badge/license-Apache--2.0-green)](https://www.apache.org/licenses/LICENSE-2.0)

This repo builds a **Talos system extension** that adds:

- `firecracker`
- `jailer`
- `/usr/local/share/imp/vmlinux` (Firecracker CI guest kernel, `6.1.155`)

In plain terms: it gives a Talos node the Firecracker binaries so that higher-level systems can start lightweight microVMs.

## What This Does

1. Downloads Firecracker release tarballs for `amd64` and `arm64`
2. Verifies tarball checksums before extracting
3. Packages binaries into a Talos extension image
1. Downloads Firecracker release tarballs and the pinned Firecracker CI guest kernel for `amd64` and `arm64`
2. Verifies all artifact checksums before installing them
3. Packages Firecracker, Jailer, and the Imp guest kernel into a Talos extension image
4. Publishes multi-arch images to GHCR on tagged releases
5. Signs the pushed image digest recursively with Cosign so Image Factory can verify it

Expand Down Expand Up @@ -54,6 +55,19 @@ retired key.

## Quick Start

## Use With Imp

The Imp Helm chart must mount the kernel installed by this extension:

```yaml
agent:
env:
kernelPath: /usr/local/share/imp/vmlinux
```

This path is Talos-specific. Local and Kind-based Imp tests provision their own
kernel at `/var/lib/imp/vmlinux` and should retain that configuration.

Build locally:

```bash
Expand All @@ -63,6 +77,7 @@ docker buildx build --platform linux/amd64,linux/arm64 -t talos-ext-firecracker:
Run local checks:

```bash
./hack/verify.sh
pre-commit run --all-files
```

Expand All @@ -75,8 +90,9 @@ pre-commit install --hook-type commit-msg

## Key Files

- [`Dockerfile`](Dockerfile): downloads, verifies, and installs Firecracker binaries
- [`Dockerfile`](Dockerfile): downloads, verifies, and installs Firecracker, Jailer, and the pinned Imp guest kernel
- [`manifest.yaml`](manifest.yaml): Talos extension metadata
- [`hack/verify.sh`](hack/verify.sh): validates artifact pins and installed paths
- [`.github/workflows/ci.yml`](.github/workflows/ci.yml): lint/build checks
- [`.github/workflows/release-please.yml`](.github/workflows/release-please.yml): automated release PRs
- [`.github/workflows/release.yml`](.github/workflows/release.yml): publish on tags
Expand Down
61 changes: 61 additions & 0 deletions hack/verify.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env bash
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
DOCKERFILE="${ROOT_DIR}/Dockerfile"
MANIFEST="${ROOT_DIR}/manifest.yaml"

fail() {
echo "verification failed: $*" >&2
exit 1
}

require_file() {
[[ -f "$1" ]] || fail "missing file: $1"
}

require_file "${DOCKERFILE}"
require_file "${MANIFEST}"

grep -q '^ name: firecracker$' "${MANIFEST}" || fail "manifest name is not pinned"
grep -Eq '^ version: [0-9]+\.[0-9]+\.[0-9]+([-.][0-9A-Za-z.]+)?$' "${MANIFEST}" \
|| fail "manifest version is not a semantic version"
grep -q 'pinned Imp guest vmlinux' "${MANIFEST}" || fail "manifest description is missing the guest kernel"

grep -q 'FIRECRACKER_VERSION=v1\.15\.0' "${DOCKERFILE}" || fail "Firecracker version is not pinned"
grep -q 'FIRECRACKER_CI_PREFIX=https://s3\.amazonaws\.com/spec\.ccfc\.min/firecracker-ci/v1\.15' "${DOCKERFILE}" \
|| fail "guest kernel source is not pinned"
grep -q 'KERNEL_VERSION=6\.1\.155' "${DOCKERFILE}" || fail "guest kernel version is not pinned"

for digest in \
00cadf7f21e709e939dc0c8d16e2d2ce7b975a62bec6c50f74b421cc8ab3cab4 \
58325e6c3c539482a412ec0b60e6f539c3320adebcf8179c7629d06736aee0bd \
e20e46d0c36c55c0d1014eb20576171b3f3d922260d9f792017aeff53af3d4f2 \
e3544b10603acbf3db492cb52e000d22ba202cb4b63b9add027565683e11c591; do
grep -q "${digest}" "${DOCKERFILE}" || fail "missing SHA-256 pin: ${digest}"
done

grep -q 'amd64) ARCH="x86_64"' "${DOCKERFILE}" || fail "amd64 architecture mapping is missing"
grep -q 'arm64) ARCH="aarch64"' "${DOCKERFILE}" || fail "arm64 architecture mapping is missing"

for path in \
/usr/local/bin/firecracker \
/usr/local/bin/jailer \
/usr/local/share/imp/vmlinux; do
grep -q "${path}" "${DOCKERFILE}" || fail "required installed path is missing: ${path}"
done

if [[ "${VERIFY_REMOTE:-false}" == "true" ]]; then
command -v curl >/dev/null 2>&1 || fail "curl is required for VERIFY_REMOTE=true"
command -v sha256sum >/dev/null 2>&1 || fail "sha256sum is required for VERIFY_REMOTE=true"

tmp_dir="$(mktemp -d)"
trap 'rm -rf "${tmp_dir}"' EXIT
base="https://s3.amazonaws.com/spec.ccfc.min/firecracker-ci/v1.15"
curl -fsSL "${base}/x86_64/vmlinux-6.1.155" -o "${tmp_dir}/x86_64"
curl -fsSL "${base}/aarch64/vmlinux-6.1.155" -o "${tmp_dir}/aarch64"
printf '%s %s\n' e20e46d0c36c55c0d1014eb20576171b3f3d922260d9f792017aeff53af3d4f2 "${tmp_dir}/x86_64" | sha256sum -c -
printf '%s %s\n' e3544b10603acbf3db492cb52e000d22ba202cb4b63b9add027565683e11c591 "${tmp_dir}/aarch64" | sha256sum -c -
fi

echo "Firecracker extension pins and installed paths verified"
2 changes: 1 addition & 1 deletion manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ metadata:
name: firecracker
version: 1.12.0
author: syscode-labs
description: Firecracker microVM and Jailer binaries for Talos Linux
description: Firecracker microVM, Jailer, and pinned Imp guest vmlinux for Talos Linux
compatibility:
talos:
version: '>= 1.7.0'
Loading