Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions tools/modules/desktops/scripts/parse_desktop_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,23 +177,29 @@ def _apply_tier_overrides(packages, source, tier, release, arch):
<tier>:
architectures:
<arch>:
packages: [...] # add on this arch in any release
packages_remove: [...] # remove on this arch in any release
releases:
<release>:
architectures:
<arch>:
packages: [...] # add on this release+arch combo
packages_remove: [...] # remove on this release+arch combo

Both layers are applied. Use the per-arch layer for permanent
arch-wide holes (e.g. blender always missing on armhf), and the
per-release-per-arch layer for transient holes (e.g. loupe missing
on bookworm because GNOME 43 didn't have it).
arch-wide additions/holes (e.g. google-chrome-stable always on
amd64, blender always missing on armhf), and the per-release-per-
arch layer for transient differences (e.g. loupe missing on
bookworm because GNOME 43 didn't have it).
"""
tier_block = _as_dict(_as_dict(source.get("tier_overrides")).get(tier))

# Per-arch (any release) layer.
archs = _as_dict(tier_block.get("architectures"))
arch_block = _as_dict(archs.get(arch))
for pkg in _as_list(arch_block.get("packages")):
if pkg not in packages:
packages.append(pkg)
for pkg in _as_list(arch_block.get("packages_remove")):
if pkg in packages:
packages.remove(pkg)
Expand All @@ -203,6 +209,9 @@ def _apply_tier_overrides(packages, source, tier, release, arch):
release_block = _as_dict(releases.get(release))
release_archs = _as_dict(release_block.get("architectures"))
release_arch_block = _as_dict(release_archs.get(arch))
for pkg in _as_list(release_arch_block.get("packages")):
if pkg not in packages:
packages.append(pkg)
for pkg in _as_list(release_arch_block.get("packages_remove")):
if pkg in packages:
packages.remove(pkg)
Expand Down
102 changes: 43 additions & 59 deletions tools/modules/desktops/yaml/common.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ tiers:
- vlc # media player
- file-roller # archive manager
- transmission-gtk # torrent client
- armbian-imager # SD-card image flasher (from apt.armbian.com)

full:
packages:
Expand All @@ -55,6 +56,7 @@ tiers:
- inkscape
- thunderbird
- audacity
- code # vscode (from apt.armbian.com)

Comment on lines +59 to 60
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
python - <<'PY'
import urllib.request, gzip, lzma, re

BASE = "https://apt.armbian.com/dists"
checks = {
    "code": {
        "releases": ["bookworm", "trixie", "forky", "sid", "jammy", "noble", "plucky", "questing", "resolute"],
        "arches": ["amd64", "arm64", "armhf", "riscv64", "loong64"],
    },
    "thunderbird": {
        "releases": ["jammy", "noble", "plucky", "questing", "resolute"],
        "arches": ["amd64", "arm64"],
    },
}

def fetch(url):
    with urllib.request.urlopen(url, timeout=15) as r:
        return r.read()

def get_components(release):
    try:
        txt = fetch(f"{BASE}/{release}/Release").decode("utf-8", "ignore")
    except Exception as e:
        return [], f"Release file missing/unreadable: {e}"
    for line in txt.splitlines():
        if line.startswith("Components:"):
            parts = line.split()[1:]
            return (parts if parts else ["main"]), None
    return ["main"], None

def fetch_packages_index(release, comp, arch):
    for ext, dec in [("xz", lzma.decompress), ("gz", gzip.decompress)]:
        url = f"{BASE}/{release}/{comp}/binary-{arch}/Packages.{ext}"
        try:
            raw = fetch(url)
            return dec(raw).decode("utf-8", "ignore"), None
        except Exception:
            pass
    return None, "No Packages.{xz,gz} index"

def has_pkg(index_text, pkg):
    return re.search(rf"(?m)^Package:\s*{re.escape(pkg)}\s*$", index_text) is not None

for pkg, spec in checks.items():
    print(f"\n=== Checking package: {pkg} ===")
    for rel in spec["releases"]:
        comps, err = get_components(rel)
        if err:
            print(f"{rel:10} {'-':8} ERROR {err}")
            continue
        for arch in spec["arches"]:
            found = False
            idx_errs = []
            for comp in comps:
                idx, idx_err = fetch_packages_index(rel, comp, arch)
                if idx is None:
                    idx_errs.append(f"{comp}:{idx_err}")
                    continue
                if has_pkg(idx, pkg):
                    print(f"{rel:10} {arch:8} FOUND (component={comp})")
                    found = True
                    break
            if not found:
                reason = "; ".join(idx_errs) if idx_errs else "package not present"
                print(f"{rel:10} {arch:8} MISSING ({reason})")
PY

Repository: armbian/configng

Length of output: 2748


🏁 Script executed:

git ls-files tools/modules/desktops/yaml/ | head -20

Repository: armbian/configng

Length of output: 588


🏁 Script executed:

cat -n tools/modules/desktops/yaml/common.yaml | sed -n '55,65p'

Repository: armbian/configng

Length of output: 436


🏁 Script executed:

cat -n tools/modules/desktops/yaml/common.yaml | sed -n '230,260p'

Repository: armbian/configng

Length of output: 1573


🏁 Script executed:

#!/bin/bash
python - <<'PY'
import urllib.request, gzip, lzma, re, ssl

# Disable SSL verification for sandbox environment
ssl._create_default_https_context = ssl._create_unverified_context

BASE = "https://apt.armbian.com/dists"
checks = {
    "code": {
        "releases": ["bookworm", "trixie", "forky", "sid", "jammy", "noble", "plucky", "questing", "resolute"],
        "arches": ["amd64", "arm64", "armhf", "riscv64", "loong64"],
    },
    "thunderbird": {
        "releases": ["jammy", "noble", "plucky", "questing", "resolute"],
        "arches": ["amd64", "arm64"],
    },
}

def fetch(url):
    with urllib.request.urlopen(url, timeout=15) as r:
        return r.read()

def get_components(release):
    try:
        txt = fetch(f"{BASE}/{release}/Release").decode("utf-8", "ignore")
    except Exception as e:
        return [], f"Release file missing/unreadable"
    for line in txt.splitlines():
        if line.startswith("Components:"):
            parts = line.split()[1:]
            return (parts if parts else ["main"]), None
    return ["main"], None

def fetch_packages_index(release, comp, arch):
    for ext, dec in [("xz", lzma.decompress), ("gz", gzip.decompress)]:
        url = f"{BASE}/{release}/{comp}/binary-{arch}/Packages.{ext}"
        try:
            raw = fetch(url)
            return dec(raw).decode("utf-8", "ignore"), None
        except Exception:
            pass
    return None, "No Packages.{xz,gz} index"

def has_pkg(index_text, pkg):
    return re.search(rf"(?m)^Package:\s*{re.escape(pkg)}\s*$", index_text) is not None

for pkg, spec in checks.items():
    print(f"\n=== Checking package: {pkg} ===")
    for rel in spec["releases"]:
        comps, err = get_components(rel)
        if err:
            print(f"{rel:10} {'-':8} ERROR {err}")
            continue
        for arch in spec["arches"]:
            found = False
            idx_errs = []
            for comp in comps:
                idx, idx_err = fetch_packages_index(rel, comp, arch)
                if idx is None:
                    idx_errs.append(f"{comp}:{idx_err}")
                    continue
                if has_pkg(idx, pkg):
                    print(f"{rel:10} {arch:8} FOUND (component={comp})")
                    found = True
                    break
            if not found:
                reason = "; ".join(idx_errs) if idx_errs else "package not present"
                print(f"{rel:10} {arch:8} MISSING ({reason})")
PY

Repository: armbian/configng

Length of output: 2914


Fix apt.armbian.com package availability gaps or update YAML conditionals.

Verification reveals missing packages in apt.armbian.com that will cause install failures:

  • code (line 59): Missing on forky, sid, jammy, plucky, questing, resolute (all architectures), and riscv64/loong64 on bookworm/trixie
  • thunderbird (lines 235–258): Missing on jammy, plucky, questing, resolute (amd64/arm64), yet YAML doesn't remove it for those combinations—only armhf/riscv64

Either add packages to apt.armbian.com, define release/arch conditionals in YAML to exclude unavailable combinations, or document the limitation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tools/modules/desktops/yaml/common.yaml` around lines 59 - 60, The YAML
currently lists packages "code" and "thunderbird" without excluding OS
release/architecture combos where apt.armbian.com is missing them; update the
common.yaml package entries for "code" and "thunderbird" to include conditional
removal rules (e.g., per-release and per-arch booleans or if/when selectors)
that exclude the combinations reported (forky, sid, jammy, plucky, questing,
resolute across all arches for "code", and jammy/plucky/questing/resolute on
amd64/arm64 for "thunderbird"), or alternately add a documented note in the YAML
comments indicating unsupported release/arch combinations; ensure the changes
target the package list entries named "code" and "thunderbird" so installs skip
unavailable packages rather than failing.

# Browser substitution table for the literal `browser` token in any
# tier. The parser replaces `browser` with the right package per
Expand All @@ -74,68 +76,64 @@ tiers:
# - Debian has 'firefox-esr' but NO 'firefox' package.
# - Ubuntu's 'chromium' .deb is a snap-shim wrapper that pulls in
# 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.
# runtime — apt.armbian.com hosts real .debs (chromium, firefox,
# google-chrome-stable) used in this map instead.
# - amd64 always gets google-chrome-stable (Google publishes no
# arm/riscv builds, so this is amd64-only).
# - 'chromium' isn't built for riscv64 in either Debian or Ubuntu.
#
# Verified against Debian bookworm/trixie and Ubuntu noble/plucky as
# of 2026-04. Update this map when new releases ship or when an
# arch dependency changes.
# Verified against Debian bookworm/trixie, Ubuntu noble/plucky, and
# apt.armbian.com as of 2026-04. Update this map when new releases
# ship or when an arch dependency changes.
browser:
bookworm:
amd64: chromium
amd64: google-chrome-stable
arm64: chromium
armhf: chromium
# bookworm has no riscv64 port — no entry needed
trixie:
amd64: chromium
amd64: google-chrome-stable
arm64: chromium
armhf: chromium
riscv64: firefox-esr # 'firefox' does not exist in Debian
noble:
amd64: epiphany-browser # 'chromium' deb is a snap-shim
arm64: epiphany-browser
armhf: epiphany-browser
riscv64: epiphany-browser # 'chromium'/'firefox' both missing
amd64: google-chrome-stable
arm64: chromium # apt.armbian.com real .deb (Ubuntu's is snap-shim)
armhf: chromium
riscv64: firefox # apt.armbian.com real .deb
plucky:
amd64: epiphany-browser
arm64: epiphany-browser
armhf: epiphany-browser
riscv64: epiphany-browser
amd64: google-chrome-stable
arm64: chromium
armhf: chromium
riscv64: firefox
jammy:
# Ubuntu 22.04 LTS — same snap-shim situation as noble; the
# 'chromium' deb just invokes snapd which Armbian doesn't ship.
# epiphany-browser is a real native deb available on all arches.
amd64: epiphany-browser
arm64: epiphany-browser
armhf: epiphany-browser
riscv64: epiphany-browser
# Ubuntu 22.04 LTS — chromium / firefox apt names on Ubuntu are
# snap-shims; apt.armbian.com hosts real .debs of the same name.
amd64: google-chrome-stable
arm64: chromium
armhf: chromium
riscv64: firefox
questing:
# Ubuntu 25.10 — same snap-shim situation as noble/plucky.
amd64: epiphany-browser
arm64: epiphany-browser
armhf: epiphany-browser
riscv64: epiphany-browser
# Ubuntu 25.10
amd64: google-chrome-stable
arm64: chromium
armhf: chromium
riscv64: firefox
resolute:
# Ubuntu 26.04 LTS — same snap-shim situation as noble/plucky.
amd64: epiphany-browser
arm64: epiphany-browser
armhf: epiphany-browser
riscv64: epiphany-browser
# Ubuntu 26.04 LTS
amd64: google-chrome-stable
arm64: chromium
armhf: chromium
riscv64: firefox
forky:
# Debian 14 — same rules as trixie: 'firefox' is not a Debian
# package, only 'firefox-esr' exists; chromium is available for
# the three tier-1 arches.
amd64: chromium
# Debian 14 — same rules as trixie.
amd64: google-chrome-stable
arm64: chromium
armhf: chromium
riscv64: firefox-esr # 'firefox' does not exist in Debian
sid:
# Debian unstable — same rules as trixie/forky.
# loong64 gets firefox-esr because chromium is not yet built for
# this architecture in the Debian archive.
amd64: chromium
amd64: google-chrome-stable
arm64: chromium
armhf: chromium
riscv64: firefox-esr # 'firefox' does not exist in Debian
Expand Down Expand Up @@ -234,42 +232,28 @@ tier_overrides:
architectures:
armhf: { packages_remove: [thunderbird] }
noble:
# thunderbird on Ubuntu is a snap-shim that only exists on
# amd64/arm64; the deb is missing on armhf and riscv64.
# We strip it on EVERY arch on Ubuntu because the shim
# requires snapd which Armbian doesn't ship.
# Ubuntu's thunderbird .deb on amd64/arm64 is a snap-shim
# wrapper, but apt.armbian.com hosts a real thunderbird .deb
# for those arches that wins by version. armhf and riscv64
# have no upstream Ubuntu deb at all and we don't (yet) ship
# them via apt.armbian.com — strip on those arches only.
architectures:
amd64: { packages_remove: [thunderbird] }
arm64: { packages_remove: [thunderbird] }
armhf: { packages_remove: [thunderbird] }
riscv64: { packages_remove: [thunderbird] }
plucky:
architectures:
amd64: { packages_remove: [thunderbird] }
arm64: { packages_remove: [thunderbird] }
armhf: { packages_remove: [thunderbird] }
riscv64: { packages_remove: [thunderbird] }
jammy:
# thunderbird on Ubuntu 22.04 (jammy) was migrated to a
# snap-shim deb; Armbian doesn't ship snapd so the shim is
# broken at runtime. Strip it on all arches, same as noble/plucky.
architectures:
amd64: { packages_remove: [thunderbird] }
arm64: { packages_remove: [thunderbird] }
armhf: { packages_remove: [thunderbird] }
riscv64: { packages_remove: [thunderbird] }
questing:
# Same snap-shim situation as noble/plucky.
architectures:
amd64: { packages_remove: [thunderbird] }
arm64: { packages_remove: [thunderbird] }
armhf: { packages_remove: [thunderbird] }
riscv64: { packages_remove: [thunderbird] }
resolute:
# Same snap-shim situation as noble/plucky.
architectures:
amd64: { packages_remove: [thunderbird] }
arm64: { packages_remove: [thunderbird] }
armhf: { packages_remove: [thunderbird] }
riscv64: { packages_remove: [thunderbird] }
forky:
Expand Down
Loading