Skip to content

Commit 6fa4e0e

Browse files
committed
desktops: refresh browser map, tier_overrides, remove lifecycle, release list
Four corrections after the build framework / CI work: 1. Browser virtual table was stuck on a pre-apt.armbian.com draft where noble and plucky both used epiphany-browser on every arch. Reality: amd64 uses google-chrome-stable, arm64/armhf use chromium from apt.armbian.com (Ubuntu's chromium deb is a snap-shim), Debian riscv64 uses firefox-esr, Ubuntu riscv64 falls back to epiphany-browser. Also document the loong64/sid entry and drop the plucky block entirely — plucky is EOS, resolute replaced it. 2. tier_overrides example was built around plucky. Replace with the current common.yaml shape: arch-wide strip of armbian-imager (armhf/riscv64/loong64) at mid, arch-wide strip of 'code' (armhf pre-t64 .deb + no riscv64 upstream) at full, and the current per-release thunderbird-on-armhf-or-riscv64 holes. 3. Remove lifecycle step 9 was documented as 'pkg_remove → apt-get autopurge'. The remove path now calls apt-get purge directly after filtering out any package apt flags as essential-breaking from a dry-run. Update the step list and add a paragraph explaining why autopurge was dropped (t64-era orphan-cascade into e2fsprogs) and why a dry-run-filter is still needed (some base images ship without e2fsprogs, so the DE install pulls it in and the purge list would otherwise target it). 4. Release list in overview, schema table, packages_uninstall pitfall, and audit report example all mentioned plucky. Replace with resolute/forky/sid/jammy to match the actual release set the inventory declares in 2026.
1 parent e381594 commit 6fa4e0e

1 file changed

Lines changed: 78 additions & 38 deletions

File tree

docs/Developer-Guide_Desktops.md

Lines changed: 78 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ The submodule provides:
1414
- **Per-install manifest** — every install records exactly which packages it added so removal and downgrades only undo what they themselves did.
1515
- **Custom APT repositories**, branding, group memberships, and skel sync.
1616
- **Auto-login** management for `gdm3`, `sddm`, and `lightdm`, with non-destructive in-place edits of the underlying config files.
17-
- **Per-release / per-arch package overrides** so the same YAML works across Debian bookworm/trixie and Ubuntu noble/plucky on amd64/arm64/armhf/riscv64 with different package availability.
18-
- **Browser virtual token** that resolves per-release-per-arch (chromium on Debian, epiphany-browser on Ubuntu, firefox-esr on Debian riscv64, …).
17+
- **Per-release / per-arch package overrides** so the same YAML works across Debian bookworm/trixie/forky/sid and Ubuntu jammy/noble/resolute on amd64/arm64/armhf/riscv64/loong64 with different package availability.
18+
- **Browser virtual token** that resolves per-release-per-arch (google-chrome-stable on amd64, chromium on Debian/Ubuntu arm arches, firefox-esr on Debian riscv64, epiphany-browser on Ubuntu riscv64, …).
1919
- **Container/CI awareness** so the same code path can be used inside Docker without trying to start a display manager.
2020

2121
## Tier model
@@ -110,7 +110,7 @@ Each desktop is defined in a single YAML file under `tools/modules/desktops/yaml
110110
| `status` | string | yes | Editorial label — one of `supported`, `community`, `unsupported`. Reported via `DESKTOP_STATUS`. Affects only labelling and catalog filtering — does not block install. `community` is used for DEs that work but are maintained on a best-effort basis; `unsupported` for DEs that are known-broken or not vetted. |
111111
| `tiers` | mapping | yes | Per-tier package lists, keyed by `minimal`, `mid`, `full`. See [Tier blocks](#tier-blocks). |
112112
| `tier_overrides` | mapping | optional | Per-arch and/or per-release-per-arch package removals (and additions) for tier holes. See [tier_overrides](#tier-overrides). |
113-
| `releases` | mapping | yes | Per-release overrides keyed by release codename (`bookworm`, `trixie`, `noble`, `plucky`, ...). |
113+
| `releases` | mapping | yes | Per-release overrides keyed by release codename (`bookworm`, `trixie`, `forky`, `sid`, `jammy`, `noble`, `resolute`, ...). |
114114
| `repo` | mapping | optional | Custom APT repository, see below. |
115115

116116
### Tier blocks
@@ -305,37 +305,66 @@ tiers:
305305

306306
browser:
307307
bookworm:
308-
amd64: chromium
308+
amd64: google-chrome-stable
309309
arm64: chromium
310310
armhf: chromium
311+
# bookworm has no riscv64 port — no entry needed
311312
trixie:
312-
amd64: chromium
313+
amd64: google-chrome-stable
313314
arm64: chromium
314315
armhf: chromium
315-
riscv64: firefox-esr # 'firefox' does not exist in Debian
316+
riscv64: firefox-esr # 'firefox' does not exist in Debian
316317
noble:
317-
amd64: epiphany-browser # 'chromium' deb is a snap-shim
318-
arm64: epiphany-browser
319-
armhf: epiphany-browser
320-
riscv64: epiphany-browser
321-
plucky:
322-
amd64: epiphany-browser
323-
arm64: epiphany-browser
324-
armhf: epiphany-browser
318+
amd64: google-chrome-stable
319+
arm64: chromium # apt.armbian.com real .deb (Ubuntu's is snap-shim)
320+
armhf: chromium
321+
riscv64: epiphany-browser # firefox/chromium not built for Ubuntu riscv64
322+
resolute:
323+
amd64: google-chrome-stable
324+
arm64: chromium
325+
armhf: chromium
325326
riscv64: epiphany-browser
327+
forky:
328+
amd64: google-chrome-stable
329+
arm64: chromium
330+
armhf: chromium
331+
riscv64: firefox-esr
332+
sid:
333+
amd64: google-chrome-stable
334+
arm64: chromium
335+
armhf: chromium
336+
riscv64: firefox-esr
337+
loong64: firefox-esr # chromium not yet built for loong64
326338

327339
tier_overrides:
328340
mid:
341+
# armbian-imager ships only amd64/arm64 upstream — strip it on
342+
# every other arch, across every release.
343+
architectures:
344+
armhf: { packages_remove: [armbian-imager] }
345+
riscv64: { packages_remove: [armbian-imager] }
346+
loong64: { packages_remove: [armbian-imager] }
329347
releases:
330348
bookworm:
331349
architectures:
332350
amd64: { packages_remove: [loupe] } # GNOME 43 era — no loupe
333351
arm64: { packages_remove: [loupe] }
334352
armhf: { packages_remove: [loupe] }
335-
plucky:
353+
jammy:
336354
architectures:
337-
armhf: { packages_remove: [loupe] } # dropped on plucky/armhf
355+
amd64: { packages_remove: [loupe] } # GNOME 42 — no loupe
356+
arm64: { packages_remove: [loupe] }
357+
armhf: { packages_remove: [loupe] }
358+
riscv64: { packages_remove: [loupe] }
338359
full:
360+
# The 'code' (VSCode) .deb on apt.armbian.com links against the
361+
# pre-t64 library names, which don't exist on post-t64 releases
362+
# (trixie+, noble+). amd64/arm64 were rebuilt; armhf wasn't. No
363+
# riscv64 upstream build exists at all. Strip arch-wide on both
364+
# until/unless the armhf .deb is refreshed.
365+
architectures:
366+
armhf: { packages_remove: [code] }
367+
riscv64: { packages_remove: [code] }
339368
releases:
340369
bookworm:
341370
architectures:
@@ -344,17 +373,14 @@ tier_overrides:
344373
architectures:
345374
armhf: { packages_remove: [thunderbird] }
346375
noble:
347-
# thunderbird on Ubuntu is a snap-shim that requires snapd
348-
# which Armbian doesn't ship — strip it on every arch.
376+
# thunderbird on Ubuntu noble armhf/riscv64 is absent (no
377+
# upstream Ubuntu deb there), so strip on those two arches
378+
# only. amd64/arm64 get the real .deb from apt.armbian.com.
349379
architectures:
350-
amd64: { packages_remove: [thunderbird] }
351-
arm64: { packages_remove: [thunderbird] }
352380
armhf: { packages_remove: [thunderbird] }
353381
riscv64: { packages_remove: [thunderbird] }
354-
plucky:
382+
resolute:
355383
architectures:
356-
amd64: { packages_remove: [thunderbird] }
357-
arm64: { packages_remove: [thunderbird] }
358384
armhf: { packages_remove: [thunderbird] }
359385
riscv64: { packages_remove: [thunderbird] }
360386
```
@@ -370,9 +396,12 @@ The literal string `browser` inside any tier block resolves to a real package na
370396
The per-release layer is needed because the same arch can resolve differently across releases:
371397

372398
- Debian has `firefox-esr` but **no** `firefox` package.
373-
- Ubuntu's `chromium` deb is a snap-shim wrapper that requires `snapd`. Armbian doesn't ship snapd, so the shim is broken at runtime — substitute a real GTK browser instead. `epiphany-browser` (GNOME Web) is small, native deb, and available on every Ubuntu arch.
399+
- Ubuntu's `chromium` / `firefox` debs are snap-shim wrappers that require `snapd`. Armbian doesn't ship snapd, so the shims are broken at runtime — apt.armbian.com hosts real `chromium` / `firefox` / `google-chrome-stable` .debs used instead.
400+
- amd64 always gets `google-chrome-stable` (Google publishes no arm/riscv builds, so this is amd64-only).
374401
- `chromium` isn't built for riscv64 in either Debian or Ubuntu.
375-
- `firefox` isn't built for noble/plucky riscv64 either.
402+
- Ubuntu doesn't publish `firefox` or `firefox-esr` for riscv64 (Mozilla has no riscv64 binaries, and `firefox-esr` is a Debian-only package name). Fall back to `epiphany-browser` (GNOME Web) there — native GTK, small, and available on every Ubuntu arch.
403+
- Debian riscv64 gets `firefox-esr` because the Debian archive does publish it for riscv64.
404+
- `loong64` is only declared for `sid` in the inventory; `chromium` isn't built there yet either, so it uses `firefox-esr`.
376405

377406
## Python helper: parse_desktop_yaml.py
378407

@@ -661,24 +690,35 @@ If step 11 or 12 fails, the function returns 1 with no further state changes —
661690
## Lifecycle: remove
662691

663692
```{ .text linenums="0" }
664-
1. Validate args de= required
665-
2. Read installed tier marker /etc/armbian/desktop/<de>.tier (default: minimal)
666-
3. Parse YAML at the installed module_desktop_yamlparse $de $arch $release $installed_tier
693+
1. Validate args de= required
694+
2. Read installed tier marker /etc/armbian/desktop/<de>.tier (default: minimal)
695+
3. Parse YAML at the installed module_desktop_yamlparse $de $arch $release $installed_tier
667696
tier
668-
4. Disable auto-login module_desktops manual de=$de
669-
5. Stop display manager systemctl stop display-manager
670-
6. Switch default.target systemctl set-default multi-user.target
671-
7. Isolate to multi-user systemctl isolate multi-user.target (drops running session
697+
4. Disable auto-login module_desktops manual de=$de
698+
5. Stop display manager systemctl stop display-manager
699+
6. Switch default.target systemctl set-default multi-user.target
700+
7. Isolate to multi-user systemctl isolate multi-user.target (drops running session
672701
to console immediately, no reboot needed)
673-
8. Compute removable set from /etc/armbian/desktop/<de>.packages
702+
8. Compute removable set from /etc/armbian/desktop/<de>.packages
674703
fallback: walk DESKTOP_PACKAGES through dpkg-query
675-
9. pkg_remove apt-get autopurge
676-
10. Delete manifest files rm /etc/armbian/desktop/<de>.{packages,tier}
677-
11. pkg_clean apt-get clean — reclaim downloaded .deb cache
704+
9. Filter out essentials apt-get -s -y purge <list> (simulation, stderr parsed)
705+
every package apt flags under "WARNING: The following
706+
essential packages will be removed" is dropped from
707+
the removable set — see note below
708+
10. Purge remaining set apt-get -y purge <filtered list> ← bail on failure,
709+
manifest preserved for retry
710+
11. Delete manifest files rm /etc/armbian/desktop/<de>.{packages,tier} (only after 10 succeeds)
711+
12. pkg_clean apt-get clean — reclaim downloaded .deb cache
678712
```
679713

680714
The `set-default` and `isolate` calls together ensure the user gets a console login on tty1 immediately after the uninstall, without needing to reboot. Without them, the system stays pinned to `graphical.target` with no DM behind it and the local console is blank.
681715

716+
**Why the essential filter (step 9).** The remove path calls `apt-get -y purge` directly — **not** `pkg_remove` (which wraps `apt-get autopurge`). `autopurge` adds an orphan-cleanup cascade on top of the removal, and on fresh post-t64 images (trixie+, noble+) several shared libs pulled in alongside `e2fsprogs` (`libext2fs2t64`, `libss2`, `logsave`) are marked auto-installed. Once the DE is gone nothing manual depends on them, autopurge proposes to orphan-remove the whole chain, and apt 2.9+ / solver 3.0 vetoes the transaction with `E: Essential packages were removed and -y was used without --allow-remove-essential` — nothing actually gets removed. A plain `apt-get purge` avoids the cascade, and the manifest is already the complete list, so no cascade is needed.
717+
718+
A separate case the filter catches: some base images (notably `armbian/repository-update:*-armhf` tags rebuilt from debian-slim) ship without `e2fsprogs` pre-installed. When a DE's install pulls in `dracut-install` or `gnome-disk-utility` transitively, those pull `e2fsprogs`, it lands in the manifest, and purging it would touch an Essential package. Step 9 simulates the purge, parses apt's essential-warning block (stripping `(due to X)` annotations), and drops every flagged name from the list before the real purge runs.
719+
720+
On failure of step 10 the function returns 1 with the manifest left in place, so the next `remove` retries against the same list rather than falling into the less-precise YAML-walk path.
721+
682722
## Lifecycle: upgrade and downgrade
683723

684724
`upgrade` and `downgrade` are the two halves of `_module_desktops_change_tier`:
@@ -815,7 +855,7 @@ Report shape (`audit-report.json`):
815855
816856
```json
817857
{
818-
"scanned_releases": ["bookworm", "noble", "plucky", "trixie"],
858+
"scanned_releases": ["bookworm", "noble", "resolute", "trixie"],
819859
"build_distributions": { "<release>": { "name": "...", "support": "supported|csc|eos", "architectures": [...] } },
820860
"missing_releases": [ { "release": "resolute", "support_status": "csc", "architectures": [...] } ],
821861
"package_holes": [ { "de": "xfce", "release": "trixie", "arch": "riscv64", "tier": "full", "missing": ["libfoo"] } ],
@@ -890,7 +930,7 @@ If Claude judged the report non-actionable (e.g. the only finding is a `csc`-tie
890930
891931
### packages_uninstall cascade
892932
893-
Listing a package in `tiers.minimal.packages_uninstall` runs `apt-get remove --purge` on it after the install. If that package is a hard `Depends:` of any meta package the DE install pulled in, apt's autoremove cascade will yank the meta package along with it — and on systems with `APT::Get::AutomaticRemove "true"` (Ubuntu noble/plucky), the cascade keeps going and rips out a chunk of the desktop. Real examples that bit us:
933+
Listing a package in `tiers.minimal.packages_uninstall` runs `apt-get remove --purge` on it after the install. If that package is a hard `Depends:` of any meta package the DE install pulled in, apt's autoremove cascade will yank the meta package along with it — and on systems with `APT::Get::AutomaticRemove "true"` (Ubuntu noble/resolute), the cascade keeps going and rips out a chunk of the desktop. Real examples that bit us:
894934

895935
- Listing any `xfce4-goodies` plugin (e.g. `xfce4-clipman-plugin`) yanks `xfce4-goodies` itself, then half the desktop.
896936
- Listing `language-selector-gnome` yanks `gnome-control-center` (which has it as a hard Depends on Ubuntu), so the user loses Settings.

0 commit comments

Comments
 (0)