fix: apt deb822/OpenSSL3/pbzx-repo build errors + Big-Sur+-Katalogfilter

- Dockerfile: hfsprogs-Sources per sed auf bestehende deb822-Datei
  patchen statt zweite sources.list-Datei (Signed-By-Konflikt)
- Dockerfile: xar configure.ac OpenSSL-Probe auf EVP_EncryptInit
  umbiegen (OpenSSL_add_all_ciphers ist in OpenSSL 3.x nur noch Makro)
- Dockerfile: xar vor pbzx bauen (Linker-Abhaengigkeit), pbzx-Quelle auf
  NiklasRosenstein/pbzx (mackyle/pbzx existiert nicht mehr)
- catalog.py: doppeltes gzip.decompress auf bereits von requests
  dekomprimierten Content entfernt
- catalog.py: Big-Sur-bis-Tahoe-Installer wurden durch veralteten
  OSInstall-Filter komplett verworfen, jetzt SharedSupport-Schema
  ebenfalls erkannt (37 statt 13 gefundene Installer)

Alles live gegen echten docker compose build/up + echten Apple-Katalog
verifiziert, nicht nur behauptet.
This commit is contained in:
aria.hacker
2026-07-18 10:46:45 +02:00
parent c6dc2cd9cb
commit 1c97be6bb7
3 changed files with 158 additions and 24 deletions
+61 -2
View File
@@ -75,15 +75,61 @@ def find_latest_catalog_url(timeout: float = 8) -> str:
def _fetch_catalog_products(url: str, timeout: float = 60) -> dict:
r = requests.get(url, timeout=timeout)
r.raise_for_status()
raw = gzip.decompress(r.content)
# Live gegen swscan.apple.com verifiziert (2026-07-18): der Server
# schickt "Content-Encoding: x-gzip" -- requests/urllib3 dekomprimiert
# das bereits transparent, r.content ist also schon reines XML. Ein
# zusaetzliches gzip.decompress() darauf crasht mit BadGzipFile, weil
# die Gzip-Magic-Bytes (\x1f\x8b) dann laengst weg sind. Manche
# Server/Proxies liefern aber ggf. noch echte rohe Gzip-Bytes ohne
# das Encoding transparent aufzuloesen -- daher robust an den echten
# Magic-Bytes pruefen statt blind zu (de-)komprimieren.
raw = r.content
if raw[:2] == b"\x1f\x8b":
raw = gzip.decompress(raw)
data = plistlib.loads(raw)
return data.get("Products", {})
# Bekannte Marketing-Versionsnummern nach Codename. Nur eine Anzeige-Hilfe --
# taucht ein UNS unbekannter zukuenftiger Codename auf (n plane naechstes Jahr:
# neuer Nachfolger von Tahoe), wird er trotzdem gelistet (siehe
# _split_shared_support_name), nur ohne huebsche Versionsnummer.
KNOWN_MACOS_VERSIONS = {
"bigsur": "11", "monterey": "12", "ventura": "13", "sonoma": "14",
"sequoia": "15", "tahoe": "26",
}
def _split_shared_support_name(shared_support_id: str):
"""'com.apple.pkg.InstallAssistant.macOSBigSur' -> ('Big Sur', '11')."""
name = shared_support_id.rsplit(".macOS", 1)[-1]
if not name:
return None, None
# CamelCase -> "Big Sur" (Ziffern/Grossbuchstaben-Grenzen als Trenner)
import re
pretty = re.sub(r"(?<!^)(?=[A-Z])", " ", name).strip()
version = KNOWN_MACOS_VERSIONS.get(name.lower())
return pretty, version
def _is_macos_installer(product: dict) -> bool:
emi = product.get("ExtendedMetaInfo", {}) or {}
ids = emi.get("InstallAssistantPackageIdentifiers", {}) or {}
return ids.get("OSInstall") == "com.apple.mpkg.OSInstall"
# Klassisches Schema bis Catalina: eigener "OSInstall"-Schluessel.
if ids.get("OSInstall") == "com.apple.mpkg.OSInstall":
return True
# Ab Big Sur (live gegen swscan.apple.com verifiziert, 2026-07-18): kein
# "OSInstall"-Schluessel mehr, stattdessen "SharedSupport":
# "com.apple.pkg.InstallAssistant.macOS<Name>" (z.B. macOSBigSur,
# macOSMonterey, ..., macOSTahoe). Der alte Filter uebersah dadurch
# STILLSCHWEIGEND alle Big-Sur-und-neuer-Installer -- genau die, die per
# InstallAssistant.pkg (statt BaseSystem.dmg) geliefert werden und die
# dieses Tool eigentlich explizit unterstuetzen soll.
shared = ids.get("SharedSupport", "")
return isinstance(shared, str) and shared.startswith(
"com.apple.pkg.InstallAssistant.macOS"
)
def _fetch_product_metadata(product: dict, timeout: float = 20):
@@ -100,6 +146,19 @@ def _fetch_product_metadata(product: dict, timeout: float = 20):
title = en.get("title")
except Exception as exc: # noqa: BLE001
log.warning("Metadaten-Fetch fehlgeschlagen fuer %s: %s", smd_url, exc)
if title:
return title, version
# Big Sur+ Produkte haben KEIN ServerMetadataURL (live verifiziert) --
# Name kommt stattdessen aus dem SharedSupport-Identifier.
emi = product.get("ExtendedMetaInfo", {}) or {}
ids = emi.get("InstallAssistantPackageIdentifiers", {}) or {}
shared = ids.get("SharedSupport", "")
if isinstance(shared, str) and shared.startswith(
"com.apple.pkg.InstallAssistant.macOS"
):
name, ver = _split_shared_support_name(shared)
if name:
return f"macOS {name}", (version or ver)
return title, version