fix: resolve grub-pc / grub-efi-amd64 "held broken packages" conflict
The edition package lists installed BOTH grub-pc and grub-efi-amd64 (+ shim-signed). Those provide the same bootloader role and conflict in apt, so every rootfs build failed with "unable to correct problems, you have held broken packages". A rootfs now carries exactly ONE bootloader, chosen by the BOOT variable (mirroring the existing --boot bios|efi deploy option): - versions.mk / common.sh: BOOT := bios (bios -> grub-pc, efi -> grub-efi-amd64 + shim-signed + mokutil), exported via the Makefile. - build-rootfs.sh validates BOOT early and injects the matching boot packages into the apt install; the static package lists no longer contain any grub package. - deploy-disk.sh / build-image.sh / install.sh default --boot from the same BOOT variable, so a rootfs and the artifact deployed from it can never disagree (BOOT=efi make image-cloud produces a UEFI image). - mokutil is now installed explicitly in the efi flavour (it was not pulled in because we install with --no-install-recommends). - docs updated (building.md knob + rationale, secureboot.md note).
This commit is contained in:
4
Makefile
4
Makefile
@@ -28,7 +28,7 @@ include versions.mk
|
|||||||
# Pass edition + env through to the scripts.
|
# Pass edition + env through to the scripts.
|
||||||
export DISTRO_NAME DISTRO_ID VERSION RELEASE_NAME
|
export DISTRO_NAME DISTRO_ID VERSION RELEASE_NAME
|
||||||
export DEBIAN_SUITE DEBIAN_MIRROR SECURITY_MIRROR ARCH
|
export DEBIAN_SUITE DEBIAN_MIRROR SECURITY_MIRROR ARCH
|
||||||
export KERNEL_PACKAGE KERNEL_VERSION
|
export KERNEL_PACKAGE KERNEL_VERSION BOOT
|
||||||
export BUILD_DIR ROOTFS_DIR IMAGE_DIR DEB_DIR LOG_DIR ARTIFACT_DIR
|
export BUILD_DIR ROOTFS_DIR IMAGE_DIR DEB_DIR LOG_DIR ARTIFACT_DIR
|
||||||
export TOOLCHAIN_REPO
|
export TOOLCHAIN_REPO
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ help:
|
|||||||
@echo
|
@echo
|
||||||
@echo "Configuration (see versions.mk):"
|
@echo "Configuration (see versions.mk):"
|
||||||
@echo " VERSION=$(VERSION) DEBIAN_SUITE=$(DEBIAN_SUITE) ARCH=$(ARCH)"
|
@echo " VERSION=$(VERSION) DEBIAN_SUITE=$(DEBIAN_SUITE) ARCH=$(ARCH)"
|
||||||
@echo " ARCLINE_TOOLCHAIN=auto|skip|require (toolchain in image builds)"
|
@echo " BOOT=$(BOOT) ARCLINE_TOOLCHAIN=auto|skip|require (bootloader / toolchain in image builds)"
|
||||||
|
|
||||||
# ── host deps ────────────────────────────────────────────────────────────────
|
# ── host deps ────────────────────────────────────────────────────────────────
|
||||||
deps:
|
deps:
|
||||||
|
|||||||
@@ -81,6 +81,13 @@ Set these as environment variables or edit `versions.mk`:
|
|||||||
| `ARCLINE_EXTRA_REPOS` | fetch grafana/loki upstream repos | `0` |
|
| `ARCLINE_EXTRA_REPOS` | fetch grafana/loki upstream repos | `0` |
|
||||||
| `ARCLINE_TOOLCHAIN` | toolchain in image builds | `auto` |
|
| `ARCLINE_TOOLCHAIN` | toolchain in image builds | `auto` |
|
||||||
| `ARCLINE_SIGN` | sign boot chain with the MOK (secure boot) | `0` |
|
| `ARCLINE_SIGN` | sign boot chain with the MOK (secure boot) | `0` |
|
||||||
|
| `BOOT` | bootloader in the image: `bios` → grub-pc, `efi` → grub-efi-amd64 + shim-signed | `bios` |
|
||||||
|
|
||||||
|
> **Why one bootloader?** `grub-pc` and `grub-efi-amd64` conflict, so apt fails
|
||||||
|
> with *"held broken packages"* if both are in a package list. Arcline ships
|
||||||
|
> exactly the one matching `BOOT` (injected by `build-rootfs.sh`). For a UEFI +
|
||||||
|
> secure-boot build: `BOOT=efi make iso-server` (or `make image-cloud` with
|
||||||
|
> `BOOT=efi`). The deployed image/install uses the same variable by default.
|
||||||
|
|
||||||
## Building without the Arcline toolchain
|
## Building without the Arcline toolchain
|
||||||
|
|
||||||
|
|||||||
@@ -53,9 +53,10 @@ against your MOK.
|
|||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- Requires `sbsigntool` on the build host and `mokutil` in the image
|
- Requires `sbsigntool` on the build host. `mokutil` (for enrollment) is
|
||||||
(`mokutil` is pulled in by the `shim-signed` package already in the package
|
installed in the image as part of the EFI boot flavour:
|
||||||
lists).
|
`BOOT=efi make iso-server` (the `efi` flavour adds `grub-efi-amd64
|
||||||
|
shim-signed mokutil`).
|
||||||
- Losing `MOK.priv` means you cannot sign future updates — back it up.
|
- Losing `MOK.priv` means you cannot sign future updates — back it up.
|
||||||
- Full vendor CA / Microsoft KEK signing is intentionally not used; revisit
|
- Full vendor CA / Microsoft KEK signing is intentionally not used; revisit
|
||||||
only if a commercial distribution is ever pursued.
|
only if a commercial distribution is ever pursued.
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ locales
|
|||||||
tzdata
|
tzdata
|
||||||
|
|
||||||
# ── boot ────────────────────────────────────────────────────────────────────
|
# ── boot ────────────────────────────────────────────────────────────────────
|
||||||
grub-pc
|
# The bootloader is chosen by the BOOT build variable and injected by
|
||||||
grub-efi-amd64
|
# build-rootfs.sh: bios → grub-pc, efi → grub-efi-amd64 + shim-signed.
|
||||||
shim-signed
|
# (Installing grub-pc and grub-efi-amd64 together makes apt fail with a
|
||||||
|
# "held broken packages" conflict — exactly one is ever installed.)
|
||||||
|
|
||||||
# ── kernel (cloud variant) ──────────────────────────────────────────────────
|
# ── kernel (cloud variant) ──────────────────────────────────────────────────
|
||||||
linux-image-cloud-amd64
|
linux-image-cloud-amd64
|
||||||
|
|||||||
@@ -13,9 +13,10 @@ locales
|
|||||||
tzdata
|
tzdata
|
||||||
|
|
||||||
# ── boot ────────────────────────────────────────────────────────────────────
|
# ── boot ────────────────────────────────────────────────────────────────────
|
||||||
grub-pc
|
# The bootloader is chosen by the BOOT build variable and injected by
|
||||||
grub-efi-amd64
|
# build-rootfs.sh: bios → grub-pc, efi → grub-efi-amd64 + shim-signed.
|
||||||
shim-signed
|
# (Installing grub-pc and grub-efi-amd64 together makes apt fail with a
|
||||||
|
# "held broken packages" conflict — exactly one is ever installed.)
|
||||||
os-prober
|
os-prober
|
||||||
|
|
||||||
# ── kernel / firmware ───────────────────────────────────────────────────────
|
# ── kernel / firmware ───────────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -12,9 +12,10 @@ locales
|
|||||||
tzdata
|
tzdata
|
||||||
|
|
||||||
# ── boot ────────────────────────────────────────────────────────────────────
|
# ── boot ────────────────────────────────────────────────────────────────────
|
||||||
grub-pc
|
# The bootloader is chosen by the BOOT build variable and injected by
|
||||||
grub-efi-amd64
|
# build-rootfs.sh: bios → grub-pc, efi → grub-efi-amd64 + shim-signed.
|
||||||
shim-signed
|
# (Installing grub-pc and grub-efi-amd64 together makes apt fail with a
|
||||||
|
# "held broken packages" conflict — exactly one is ever installed.)
|
||||||
os-prober
|
os-prober
|
||||||
|
|
||||||
# ── kernel / firmware ───────────────────────────────────────────────────────
|
# ── kernel / firmware ───────────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
|
|||||||
EDITION="${1:?usage: build-image.sh <edition> [--format qcow2|raw] [--size 4G] [--boot bios|efi]}"
|
EDITION="${1:?usage: build-image.sh <edition> [--format qcow2|raw] [--size 4G] [--boot bios|efi]}"
|
||||||
FORMAT="qcow2"
|
FORMAT="qcow2"
|
||||||
SIZE="4G"
|
SIZE="4G"
|
||||||
BOOT="bios"
|
BOOT="${BOOT:-bios}" # default from the BOOT build variable (see versions.mk)
|
||||||
|
|
||||||
shift || true
|
shift || true
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
|
|||||||
@@ -29,6 +29,14 @@ case "$ARCLINE_TOOLCHAIN" in
|
|||||||
*) die "ARCLINE_TOOLCHAIN must be auto|skip|require (got '$ARCLINE_TOOLCHAIN')" ;;
|
*) die "ARCLINE_TOOLCHAIN must be auto|skip|require (got '$ARCLINE_TOOLCHAIN')" ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# Fail fast on a bad boot flavour. grub-pc and grub-efi-amd64 conflict, so we
|
||||||
|
# install exactly the one matching BOOT (never both).
|
||||||
|
case "$BOOT" in
|
||||||
|
bios) BOOT_PKGS="grub-pc" ;;
|
||||||
|
efi) BOOT_PKGS="grub-efi-amd64 shim-signed mokutil" ;;
|
||||||
|
*) die "BOOT must be bios|efi (got '$BOOT')" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
EDIR="$(edition_dir "$EDITION")"
|
EDIR="$(edition_dir "$EDITION")"
|
||||||
ROOTFS="$ROOTFS_DIR/$EDITION"
|
ROOTFS="$ROOTFS_DIR/$EDITION"
|
||||||
ARTIFACT="$ARTIFACT_DIR/arcline-$EDITION-$VERSION-$ARCH.tar.xz"
|
ARTIFACT="$ARTIFACT_DIR/arcline-$EDITION-$VERSION-$ARCH.tar.xz"
|
||||||
@@ -73,8 +81,8 @@ trap 'unmount_pseudo' EXIT
|
|||||||
chroot_run() { chroot "$ROOTFS" /bin/bash -c "$*"; }
|
chroot_run() { chroot "$ROOTFS" /bin/bash -c "$*"; }
|
||||||
|
|
||||||
# ── 3. install edition packages ─────────────────────────────────────────────
|
# ── 3. install edition packages ─────────────────────────────────────────────
|
||||||
log "[3/6] installing edition packages (${EDITION})"
|
log "[3/6] installing edition packages (${EDITION}, boot: $BOOT)"
|
||||||
PKGS="$(grep -vE '^\s*(#|$)' "$EDIR/packages.list" | tr '\n' ' ')"
|
PKGS="$(grep -vE '^\s*(#|$)' "$EDIR/packages.list" | tr '\n' ' ')$BOOT_PKGS"
|
||||||
mount_pseudo
|
mount_pseudo
|
||||||
chroot_run "export DEBIAN_FRONTEND=noninteractive; apt-get update -qq && apt-get install -y --no-install-recommends $PKGS" \
|
chroot_run "export DEBIAN_FRONTEND=noninteractive; apt-get update -qq && apt-get install -y --no-install-recommends $PKGS" \
|
||||||
| tee "$LOG_DIR/packages-$EDITION.log"
|
| tee "$LOG_DIR/packages-$EDITION.log"
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ set -euo pipefail
|
|||||||
: "${KERNEL_PACKAGE:=linux-image-amd64}"
|
: "${KERNEL_PACKAGE:=linux-image-amd64}"
|
||||||
: "${KERNEL_VERSION:=6.12}"
|
: "${KERNEL_VERSION:=6.12}"
|
||||||
|
|
||||||
|
# Boot flavour (mirrors versions.mk): bios → grub-pc, efi → grub-efi-amd64.
|
||||||
|
: "${BOOT:=bios}"
|
||||||
|
|
||||||
# Toolchain policy for image builds:
|
# Toolchain policy for image builds:
|
||||||
# auto (default) install the Arcline tools if build/debs/*.deb exist,
|
# auto (default) install the Arcline tools if build/debs/*.deb exist,
|
||||||
# otherwise build without them (with a warning)
|
# otherwise build without them (with a warning)
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
|
|||||||
DEV="${1:?usage: deploy-disk.sh <device> <rootfs> <edition> [--boot bios|efi]}"
|
DEV="${1:?usage: deploy-disk.sh <device> <rootfs> <edition> [--boot bios|efi]}"
|
||||||
ROOTFS="${2:?usage: deploy-disk.sh <device> <rootfs> <edition> [--boot bios|efi]}"
|
ROOTFS="${2:?usage: deploy-disk.sh <device> <rootfs> <edition> [--boot bios|efi]}"
|
||||||
EDITION="${3:?usage: deploy-disk.sh <device> <rootfs> <edition> [--boot bios|efi]}"
|
EDITION="${3:?usage: deploy-disk.sh <device> <rootfs> <edition> [--boot bios|efi]}"
|
||||||
BOOT="${4:-bios}"
|
BOOT="${4:-$BOOT}" # default from the BOOT build variable (see versions.mk)
|
||||||
|
|
||||||
require_root "$0" "$@"
|
require_root "$0" "$@"
|
||||||
validate_edition "$EDITION"
|
validate_edition "$EDITION"
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
|
|||||||
|
|
||||||
DEV="${1:?usage: install.sh <device> [--edition server] [--boot bios|efi] [--rootfs <dir>|--image <tar.xz>]}"
|
DEV="${1:?usage: install.sh <device> [--edition server] [--boot bios|efi] [--rootfs <dir>|--image <tar.xz>]}"
|
||||||
EDITION="server"
|
EDITION="server"
|
||||||
BOOT="bios"
|
BOOT="${BOOT:-bios}" # default from the BOOT build variable (see versions.mk)
|
||||||
ROOTFS_SRC=""
|
ROOTFS_SRC=""
|
||||||
|
|
||||||
shift || true
|
shift || true
|
||||||
|
|||||||
@@ -25,6 +25,12 @@ ARCH := amd64
|
|||||||
KERNEL_PACKAGE := linux-image-amd64
|
KERNEL_PACKAGE := linux-image-amd64
|
||||||
KERNEL_VERSION := 6.12
|
KERNEL_VERSION := 6.12
|
||||||
|
|
||||||
|
# Boot flavour for installed systems — decides which GRUB lands in the image.
|
||||||
|
# bios → grub-pc (bare metal + most clouds; the default)
|
||||||
|
# efi → grub-efi-amd64 + shim-signed + mokutil (UEFI + secure boot)
|
||||||
|
# grub-pc and grub-efi-amd64 conflict, so exactly one is ever installed.
|
||||||
|
BOOT := bios
|
||||||
|
|
||||||
# Edition codenames (the "what do I install" flavours).
|
# Edition codenames (the "what do I install" flavours).
|
||||||
EDITIONS := server workstation cloud
|
EDITIONS := server workstation cloud
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user