From b69f69c55aa341a6bf67bb5dd4ada63258c68ec1 Mon Sep 17 00:00:00 2001 From: navigator Date: Thu, 8 Oct 2026 06:55:43 +0000 Subject: [PATCH] feat: the kernel, initrd, firmware, bootloaders and installer move to plans/keel-boot Decision 0052: a separate boot layer per appliance, used only by the ISO, carries what a machine boots and installs with, so the layers a container template is assembled from never do. plans/turnkey/base no longer includes plans/boot and no longer lists grub-pc, tkl-installer, efivar, eject, jitterentropy-rngd, qemu-guest-agent and acpi-support-base; it lists systemd and systemd-sysv, which plans/boot used to bring. plans/keel-boot has them, with GRUB's overlay (overlays/keel-boot, was overlays/turnkey.d/grub) and conf (conf/keel-boot). grub-debug is split: its journald half, which a container needs as well, is conf/turnkey.d/journald-no-wall. tests/plans-boot.bats resolves the plans with cpp as fab-plan-resolve does and fails when turnkey/base names a package keel assemble refuses in a template. --- .github/workflows/tests.yml | 5 +- changes/turnkey.changelog | 18 ++++ conf/keel-boot/grub-debug | 8 ++ .../grub-iface-naming | 0 conf/turnkey.d/grub-debug | 9 -- conf/turnkey.d/journald-no-wall | 8 ++ mk/turnkey-desktop.mk | 2 +- .../grub => keel-boot}/etc/default/grub | 0 plans/keel-boot | 28 ++++++ plans/turnkey/base | 39 +++----- tests/plans-boot.bats | 91 +++++++++++++++++++ 11 files changed, 169 insertions(+), 39 deletions(-) create mode 100755 conf/keel-boot/grub-debug rename conf/{turnkey.d => keel-boot}/grub-iface-naming (100%) delete mode 100755 conf/turnkey.d/grub-debug create mode 100755 conf/turnkey.d/journald-no-wall rename overlays/{turnkey.d/grub => keel-boot}/etc/default/grub (100%) create mode 100644 plans/keel-boot create mode 100644 tests/plans-boot.bats diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8e963a88..c550afb4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,5 +13,6 @@ jobs: threshold: 100 # tests/anubis-signing-key.bats: packages/anubis/spec-key reads the # instance spec with PyYAML, as keel does. tests/locale.bats: dialog, - # to see the boxes it draws under C and under C.UTF-8 - apt-packages: python3-yaml dialog + # to see the boxes it draws under C and under C.UTF-8. tests/plans-boot.bats: + # cpp, to resolve the plans as fab-plan-resolve does + apt-packages: python3-yaml dialog cpp diff --git a/changes/turnkey.changelog b/changes/turnkey.changelog index 21c35483..ea34c354 100644 --- a/changes/turnkey.changelog +++ b/changes/turnkey.changelog @@ -1,3 +1,21 @@ +turnkey-core-19.0 (1) turnkey; urgency=low + + * The kernel, initrd, firmware, bootloaders and installer leave the + shared layers for a boot layer the ISO alone uses (handbook decision + 0052). [ Marcos Mendez ] + + plans/turnkey/base no longer includes plans/boot and no longer lists + grub-pc, tkl-installer, efivar, eject, jitterentropy-rngd, + qemu-guest-agent and acpi-support-base; it lists systemd and + systemd-sysv, which plans/boot used to bring. They are all in the new + plans/keel-boot, with GRUB's overlay (overlays/keel-boot) and conf + (conf/keel-boot/grub-iface-naming and grub-debug). The journald half + of grub-debug, which a container needs too, is + conf/turnkey.d/journald-no-wall. The core 19.0-9 template carried 28 + such packages, about 190 MB of its 904 MB. + + -- Marcos Mendez Thu, 08 Oct 2026 12:00:00 +0000 + turnkey-core-19.0 (1) turnkey; urgency=low * No database password is set at build time, and mysqltuner comes from diff --git a/conf/keel-boot/grub-debug b/conf/keel-boot/grub-debug new file mode 100755 index 00000000..5bcf7369 --- /dev/null +++ b/conf/keel-boot/grub-debug @@ -0,0 +1,8 @@ +#!/bin/bash -e + +# If DEBUG=y add debug options to grub (conf/turnkey.d/journald-no-wall is +# the other half, which a container needs too) + +if [[ $DEBUG = 'y' ]]; then + sed -i '/^GRUB_CMDLINE_LINUX=/ s|"\(.*\)"|"\1 debug ignore_loglevel"|' /etc/default/grub +fi diff --git a/conf/turnkey.d/grub-iface-naming b/conf/keel-boot/grub-iface-naming similarity index 100% rename from conf/turnkey.d/grub-iface-naming rename to conf/keel-boot/grub-iface-naming diff --git a/conf/turnkey.d/grub-debug b/conf/turnkey.d/grub-debug deleted file mode 100755 index b9f6297c..00000000 --- a/conf/turnkey.d/grub-debug +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -e - -# If DEBUG=y add debug options to grub; else disable Journalctl logging to console - -if [[ $DEBUG = 'y' ]]; then - sed -i '/^GRUB_CMDLINE_LINUX=/ s|"\(.*\)"|"\1 debug ignore_loglevel"|' /etc/default/grub -else - sed -i "\|ForwardToWall|s|#\([a-zA-Z]*=\).*|\1no|" /etc/systemd/journald.conf -fi diff --git a/conf/turnkey.d/journald-no-wall b/conf/turnkey.d/journald-no-wall new file mode 100755 index 00000000..2fdbe90c --- /dev/null +++ b/conf/turnkey.d/journald-no-wall @@ -0,0 +1,8 @@ +#!/bin/bash -e + +# Unless DEBUG=y, disable Journalctl logging to console (it was the other +# half of conf/keel-boot/grub-debug, which only the boot layer runs) + +if [[ $DEBUG != 'y' ]]; then + sed -i "\|ForwardToWall|s|#\([a-zA-Z]*=\).*|\1no|" /etc/systemd/journald.conf +fi diff --git a/mk/turnkey-desktop.mk b/mk/turnkey-desktop.mk index ea6af13b..bd031771 100644 --- a/mk/turnkey-desktop.mk +++ b/mk/turnkey-desktop.mk @@ -9,7 +9,7 @@ CONF_VARS += HOSTNAME ROOT_PASS NONFREE COMMON_OVERLAYS_TMP := $(COMMON_OVERLAYS) COMMON_OVERLAYS := bootstrap_apt COMMON_OVERLAYS += turnkey.d/bashrc -COMMON_OVERLAYS += turnkey.d/grub +COMMON_OVERLAYS += keel-boot COMMON_OVERLAYS += turnkey.d/profile COMMON_OVERLAYS += $(COMMON_OVERLAYS_TMP) diff --git a/overlays/turnkey.d/grub/etc/default/grub b/overlays/keel-boot/etc/default/grub similarity index 100% rename from overlays/turnkey.d/grub/etc/default/grub rename to overlays/keel-boot/etc/default/grub diff --git a/plans/keel-boot b/plans/keel-boot new file mode 100644 index 00000000..815aa369 --- /dev/null +++ b/plans/keel-boot @@ -0,0 +1,28 @@ +/* The boot layer (handbook decision 0052): what a virtual or a real machine + boots and installs with, and an LXC container never uses. Built by + "bt-layer --boot APPLIANCE" on top of the appliance layer, from the boot + product of buildtasks, and used by the ISO alone; the container template + is assembled from the layers below it. keel assemble refuses a template + that has any of these (keel.layers.container). */ + +#include + +// Grub packages +// * 'grub-pc' is required for legacy BIOS boot install +// * 'grub-efi-amd64' is required for UEFI boot install +// These grub packages conflict with one another but neither need be installed +// within the live rootfs/squashfs - but are required for 'grub-install'. +// We install grub-pc & ship grub-efi-amd64 deb (and deps) in the ISO. +// If required, grub-efi-amd64 will be installed into the target chroot. +grub-pc + +tkl-installer /* new custom TKL installer - replaces di-live */ +efivar /* installer depends - ISO UEFI boot */ +eject /* installer recommends */ + +// jitterentropy-rngd provides entropy from cpu jitter; req'd to seed entropy +// in early boot (especially useful when live booting). +jitterentropy-rngd + +qemu-guest-agent /* QEMU/KVM guest tools - as requested in #1356 */ +acpi-support-base /* ACPI power button and lid events */ diff --git a/plans/turnkey/base b/plans/turnkey/base index 117ba02d..bb6da203 100644 --- a/plans/turnkey/base +++ b/plans/turnkey/base @@ -1,29 +1,24 @@ -#include +/* The kernel, the initrd, firmware, the bootloaders and the installer are + not here: they are in plans/keel-boot, which only the boot layer the ISO + is made from installs (handbook decision 0052). A layer built from this + plan is a container's: it runs on the host's kernel. systemd is the + init, which plans/boot used to bring. */ +systemd +#ifdef DEBIAN +systemd-sysv +#endif #include #include wget curl rsync -zstd /* if installed will be used to compress initramfs */ +zstd keel-archive-keyring /* the key of archive.keellinux.org, overlays/turnkey.d/keel-apt */ -// Grub packages -// * 'grub-pc' is required for legacy BIOS boot install -// * 'grub-efi-amd64' is required for UEFI boot install -// These grub packages conflict with one another but neither need be installed -// within the live rootfs/squashfs - but are required for 'grub-install'. -// We install grub-pc & ship grub-efi-amd64 deb (and deps) in the ISO. -// If required, grub-efi-amd64 will be installed into the target chroot. -grub-pc - -tkl-installer /* new custom TKL installer - replaces di-live */ - -efivar /* installer depends - ISO UEFI boot */ -lvm2 /* installer recommends */ -file /* installer recommends */ -eject /* installer recommends */ +lvm2 /* webmin-lvm depends; the installer recommends */ +file confconsole kbd /* confconsole recommends */ @@ -31,10 +26,6 @@ resolvconf /* confconsole recommends */ dbus /* dbus installed by default since v18.x */ -// jiiterentropy-rngd provides entropy from cpu jitter; req'd to seed entropy -// in early boot (especially useful when live booting). -jitterentropy-rngd - /* tklbam, hubdns and webmin-tklbam are not installed: backup is Keel Backup (handbook decision 0040) and DNS registration is Keel Cloud, and neither turnkey-pypy2 nor py3curl-wrapper, which only they pulled in, is wanted */ @@ -95,13 +86,7 @@ bsd-mailx postfix webmin-postfix -qemu-guest-agent /* QEMU/KVM guest tools - as requested in #1356 */ - authbind /* add-water (confconsole lets encrypt) depends */ dehydrated /* add-water (confconsole lets encrypt) recommends (actually depends) */ python3-bottle /* add-water (confconsole lets encrypt) depends */ python3-requests /* confconsole lets encrypt recommends (actually depends) */ - -//ifndef CHROOT_ONLY -acpi-support-base -//endif diff --git a/tests/plans-boot.bats b/tests/plans-boot.bats new file mode 100644 index 00000000..8ee1f868 --- /dev/null +++ b/tests/plans-boot.bats @@ -0,0 +1,91 @@ +#!/usr/bin/env bats +# The plans of handbook decision 0052: a layer built from turnkey/base is a +# container's and has no kernel, initrd, firmware, bootloader or installer; +# plans/keel-boot, which only the boot layer of the ISO installs, has them. +# The plans are put through cpp as fab-plan-resolve does, with the defines +# of an amd64 Debian build and without CHROOT_ONLY, which Keel's layers are +# not built with. The patterns are those keel assemble refuses in a +# template (keel.layers.container.MACHINE_ONLY). + +bats_require_minimum_version 1.5.0 + +setup() { + TESTS_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")" && pwd)" + PLANS="$TESTS_DIR/../plans" + MACHINE_ONLY='^(linux-image-.*|linux-headers-.*|linux-base|initramfs-tools.*|dracut.*|klibc-utils|libklibc|live-boot.*|live-config.*|live-tools|tkl-installer|firmware-.*|.*-microcode|grub.*|shim.*|efibootmgr|mokutil|efivar|syslinux.*|isolinux|extlinux|os-prober|hdparm|qemu-guest-agent|acpi-support-base|acpid|jitterentropy-rngd)$' +} + +# resolve PLAN: the package names PLAN lists, one per line +resolve() { + cpp -P -undef -nostdinc -I "$PLANS" -D DEBIAN=y -D AMD64=y "$PLANS/$1" \ + | sed 's/#.*//' | awk 'NF { print $1 }' | sort -u +} + +@test "a layer built from turnkey/base has no package only a machine boots with" { + run --separate-stderr resolve turnkey/base + [ "$status" -eq 0 ] + [ -n "$output" ] + run ! grep -E "$MACHINE_ONLY" <<< "$output" +} + +@test "turnkey/base still installs systemd as the init" { + run resolve turnkey/base + [ "$status" -eq 0 ] + grep -qx systemd <<< "$output" + grep -qx systemd-sysv <<< "$output" +} + +@test "the boot layer has the kernel, the initrd, GRUB, the live boot and the installer" { + run --separate-stderr resolve keel-boot + [ "$status" -eq 0 ] + for name in linux-image-amd64 initramfs-tools firmware-linux-free grub-pc \ + live-boot isolinux tkl-installer efivar qemu-guest-agent; do + grep -qx "$name" <<< "$output" + done +} + +@test "every package taken out of turnkey/base is in the boot layer" { + for name in grub-pc tkl-installer efivar eject jitterentropy-rngd \ + qemu-guest-agent acpi-support-base; do + resolve keel-boot | grep -qx "$name" + run ! grep -qx "$name" <<< "$(resolve turnkey/base)" + done +} + +@test "only the boot layer's conf and overlay touch GRUB's configuration" { + run ! grep -rl '/etc/default/grub' "$TESTS_DIR/../conf/turnkey.d" + run ! test -e "$TESTS_DIR/../overlays/turnkey.d/grub" + grep -q /etc/default/grub "$TESTS_DIR/../conf/keel-boot/grub-iface-naming" + test -f "$TESTS_DIR/../overlays/keel-boot/etc/default/grub" +} + +# stub_sed: sed records its arguments instead of editing the host +stub_sed() { + mkdir -p "$BATS_TEST_TMPDIR/stubs" + printf '#!/bin/sh\necho "sed $*" >> "%s/calls"\n' "$BATS_TEST_TMPDIR" \ + > "$BATS_TEST_TMPDIR/stubs/sed" + chmod +x "$BATS_TEST_TMPDIR/stubs/sed" + PATH="$BATS_TEST_TMPDIR/stubs:$PATH" +} + +@test "a container still keeps the journal off the console, which grub-debug used to do" { + stub_sed + unset DEBUG + run "$TESTS_DIR/../conf/turnkey.d/journald-no-wall" + [ "$status" -eq 0 ] + grep -q 'ForwardToWall.*/etc/systemd/journald.conf$' "$BATS_TEST_TMPDIR/calls" + run "$TESTS_DIR/../conf/keel-boot/grub-debug" + [ "$status" -eq 0 ] + [ "$(wc -l < "$BATS_TEST_TMPDIR/calls")" -eq 1 ] +} + +@test "a debug build adds the debug options to GRUB and leaves the journal alone" { + stub_sed + export DEBUG=y + run "$TESTS_DIR/../conf/turnkey.d/journald-no-wall" + [ "$status" -eq 0 ] + run "$TESTS_DIR/../conf/keel-boot/grub-debug" + [ "$status" -eq 0 ] + [ "$(wc -l < "$BATS_TEST_TMPDIR/calls")" -eq 1 ] + grep -q 'debug ignore_loglevel.* /etc/default/grub$' "$BATS_TEST_TMPDIR/calls" +}