#!/bin/bash # ============================================================================= # fix-calamares.sh – przebudowuje TYLKO Calamaresa (bez pełnego build-pagan.sh) # ----------------------------------------------------------------------------- # Po co: gdy Calamares jest zepsuty (np. linkuje Qt6 QML / zła wersja symboli), # pełny `build-pagan.sh` odbudowuje przy okazji kilka pakietów i zjada zasoby. # Ten skrypt korzysta z istniejącego rootfsu i odbudowuje WYŁĄCZNIE calamares # (opcjonalnie kpmcore), a na końcu może przepakować samo ISO (bez przebudowy # pakietów – to robi create_iso z buildera). # # Użycie: # sudo ./fix-calamares.sh # przebuduj calamares + przepakuj ISO # sudo ./fix-calamares.sh --no-respin # tylko przebuduj (bez ISO) # sudo ./fix-calamares.sh --jobs 4 # limit równoległości (domyślnie auto: RAM/2) # sudo ./fix-calamares.sh --with-kpmcore # dobuduj też kpmcore # sudo ./fix-calamares.sh --respin-only # nic nie buduj, tylko przepakuj ISO # ============================================================================= set -euo pipefail cd "$(dirname "$0")" RESPIN=1 RESPIN_ONLY=0 WITH_KPMCORE=0 JOBS="${PAGAN_JOBS:-}" while [[ $# -gt 0 ]]; do case "$1" in --no-respin) RESPIN=0; shift ;; --respin) RESPIN=1; shift ;; --respin-only) RESPIN_ONLY=1; RESPIN=1; shift ;; --with-kpmcore) WITH_KPMCORE=1; shift ;; --jobs) JOBS="$2"; shift 2 ;; --jobs=*) JOBS="${1#*=}"; shift ;; -h|--help) awk 'NR>1 && /^#/ {print; next} NR>1 {exit}' "$0"; exit 0 ;; *) echo "Nieznany argument: $1" >&2; exit 2 ;; esac done if [[ ${EUID:-$(id -u)} -ne 0 ]]; then echo "❌ Uruchom jako root: sudo ./fix-calamares.sh" >&2 exit 1 fi [[ -n "$JOBS" ]] && export PAGAN_JOBS="$JOBS" true # ── Wczytaj funkcje buildera (main NIE wystartuje – plik jest source'owany) ── set -- source ./build-pagan.sh trap - EXIT # bez podsumowania buildera [[ -d "$PAGAN_ROOT/usr/lib" ]] || { echo "❌ Brak rootfs w $PAGAN_ROOT – zrób najpierw pełny build." >&2; exit 1; } echo "═══ NAPRAWA CALAMARES ═══" echo " Rootfs: $PAGAN_ROOT" echo " Zadania: ${PAGAN_JOBS:-auto} (rdzeni: $(nproc 2>/dev/null || echo '?'))" echo " Respin ISO: $([[ $RESPIN -eq 1 ]] && echo tak || echo nie)" # ── Środowisko identyczne jak w install_calamares ── export PATH="$TOOLS_DIR/bin:$PATH" export PKG_CONFIG_PATH="$PAGAN_ROOT/usr/lib/pkgconfig:$PAGAN_ROOT/usr/share/pkgconfig" export CMAKE_PREFIX_PATH="$PAGAN_ROOT/usr:/usr" if [[ -f "$PAGAN_ROOT/usr/share/ECM/cmake/ECMConfig.cmake" ]]; then export ECM_DIR="$PAGAN_ROOT/usr/share/ECM/cmake" fi export LD_LIBRARY_PATH="$PAGAN_ROOT/usr/lib:/usr/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" export XDG_DATA_DIRS="$PAGAN_ROOT/usr/share${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}" # ── Limit równoległości (wrapper ninja w $TOOLS_DIR/bin) ── _install_ninja_wrapper # ── Naprawa absolutnej ścieżki DT_NEEDED w polkitd ── # Starsze buildy linkowały bez SONAME i wpisywały /mnt/pagan/usr/lib/libduktape.so. # W zainstalowanym systemie kończy się to kodem 127. Naprawiamy zależności przed # Calamaresem, żeby także fix-calamares sam wystarczał do przygotowania ISO. if [[ -x "$PAGAN_ROOT/usr/lib/polkit-1/polkitd" ]] && \ readelf -d "$PAGAN_ROOT/usr/lib/polkit-1/polkitd" 2>/dev/null | grep -q '/mnt/pagan/'; then echo " Naprawiam polkitd: usuwam absolutną zależność do /mnt/pagan..." sed -i -E '/^(duktape-2\.7\.0|polkit-127)$/d' "$RESUME_FILE" 2>/dev/null || true build_lfs_pkg "duktape" "2.7.0" \ "https://duktape.org/duktape-2.7.0.tar.xz" "SKIP" \ "cd src && gcc -O2 -fPIC -shared -Wl,-soname,libduktape.so -o libduktape.so duktape.c && install -m 755 libduktape.so \$PAGAN_ROOT/usr/lib/libduktape.so && install -m 644 duktape.h \$PAGAN_ROOT/usr/include/duktape.h && install -m 644 duk_config.h \$PAGAN_ROOT/usr/include/duk_config.h" build_lfs_pkg "polkit" "127" \ "https://github.com/polkit-org/polkit/archive/127/polkit-127.tar.gz" "SKIP" \ "( export LIBRARY_PATH=\"\$PAGAN_ROOT/usr/lib\"; meson setup build --prefix=/usr -Dintrospection=false && ninja -C build && DESTDIR=\$PAGAN_ROOT ninja -C build install )" fi # ── Usuń zaległy Qt6 QML/Quick i stare KF6-QML (mieszanie wersji = symbol lookup error) ── _purge_stale_qt # ── Napraw stale configi Qt6 CMake (po rollbacku paga wskazują usuniętą wersję) ── _fix_stale_qt_cmake # ── Konfiguracja (settings.conf z modules-search + moduły) i branding ── _write_calamares_config _write_calamares_branding # ── Ikona instalatora na pulpicie XFCE (live = autologin root) + ustawienia # xfdesktop (style ikon, tapeta). Idempotentne; bez tego respin ISO nie odświeży # pulpitu. if [[ "${PAGAN_DE:-xfce}" == "xfce" ]]; then _setup_xfce_live_desktop fi # ── Release notes (pagan-news / pagan-update + wpisy changelogu) ── _write_pagan_news # ── Grupy systemowe: napraw wcięcia + dołóż grupy dla Calamaresa ── _ensure_system_groups # ── Polkit: dopełnij pliki usługi (bez polkitd KPMcore nie widzi dysków) ── _ensure_polkit_units # ── D-Bus: jednostki bez cyklu zależności (inaczej dbus.service jest pomijany # przez systemd → brak polkitd/NetworkManager/lightdm). ── _ensure_dbus_units # ── D-Bus: polityka systemd (org.freedesktop.systemd1.conf). Bez niej PID1 nie # zajmie nazwy org.freedesktop.systemd1 → systemctl/aktywacja usług/logind # padają. To ta sama usterka, której objawem jest „Got disconnect on API bus”. ── _ensure_systemd_dbus_policy # ── WiFi: wpa_supplicant w /usr/sbin + aktywacja D-Bus dla NetworkManagera. ── _ensure_wifi_supplicant # ── Netinstall: backend `pag` w module packages Calamaresa. ── _install_pag_package_backend # ── Udev: baza hwdb (bez niej generator imds zgłasza błąd przy starcie). ── _ensure_hwdb # ── Strefy czasowe: bez skompilowanych danych moduł locale Calamaresa pada z # „Bad path: …/zoneinfo/Europe/Warsaw” (kiedyś tzdata było tylko kopiowane). ── _install_tzdata # ── GRUB/initramfs: aliasy initramfs-.img + /etc/default/grub. Bez nich # grub-mkconfig nie wstawi linii `initrd` → zainstalowany system nie wstanie. ── _ensure_grub_boot_artifacts # ── Wtyczki: udostępnij /qt6/plugins w katalogu runtime Qt ── # (backend KPMcore + wtyczki KF6); bez tego qFatal „Failed to initialize KPMcore backend”. _sync_qt_plugin_dirs if _kpmcore_backend_ok; then echo " ✓ backend KPMcore dostępny dla Qt ($(_qt_runtime_plugin_dir))" else echo " ⚠ backend KPMcore nadal niewidoczny – sprawdź instalację kpmcore" >&2 fi if [[ $RESPIN_ONLY -eq 0 ]]; then # Wymuś przebudowę calamaresa mimo wpisu w resume. sed -i '/^calamares-3\.3\.14$/d' "$RESUME_FILE" 2>/dev/null || true # Martwe libpwquality (brak libcrack) → usuń, inaczej moduł „users” się go # podlinkuje i nie załaduje przy starcie („Module users loading FAILED”). _purge_broken_pwquality # os-prober – moduł partition woła go bezwarunkowo (inaczej „os-prober cannot start.”). if ! ( set +e; install_os_prober ); then echo " ⚠ os-prober: budowa nieudana – Calamares zaloguje 'os-prober cannot start.'" >&2 fi # KPMcore tylko jeśli brakuje albo wyraźnie zażądano. if [[ $WITH_KPMCORE -eq 1 || ! -e "$PAGAN_ROOT/usr/lib/cmake/KPMcore/KPMcoreConfig.cmake" ]]; then echo " Buduję kpmcore-26.04.3..." build_lfs_pkg "kpmcore" "26.04.3" \ "https://download.kde.org/stable/release-service/26.04.3/src/kpmcore-26.04.3.tar.xz" \ "SKIP" \ "cmake -B build -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -G Ninja && DESTDIR=\$PAGAN_ROOT ninja -C build install" fi # ── KF6: napraw configi eksportujące QML (stare, z pełnego KF6) ── # Budujemy minimalny KF6 bez QML; build_lfs_pkg pominie już zbudowane. KFURL="https://download.kde.org/stable/frameworks/6.28.0"; KFVER="6.28.0" _KFCFG="cmake -B build -G Ninja -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_TESTING=OFF -DKDE_INSTALL_USE_QT_SYS_PATHS=ON -DKDE_INSTALL_QTMETATYPESDIR=metatypes -DBUILD_PYTHON_BINDINGS=OFF" for _pp in "kcoreaddons:KF6CoreAddons" "kconfig:KF6Config" "ki18n:KF6I18n" "kwidgetsaddons:KF6WidgetsAddons"; do _cm="${_pp##*:}"; _tp="$PAGAN_ROOT/usr/lib/cmake/$_cm/${_cm}Targets.cmake" [[ -f "$_tp" ]] || continue if grep -q "Qml" "$_tp" 2>/dev/null; then echo " KF6 $_cm: stary config z QML – wymuszam przebudowę ${_pp%%:*}" sed -i "/^${_pp%%:*}-6\.28\.0$/d" "$RESUME_FILE" 2>/dev/null || true fi done # KConfig/KI18n są wymagane przez Calamares (KPMcoreHelper) – przebuduj na # pewno bez QML (nawet jeśli detekcja nic nie znalazła, np. config już usunięty). sed -i -E '/^(kconfig|ki18n)-6\.28\.0$/d' "$RESUME_FILE" 2>/dev/null || true build_lfs_pkg "extra-cmake-modules" "$KFVER" "$KFURL/extra-cmake-modules-$KFVER.tar.xz" "SKIP" \ "$_KFCFG && ninja -C build && DESTDIR=\$PAGAN_ROOT ninja -C build install" build_lfs_pkg "kcoreaddons" "$KFVER" "$KFURL/kcoreaddons-$KFVER.tar.xz" "SKIP" \ "$_KFCFG -DKCOREADDONS_USE_QML=OFF && ninja -C build && DESTDIR=\$PAGAN_ROOT ninja -C build install" build_lfs_pkg "kconfig" "$KFVER" "$KFURL/kconfig-$KFVER.tar.xz" "SKIP" \ "$_KFCFG -DKCONFIG_USE_QML=OFF && ninja -C build && DESTDIR=\$PAGAN_ROOT ninja -C build install" build_lfs_pkg "ki18n" "$KFVER" "$KFURL/ki18n-$KFVER.tar.xz" "SKIP" \ "$_KFCFG -DBUILD_WITH_QML=OFF && ninja -C build && DESTDIR=\$PAGAN_ROOT ninja -C build install" build_lfs_pkg "kwidgetsaddons" "$KFVER" "$KFURL/kwidgetsaddons-$KFVER.tar.xz" "SKIP" \ "$_KFCFG -DBUILD_DESIGNERPLUGIN=OFF && ninja -C build && DESTDIR=\$PAGAN_ROOT ninja -C build install" # Calamares bez QML, ale Z modułami Pythonowymi (mount/unpackfs/fstab/ # bootloader/services-systemd/…) – bez nich settings.conf nie odpali # („Initialization Failed”), a system nie wstanie po instalacji. echo " Buduję calamares-3.3.14 (WITH_QML=OFF, WITH_PYTHON=ON)..." build_lfs_pkg "calamares" "3.3.14" \ "https://github.com/calamares/calamares/releases/download/v3.3.14/calamares-3.3.14.tar.gz" \ "SKIP" \ "cmake -B build -G Ninja -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DWITH_QT6=ON -DWITH_QML=OFF -DWITH_PYTHON=ON -DWITH_PYBIND11=ON -DCMAKE_DISABLE_FIND_PACKAGE_LibPWQuality=TRUE -DPython_EXECUTABLE=\$PAGAN_ROOT/usr/bin/python3 -DPython_ROOT_DIR=\$PAGAN_ROOT/usr -DBUILD_SCHEMA_TESTING=OFF -DBUILD_TESTING=OFF -DBUILD_CRASH_REPORTING=OFF && DESTDIR=\$PAGAN_ROOT ninja -C build install" # ── Weryfikacja ── echo "" echo "── Weryfikacja ──" if [[ -x "$PAGAN_ROOT/usr/bin/calamares" ]]; then echo " ✓ /usr/bin/calamares obecny" else echo " ✗ Brak /usr/bin/calamares" >&2 exit 1 fi if objdump -p "$PAGAN_ROOT/usr/lib/libcalamaresui.so.3.3.14" 2>/dev/null | grep -q 'NEEDED.*libQt6Qml'; then echo " ✗ libcalamaresui NADAL linkuje libQt6Qml – -DWITH_QML=OFF nie zadziałało" >&2 exit 1 else echo " ✓ libcalamaresui bez QML" fi # Komplet modułów wymaganych przez settings.conf (w tym Pythonowe). if ! _calamares_modules_ok; then echo " ✗ Brakujące moduły Calamares: $(_calamares_missing_modules)" >&2 echo " Calamares MUSI być zbudowany z -DWITH_PYTHON=ON -DWITH_PYBIND11=ON" >&2 echo " (WITH_QML=OFF). Sprawdź w logu: '-- Skipped mount (No Python support)'." >&2 exit 1 else echo " ✓ komplet modułów wymaganych przez settings.conf" fi # settings.conf MUSI mieć modules-search – inaczej Calamares nie znajdzie żadnego modułu. if ! grep -q '^modules-search:' "$PAGAN_ROOT/etc/calamares/settings.conf" 2>/dev/null; then echo " ✗ settings.conf bez 'modules-search' – Calamares nie znajdzie modułów" >&2 exit 1 else echo " ✓ settings.conf ma modules-search" fi # Backend KPMcore widoczny dla runtime Qt. if ! _kpmcore_backend_ok; then echo " ✗ Backend KPMcore niewidoczny w '$(_qt_runtime_plugin_dir)'" >&2 echo " (_sync_qt_plugin_dirs powinno skopiować kpmcore do katalogu wtyczek Qt)" >&2 exit 1 else echo " ✓ backend KPMcore widoczny dla Qt" fi # Świeży cache dynamicznego linkera w rootfsie (po usunięciu starych libek). ldconfig -r "$PAGAN_ROOT" 2>/dev/null || true fi # ── Przepakowanie ISO z istniejącego rootfsu (bez przebudowy pakietów) ── if [[ $RESPIN -eq 1 ]]; then echo "" echo "── Respin ISO (create_iso) ──" export PAGAN_DE="${PAGAN_DE:-xfce}" export BUILD_IMG=0 BUILD_ISO=1 umount_virtual_fs >/dev/null 2>&1 || true # Initramfs przebudowujemy zawsze – jest szybki, a zawiera logikę znajdowania # nośnika live (Ventoy/exFAT) i uruchamiania sesji; bez tego respin ISO # pakowałby stary initramfs. build_initramfs create_iso report_artifacts || true fi echo "" echo "✅ Gotowe. Calamares: $PAGAN_ROOT/usr/bin/calamares" if [[ $RESPIN -eq 1 ]]; then ls -la --time-style=+%H:%M "$OUTPUT_DIR" 2>/dev/null || true fi