Ship yay, wire up LUKS disk encryption, self-signed Secure Boot, release signing
yay (yay-bin, AUR-only like calamares/bibata) republished to [breadway] via the same PKGBUILD + Forgejo workflow pattern, so users can reach the wider AUR beyond bakery's bread ecosystem. Disk encryption: Calamares' partition module already has LUKS support enabled by default, but the checkbox led nowhere — no cryptsetup on the live/target image, no mkinitcpio encrypt hook, no GRUB cryptodisk wiring. An encrypted install would partition fine and then never boot. Added cryptsetup, pinned luksGeneration to luks1 (GRUB doesn't support LUKS2 + Argon2id), and post-install.sh now detects an encrypted root (lsblk TYPE == crypt) and conditionally adds the encrypt hook + GRUB_ENABLE_CRYPTODISK + --modules="cryptodisk luks luks2" on both grub-install passes. No effect on a normal unencrypted install. Secure Boot: self-signed via sbctl (shipped in packages.x86_64). BOS can't ship a Microsoft-signed shim without going through Microsoft's own paid UEFI CA process, so post-install.sh enrolls BOS's own keys automatically only when the firmware is already in Setup Mode (sbctl status --json), signs the kernel/bootloader, and leaves it alone otherwise — sbctl's own pacman hook re-signs on every future kernel/GRUB update, no further wiring needed. Release signing: generated a dedicated Ed25519 "BOS Release Signing" key (not reused from anything else), stored as the GPG_PRIVATE_KEY Forgejo Actions secret. release-iso.yml now generates SHA256SUMS and a detached SHA256SUMS.asc signature alongside every ISO upload; public key committed at KEYS.asc with verification instructions in the README. README updated: fixed a stale "greetd + tuigreet" line (breadgreet since round 3), documented yay/encryption/secure-boot/verification.
This commit is contained in:
parent
489d472240
commit
5aaf71e80a
8 changed files with 282 additions and 35 deletions
|
|
@ -7,8 +7,13 @@ name: Build and release ISO
|
|||
# (GitHub releases cannot host files larger than 2 GB).
|
||||
#
|
||||
# Required secrets:
|
||||
# RELEASE_TOKEN — Forgejo API token with write:repository scope
|
||||
# MIRROR_TOKEN — GitHub personal access token with repo scope (already used by mirror.yml)
|
||||
# RELEASE_TOKEN — Forgejo API token with write:repository scope
|
||||
# MIRROR_TOKEN — GitHub personal access token with repo scope (already used by mirror.yml)
|
||||
# GPG_PRIVATE_KEY — armoured secret key for the dedicated "BOS Release Signing"
|
||||
# identity (releases@breadway.dev); public half is committed
|
||||
# at KEYS.asc for verification. No passphrase (CI-only key,
|
||||
# access controlled via the Forgejo secret store, not a
|
||||
# passphrase nobody could type non-interactively anyway).
|
||||
|
||||
on:
|
||||
push:
|
||||
|
|
@ -129,14 +134,35 @@ jobs:
|
|||
bash build-local.sh
|
||||
ls -lh /bos-out/*.iso
|
||||
|
||||
- name: Create Forgejo release and upload ISO
|
||||
- name: Checksum and sign
|
||||
env:
|
||||
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
VERSION="${{ steps.vars.outputs.version }}"
|
||||
ISO=$(ls /bos-out/*.iso | head -1)
|
||||
ISO_NAME="bos-${VERSION}-x86_64.iso"
|
||||
cd /bos-out
|
||||
mv "$(basename "$ISO")" "$ISO_NAME"
|
||||
|
||||
sha256sum "$ISO_NAME" > SHA256SUMS
|
||||
cat SHA256SUMS
|
||||
|
||||
pacman -Sy --noconfirm --needed gnupg
|
||||
export GNUPGHOME=/tmp/gnupg-release
|
||||
mkdir -m 700 -p "$GNUPGHOME"
|
||||
echo "$GPG_PRIVATE_KEY" | gpg --batch --import
|
||||
gpg --batch --yes --local-user releases@breadway.dev \
|
||||
--detach-sign --armor -o SHA256SUMS.asc SHA256SUMS
|
||||
echo "Signed SHA256SUMS -> SHA256SUMS.asc"
|
||||
|
||||
- name: Create Forgejo release and upload assets
|
||||
env:
|
||||
FORGEJO_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
TAG="${{ steps.vars.outputs.tag }}"
|
||||
VERSION="${{ steps.vars.outputs.version }}"
|
||||
ISO=$(ls /bos-out/*.iso | head -1)
|
||||
ISO_NAME="bos-${VERSION}-x86_64.iso"
|
||||
|
||||
# Use an existing release for this tag if one exists (e.g. created
|
||||
|
|
@ -157,35 +183,41 @@ jobs:
|
|||
\"tag_name\": \"${TAG}\",
|
||||
\"name\": \"BOS ${TAG}\",
|
||||
\"prerelease\": false,
|
||||
\"body\": \"ISO image attached below.\\n\\nSee the [README](https://github.com/Breadway/bos#testing-in-a-vm) for VM testing instructions.\"
|
||||
\"body\": \"ISO image attached below. Verify with SHA256SUMS + SHA256SUMS.asc (signed by the BOS Release Signing key — see KEYS.asc in the repo).\\n\\nSee the [README](https://github.com/Breadway/bos#testing-in-a-vm) for VM testing instructions.\"
|
||||
}")
|
||||
RELEASE_ID=$(echo "${RELEASE}" | python3 -c "import json,sys; print(json.load(sys.stdin)['id'])")
|
||||
fi
|
||||
echo "Using release ID: ${RELEASE_ID}"
|
||||
|
||||
# Remove any existing asset with the same name before uploading
|
||||
ASSET_ID=$(curl -sf \
|
||||
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||
"http://localhost:3002/api/v1/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets" \
|
||||
| python3 -c "
|
||||
upload_asset() {
|
||||
local file="$1" name
|
||||
name="$(basename "$file")"
|
||||
local asset_id
|
||||
asset_id=$(curl -sf \
|
||||
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||
"http://localhost:3002/api/v1/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets" \
|
||||
| python3 -c "
|
||||
import json,sys
|
||||
assets=json.load(sys.stdin)
|
||||
match=[a['id'] for a in assets if a['name']=='${ISO_NAME}']
|
||||
match=[a['id'] for a in assets if a['name']=='${name}']
|
||||
print(match[0] if match else '')
|
||||
" 2>/dev/null || true)
|
||||
|
||||
if [ -n "${ASSET_ID}" ]; then
|
||||
curl -fsS -X DELETE \
|
||||
if [ -n "${asset_id}" ]; then
|
||||
curl -fsS -X DELETE \
|
||||
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||
"http://localhost:3002/api/v1/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets/${asset_id}"
|
||||
echo "Removed existing ${name} asset"
|
||||
fi
|
||||
curl -fsS -X POST \
|
||||
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||
"http://localhost:3002/api/v1/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets/${ASSET_ID}"
|
||||
echo "Removed existing ${ISO_NAME} asset"
|
||||
fi
|
||||
-F "attachment=@${file};filename=${name}" \
|
||||
"http://localhost:3002/api/v1/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets"
|
||||
echo "Uploaded: ${name}"
|
||||
}
|
||||
|
||||
curl -fsS -X POST \
|
||||
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||
-F "attachment=@${ISO};filename=${ISO_NAME}" \
|
||||
"http://localhost:3002/api/v1/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets"
|
||||
echo "Uploaded: ${ISO_NAME}"
|
||||
upload_asset "/bos-out/${ISO_NAME}"
|
||||
upload_asset "/bos-out/SHA256SUMS"
|
||||
upload_asset "/bos-out/SHA256SUMS.asc"
|
||||
|
||||
- name: Create GitHub release
|
||||
env:
|
||||
|
|
@ -196,7 +228,7 @@ jobs:
|
|||
VERSION="${{ steps.vars.outputs.version }}"
|
||||
FORGEJO_URL="https://git.breadway.dev/${GITHUB_REPOSITORY}/releases/tag/${TAG}"
|
||||
|
||||
printf '**Download ISO:** %s\n\nGitHub releases cannot host files >2 GB; the `bos-%s-x86_64.iso` (~2.5 GB) is on Forgejo.\n\nSee the [README](https://github.com/Breadway/bos#testing-in-a-vm) for VM testing instructions.' \
|
||||
printf '**Download ISO:** %s\n\nGitHub releases cannot host files >2 GB; the `bos-%s-x86_64.iso` (~2.5 GB), SHA256SUMS, and SHA256SUMS.asc (signed by the BOS Release Signing key — public half at [KEYS.asc](https://github.com/Breadway/bos/blob/main/KEYS.asc)) are all on Forgejo.\n\nSee the [README](https://github.com/Breadway/bos#testing-in-a-vm) for VM testing instructions.' \
|
||||
"${FORGEJO_URL}" "${VERSION}" > /tmp/gh-release-notes.md
|
||||
|
||||
gh release create "${TAG}" \
|
||||
|
|
|
|||
36
.forgejo/workflows/yay-bin.yml
Normal file
36
.forgejo/workflows/yay-bin.yml
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
name: Build and publish yay-bin
|
||||
|
||||
# yay (and every AUR helper) is AUR-only — not in Arch's official repos — so
|
||||
# BOS maintains an in-house PKGBUILD and publishes the built package to the
|
||||
# [breadway] repo, same as bibata-cursor-theme and calamares. Prebuilt
|
||||
# release tarball, no build step.
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'packaging/yay-bin/**'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
yay-bin:
|
||||
runs-on: [self-hosted, hestia]
|
||||
container:
|
||||
image: archlinux:latest
|
||||
steps:
|
||||
- name: Build and publish
|
||||
env:
|
||||
PUBLISH_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
pacman -Syu --noconfirm base-devel git
|
||||
useradd -m builder
|
||||
git config --global --add safe.directory '*'
|
||||
git clone --depth 1 --branch "${GITHUB_REF_NAME}" \
|
||||
"https://git.breadway.dev/${GITHUB_REPOSITORY}.git" /home/builder/src
|
||||
chown -R builder:builder /home/builder/src
|
||||
su builder -c "cd /home/builder/src/packaging/yay-bin && makepkg -f --noconfirm --nocheck"
|
||||
PKG=$(find /home/builder/src/packaging/yay-bin -name '*.pkg.tar.zst' | head -1)
|
||||
curl -fsS -X PUT \
|
||||
-H "Authorization: token ${PUBLISH_TOKEN}" \
|
||||
-H "Content-Type: application/octet-stream" \
|
||||
--data-binary "@${PKG}" \
|
||||
"https://git.breadway.dev/api/packages/Breadway/arch/os"
|
||||
15
KEYS.asc
Normal file
15
KEYS.asc
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mDMEakhwGhYJKwYBBAHaRw8BAQdA/sZ/GYec5M2MD+w20mVF5tMUhGji210Dg7zL
|
||||
TAhNsg60WUJPUyBSZWxlYXNlIFNpZ25pbmcgKGdpdC5icmVhZHdheS5kZXYvQnJl
|
||||
YWR3YXkvYm9zIHJlbGVhc2VzIG9ubHkpIDxyZWxlYXNlc0BicmVhZHdheS5kZXY+
|
||||
iJYEExYKAD4WIQRWIDuGoRBpWufzEJNK8zI9Z4614gUCakhwGgIbIwUJA8JnAAUL
|
||||
CQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRBK8zI9Z4614ggYAQDP8FTZ14i9YPKD
|
||||
ARvZuP5QaYOUFhQ8uyG0CowXKy9O0AEAqYfjnvyJI3N651pVFSNUXyP16w1kMPSs
|
||||
K0g3CLsztQ+4OARqSHAaEgorBgEEAZdVAQUBAQdAuJFuy2GHz5m9wXTm/PdSpLE9
|
||||
gERwHOLyM1OFuttrJW4DAQgHiH4EGBYKACYWIQRWIDuGoRBpWufzEJNK8zI9Z461
|
||||
4gUCakhwGgIbDAUJA8JnAAAKCRBK8zI9Z4614nzLAP9grcIFsAAeCyVKhziHmpXq
|
||||
E0Hm6FfIr4sdEf63HZkyfwD/XeKeWfb3EWvVsloJrZZ9tDmR67iK52Hwl82wfFAU
|
||||
cAo=
|
||||
=Mrh1
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
53
README.md
53
README.md
|
|
@ -20,17 +20,23 @@ wiring up dotfiles, no per-tool bakery installs.
|
|||
- **bos-settings**: a GTK4 control panel that configures every bread\* app's
|
||||
config from a GUI (non-destructively), plus snapshot rollback and bakery
|
||||
updates. See below.
|
||||
- **Login**: greetd + tuigreet → Hyprland session.
|
||||
- **Login**: greetd + breadgreet (bread-ecosystem's own greeter, under `cage`)
|
||||
→ Hyprland session.
|
||||
- **Boot splash**: Plymouth `bos` theme (logo + spinner, black background).
|
||||
- **Theming**: global dark across GTK3 (Adwaita-dark), GTK4/libadwaita
|
||||
(`color-scheme: prefer-dark`), and Qt (qt5ct/qt6ct Fusion dark); Papirus-Dark
|
||||
icons; Bibata cursor.
|
||||
- **Apps**: kitty, nautilus (+ gvfs), Zen browser, VLC, loupe, gnome-text-editor,
|
||||
gnome-calculator, file-roller, with file associations wired in `mimeapps.list`.
|
||||
`yay` ships for AUR access beyond bakery's bread ecosystem + `[breadway]`.
|
||||
- **Hardware**: pipewire audio, NetworkManager, BlueZ + blueman, CUPS printing
|
||||
with avahi mDNS discovery, TLP power management, fwupd firmware updates.
|
||||
- **Resilience**: btrfs + snapper + snap-pac + grub-btrfs snapshots on every
|
||||
pacman transaction; zram swap; ufw firewall (deny-incoming, mDNS allowed).
|
||||
- **Security**: full-disk encryption (LUKS, via Calamares' built-in support —
|
||||
cryptsetup + the matching mkinitcpio/GRUB wiring ship so an encrypted
|
||||
install actually boots) and self-signed Secure Boot (via `sbctl`, enrolled
|
||||
automatically at install time when the firmware is in Setup Mode).
|
||||
|
||||
## Repo layout
|
||||
|
||||
|
|
@ -73,11 +79,30 @@ to the Tailscale-reachable Forgejo registry for the build.
|
|||
|
||||
### Why some packages are in-house
|
||||
|
||||
`calamares`, `zen-browser-bin`, and `bibata-cursor-theme` are AUR-only. BOS
|
||||
keeps a PKGBUILD for each under `packaging/` and republishes the built package
|
||||
to the `[breadway]` repo via a Forgejo Actions workflow (built on the hestia
|
||||
self-hosted runner, published with a scoped registry token). `bos-settings`
|
||||
itself publishes the same way on a `v*` tag.
|
||||
`calamares`, `zen-browser-bin`, `bibata-cursor-theme`, and `yay-bin` are
|
||||
AUR-only. BOS keeps a PKGBUILD for each under `packaging/` and republishes the
|
||||
built package to the `[breadway]` repo via a Forgejo Actions workflow (built
|
||||
on the hestia self-hosted runner, published with a scoped registry token).
|
||||
`bos-settings` itself publishes the same way on a `v*` tag.
|
||||
|
||||
### Verifying a release
|
||||
|
||||
Every tagged release ISO on the [Forgejo releases
|
||||
page](https://git.breadway.dev/Breadway/bos/releases) ships alongside a
|
||||
`SHA256SUMS` file and a detached signature `SHA256SUMS.asc`, signed by a
|
||||
dedicated release-signing key (not reused from anything else):
|
||||
|
||||
```
|
||||
5620 3B86 A110 695A E7F3 1093 4AF3 323D 678E B5E2
|
||||
```
|
||||
|
||||
The public half is committed at [`KEYS.asc`](KEYS.asc). To verify a download:
|
||||
|
||||
```sh
|
||||
gpg --import KEYS.asc
|
||||
gpg --verify SHA256SUMS.asc SHA256SUMS
|
||||
sha256sum -c SHA256SUMS
|
||||
```
|
||||
|
||||
## Testing in a VM
|
||||
|
||||
|
|
@ -166,9 +191,19 @@ cheatsheet in-session; first boot shows a short welcome (once).
|
|||
`virtio-vga-gl` + `-display gtk,gl=on` (virgl); plain software rendering is
|
||||
noticeably laggy.
|
||||
- **Wayland-first**: X11-only apps run through XWayland; a few may misbehave.
|
||||
- **Secure Boot**: not configured. Boot with Secure Boot disabled, or enroll
|
||||
your own keys. The installer writes both an NVRAM entry and the removable
|
||||
`EFI/BOOT/BOOTX64.EFI` fallback.
|
||||
- **Secure Boot**: self-signed only, via `sbctl` — BOS can't ship a
|
||||
Microsoft-signed shim (that needs going through Microsoft's own paid UEFI
|
||||
CA process). Post-install enrolls BOS's own keys automatically, but only
|
||||
when the firmware is already in Setup Mode (no vendor keys installed yet);
|
||||
otherwise it's skipped and you can run
|
||||
`sudo sbctl enroll-keys --microsoft && sudo sbctl sign-all -g` yourself
|
||||
later (after clearing your firmware's existing keys, if any). The installer
|
||||
writes both an NVRAM entry and the removable `EFI/BOOT/BOOTX64.EFI` fallback
|
||||
either way.
|
||||
- **Disk encryption**: full-disk LUKS is available on the installer's "Erase
|
||||
disk" page (Calamares' own checkbox) and on manually-created partitions —
|
||||
BOS ships the matching `cryptsetup`/mkinitcpio/GRUB wiring so an encrypted
|
||||
install actually boots (LUKS1, since GRUB doesn't support LUKS2 + Argon2id).
|
||||
- **Snapshots assume btrfs**: the snapper/grub-btrfs tooling expects the default
|
||||
btrfs subvolume layout the installer creates.
|
||||
|
||||
|
|
|
|||
|
|
@ -19,3 +19,15 @@ userSwapChoices:
|
|||
- small
|
||||
- suspend
|
||||
- file
|
||||
|
||||
# Full-disk encryption (LUKS) is enabled by default in Calamares' partition
|
||||
# module (enableLuksAutomatedPartitioning defaults to true) — the checkbox
|
||||
# already shows on the "Erase disk" page with no config needed here. Pin the
|
||||
# LUKS generation explicitly rather than relying on Calamares' own implicit
|
||||
# default: GRUB doesn't support LUKS2 + Argon2id, only PBKDF2, and using the
|
||||
# wrong KDF produces an encrypted install GRUB can't unlock at boot. luks1
|
||||
# is unconditionally safe with BOS's plain grub-install setup (no separate
|
||||
# unencrypted /boot — GRUB itself has to unlock the LUKS container to read
|
||||
# the kernel). See post-install.sh for the matching cryptsetup/mkinitcpio/
|
||||
# GRUB wiring this actually needs to be bootable.
|
||||
luksGeneration: luks1
|
||||
|
|
|
|||
|
|
@ -10,6 +10,19 @@ set -uo pipefail
|
|||
|
||||
MAIN_USER="$(getent passwd 1000 | cut -d: -f1 || true)"
|
||||
|
||||
# Whether Calamares encrypted the root partition (LUKS) — checked once here,
|
||||
# used below to conditionally wire mkinitcpio's encrypt hook and GRUB's
|
||||
# cryptodisk support. `lsblk TYPE` reports "crypt" for a cryptsetup-opened
|
||||
# mapper device regardless of what Calamares named it, so this works whether
|
||||
# the user picked automated "Erase disk" encryption or hand-encrypted a
|
||||
# partition in manual mode.
|
||||
ROOT_SRC="$(findmnt -no SOURCE / | sed 's/\[.*\]//')"
|
||||
if [[ "$(lsblk -no TYPE "$ROOT_SRC" 2>/dev/null)" == "crypt" ]]; then
|
||||
ROOT_ENCRYPTED=1
|
||||
else
|
||||
ROOT_ENCRYPTED=0
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Strip live-only bits that unpackfs copied verbatim from the live medium.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -57,6 +70,15 @@ if [[ -f /etc/mkinitcpio.conf ]]; then
|
|||
sed -i 's/^\(HOOKS=.*\budev\b\)/\1 plymouth/' /etc/mkinitcpio.conf \
|
||||
|| echo "WARN: adding plymouth hook failed"
|
||||
fi
|
||||
# encrypt — only when root is actually LUKS-encrypted (ROOT_ENCRYPTED,
|
||||
# detected above). Must sit after `block` (provides the device nodes the
|
||||
# encrypt hook opens) and before `filesystems` (mounts the now-unlocked
|
||||
# root) — both already present in stock mkinitcpio.conf's default HOOKS.
|
||||
if [[ "$ROOT_ENCRYPTED" == "1" ]] \
|
||||
&& ! grep -qE '^HOOKS=.*\bencrypt\b' /etc/mkinitcpio.conf; then
|
||||
sed -i 's/^\(HOOKS=.*\bblock\b\)/\1 encrypt/' /etc/mkinitcpio.conf \
|
||||
|| echo "WARN: adding encrypt hook failed"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -74,6 +96,17 @@ if command -v plymouth-set-default-theme &>/dev/null; then
|
|||
plymouth-set-default-theme bos || echo "WARN: plymouth-set-default-theme failed"
|
||||
fi
|
||||
|
||||
# GRUB needs to unlock LUKS itself to reach the kernel — there's no separate
|
||||
# unencrypted /boot partition (only /boot/efi is separate). GRUB_ENABLE_CRYPTODISK
|
||||
# makes grub-mkconfig emit the cryptomount commands grub.cfg needs; the
|
||||
# --modules flags below (on both grub-install calls) make sure the cryptodisk
|
||||
# and luks decoders are actually compiled into core.img, not just referenced.
|
||||
if [[ "$ROOT_ENCRYPTED" == "1" ]] && [[ -f /etc/default/grub ]] \
|
||||
&& ! grep -q '^GRUB_ENABLE_CRYPTODISK=' /etc/default/grub; then
|
||||
echo 'GRUB_ENABLE_CRYPTODISK=y' >> /etc/default/grub \
|
||||
|| echo "WARN: adding GRUB_ENABLE_CRYPTODISK failed"
|
||||
fi
|
||||
|
||||
# Rebuild every preset (default + fallback that bos-copy-kernel wrote) so the
|
||||
# microcode + plymouth HOOKS above are actually baked into the initramfs.
|
||||
mkinitcpio -P || echo "WARN: mkinitcpio -P failed"
|
||||
|
|
@ -95,18 +128,20 @@ mkinitcpio -P || echo "WARN: mkinitcpio -P failed"
|
|||
# BIOS: MBR install onto the disk hosting /.
|
||||
# ---------------------------------------------------------------------------
|
||||
if command -v grub-install &>/dev/null; then
|
||||
CRYPT_MODULES=()
|
||||
[[ "$ROOT_ENCRYPTED" == "1" ]] && CRYPT_MODULES=(--modules="cryptodisk luks luks2")
|
||||
if [[ -d /sys/firmware/efi ]]; then
|
||||
grub-install --target=x86_64-efi --efi-directory=/boot/efi \
|
||||
--bootloader-id=BOS --recheck \
|
||||
--bootloader-id=BOS --recheck "${CRYPT_MODULES[@]}" \
|
||||
|| echo "WARN: grub-install (nvram) failed"
|
||||
grub-install --target=x86_64-efi --efi-directory=/boot/efi \
|
||||
--removable --recheck \
|
||||
--removable --recheck "${CRYPT_MODULES[@]}" \
|
||||
|| echo "WARN: grub-install (removable) failed"
|
||||
else
|
||||
ROOT_DEV="$(findmnt -no SOURCE / | sed 's/\[.*\]//')"
|
||||
ROOT_DISK="$(lsblk -no pkname "$ROOT_DEV" 2>/dev/null)"
|
||||
if [[ -n "$ROOT_DISK" ]]; then
|
||||
grub-install --target=i386-pc --recheck "/dev/$ROOT_DISK" \
|
||||
grub-install --target=i386-pc --recheck "${CRYPT_MODULES[@]}" "/dev/$ROOT_DISK" \
|
||||
|| echo "WARN: grub-install (BIOS) failed"
|
||||
else
|
||||
echo "WARN: could not determine the disk hosting / (root device: ${ROOT_DEV:-unknown}) — BIOS grub-install skipped"
|
||||
|
|
@ -117,6 +152,33 @@ if command -v grub-mkconfig &>/dev/null; then
|
|||
grub-mkconfig -o /boot/grub/grub.cfg || echo "WARN: grub-mkconfig failed"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Secure Boot: self-signed keys via sbctl, only when the firmware is already
|
||||
# in Setup Mode (no vendor PK enrolled — the state a fresh/never-used
|
||||
# machine boots in, or one where the user cleared their firmware's keys
|
||||
# before installing). BOS can't ship a Microsoft-signed shim — that requires
|
||||
# going through Microsoft's own paid UEFI CA signing process — so this is
|
||||
# the realistic path for an Arch-based distro: generate our own keys, enroll
|
||||
# them (plus Microsoft's, so a dual-booted Windows bootmgr and fwupd's
|
||||
# signed capsule updates still verify), and sign the kernel + GRUB. sbctl's
|
||||
# own package ships a pacman hook (zz-sbctl.hook) that re-signs everything
|
||||
# automatically on every future kernel/GRUB update — nothing else to wire up.
|
||||
# Best-effort and silent-skip (not a WARN) when out of Setup Mode — that's
|
||||
# the expected state on most real hardware, not a failure.
|
||||
# ---------------------------------------------------------------------------
|
||||
if [[ -d /sys/firmware/efi ]] && command -v sbctl &>/dev/null; then
|
||||
SETUP_MODE="$(sbctl status --json 2>/dev/null | python3 -c \
|
||||
'import json,sys; print(json.load(sys.stdin).get("setup_mode", False))' 2>/dev/null)"
|
||||
if [[ "$SETUP_MODE" == "True" ]]; then
|
||||
sbctl create-keys || echo "WARN: sbctl create-keys failed"
|
||||
sbctl enroll-keys --microsoft || echo "WARN: sbctl enroll-keys failed"
|
||||
sbctl sign-all -g || echo "WARN: sbctl sign-all failed"
|
||||
echo "Secure Boot: keys enrolled and boot files signed."
|
||||
else
|
||||
echo "Secure Boot: firmware not in Setup Mode — skipped (run 'sudo sbctl enroll-keys --microsoft && sudo sbctl sign-all -g' manually later if desired)."
|
||||
fi
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Create @snapshots, @log, @cache as top-level btrfs subvolumes (peers of @,
|
||||
# not nested under it — so snapshots of @ don't recursively include
|
||||
|
|
|
|||
|
|
@ -30,6 +30,15 @@ efibootmgr
|
|||
btrfs-progs
|
||||
dosfstools
|
||||
mtools
|
||||
# LUKS full-disk encryption — Calamares' partition module has encryption
|
||||
# support built in and enabled by default, but needs cryptsetup actually
|
||||
# present (live, to create the container; installed, to unlock at boot via
|
||||
# mkinitcpio's encrypt hook) or the checkbox leads to an unbootable system.
|
||||
cryptsetup
|
||||
# Secure Boot key enrollment/signing (self-signed — see post-install.sh).
|
||||
# Ships its own pacman hook (zz-sbctl.hook) that re-signs the kernel/
|
||||
# bootloader automatically on every future update once enrolled.
|
||||
sbctl
|
||||
# squashfs-tools: provides unsquashfs, which Calamares' unpackfs module uses
|
||||
# to extract airootfs.sfs onto the target during install.
|
||||
squashfs-tools
|
||||
|
|
@ -161,6 +170,12 @@ mailcap
|
|||
# (calamares 3.4.x is already Qt6; there is no separate calamares-qt6 package)
|
||||
calamares
|
||||
|
||||
# AUR helper — yay-bin is AUR-only (no AUR helper ships in the official
|
||||
# repos), so it's republished to [breadway] the same way (see
|
||||
# packaging/yay-bin). Lets users reach the wider AUR beyond bakery's bread
|
||||
# ecosystem + [breadway]'s own small set of republished packages.
|
||||
yay-bin
|
||||
|
||||
# Bread ecosystem.
|
||||
#
|
||||
# The bread apps themselves (bakery, bread, breadbar, breadbox, breadcrumbs,
|
||||
|
|
|
|||
40
packaging/yay-bin/PKGBUILD
Normal file
40
packaging/yay-bin/PKGBUILD
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# BOS in-house rebuild of yay-bin (AUR-only upstream — no AUR helper is in
|
||||
# the official Arch repos, including yay itself). Republished to the
|
||||
# [breadway] repo so the ISO build can pull it via pacman (same pattern as
|
||||
# bibata-cursor-theme and calamares). Prebuilt release tarball — no build step.
|
||||
# Upstream maintainer: Jguer <pkgbuilds at jguer.space>
|
||||
pkgname=yay-bin
|
||||
pkgver=13.0.1
|
||||
pkgrel=1
|
||||
pkgdesc="Yet another yogurt. Pacman wrapper and AUR helper written in go. Pre-compiled."
|
||||
arch=('x86_64')
|
||||
url="https://github.com/Jguer/yay"
|
||||
license=('GPL-3.0-or-later')
|
||||
depends=(
|
||||
'pacman>6.1'
|
||||
'git'
|
||||
)
|
||||
optdepends=(
|
||||
'sudo: privilege elevation'
|
||||
'doas: privilege elevation'
|
||||
)
|
||||
provides=('yay')
|
||||
conflicts=('yay')
|
||||
|
||||
source=("https://github.com/Jguer/yay/releases/download/v${pkgver}/${pkgname/-bin/}_${pkgver}_x86_64.tar.gz")
|
||||
sha256sums=('1fdfcb5f7f387bc858d3a5754bdf4e4575bfbddac9560535a716d0ed7189c057')
|
||||
|
||||
package() {
|
||||
_output="${srcdir}/${pkgname/-bin/}_${pkgver}_${CARCH}"
|
||||
install -Dm755 "${_output}/${pkgname/-bin/}" "${pkgdir}/usr/bin/${pkgname/-bin/}"
|
||||
install -Dm644 "${_output}/yay.8" "${pkgdir}/usr/share/man/man8/yay.8"
|
||||
|
||||
install -Dm644 "${_output}/bash" "${pkgdir}/usr/share/bash-completion/completions/yay"
|
||||
install -Dm644 "${_output}/zsh" "${pkgdir}/usr/share/zsh/site-functions/_yay"
|
||||
install -Dm644 "${_output}/fish" "${pkgdir}/usr/share/fish/vendor_completions.d/yay.fish"
|
||||
|
||||
LANGS="ca cs de en es eu fr_FR he id it_IT ja ko pl_PL pt_BR pt ru_RU ru sv tr uk zh_CN zh_TW"
|
||||
for lang in ${LANGS}; do
|
||||
install -Dm644 "${_output}/${lang}.mo" "${pkgdir}/usr/share/locale/${lang}/LC_MESSAGES/yay.mo"
|
||||
done
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue