import { copyFile, readFile, rm, writeFile } from "node:fs/promises"; import path from "node:path"; import { Alpine } from "./alpine.js"; import { execFile } from "./helpers/better-api.js"; export type Kind = "lts" | "virt"; export type Kernel = { initramfs: string; vmlinuz: string; kind: Kind; }; export async function setupKernel( alpine: Alpine, output: string ): Promise { const kind: Kind = "virt"; await alpine.writeFile( "/etc/update-extlinux.conf", `# configuration for extlinux config builder # Overwrite current /boot/extlinux.conf. overwrite=1 # vesa_menu # use fancy vesa menu (vesamenu.c32) menus, won't work with serial vesa_menu=1 #default_kernel_opts=quiet default_kernel_opts= modules=loop,squashfs,sd-mod,usb-storage,ext4,vfat # root device - if not specified, will be guessed using # blkid -o export /dev/root root=/dev/sda # if set to non-zero, update-extlinux will be a lot more verbose. verbose=0 hidden=0 timeout=3 default=lts ` ); const features = [ "squashfs", "ata", "base", "cdrom", "ext4", "keymap", "kms", "mmc", "nvme", "scsi", "usb", ...(kind === "virt" ? ["virtio"] : []), ]; await alpine.writeFile( "/etc/mkinitfs/mkinitfs.conf", `features="${features.join(" ")}" disable_trigger=yes` ); await alpine.installPackages([`linux-${kind}`, "zstd"]); // patch mkinitfs to use faster zstd const mkinitfs = alpine.path("/sbin/mkinitfs"); const newMkinitfs = (await readFile(mkinitfs, "utf-8")).replace( 'comp="zstd -19"', 'comp="zstd -3"' ); await writeFile(mkinitfs, newMkinitfs); const kernelRelease = ( await readFile( alpine.path(`/usr/share/kernel/${kind}/kernel.release`), "utf-8" ) ).trim(); // TODO: poner en un mejor lugar await alpine.writeExecutable( "/etc/mkinitfs/init", await readFile("./initramfs-init", "utf-8") ); // run mkinitfs manually as trigger was diabled await execFile("chroot", [ alpine.dir, "mkinitfs", "-C", "zstd", "-o", `/boot/initramfs-${kind}`, "-i", "/etc/mkinitfs/init", kernelRelease, ]); const initramfs = path.join(alpine.dir, `/boot/initramfs-${kind}`); const vmlinuz = path.join(alpine.dir, `/boot/vmlinuz-${kind}`); const kernel: Kernel = { kind, initramfs: path.join(output, "initramfs"), vmlinuz: path.join(output, "vmlinuz"), }; await copyFile(initramfs, kernel.initramfs); await copyFile(vmlinuz, kernel.vmlinuz); await rm(initramfs); await rm(vmlinuz); return kernel; }