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
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@ This project automates the building of custom Linux kernels for Firecracker micr
# or directly
./build.sh
```
The built kernels will be placed in `builds/vmlinux-<version>/vmlinux.bin`.
The built kernels will be placed in `builds/vmlinux-<version>/<arch>/vmlinux.bin` where `<arch>` is `amd64` or `arm64` (Go/OCI convention). For x86_64 backward compatibility, a legacy copy is also placed at `builds/vmlinux-<version>/vmlinux.bin`.

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

## Architecture naming

Output directories use Go's `runtime.GOARCH` convention (`amd64`, `arm64`) so they match the infra orchestrator's `TargetArch()` path resolution. The build-time variable `TARGET_ARCH` (`x86_64`, `arm64`) is only used internally for config paths and cross-compilation flags.

## New Kernel in E2B's infra
_Note: these steps should give you new kernel on your self-hosted E2B using https://github.com/e2b-dev/infra_

Expand Down
22 changes: 17 additions & 5 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ set -euo pipefail
TARGET_ARCH="${TARGET_ARCH:-x86_64}"
HOST_ARCH="$(uname -m)"

# Go/OCI-normalized arch name for output directory structure.
# The infra orchestrator uses Go's runtime.GOARCH convention (amd64/arm64)
# for path resolution, so output directories must match.
normalize_arch() {
case "$1" in
x86_64) echo "amd64" ;;
aarch64) echo "arm64" ;;
*) echo "$1" ;;
esac
}
OUTPUT_ARCH="$(normalize_arch "$TARGET_ARCH")"

function install_dependencies {
local packages=(
bc bison busybox-static cpio curl flex gcc libelf-dev libssl-dev make patch squashfs-tools tree
Expand Down Expand Up @@ -59,14 +71,14 @@ function build_version {
fi

echo "Copying finished build to builds directory"
# Always output to {arch}/ subdirectory
mkdir -p "../builds/vmlinux-${version}/${TARGET_ARCH}"
# Output to normalized arch dir (amd64/arm64) matching Go's runtime.GOARCH
mkdir -p "../builds/vmlinux-${version}/${OUTPUT_ARCH}"
if [[ "$TARGET_ARCH" == "arm64" ]]; then
cp arch/arm64/boot/Image "../builds/vmlinux-${version}/${TARGET_ARCH}/vmlinux.bin"
cp arch/arm64/boot/Image "../builds/vmlinux-${version}/${OUTPUT_ARCH}/vmlinux.bin"
else
cp vmlinux "../builds/vmlinux-${version}/${TARGET_ARCH}/vmlinux.bin"
cp vmlinux "../builds/vmlinux-${version}/${OUTPUT_ARCH}/vmlinux.bin"
fi

# x86_64: also copy to legacy path (no arch subdir) for backwards compat
if [[ "$TARGET_ARCH" == "x86_64" ]]; then
cp vmlinux "../builds/vmlinux-${version}/vmlinux.bin"
Expand Down
94 changes: 94 additions & 0 deletions migrate-gcs-arch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/bin/bash
# Copies kernel files from x86_64/ to amd64/ subdirectories in GCS buckets.
#
# The infra orchestrator's TargetArch() normalizes x86_64 -> amd64 (Go convention),
# so kernels stored under x86_64/ are never found by the arch-aware path resolution,
# causing a gcsfuse stat penalty on every sandbox create.
#
# Usage:
# ./migrate-gcs-arch.sh <bucket> # dry-run: show what would be copied
# ./migrate-gcs-arch.sh <bucket> --apply # copy x86_64/ -> amd64/
# ./migrate-gcs-arch.sh <bucket> --delete-old # dry-run: show what old x86_64/ files would be deleted
# ./migrate-gcs-arch.sh <bucket> --delete-old --apply # actually delete old x86_64/ files
#
# Recommended workflow:
# 1. ./migrate-gcs-arch.sh gs://my-bucket # review what will be copied
# 2. ./migrate-gcs-arch.sh gs://my-bucket --apply # copy to amd64/
# 3. ... verify everything works ...
# 4. ./migrate-gcs-arch.sh gs://my-bucket --delete-old # review what will be deleted
# 5. ./migrate-gcs-arch.sh gs://my-bucket --delete-old --apply # clean up old x86_64/

set -euo pipefail

BUCKET="${1:?Usage: $0 <bucket> [--apply] [--delete-old]}"
shift

APPLY=false
DELETE_OLD=false
for arg in "$@"; do
case "$arg" in
--apply) APPLY=true ;;
--delete-old) DELETE_OLD=true ;;
*) echo "Unknown flag: $arg"; exit 1 ;;
esac
done

# Normalize bucket name — strip gs:// prefix if provided, we add it back
BUCKET="${BUCKET#gs://}"

echo "Scanning gs://${BUCKET} for x86_64/ paths..."
echo ""

objects=$(gsutil ls -r "gs://${BUCKET}/**/x86_64/**" 2>/dev/null || true)

if [[ -z "$objects" ]]; then
echo "No x86_64/ paths found in gs://${BUCKET}"
exit 0
fi

count=0
if [[ "$DELETE_OLD" == true ]]; then
while IFS= read -r src; do
[[ -z "$src" ]] && continue
[[ "$src" == */ ]] && continue

if [[ "$APPLY" == true ]]; then
echo " DELETE $src"
gsutil rm "$src"
else
echo " [dry-run] would delete $src"
fi
((count++)) || true
done <<< "$objects"

echo ""
echo "Total: $count objects"
if [[ "$APPLY" != true ]]; then
echo ""
echo "This was a dry run. Add --apply to actually delete."
fi
else
while IFS= read -r src; do
[[ -z "$src" ]] && continue
[[ "$src" == */ ]] && continue

dst="${src/\/x86_64\//\/amd64\/}"

if [[ "$APPLY" == true ]]; then
echo " COPY $src"
echo " -> $dst"
gsutil cp "$src" "$dst"
else
echo " [dry-run] $src"
echo " -> $dst"
fi
((count++)) || true
done <<< "$objects"

echo ""
echo "Total: $count objects"
if [[ "$APPLY" != true ]]; then
echo ""
echo "This was a dry run. Add --apply to actually copy."
fi
fi
Loading