Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 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
71 changes: 71 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Build Firecracker Versions

on:
workflow_call:
outputs:
versions:
description: "JSON array of versions that were built"
value: ${{ jobs.prepare.outputs.versions }}
workflow_dispatch:

jobs:
prepare:
runs-on: ubuntu-latest
outputs:
versions: ${{ steps.set-versions.outputs.versions }}
steps:
- uses: actions/checkout@v4

- name: Parse versions from file
id: set-versions
run: |
# Read versions, skip comments and empty lines, output as JSON array
versions=$(grep -v '^ *#' firecracker_versions.txt | grep -v '^$' | jq -R -s -c 'split("\n") | map(select(length > 0))')
echo "versions=$versions" >> $GITHUB_OUTPUT
echo "Building versions: $versions"

build:
needs: prepare
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
version: ${{ fromJson(needs.prepare.outputs.versions) }}
steps:
- uses: actions/checkout@v4

# Set up Docker Buildx for better caching
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

# Cache Docker layers
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: docker-buildx-${{ runner.os }}-${{ matrix.version }}-${{ github.sha }}
restore-keys: |
docker-buildx-${{ runner.os }}-${{ matrix.version }}-
docker-buildx-${{ runner.os }}-

# Cache Cargo registry and git dependencies
- name: Cache Cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: cargo-${{ runner.os }}-${{ matrix.version }}-${{ github.sha }}
restore-keys: |
cargo-${{ runner.os }}-${{ matrix.version }}-
cargo-${{ runner.os }}-

- name: Build Firecracker ${{ matrix.version }}
run: ./build.sh "${{ matrix.version }}"

- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: firecracker-${{ matrix.version }}
path: builds/
retention-days: 30
33 changes: 20 additions & 13 deletions .github/workflows/fc-versions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@ name: FC Versions

on:
push:
workflow_dispatch:

permissions:
id-token: write
contents: write

jobs:
# Run parallel builds via reusable workflow
build:
uses: ./.github/workflows/build.yml

# Collect artifacts and publish
publish:
name: Build Firecracker and upload
name: Collect and upload builds
needs: build
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
Expand Down Expand Up @@ -47,23 +54,24 @@ jobs:
- name: Test next version
run: echo "Next version is ${{ steps.get-version.outputs.version }}"

# Download all build artifacts
- name: Download all build artifacts
uses: actions/download-artifact@v4
with:
path: builds
pattern: firecracker-*
merge-multiple: true

- name: List downloaded builds
run: find builds -type f | head -20

- name: Setup Service Account
if: github.ref_name == 'main'
uses: google-github-actions/auth@v2
with:
project_id: ${{ secrets.GCP_PROJECT_ID }}
workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}

- name: Build firecrackers
run: sudo make build

- name: Upload firecrackers as artifact
if: github.ref_name != 'main'
uses: actions/upload-artifact@v4
with:
name: firecracker-${{ github.run_id }}
path: ./builds
retention-days: 7

- name: Upload firecrackers to GCS
if: github.ref_name == 'main'
uses: "google-github-actions/upload-cloud-storage@v1"
Expand All @@ -83,7 +91,6 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


- name: Prepare release assets
if: github.ref_name == 'main'
run: |
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,19 @@ This project automates the building of custom Firecracker. It supports building
- Edit `firecracker_versions.txt` to specify which kernel versions to build (one per line, e.g., `<last_tag-prelease>-<first-8-letters-of-the-specific-commit>`).

2. **Build:**

```sh
make build
# or directly
./build.sh
```

The built kernels will be placed in `builds/vmlinux-<version>/vmlinux.bin`.

## Development Workflow

- On every push, GitHub Actions will automatically build the kernels and save it as an artifact.

## License

This project is licensed under the Apache License 2.0. See [LICENSE](LICENSE) for details.
This project is licensed under the Apache License 2.0. See [LICENSE](LICENSE) for details.
53 changes: 45 additions & 8 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,44 @@

set -euo pipefail

FIRECRACKER_REPO_URL="https://github.com/e2b-dev/firecracker.git"

function build_version {
local version=$1
echo "Starting build for Firecracker commit: $version"

echo "Checking out repo for Firecracker at commit: $version"
git checkout "${version}"
# Detect if the version is of the form tag_shorthash (e.g., v1.12.1_abcdef12)
if [[ "$version" =~ ^([^_]+)_([0-9a-fA-F]+)$ ]]; then
local tag="${BASH_REMATCH[1]}"
local shorthash="${BASH_REMATCH[2]}"
echo "Starting build for Firecracker tag: $tag and shorthash: $shorthash"

echo "Checking out repo at tag: $tag"
git checkout "$tag"

# Find full hash from shorthash
fullhash=$(git rev-parse --verify "$shorthash^{commit}" 2>/dev/null || true)
if [[ -z "$fullhash" ]]; then
echo "Error: Could not resolve hash $shorthash"
exit 1
fi

# Ensure that $fullhash is a descendant of $tag
if git merge-base --is-ancestor "$tag" "$fullhash"; then
echo "Shorthash $shorthash is AFTER tag $tag -- proceeding"
git checkout "$fullhash"
else
echo "Error: shorthash $shorthash is not a descendant of tag $tag"
exit 1
fi
version_name="${tag}_$shorthash"
else
echo "Starting build for Firecracker at commit: $version"
echo "Checking out repo for Firecracker at commit: $version"
git checkout "${version}"
# The format will be: latest_tag_latest_commit_hash — v1.7.0-dev_g8bb88311
version_name=$(git describe --tags --abbrev=0 "$(git rev-parse HEAD)")_$(git rev-parse --short HEAD)
fi

# The format will be: latest_tag_latest_commit_hash — v1.7.0-dev_g8bb88311
version_name=$(git describe --tags --abbrev=0 $(git rev-parse HEAD))_$(git rev-parse --short HEAD)
echo "Version name: $version_name"

echo "Building Firecracker version: $version_name"
Expand All @@ -21,13 +50,21 @@ function build_version {
cp build/cargo_target/x86_64-unknown-linux-musl/release/firecracker "../builds/${version_name}/firecracker"
}

# If a version is passed as argument, build only that version
# Otherwise, build all versions from firecracker_versions.txt
if [[ $# -ge 1 ]]; then
versions=("$@")
else
mapfile -t versions < <(grep -v '^ *#' firecracker_versions.txt | grep -v '^$')
fi

echo "Cloning the Firecracker repository"
git clone https://github.com/firecracker-microvm/firecracker.git firecracker
git clone $FIRECRACKER_REPO_URL firecracker
cd firecracker

grep -v '^ *#' <../firecracker_versions.txt | while IFS= read -r version; do
for version in "${versions[@]}"; do
build_version "$version"
done

cd ..
rm -rf firecracker
rm -rf firecracker
4 changes: 3 additions & 1 deletion firecracker_versions.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
v1.10.1
v1.12.1
v1.12.1
v1.10.1_99e280c5
v1.12.1_0bb99c51
Loading