Compare commits
No commits in common. "main" and "v0.6.1" have entirely different histories.
23 changed files with 104 additions and 512 deletions
|
|
@ -1,39 +0,0 @@
|
||||||
name: Build and publish python-pywal
|
|
||||||
|
|
||||||
# python-pywal was dropped from Arch's [extra] repo (AUR-only now), but the ISO
|
|
||||||
# needs the `wal` binary (bread-theme extracts the wallpaper palette with it).
|
|
||||||
# BOS keeps an in-house PKGBUILD and publishes to the [breadway] repo — same
|
|
||||||
# pattern as calamares / bibata / powerlevel10k / yay-bin.
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- 'packaging/python-pywal/**'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
python-pywal:
|
|
||||||
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 \
|
|
||||||
python python-build python-installer python-wheel python-setuptools imagemagick
|
|
||||||
useradd -m builder
|
|
||||||
git config --global --add safe.directory '*'
|
|
||||||
# Clone the ref that triggered this run (not the default branch) —
|
|
||||||
# same as the other packaging workflows.
|
|
||||||
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/python-pywal && makepkg -f --noconfirm"
|
|
||||||
PKG=$(find /home/builder/src/packaging/python-pywal -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"
|
|
||||||
|
|
@ -21,7 +21,6 @@ on:
|
||||||
- Build and publish bibata-cursor-theme
|
- Build and publish bibata-cursor-theme
|
||||||
- Build and publish powerlevel10k
|
- Build and publish powerlevel10k
|
||||||
- Build and publish yay-bin
|
- Build and publish yay-bin
|
||||||
- Build and publish python-pywal
|
|
||||||
types: [completed]
|
types: [completed]
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ taken as current:
|
||||||
| Work on `dev`; origin = GitHub | Single-trunk `main`; `stable` is a CI marker. `origin` = Forgejo, `github` = GitHub. |
|
| Work on `dev`; origin = GitHub | Single-trunk `main`; `stable` is a CI marker. `origin` = Forgejo, `github` = GitHub. |
|
||||||
| `[breadway]` provides bakery/breadbar/bos-settings | `[breadway]` is breadlock + AUR republishes. Desktop apps are bakery. **Not shipped:** breadcast, breadarr. |
|
| `[breadway]` provides bakery/breadbar/bos-settings | `[breadway]` is breadlock + AUR republishes. Desktop apps are bakery. **Not shipped:** breadcast, breadarr. |
|
||||||
| NVIDIA / A/B / Secure Boot / LUKS2 | NVIDIA proprietary is **unsupported**. A/B root swapping is **not implemented**. Secure Boot is **Setup Mode only** (self-signed `sbctl`). Disk encryption is **LUKS1** because GRUB cannot unlock LUKS2+Argon2id. |
|
| NVIDIA / A/B / Secure Boot / LUKS2 | NVIDIA proprietary is **unsupported**. A/B root swapping is **not implemented**. Secure Boot is **Setup Mode only** (self-signed `sbctl`). Disk encryption is **LUKS1** because GRUB cannot unlock LUKS2+Argon2id. |
|
||||||
| `SigLevel = Required` on `[breadway]` | **Yes, as of the signed repo.** `[breadway]` points at `https://dl.breadway.dev/arch` where `scripts/ci-publish-signed-repo.sh` detach-signs every `.pkg.tar.zst` and the db with the BOS release key (`56203B86…`, `KEYS.asc`). That key is trusted in the pacman keyring at build time, on the live medium, and on the installed target. |
|
| `SigLevel = Required` on `[breadway]` | **No.** Forgejo's Arch registry has no pacman-compatible db signatures. `SigLevel = Never` is TLS only; flipping Required without a signed db breaks installs. `KEYS.asc` signs ISO SHA256SUMS, not the pacman repo. |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
13
README.md
13
README.md
|
|
@ -174,10 +174,10 @@ dedicated release-signing key (not reused from anything else):
|
||||||
5620 3B86 A110 695A E7F3 1093 4AF3 323D 678E B5E2
|
5620 3B86 A110 695A E7F3 1093 4AF3 323D 678E B5E2
|
||||||
```
|
```
|
||||||
|
|
||||||
The public half is committed at [`KEYS.asc`](KEYS.asc). The same key signs
|
The public half is committed at [`KEYS.asc`](KEYS.asc). That key signs
|
||||||
the ISO checksums **and** the `[breadway]` pacman repo — every package and
|
**ISO checksums only** — it does not sign the `[breadway]` pacman repo
|
||||||
the db at `https://dl.breadway.dev/arch` carry a `.sig` from it, and that
|
(Forgejo's Arch registry has no pacman-compatible db signatures; that
|
||||||
section is `SigLevel = Required` (see
|
section stays `SigLevel = Never` until a signed repo exists — see
|
||||||
[docs/signed-repo.md](docs/signed-repo.md)). To verify a download:
|
[docs/signed-repo.md](docs/signed-repo.md)). To verify a download:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|
@ -381,9 +381,8 @@ until `dl.breadway.dev/arch` exists).
|
||||||
- **Snapshots assume btrfs**: the snapper/grub-btrfs tooling expects the default
|
- **Snapshots assume btrfs**: the snapper/grub-btrfs tooling expects the default
|
||||||
btrfs subvolume layout the installer creates. Recovery is the GRUB
|
btrfs subvolume layout the installer creates. Recovery is the GRUB
|
||||||
snapshots submenu, not `snapper rollback` — [docs/hardware.md](docs/hardware.md).
|
snapshots submenu, not `snapper rollback` — [docs/hardware.md](docs/hardware.md).
|
||||||
- **`[breadway]` signatures**: `SigLevel = Required` — the signed repo at
|
- **`[breadway]` signatures**: `SigLevel = Never` until a signed repo is
|
||||||
`dl.breadway.dev/arch` is live (db + every package `.sig`ned with the BOS
|
stood up at `dl.breadway.dev/arch`. See [docs/signed-repo.md](docs/signed-repo.md).
|
||||||
release key). See [docs/signed-repo.md](docs/signed-repo.md).
|
|
||||||
|
|
||||||
## Recovery
|
## Recovery
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,19 +25,14 @@ OUT="${OUT:-$REPO/out}"
|
||||||
STAGE=/tmp/bos-iso-stage
|
STAGE=/tmp/bos-iso-stage
|
||||||
rm -rf "$STAGE" && cp -a "$REPO/iso" "$STAGE"
|
rm -rf "$STAGE" && cp -a "$REPO/iso" "$STAGE"
|
||||||
|
|
||||||
# [breadway] now points at the signed public repo https://dl.breadway.dev/arch
|
# Rewrite the [breadway] pacman repo URL to the fastest reachable address.
|
||||||
# (SigLevel = Required) — no Forgejo-registry URL rewrite needed anymore.
|
# CI_BUILD=1 — container runs on hestia with --network=host; localhost:3002 is direct
|
||||||
#
|
# default — building on hermes; git.breadway.dev is flaky from there, use Tailscale
|
||||||
# Trust the [breadway] repo key in *this* build host's pacman keyring so
|
# Only ever rewrites the staged copy, never the committed pacman.conf.
|
||||||
# `pacstrap` can verify [breadway] packages while assembling the airootfs.
|
if [ "${CI_BUILD:-0}" = "1" ]; then
|
||||||
# The same key is baked into the image at etc/pacman.d/breadway-repo.asc and
|
sed -i 's#https://git.breadway.dev/api/packages/Breadway/arch/os#http://localhost:3002/api/packages/Breadway/arch/os#' "$STAGE/pacman.conf"
|
||||||
# re-trusted on the live medium / installed target (calamares/post-install.sh).
|
else
|
||||||
BREADWAY_KEY_FPR="56203B86A110695AE7F310934AF3323D678EB5E2"
|
sed -i 's#https://git.breadway.dev/api/packages/Breadway/arch/os#http://100.66.238.26:3002/api/packages/Breadway/arch/os#' "$STAGE/pacman.conf"
|
||||||
BREADWAY_KEY_SRC="$REPO/iso/airootfs/etc/pacman.d/breadway-repo.asc"
|
|
||||||
if ! pacman-key --list-keys "$BREADWAY_KEY_FPR" &>/dev/null; then
|
|
||||||
echo "=== trusting [breadway] repo key ($BREADWAY_KEY_FPR) in the host pacman keyring ==="
|
|
||||||
pacman-key --add "$BREADWAY_KEY_SRC"
|
|
||||||
pacman-key --lsign-key "$BREADWAY_KEY_FPR"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${FAST_BUILD:-0}" = "1" ]; then
|
if [ "${FAST_BUILD:-0}" = "1" ]; then
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,18 @@
|
||||||
# Signed `[breadway]` repo
|
# Signed `[breadway]` repo
|
||||||
|
|
||||||
**Status: live.** The ISO's `[breadway]` section is `SigLevel = Required`
|
Today the ISO's `[Breadway.os.git.breadway.dev]` section is
|
||||||
and points at `https://dl.breadway.dev/arch/$arch`, where every
|
`SigLevel = Never`. That is TLS-only integrity: packages come from Forgejo's
|
||||||
`.pkg.tar.zst` and the db carry a detached `.sig` from the BOS release key
|
Arch registry, which does **not** serve pacman-compatible database
|
||||||
(`56203B86…`, `KEYS.asc`, `releases@breadway.dev`). That key is trusted in
|
signatures. `KEYS.asc` signs **ISO `SHA256SUMS`** and, once published, the
|
||||||
the pacman keyring at build time (`build-local.sh`), on the live medium
|
`dl.breadway.dev/arch` database. It is **not** imported as a pacman repo key
|
||||||
(`iso/airootfs/root/customize_airootfs.sh`), and on the installed target
|
on the ISO yet. Do not flip `SigLevel` to `Required` on that section until
|
||||||
(`iso/airootfs/etc/calamares/post-install.sh`).
|
a signed repo exists and has been verified; Required without signatures
|
||||||
|
breaks the ISO and every installed system.
|
||||||
|
|
||||||
Forgejo publishing is unchanged: `package.yml` / packaging workflows still
|
The signed repo belongs at `https://dl.breadway.dev/arch`, not on Forgejo's
|
||||||
PUT unsigned `.pkg.tar.zst` to Forgejo's Arch registry. The signed tree at
|
registry. Forgejo publishing stays as it is (`package.yml` / packaging
|
||||||
`dl.breadway.dev/arch` is rebuilt from that registry by
|
workflows PUT unsigned `.pkg.tar.zst` so existing Never installs keep
|
||||||
`.forgejo/workflows/signed-repo.yml` + `scripts/ci-publish-signed-repo.sh`.
|
working).
|
||||||
|
|
||||||
The rest of this doc is the original stand-up / verification procedure,
|
|
||||||
kept for reference and for re-verifying after key rotation.
|
|
||||||
|
|
||||||
## Stand up `dl.breadway.dev/arch`
|
## Stand up `dl.breadway.dev/arch`
|
||||||
|
|
||||||
|
|
@ -49,7 +47,7 @@ On disk: `/srv/breadway-dl/arch/x86_64/` (nginx already serves
|
||||||
|
|
||||||
The job collects the current ISO `[breadway]` set from the Forgejo Arch
|
The job collects the current ISO `[breadway]` set from the Forgejo Arch
|
||||||
registry (breadlock + calamares, zen-browser-bin, bibata-cursor-theme-bin,
|
registry (breadlock + calamares, zen-browser-bin, bibata-cursor-theme-bin,
|
||||||
zsh-theme-powerlevel10k, yay-bin, python-pywal). Leftover bakery-channel pacman packages
|
zsh-theme-powerlevel10k, yay-bin). Leftover bakery-channel pacman packages
|
||||||
still sitting in that registry are **not** copied. Optional
|
still sitting in that registry are **not** copied. Optional
|
||||||
`BREADWAY_PKG_DIR` on the runner overrides individual files.
|
`BREADWAY_PKG_DIR` on the runner overrides individual files.
|
||||||
|
|
||||||
|
|
@ -76,7 +74,7 @@ Pacman fetches `<section>.db` + `<section>.db.sig` from `Server`.
|
||||||
## Dispatch the workflow
|
## Dispatch the workflow
|
||||||
|
|
||||||
Forgejo UI: **Actions → "Publish signed [breadway] repo" → Run workflow**.
|
Forgejo UI: **Actions → "Publish signed [breadway] repo" → Run workflow**.
|
||||||
Select `main`.
|
Select this branch (`feature/signed-repo`) until it is on `main`.
|
||||||
|
|
||||||
API (`workflow_dispatch`):
|
API (`workflow_dispatch`):
|
||||||
|
|
||||||
|
|
@ -85,11 +83,13 @@ curl -fsS -X POST \
|
||||||
-H "Authorization: token ${RELEASE_TOKEN}" \
|
-H "Authorization: token ${RELEASE_TOKEN}" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
"https://git.breadway.dev/api/v1/repos/Breadway/bos/actions/workflows/signed-repo.yml/dispatches" \
|
"https://git.breadway.dev/api/v1/repos/Breadway/bos/actions/workflows/signed-repo.yml/dispatches" \
|
||||||
-d '{"ref":"main"}'
|
-d '{"ref":"feature/signed-repo"}'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
After merge, use `"ref":"main"`.
|
||||||
|
|
||||||
It also runs after the in-repo AUR republish workflows complete
|
It also runs after the in-repo AUR republish workflows complete
|
||||||
(`calamares` / `bibata` / `powerlevel10k` / `yay-bin` / `python-pywal`). breadlock lives in
|
(`calamares` / `bibata` / `powerlevel10k` / `yay-bin`). breadlock lives in
|
||||||
another repo; that job can fire this one with `repository_dispatch` event
|
another repo; that job can fire this one with `repository_dispatch` event
|
||||||
`publish-signed-repo` (or dispatch from the UI after a breadlock tag).
|
`publish-signed-repo` (or dispatch from the UI after a breadlock tag).
|
||||||
|
|
||||||
|
|
@ -141,29 +141,15 @@ stays; Never installs keep working. The signed tree is rebuilt by the bos
|
||||||
workflow above (registry fetch + sign + `repo-add -s`), not by writing
|
workflow above (registry fetch + sign + `repo-add -s`), not by writing
|
||||||
`/srv` from breadlock's container.
|
`/srv` from breadlock's container.
|
||||||
|
|
||||||
## The ISO flip (done)
|
## After the signed repo exists
|
||||||
|
|
||||||
All three steps have landed:
|
Only after `https://dl.breadway.dev/arch/x86_64/breadway.db.sig` HEADs 200
|
||||||
|
and the verify commands above succeed:
|
||||||
|
|
||||||
1. **Key trusted.** The public key is committed at
|
1. Import `KEYS.asc` into the ISO keyring (`pacman-key --add` + `--lsign-key`).
|
||||||
`iso/airootfs/etc/pacman.d/breadway-repo.asc`. `build-local.sh`
|
2. Point `[breadway]` `Server` at `https://dl.breadway.dev/arch/$arch`.
|
||||||
`pacman-key --add` + `--lsign-key`s it into the build host keyring;
|
3. Only then flip that section to `SigLevel = Required`.
|
||||||
`customize_airootfs.sh` does the same in the airootfs;
|
|
||||||
`calamares/post-install.sh` re-does it in the target chroot.
|
|
||||||
2. **`Server`** in `iso/pacman.conf` and `iso/airootfs/etc/pacman.conf`
|
|
||||||
points at `https://dl.breadway.dev/arch/$arch`, section renamed to
|
|
||||||
`[breadway]` (matching `breadway.db`).
|
|
||||||
3. **`SigLevel = Required`** on that section.
|
|
||||||
|
|
||||||
### Re-verify after any build
|
Do not do those three steps against Forgejo's registry. See
|
||||||
|
`iso/pacman.conf` and `iso/airootfs/etc/pacman.conf`. This branch does
|
||||||
In a VM booted from a fresh ISO:
|
**not** change either file.
|
||||||
|
|
||||||
```sh
|
|
||||||
sudo pacman -Sy # must fetch breadway.db + .sig, no signature error
|
|
||||||
sudo pacman -Si breadlock # lists the [breadway] section
|
|
||||||
sudo pacman -S --noconfirm yay-bin # installs with no key prompt
|
|
||||||
```
|
|
||||||
|
|
||||||
Then run the installer and, on the installed system, `sudo pacman -Sy`
|
|
||||||
again — the target keyring must already trust `56203B86…`.
|
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,9 @@ showSupportUrl: false
|
||||||
showKnownIssuesUrl: false
|
showKnownIssuesUrl: false
|
||||||
showReleaseNotesUrl: false
|
showReleaseNotesUrl: false
|
||||||
|
|
||||||
# 3.4.2 schema: `check` is shown; only `required` blocks Next. Internet is
|
|
||||||
# informational so offline installs proceed. Do not probe archlinux.org.
|
|
||||||
requirements:
|
requirements:
|
||||||
requiredStorage: 20
|
requiredStorage: 20
|
||||||
requiredRam: 2.0
|
requiredRam: 2.0
|
||||||
internetCheckUrl: "https://breadway.dev"
|
checkInternet: true
|
||||||
check:
|
checkPower: true
|
||||||
- storage
|
internetCheckUrl: "https://archlinux.org"
|
||||||
- ram
|
|
||||||
- power
|
|
||||||
- internet
|
|
||||||
- root
|
|
||||||
required:
|
|
||||||
- storage
|
|
||||||
- ram
|
|
||||||
- root
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
# Best-effort: do NOT use `set -e`; a single failure here must not abort the rest.
|
# Best-effort: do NOT use `set -e`; a single failure here must not abort the rest.
|
||||||
set -uo pipefail
|
set -uo pipefail
|
||||||
|
|
||||||
|
MAIN_USER="$(getent passwd 1000 | cut -d: -f1 || true)"
|
||||||
|
|
||||||
# Whether Calamares encrypted the root partition (LUKS) — checked once here,
|
# Whether Calamares encrypted the root partition (LUKS) — checked once here,
|
||||||
# used below to conditionally wire mkinitcpio's encrypt hook and GRUB's
|
# used below to conditionally wire mkinitcpio's encrypt hook and GRUB's
|
||||||
# cryptodisk support. `lsblk TYPE` reports "crypt" for a cryptsetup-opened
|
# cryptodisk support. `lsblk TYPE` reports "crypt" for a cryptsetup-opened
|
||||||
|
|
@ -31,14 +33,6 @@ rm -f /usr/local/bin/bos-live-setup /usr/local/bin/bos-launch-calamares
|
||||||
rm -f /etc/sudoers.d/99-bos-live
|
rm -f /etc/sudoers.d/99-bos-live
|
||||||
userdel -r liveuser 2>/dev/null || true
|
userdel -r liveuser 2>/dev/null || true
|
||||||
|
|
||||||
# Live ISO creates liveuser as UID 1000; Calamares then creates the real
|
|
||||||
# account as 1001. Capture AFTER userdel so Snapper ALLOW_USERS and skel
|
|
||||||
# copy the installed user, not the deleted live account.
|
|
||||||
MAIN_USER="$(getent passwd 1000 | cut -d: -f1 || true)"
|
|
||||||
if [[ -z "$MAIN_USER" || "$MAIN_USER" == "liveuser" ]]; then
|
|
||||||
MAIN_USER="$(getent passwd | awk -F: '$3 >= 1000 && $3 < 60000 && $1 != "liveuser" { print $1; exit }')"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# unpackfs copies the entire live squashfs onto the target. Remove live-only
|
# unpackfs copies the entire live squashfs onto the target. Remove live-only
|
||||||
# packages (Calamares + archiso boot chain + memtest/EFI-shell payloads) so
|
# packages (Calamares + archiso boot chain + memtest/EFI-shell payloads) so
|
||||||
# they do not stay on disk forever. pacman -Rs (not -Rns) keeps /etc configs
|
# they do not stay on disk forever. pacman -Rs (not -Rns) keeps /etc configs
|
||||||
|
|
@ -73,23 +67,15 @@ passwd -l root || true
|
||||||
# over to the target (unpackfs may skip it / perms differ), leaving the installed
|
# over to the target (unpackfs may skip it / perms differ), leaving the installed
|
||||||
# system unable to verify package signatures — the first `pacman -Syu` then dies
|
# system unable to verify package signatures — the first `pacman -Syu` then dies
|
||||||
# with "keyring is not writable / required key missing". Initialise it here so a
|
# with "keyring is not writable / required key missing". Initialise it here so a
|
||||||
# fresh install can update out of the box. archlinux-keyring verifies official
|
# fresh install can update out of the box. archlinux-keyring is already present
|
||||||
# Arch packages; the BOS release key (56203B86…, shipped at
|
# and is the only keyring populated — it verifies official Arch packages.
|
||||||
# /etc/pacman.d/breadway-repo.asc) verifies the signed [breadway] repo at
|
# [breadway] stays SigLevel=Never (Forgejo does not serve pacman-compatible
|
||||||
# dl.breadway.dev/arch — SigLevel = Required there, every package and the db
|
# db signatures). Do not import KEYS.asc here: that key signs ISO SHA256SUMS,
|
||||||
# carry a .sig from it.
|
# not the pacman repo; treating it as a repo key would be a lie.
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
BREADWAY_KEY_FPR="56203B86A110695AE7F310934AF3323D678EB5E2"
|
|
||||||
if command -v pacman-key &>/dev/null; then
|
if command -v pacman-key &>/dev/null; then
|
||||||
pacman-key --init || echo "WARN: pacman-key --init failed"
|
pacman-key --init || echo "WARN: pacman-key --init failed"
|
||||||
pacman-key --populate archlinux || echo "WARN: pacman-key --populate failed"
|
pacman-key --populate archlinux || echo "WARN: pacman-key --populate failed"
|
||||||
if [[ -f /etc/pacman.d/breadway-repo.asc ]]; then
|
|
||||||
pacman-key --add /etc/pacman.d/breadway-repo.asc \
|
|
||||||
&& pacman-key --lsign-key "$BREADWAY_KEY_FPR" \
|
|
||||||
|| echo "WARN: could not trust the [breadway] repo key — pacman -Sy will fail on [breadway]"
|
|
||||||
else
|
|
||||||
echo "WARN: /etc/pacman.d/breadway-repo.asc missing — [breadway] (SigLevel=Required) will not verify"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -32,17 +32,18 @@ Include = /etc/pacman.d/mirrorlist
|
||||||
# are NOT here; they are bakery-baked into /usr/local at ISO build time.
|
# are NOT here; they are bakery-baked into /usr/local at ISO build time.
|
||||||
#
|
#
|
||||||
# Packages are published to the Forgejo Arch registry (group "os") by the
|
# Packages are published to the Forgejo Arch registry (group "os") by the
|
||||||
# .forgejo/workflows/*.yml workflows; scripts/ci-publish-signed-repo.sh then
|
# .forgejo/workflows/*.yml workflows in this repo (and breadlock's).
|
||||||
# collects them, detach-signs each .pkg.tar.zst with the BOS release key
|
|
||||||
# (releases@breadway.dev), runs `repo-add -s`, and publishes the signed db
|
|
||||||
# at https://dl.breadway.dev/arch/$arch (signed-repo.yml).
|
|
||||||
#
|
#
|
||||||
# SigLevel = Required: every package AND the db carry a .sig from key
|
# Forgejo's Arch package registry does not serve pacman-compatible db
|
||||||
# 56203B86A110695AE7F310934AF3323D678EB5E2 — the same key committed as
|
# signatures. SigLevel = Never is TLS-only integrity: the connection is
|
||||||
# KEYS.asc / etc/pacman.d/breadway-repo.asc, imported into the pacman
|
# HTTPS (or rewritten to hestia's localhost:3002 in CI). breadlock (PAM)
|
||||||
# keyring at build time (build-local.sh), on the live medium, and on the
|
# rides this repo. Do NOT flip to SigLevel = Required unless a signed db
|
||||||
# installed target (calamares/post-install.sh).
|
# has been verified to work — Required without signatures breaks the ISO
|
||||||
|
# and every install that uses [breadway]. KEYS.asc is the ISO SHA256SUMS
|
||||||
|
# signing key, not a pacman repo key.
|
||||||
# -----------------------------------------------------------------------
|
# -----------------------------------------------------------------------
|
||||||
[breadway]
|
# The section name must match Forgejo's served db filename
|
||||||
SigLevel = Required
|
# ({owner}.{group}.{domain}.db) — pacman fetches "<section>.db" from Server.
|
||||||
Server = https://dl.breadway.dev/arch/$arch
|
[Breadway.os.git.breadway.dev]
|
||||||
|
SigLevel = Never
|
||||||
|
Server = https://git.breadway.dev/api/packages/Breadway/arch/os/$arch
|
||||||
|
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
-----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-----
|
|
||||||
|
|
@ -1,228 +0,0 @@
|
||||||
-- external-monitors — behave like a normal laptop desktop
|
|
||||||
--
|
|
||||||
-- Plug in any display (HDMI, DisplayPort, USB-C dock, a random TV) and
|
|
||||||
-- the session just works. No output names to edit.
|
|
||||||
--
|
|
||||||
-- • the laptop panel stays at its preferred (native) mode
|
|
||||||
-- • each external uses its preferred mode and refresh
|
|
||||||
-- • new screens clone the laptop (set ARRANGE = "extend" to sit to the right)
|
|
||||||
-- • closing the lid does not sleep while an external is on
|
|
||||||
-- • unplug everything and the laptop is the only display again
|
|
||||||
--
|
|
||||||
-- Drop-in: copy to ~/.config/bread/modules/ and `bread reload`.
|
|
||||||
|
|
||||||
local M = bread.module({
|
|
||||||
name = "external-monitors",
|
|
||||||
version = "1.0.0",
|
|
||||||
after = { "bread.monitors" },
|
|
||||||
})
|
|
||||||
|
|
||||||
-- "mirror" = every external clones the laptop (presentations, TVs)
|
|
||||||
-- "extend" = extra desktop to the right
|
|
||||||
local ARRANGE = "mirror"
|
|
||||||
local SCALE = "auto"
|
|
||||||
|
|
||||||
local INTERNAL_RE = "^eDP"
|
|
||||||
local INHIBITOR = "/tmp/bread-lid-inhibitor.pid"
|
|
||||||
|
|
||||||
local function inhibit_lid()
|
|
||||||
if bread.fs.exists(INHIBITOR) then return end
|
|
||||||
bread.exec(
|
|
||||||
"bash -c 'systemd-inhibit --what=handle-lid-switch --who=bread "
|
|
||||||
.. "--why=external-display sleep infinity & echo $! > "
|
|
||||||
.. INHIBITOR
|
|
||||||
.. "'"
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function release_lid()
|
|
||||||
bread.exec(
|
|
||||||
"bash -c 'kill $(cat " .. INHIBITOR .. " 2>/dev/null) 2>/dev/null; rm -f " .. INHIBITOR .. "'"
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function is_internal(name)
|
|
||||||
return type(name) == "string" and name:match(INTERNAL_RE) ~= nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local function drm_status(name)
|
|
||||||
for card = 0, 5 do
|
|
||||||
local raw = bread.fs.read(string.format("/sys/class/drm/card%d-%s/status", card, name))
|
|
||||||
if raw then
|
|
||||||
return raw:match("^%s*(%S+)")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local function drm_first_mode(name)
|
|
||||||
for card = 0, 5 do
|
|
||||||
local raw = bread.fs.read(string.format("/sys/class/drm/card%d-%s/modes", card, name))
|
|
||||||
if raw then
|
|
||||||
local w, h = raw:match("(%d+)x(%d+)")
|
|
||||||
if w then
|
|
||||||
return tonumber(w), tonumber(h)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return 1920, 1080
|
|
||||||
end
|
|
||||||
|
|
||||||
local function list_connectors()
|
|
||||||
local names = {}
|
|
||||||
local ok, out = bread.exec_capture("ls /sys/class/drm", { timeout_ms = 500 })
|
|
||||||
if not ok or not out then
|
|
||||||
return names
|
|
||||||
end
|
|
||||||
for ent in out:gmatch("[^%s]+") do
|
|
||||||
local name = ent:match("^card%d+%-(.+)$")
|
|
||||||
if name and not name:match("^Writeback") then
|
|
||||||
names[#names + 1] = name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
table.sort(names)
|
|
||||||
return names
|
|
||||||
end
|
|
||||||
|
|
||||||
local function connected()
|
|
||||||
local internal, externals = nil, {}
|
|
||||||
for _, name in ipairs(list_connectors()) do
|
|
||||||
if drm_status(name) == "connected" then
|
|
||||||
if is_internal(name) then
|
|
||||||
internal = internal or name
|
|
||||||
else
|
|
||||||
externals[#externals + 1] = name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return internal or "eDP-1", externals
|
|
||||||
end
|
|
||||||
|
|
||||||
-- BOS Hyprland talks Lua (`hl.monitor`). Stock Hyprland uses the
|
|
||||||
-- `monitor=` keyword. Try eval first, then keyword.
|
|
||||||
local function apply_monitor(opts)
|
|
||||||
local extra = ""
|
|
||||||
if opts.mirror and opts.mirror ~= "" then
|
|
||||||
extra = string.format(", mirror = %q", opts.mirror)
|
|
||||||
end
|
|
||||||
local expr = string.format(
|
|
||||||
"hl.monitor({ output = %q, mode = %q, position = %q, scale = %q%s })",
|
|
||||||
opts.output,
|
|
||||||
opts.mode or "preferred",
|
|
||||||
opts.position or "0x0",
|
|
||||||
opts.scale or SCALE,
|
|
||||||
extra
|
|
||||||
)
|
|
||||||
local resp = bread.hyprland.eval(expr)
|
|
||||||
if type(resp) == "string" and resp:match("error") then
|
|
||||||
local spec = string.format(
|
|
||||||
"%s, %s, %s, %s",
|
|
||||||
opts.output,
|
|
||||||
opts.mode or "preferred",
|
|
||||||
opts.position or "0x0",
|
|
||||||
opts.scale or SCALE
|
|
||||||
)
|
|
||||||
if opts.mirror and opts.mirror ~= "" then
|
|
||||||
spec = spec .. ", mirror, " .. opts.mirror
|
|
||||||
end
|
|
||||||
bread.hyprland.keyword("monitor", spec)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function apply(internal, externals)
|
|
||||||
apply_monitor({
|
|
||||||
output = internal,
|
|
||||||
mode = "preferred",
|
|
||||||
position = "0x0",
|
|
||||||
scale = SCALE,
|
|
||||||
})
|
|
||||||
|
|
||||||
if ARRANGE == "mirror" then
|
|
||||||
for _, name in ipairs(externals) do
|
|
||||||
apply_monitor({
|
|
||||||
output = name,
|
|
||||||
mode = "preferred",
|
|
||||||
position = "0x0",
|
|
||||||
scale = SCALE,
|
|
||||||
mirror = internal,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local x = select(1, drm_first_mode(internal)) or 1920
|
|
||||||
for _, name in ipairs(externals) do
|
|
||||||
apply_monitor({
|
|
||||||
output = name,
|
|
||||||
mode = "preferred",
|
|
||||||
position = x .. "x0",
|
|
||||||
scale = SCALE,
|
|
||||||
})
|
|
||||||
local w = select(1, drm_first_mode(name)) or 1920
|
|
||||||
x = x + w
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.on_load()
|
|
||||||
local last = nil
|
|
||||||
local applied = false
|
|
||||||
|
|
||||||
local function evaluate()
|
|
||||||
local internal, externals = connected()
|
|
||||||
local sig = internal .. "|" .. table.concat(externals, ",")
|
|
||||||
if sig == last then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
last = sig
|
|
||||||
|
|
||||||
if #externals == 0 then
|
|
||||||
if applied then
|
|
||||||
apply_monitor({
|
|
||||||
output = internal,
|
|
||||||
mode = "preferred",
|
|
||||||
position = "0x0",
|
|
||||||
scale = SCALE,
|
|
||||||
})
|
|
||||||
release_lid()
|
|
||||||
applied = false
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
apply(internal, externals)
|
|
||||||
inhibit_lid()
|
|
||||||
applied = true
|
|
||||||
bread.log("[external-monitors] " .. internal .. " + " .. table.concat(externals, ", "))
|
|
||||||
end
|
|
||||||
|
|
||||||
local settle = bread.debounce(1500, evaluate)
|
|
||||||
|
|
||||||
bread.on("bread.hyprland.monitor.connected", function(event)
|
|
||||||
local name = event.data and event.data.name
|
|
||||||
if name and not is_internal(name) then
|
|
||||||
bread.notify("Display connected: " .. name, { urgency = "low" })
|
|
||||||
end
|
|
||||||
settle()
|
|
||||||
end)
|
|
||||||
|
|
||||||
bread.on("bread.hyprland.monitor.disconnected", function()
|
|
||||||
settle()
|
|
||||||
end)
|
|
||||||
|
|
||||||
bread.on("bread.device.**", function(event)
|
|
||||||
local sub = event.data and event.data.subsystem
|
|
||||||
if sub == "drm" then
|
|
||||||
settle()
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
bread.hyprland.on_raw("configreloaded", function()
|
|
||||||
last = nil
|
|
||||||
evaluate()
|
|
||||||
end)
|
|
||||||
|
|
||||||
bread.every(3000, evaluate)
|
|
||||||
settle()
|
|
||||||
end
|
|
||||||
|
|
||||||
return M
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
{ "command": "breadhelp --autostart", "label": "BOS Help (first-run onboarding)", "enabled": true },
|
{ "command": "breadhelp --autostart", "label": "BOS Help (first-run onboarding)", "enabled": true },
|
||||||
{ "command": "bash -c 'command -v breadpaper >/dev/null && exec breadpaper listen'", "label": "Wallpaper command bus (breadpaper listen)", "enabled": true },
|
{ "command": "bash -c 'command -v breadpaper >/dev/null && exec breadpaper listen'", "label": "Wallpaper command bus (breadpaper listen)", "enabled": true },
|
||||||
{ "command": "bash -c 'command -v breadshot >/dev/null && exec breadshot listen'", "label": "Screenshot command bus (breadshot listen)", "enabled": true },
|
{ "command": "bash -c 'command -v breadshot >/dev/null && exec breadshot listen'", "label": "Screenshot command bus (breadshot listen)", "enabled": true },
|
||||||
{ "command": "bash -c 'command -v breadlock >/dev/null && exec breadlock listen'", "label": "Lock command bus (breadlock listen)", "enabled": true },
|
|
||||||
{ "command": "bash -c 'command -v breadbox >/dev/null && exec breadbox listen'", "label": "Launcher command bus (breadbox listen)", "enabled": true },
|
{ "command": "bash -c 'command -v breadbox >/dev/null && exec breadbox listen'", "label": "Launcher command bus (breadbox listen)", "enabled": true },
|
||||||
{ "command": "bash -c 'command -v breadhelp >/dev/null && exec breadhelp listen'", "label": "Help command bus (breadhelp listen)", "enabled": true },
|
{ "command": "bash -c 'command -v breadhelp >/dev/null && exec breadhelp listen'", "label": "Help command bus (breadhelp listen)", "enabled": true },
|
||||||
{ "command": "bash -c 'command -v breadsearch >/dev/null && exec breadsearch listen'", "label": "Search command bus (breadsearch listen)", "enabled": true },
|
{ "command": "bash -c 'command -v breadsearch >/dev/null && exec breadsearch listen'", "label": "Search command bus (breadsearch listen)", "enabled": true },
|
||||||
|
|
|
||||||
|
|
@ -137,9 +137,9 @@ hl.on("hyprland.start", function()
|
||||||
-- Clipboard history is breadclipd, a bakery-managed systemd --user
|
-- Clipboard history is breadclipd, a bakery-managed systemd --user
|
||||||
-- service (auto-started from /usr/lib/systemd/user — see
|
-- service (auto-started from /usr/lib/systemd/user — see
|
||||||
-- build-local.sh's service bake) rather than an exec-once here.
|
-- build-local.sh's service bake) rather than an exec-once here.
|
||||||
-- Prefer bread-polkit if it is on PATH (not baked; lockfile does not
|
-- Prefer bread-polkit when bakery has published it; otherwise the
|
||||||
-- ship it). Otherwise the ISO's polkit-gnome agent. command -v so a
|
-- ISO's polkit-gnome agent. command -v so a missing binary does not
|
||||||
-- missing binary does not leave the session without an auth agent.
|
-- leave the session without an auth agent.
|
||||||
"sh -c 'if command -v bread-polkit >/dev/null; then exec bread-polkit; else exec /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1; fi'",
|
"sh -c 'if command -v bread-polkit >/dev/null; then exec bread-polkit; else exec /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1; fi'",
|
||||||
"awww-daemon",
|
"awww-daemon",
|
||||||
-- Set the default wallpaper once the daemon is up (retry until ready).
|
-- Set the default wallpaper once the daemon is up (retry until ready).
|
||||||
|
|
@ -194,7 +194,6 @@ hl.on("hyprland.start", function()
|
||||||
"breadhelp --autostart",
|
"breadhelp --autostart",
|
||||||
"bash -c 'command -v breadpaper >/dev/null && exec breadpaper listen'",
|
"bash -c 'command -v breadpaper >/dev/null && exec breadpaper listen'",
|
||||||
"bash -c 'command -v breadshot >/dev/null && exec breadshot listen'",
|
"bash -c 'command -v breadshot >/dev/null && exec breadshot listen'",
|
||||||
"bash -c 'command -v breadlock >/dev/null && exec breadlock listen'",
|
|
||||||
"bash -c 'command -v breadbox >/dev/null && exec breadbox listen'",
|
"bash -c 'command -v breadbox >/dev/null && exec breadbox listen'",
|
||||||
"bash -c 'command -v breadhelp >/dev/null && exec breadhelp listen'",
|
"bash -c 'command -v breadhelp >/dev/null && exec breadhelp listen'",
|
||||||
"bash -c 'command -v breadsearch >/dev/null && exec breadsearch listen'",
|
"bash -c 'command -v breadsearch >/dev/null && exec breadsearch listen'",
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ local DEFAULT_EXTRA = {
|
||||||
{ command = "breadhelp --autostart", enabled = true },
|
{ command = "breadhelp --autostart", enabled = true },
|
||||||
{ command = "bash -c 'command -v breadpaper >/dev/null && exec breadpaper listen'", enabled = true },
|
{ command = "bash -c 'command -v breadpaper >/dev/null && exec breadpaper listen'", enabled = true },
|
||||||
{ command = "bash -c 'command -v breadshot >/dev/null && exec breadshot listen'", enabled = true },
|
{ command = "bash -c 'command -v breadshot >/dev/null && exec breadshot listen'", enabled = true },
|
||||||
{ command = "bash -c 'command -v breadlock >/dev/null && exec breadlock listen'", enabled = true },
|
|
||||||
{ command = "bash -c 'command -v breadbox >/dev/null && exec breadbox listen'", enabled = true },
|
{ command = "bash -c 'command -v breadbox >/dev/null && exec breadbox listen'", enabled = true },
|
||||||
{ command = "bash -c 'command -v breadhelp >/dev/null && exec breadhelp listen'", enabled = true },
|
{ command = "bash -c 'command -v breadhelp >/dev/null && exec breadhelp listen'", enabled = true },
|
||||||
{ command = "bash -c 'command -v breadsearch >/dev/null && exec breadsearch listen'", enabled = true },
|
{ command = "bash -c 'command -v breadsearch >/dev/null && exec breadsearch listen'", enabled = true },
|
||||||
|
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
# Run by mkarchiso inside the airootfs chroot, after packages are installed
|
|
||||||
# and before the squashfs is built. (archiso prints a deprecation warning for
|
|
||||||
# this hook, but there is no non-deprecated replacement for "trust an extra
|
|
||||||
# pacman repo key in the image keyring", and BOS ships no pacman-init.service.)
|
|
||||||
#
|
|
||||||
# Purpose: trust the BOS release key (56203B86…) in the image's pacman
|
|
||||||
# keyring so the signed [breadway] repo (SigLevel = Required,
|
|
||||||
# https://dl.breadway.dev/arch) verifies both on the live medium and — via
|
|
||||||
# calamares' unpackfs, which copies this squashfs to the target — on the
|
|
||||||
# installed system. calamares/post-install.sh re-does this in the target
|
|
||||||
# chroot as a fallback (unpackfs can skip /etc/pacman.d/gnupg).
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
BREADWAY_KEY_FPR="56203B86A110695AE7F310934AF3323D678EB5E2"
|
|
||||||
KEY_FILE="/etc/pacman.d/breadway-repo.asc"
|
|
||||||
|
|
||||||
pacman-key --init
|
|
||||||
pacman-key --populate archlinux
|
|
||||||
|
|
||||||
if [[ -f "$KEY_FILE" ]]; then
|
|
||||||
pacman-key --add "$KEY_FILE"
|
|
||||||
pacman-key --lsign-key "$BREADWAY_KEY_FPR"
|
|
||||||
echo "customize_airootfs: trusted [breadway] repo key $BREADWAY_KEY_FPR"
|
|
||||||
else
|
|
||||||
echo "customize_airootfs: WARNING $KEY_FILE missing; [breadway] will not verify" >&2
|
|
||||||
fi
|
|
||||||
|
|
@ -47,15 +47,7 @@ fi
|
||||||
echo
|
echo
|
||||||
bold "==> Bread ecosystem (bakery update --all)"
|
bold "==> Bread ecosystem (bakery update --all)"
|
||||||
if command -v bakery >/dev/null; then
|
if command -v bakery >/dev/null; then
|
||||||
# /usr/local is root-owned. Never run bakery as the user against it;
|
bakery update --all || echo "WARN: bakery update failed"
|
||||||
# bakery itself also tries sudo -n then pkexec for privileged writes.
|
|
||||||
if sudo -n true >/dev/null 2>&1; then
|
|
||||||
sudo -n bakery update --all || echo "WARN: bakery update failed"
|
|
||||||
elif command -v pkexec >/dev/null; then
|
|
||||||
pkexec bakery update --all || echo "WARN: bakery update failed"
|
|
||||||
else
|
|
||||||
echo "WARN: bakery update needs sudo -n or pkexec for /usr/local"
|
|
||||||
fi
|
|
||||||
else
|
else
|
||||||
echo "bakery not found; skipping"
|
echo "bakery not found; skipping"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
# build-local.sh and CI (scripts/ci-stage-bakery.py) read this file. A missing
|
# build-local.sh and CI (scripts/ci-stage-bakery.py) read this file. A missing
|
||||||
# *required* binary fails the bake: a hollow ISO is worse than a failed build.
|
# *required* binary fails the bake: a hollow ISO is worse than a failed build.
|
||||||
# optional_bins are baked when the verified stable index publishes them, and
|
# optional_bins are baked when the verified stable index publishes them, and
|
||||||
# skipped with a warning when it does not. bread 0.8.0 ships bread-emit and
|
# skipped with a warning when it does not (today: bread 0.8.0 has no
|
||||||
# bread-module-host, so those are required_bins.
|
# bread-emit / bread-module-host).
|
||||||
#
|
#
|
||||||
# A flat `bins` list is still accepted and treated as required_bins.
|
# A flat `bins` list is still accepted and treated as required_bins.
|
||||||
#
|
#
|
||||||
|
|
@ -23,8 +23,6 @@ required_bins = [
|
||||||
"bakery",
|
"bakery",
|
||||||
"bread",
|
"bread",
|
||||||
"breadd",
|
"breadd",
|
||||||
"bread-emit",
|
|
||||||
"bread-module-host",
|
|
||||||
"breadman",
|
"breadman",
|
||||||
"breadbar",
|
"breadbar",
|
||||||
"breadbox",
|
"breadbox",
|
||||||
|
|
@ -43,13 +41,19 @@ required_bins = [
|
||||||
"breadhelp",
|
"breadhelp",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Bake if the verified index publishes them; do not fail the ISO if absent.
|
||||||
|
optional_bins = [
|
||||||
|
"bread-emit",
|
||||||
|
"bread-module-host",
|
||||||
|
]
|
||||||
|
|
||||||
# Package name → version. Must exist at dl.breadway.dev/<pkg>/<ver>/ and
|
# Package name → version. Must exist at dl.breadway.dev/<pkg>/<ver>/ and
|
||||||
# should match the signed index so CI can verify sha256.
|
# should match the signed index so CI can verify sha256.
|
||||||
# [[pin]] { package, version } is accepted as well and merged (conflict = bake error).
|
# [[pin]] { package, version } is accepted as well and merged (conflict = bake error).
|
||||||
[versions]
|
[versions]
|
||||||
bakery = "0.7.4"
|
bakery = "0.7.3"
|
||||||
bread = "0.8.0"
|
bread = "0.8.0"
|
||||||
bread-theme = "0.7.4"
|
bread-theme = "0.7.3"
|
||||||
breadbar = "0.3.2"
|
breadbar = "0.3.2"
|
||||||
breadbox = "0.3.2"
|
breadbox = "0.3.2"
|
||||||
breadcrumbs = "2.1.8"
|
breadcrumbs = "2.1.8"
|
||||||
|
|
|
||||||
|
|
@ -225,8 +225,6 @@ slurp
|
||||||
wl-clipboard
|
wl-clipboard
|
||||||
playerctl
|
playerctl
|
||||||
# Wallpaper daemon + pywal (drives the bread* colour palette from the wallpaper).
|
# Wallpaper daemon + pywal (drives the bread* colour palette from the wallpaper).
|
||||||
# python-pywal was dropped from Arch [extra] (AUR-only now) — republished to
|
|
||||||
# [breadway], see packaging/python-pywal.
|
|
||||||
awww
|
awww
|
||||||
python-pywal
|
python-pywal
|
||||||
# Boot splash (BOS logo + spinner instead of kernel text).
|
# Boot splash (BOS logo + spinner instead of kernel text).
|
||||||
|
|
|
||||||
|
|
@ -49,17 +49,18 @@ Include = /etc/pacman.d/mirrorlist
|
||||||
# are NOT here; they are bakery-baked into /usr/local at ISO build time.
|
# are NOT here; they are bakery-baked into /usr/local at ISO build time.
|
||||||
#
|
#
|
||||||
# Packages are published to the Forgejo Arch registry (group "os") by the
|
# Packages are published to the Forgejo Arch registry (group "os") by the
|
||||||
# .forgejo/workflows/*.yml workflows; scripts/ci-publish-signed-repo.sh then
|
# .forgejo/workflows/*.yml workflows in this repo (and breadlock's).
|
||||||
# collects them, detach-signs each .pkg.tar.zst with the BOS release key
|
|
||||||
# (releases@breadway.dev), runs `repo-add -s`, and publishes the signed db
|
|
||||||
# at https://dl.breadway.dev/arch/$arch (signed-repo.yml).
|
|
||||||
#
|
#
|
||||||
# SigLevel = Required: every package AND the db carry a .sig from key
|
# Forgejo's Arch package registry does not serve pacman-compatible db
|
||||||
# 56203B86A110695AE7F310934AF3323D678EB5E2 — the same key committed as
|
# signatures. SigLevel = Never is TLS-only integrity: the connection is
|
||||||
# KEYS.asc / airootfs/etc/pacman.d/breadway-repo.asc, imported into the
|
# HTTPS (or rewritten to hestia's localhost:3002 in CI). breadlock (PAM)
|
||||||
# pacman keyring at build time (build-local.sh), on the live medium, and
|
# rides this repo. Do NOT flip to SigLevel = Required unless a signed db
|
||||||
# on the installed target (calamares/post-install.sh).
|
# has been verified to work — Required without signatures breaks the ISO
|
||||||
|
# and every install that uses [breadway]. KEYS.asc is the ISO SHA256SUMS
|
||||||
|
# signing key, not a pacman repo key.
|
||||||
# -----------------------------------------------------------------------
|
# -----------------------------------------------------------------------
|
||||||
[breadway]
|
# The section name must match Forgejo's served db filename
|
||||||
SigLevel = Required
|
# ({owner}.{group}.{domain}.db) — pacman fetches "<section>.db" from Server.
|
||||||
Server = https://dl.breadway.dev/arch/$arch
|
[Breadway.os.git.breadway.dev]
|
||||||
|
SigLevel = Never
|
||||||
|
Server = https://git.breadway.dev/api/packages/Breadway/arch/os/$arch
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ Arch packaging
|
||||||
|
|
||||||
This directory only holds `PKGBUILD`s for third-party AUR packages BOS
|
This directory only holds `PKGBUILD`s for third-party AUR packages BOS
|
||||||
republishes to the `[breadway]` pacman repo (`calamares`, `bibata`,
|
republishes to the `[breadway]` pacman repo (`calamares`, `bibata`,
|
||||||
`powerlevel10k`, `yay-bin`, `python-pywal`) — not the user's own code. See each
|
`powerlevel10k`, `yay-bin`) — not the user's own code. See each
|
||||||
subdirectory's `.forgejo/workflows/<name>.yml` (in this repo) for how each
|
subdirectory's `.forgejo/workflows/<name>.yml` (in this repo) for how each
|
||||||
one publishes on a push to `packaging/<name>/**`.
|
one publishes on a push to `packaging/<name>/**`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
# BOS in-house rebuild of python-pywal.
|
|
||||||
#
|
|
||||||
# python-pywal was dropped from Arch's [extra] repo (it is now AUR-only), but
|
|
||||||
# BOS needs the `wal` binary: bread-theme shells out to it to extract a colour
|
|
||||||
# palette from the user's wallpaper. Republished to [breadway] so the ISO can
|
|
||||||
# pull it via pacman, same pattern as calamares / bibata / powerlevel10k /
|
|
||||||
# yay-bin. Source of truth: https://aur.archlinux.org/packages/python-pywal
|
|
||||||
#
|
|
||||||
# Maintainer: Breadway <plasticbread849@gmail.com>
|
|
||||||
# Upstream maintainer: Morten Linderud <foxboron@archlinux.org>
|
|
||||||
# Contributor: Sean Haugh <seanphaugh@gmail.com>
|
|
||||||
|
|
||||||
pkgname=python-pywal
|
|
||||||
pkgver=3.3.0
|
|
||||||
pkgrel=11
|
|
||||||
pkgdesc="Generate and change colorschemes on the fly"
|
|
||||||
arch=('any')
|
|
||||||
url="https://github.com/dylanaraps/pywal/"
|
|
||||||
license=('MIT')
|
|
||||||
depends=('python' 'imagemagick')
|
|
||||||
makedepends=('python-build' 'python-installer' 'python-wheel' 'python-setuptools')
|
|
||||||
optdepends=('feh: set wallpaper'
|
|
||||||
'nitrogen: set wallpaper')
|
|
||||||
# BOS PKGBUILDs verify sources by sha256 only (no source PGP), matching
|
|
||||||
# calamares / powerlevel10k here.
|
|
||||||
source=("$pkgname-$pkgver.tar.gz::https://github.com/dylanaraps/pywal/archive/${pkgver}.tar.gz")
|
|
||||||
sha256sums=('fe8fc1c29d1cad1a1a8580293dcfe32e1fac259f9dbfd5c8877439fa5948d189')
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd "pywal-${pkgver}"
|
|
||||||
# setup.py-only project: python-build injects the setuptools backend.
|
|
||||||
python -m build --wheel --no-isolation
|
|
||||||
}
|
|
||||||
|
|
||||||
check() {
|
|
||||||
cd "pywal-${pkgver}"
|
|
||||||
python -m unittest discover -vs tests
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd "pywal-${pkgver}"
|
|
||||||
python -m installer --destdir="$pkgdir" dist/*.whl
|
|
||||||
install -Dm644 LICENSE.md "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
|
|
||||||
}
|
|
||||||
|
|
@ -22,7 +22,6 @@ PACKAGES=(
|
||||||
bibata-cursor-theme-bin
|
bibata-cursor-theme-bin
|
||||||
zsh-theme-powerlevel10k
|
zsh-theme-powerlevel10k
|
||||||
yay-bin
|
yay-bin
|
||||||
python-pywal
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ARCH="${BREADWAY_ARCH:-x86_64}"
|
ARCH="${BREADWAY_ARCH:-x86_64}"
|
||||||
|
|
@ -82,8 +81,6 @@ repo_add_signed() {
|
||||||
fi
|
fi
|
||||||
[[ -e breadway.db.tar.gz.sig || -e breadway.db.sig ]] \
|
[[ -e breadway.db.tar.gz.sig || -e breadway.db.sig ]] \
|
||||||
|| die "repo-add -s did not write breadway.db*.sig"
|
|| die "repo-add -s did not write breadway.db*.sig"
|
||||||
# gpg writes 0600; nginx and the next publish need world-readable files.
|
|
||||||
find . -maxdepth 1 -type f -exec chmod a+r {} + || true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ensure_arch_tools() {
|
ensure_arch_tools() {
|
||||||
|
|
@ -128,12 +125,7 @@ sign_and_index_anywhere() {
|
||||||
rt="$(container_runtime)" || die \
|
rt="$(container_runtime)" || die \
|
||||||
"need host gpg+repo-add, or docker/podman to run archlinux:latest (no Forgejo container: — host must see /srv/breadway-dl)"
|
"need host gpg+repo-add, or docker/podman to run archlinux:latest (no Forgejo container: — host must see /srv/breadway-dl)"
|
||||||
# Host job + bind-mount, same reason bakery writes /srv without container:.
|
# Host job + bind-mount, same reason bakery writes /srv without container:.
|
||||||
# Run as the runner user: root-owned 0600 .sig files made chmod/nginx fail
|
|
||||||
# (run 1050) and would block the next `rm -rf` of a previous tree.
|
|
||||||
"$rt" run --rm --network=host \
|
"$rt" run --rm --network=host \
|
||||||
--user "$(id -u):$(id -g)" \
|
|
||||||
-e HOME=/tmp \
|
|
||||||
-e TMPDIR=/tmp \
|
|
||||||
-e GPG_PRIVATE_KEY \
|
-e GPG_PRIVATE_KEY \
|
||||||
-e BREADWAY_SIGN_ONLY=1 \
|
-e BREADWAY_SIGN_ONLY=1 \
|
||||||
-e BREADWAY_REPO_DIR=/repo \
|
-e BREADWAY_REPO_DIR=/repo \
|
||||||
|
|
@ -251,10 +243,8 @@ publish_tree() {
|
||||||
parent="$(dirname "$DEST")"
|
parent="$(dirname "$DEST")"
|
||||||
dest_name="$(basename "$DEST")"
|
dest_name="$(basename "$DEST")"
|
||||||
mkdir -p "$parent"
|
mkdir -p "$parent"
|
||||||
chmod a+rX "$STAGE" || true
|
chmod a+rX "$STAGE"
|
||||||
# gpg --detach-sign often writes 0600 files the runner cannot chmod;
|
find "$STAGE" -type f -exec chmod a+r {} +
|
||||||
# do not fail the publish after repo-add -s already succeeded.
|
|
||||||
find "$STAGE" -type f -exec chmod a+r {} + || true
|
|
||||||
prev="$parent/${dest_name}.prev"
|
prev="$parent/${dest_name}.prev"
|
||||||
rm -rf "$prev"
|
rm -rf "$prev"
|
||||||
if [[ -e "$DEST" ]]; then
|
if [[ -e "$DEST" ]]; then
|
||||||
|
|
|
||||||
|
|
@ -40,15 +40,22 @@ check "grub-btrfs present" "pacman -Qq grub-btrfs"
|
||||||
|
|
||||||
echo "== enabled system services =="
|
echo "== enabled system services =="
|
||||||
for unit in NetworkManager.service greetd.service bluetooth.service tlp.service \
|
for unit in NetworkManager.service greetd.service bluetooth.service tlp.service \
|
||||||
cups.socket avahi-daemon.socket ufw.service systemd-timesyncd.service; do
|
cups.socket avahi-daemon.service ufw.service systemd-timesyncd.service; do
|
||||||
check "$unit enabled" "systemctl is-enabled $unit"
|
check "$unit enabled" "systemctl is-enabled $unit"
|
||||||
done
|
done
|
||||||
check "graphical.target is default" "[ \"\$(systemctl get-default)\" = graphical.target ]"
|
check "graphical.target is default" "[ \"\$(systemctl get-default)\" = graphical.target ]"
|
||||||
|
|
||||||
echo "== bread ecosystem on PATH =="
|
echo "== bread ecosystem on PATH =="
|
||||||
for bin in bakery bread breadd bread-emit bread-module-host breadbar breadbox breadbox-sync breadcrumbs breadpad breadman; do
|
for bin in bakery bread breadd breadbar breadbox breadbox-sync breadcrumbs breadpad breadman; do
|
||||||
check "$bin found" "command -v $bin"
|
check "$bin found" "command -v $bin"
|
||||||
done
|
done
|
||||||
|
for bin in bread-emit bread-module-host; do
|
||||||
|
if command -v "$bin" >/dev/null 2>&1; then
|
||||||
|
ok "$bin found"
|
||||||
|
else
|
||||||
|
note "$bin not on PATH (optional until stable bread ships it)"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
echo "== bos-settings =="
|
echo "== bos-settings =="
|
||||||
check "bos-settings installed" "command -v bos-settings"
|
check "bos-settings installed" "command -v bos-settings"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue