From a97e7cf02aa13e1b392f3e6625d7d78dda30d401 Mon Sep 17 00:00:00 2001 From: Jeffrey Alan Scudder Date: Sun, 29 Mar 2026 17:55:58 -0700 Subject: [PATCH] feat: OTA uploads slim kernel + initramfs for universal Mac/ThinkPad boot - upload-release.sh: auto-uploads vmlinuz-slim + initramfs.cpio.gz if they exist as siblings of vmlinuz - native-builder.mjs: extracts slim kernel + initramfs from Docker - ac-os pull: downloads slim kernel + initramfs from CDN when available - ac-os flash: auto-detects slim kernel and uses systemd-boot mode One `ac-os pull && ac-os flash` now produces a USB that boots on both. Co-Authored-By: Claude Opus 4.6 (1M context) --- fedac/native/ac-os | 15 +++++++++++++++ fedac/native/scripts/upload-release.sh | 16 ++++++++++++++++ oven/native-builder.mjs | 19 +++++++++++++++---- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/fedac/native/ac-os b/fedac/native/ac-os index 746e777636..c8c0e6cfc6 100755 --- a/fedac/native/ac-os +++ b/fedac/native/ac-os @@ -1184,6 +1184,21 @@ pull_ota() { fi log "SHA256 verified: ${ACTUAL_HASH:0:16}..." + # Download slim kernel + initramfs for universal Mac/ThinkPad boot + local SLIM_URL="${CDN_BASE}/native-notepat-latest.vmlinuz-slim" + local INITRAMFS_URL="${CDN_BASE}/native-notepat-latest.initramfs.cpio.gz" + local PULLED_SLIM="${PULL_DIR}/vmlinuz-slim" + local PULLED_INITRAMFS="${PULL_DIR}/initramfs.cpio.gz" + if curl -sf --head "${SLIM_URL}" >/dev/null 2>&1; then + log "Downloading slim kernel..." + curl -f --progress-bar -o "${PULLED_SLIM}" "${SLIM_URL}" || true + log "Downloading initramfs..." + curl -f --progress-bar -o "${PULLED_INITRAMFS}" "${INITRAMFS_URL}" || true + if [ -f "${PULLED_SLIM}" ] && [ -f "${PULLED_INITRAMFS}" ]; then + log "Universal boot files ready (slim $(du -sh "${PULLED_SLIM}" | cut -f1) + initramfs $(du -sh "${PULLED_INITRAMFS}" | cut -f1))" + fi + fi + # Override VMLINUZ and build name so flash_usb uses the downloaded kernel # (not the locally-generated name from scripts/build-name.sh) VMLINUZ="${PULLED_KERNEL}" diff --git a/fedac/native/scripts/upload-release.sh b/fedac/native/scripts/upload-release.sh index 279b0abfbb..a9967a185e 100755 --- a/fedac/native/scripts/upload-release.sh +++ b/fedac/native/scripts/upload-release.sh @@ -208,6 +208,18 @@ if command -v node &>/dev/null; then | node "$SCRIPT_DIR/track-build.mjs" record 2>&1 || true fi +# Upload slim kernel + initramfs for universal Mac/ThinkPad boot +SLIM_SIBLING="$(dirname "$VMLINUZ")/vmlinuz-slim" +INITRAMFS_SIBLING="$(dirname "$VMLINUZ")/initramfs.cpio.gz" +if [ -f "$SLIM_SIBLING" ]; then + echo " Uploading slim kernel ($(du -sh "$SLIM_SIBLING" | cut -f1))..." + do_upload "$SLIM_SIBLING" "os/${CHANNEL_PREFIX}native-notepat-latest.vmlinuz-slim" "application/octet-stream" +fi +if [ -f "$INITRAMFS_SIBLING" ]; then + echo " Uploading initramfs ($(du -sh "$INITRAMFS_SIBLING" | cut -f1))..." + do_upload "$INITRAMFS_SIBLING" "os/${CHANNEL_PREFIX}native-notepat-latest.initramfs.cpio.gz" "application/octet-stream" +fi + # Also upload ISO if it exists next to vmlinuz ISO_SIBLING="$(dirname "$VMLINUZ")/ac-os.iso" if [ -f "$ISO_SIBLING" ]; then @@ -218,6 +230,10 @@ fi echo "" echo "Release published: $BUILD_NAME ($FULL_VERSION)" echo " ${BASE_URL}/os/${CHANNEL_PREFIX}native-notepat-latest.vmlinuz" +if [ -f "$SLIM_SIBLING" ]; then + echo " ${BASE_URL}/os/${CHANNEL_PREFIX}native-notepat-latest.vmlinuz-slim" + echo " ${BASE_URL}/os/${CHANNEL_PREFIX}native-notepat-latest.initramfs.cpio.gz" +fi echo " ${BASE_URL}/os/${CHANNEL_PREFIX}releases.json" if [ -f "$ISO_SIBLING" ]; then echo " ${BASE_URL}/os/${CHANNEL_PREFIX}native-notepat-latest.iso" diff --git a/oven/native-builder.mjs b/oven/native-builder.mjs index 43ce06b559..2a61996830 100644 --- a/oven/native-builder.mjs +++ b/oven/native-builder.mjs @@ -412,12 +412,18 @@ async function runBuildJob(job) { job.percent = 75; - addLogLine(job, "stdout", "Phase 3: Extracting C kernel + ISO..."); + addLogLine(job, "stdout", "Phase 3: Extracting C kernel + ISO + slim kernel + initramfs..."); const cid = (await fs.readFile(cidFile, "utf8")).trim(); const isoOut = `/tmp/oven-iso-${job.id}`; - await runPhase(job, "extract", "bash", ["-c", - `docker cp ${cid}:/tmp/ac-build/vmlinuz ${vmlinuzOut} && docker cp ${cid}:/tmp/ac-build/ac-os.iso ${isoOut} 2>/dev/null; docker rm ${cid} >/dev/null` - ], repoDir); + const slimOut = `/tmp/oven-vmlinuz-slim-${job.id}`; + const initramfsOut = `/tmp/oven-initramfs-${job.id}`; + await runPhase(job, "extract", "bash", ["-c", [ + `docker cp ${cid}:/tmp/ac-build/vmlinuz ${vmlinuzOut}`, + `docker cp ${cid}:/tmp/ac-build/ac-os.iso ${isoOut} 2>/dev/null || true`, + `docker cp ${cid}:/tmp/ac-build/vmlinuz-slim ${slimOut} 2>/dev/null || true`, + `docker cp ${cid}:/tmp/ac-build/initramfs.cpio.gz ${initramfsOut} 2>/dev/null || true`, + `docker rm ${cid} >/dev/null`, + ].join("; ")], repoDir); job.percent = 80; @@ -425,9 +431,14 @@ async function runBuildJob(job) { const uploadDir = `/tmp/oven-upload-${job.id}`; const vmlinuzUpload = `${uploadDir}/vmlinuz`; const isoUpload = `${uploadDir}/ac-os.iso`; + const slimUpload = `${uploadDir}/vmlinuz-slim`; + const initramfsUpload = `${uploadDir}/initramfs.cpio.gz`; await fs.mkdir(uploadDir, { recursive: true }); await fs.rename(vmlinuzOut, vmlinuzUpload); try { await fs.rename(isoOut, isoUpload); } catch {} + try { await fs.rename(slimOut, slimUpload); } catch {} + try { await fs.rename(initramfsOut, initramfsUpload); } catch {} + // upload-release.sh auto-detects sibling files (vmlinuz-slim, initramfs.cpio.gz, ac-os.iso) await runPhase(job, "upload", "bash", [uploadScript, vmlinuzUpload], NATIVE_DIR, uploadEnv); try { await fs.rm(uploadDir, { recursive: true }); } catch {} -- 2.51.2