← recipes

Commit b2ef4b3f

3
files
+258
added
-1
deleted
@@ -1,6 +1,6 @@
1 1 pkgname: kernel
2 2 pkgver: '7.2.8'
3 -pkgrel: '1'
3 +pkgrel: '2'
4 4 pkgdesc: 'Pagan Linux kernel (rolling) – układ DOKŁADNIE jak w obrazie ISO: /boot/vmlinuz-<ver>-pagan + /usr/lib/modules/<ver>-pagan + źródła DKMS w /usr/src/kernel.'
5 5 url: 'https://www.kernel.org'
6 6 arch: x86_64
@@ -8,6 +8,7 @@ license:
8 8 - GPL-2.0-only
9 9 depends:
10 10 - kmod
11 +- pagan-initramfs
11 12
12 13 # `pag install linux` musi dalej działać (stare skrypty, pagan-drivers, haki) –
13 14 # tak samo nazywa ten pakiet build ISO (install_rolling_kernel w build-pagan.sh,
14 15 new file mode 100644
@@ -0,0 +1,18 @@
1 +pkgname: pagan-initramfs
2 +pkgver: '1.0'
3 +pkgrel: '1'
4 +pkgdesc: 'Przebudowa initramfs PaganOS – per-wersja + obsluga root=UUID/PARTUUID/LABEL (hooki kernela/dkms)'
5 +url: 'https://paganlinux.eu'
6 +arch: x86_64
7 +license:
8 +- MIT
9 +depends: []
10 +makedepends: []
11 +source:
12 +- 'pagan-initramfs'
13 +sha256sums:
14 +- SKIP
15 +build: |
16 + install -Dm755 pagan-initramfs ${PKGDIR}/usr/bin/pagan-initramfs
17 +package: |
18 + true
0 19 new file mode 100755
@@ -0,0 +1,238 @@
1 +#!/bin/bash
2 +# pagan-initramfs – przebudowa initramfs Pagan Linux (rolling: po aktualizacji jądra).
3 +#
4 +# Dla KAŻDEGO jądra (/boot/vmlinuz-<ver> + /usr/lib/modules/<ver>) buduje OSOBNY
5 +# plik /boot/initramfs-<ver>.img i aktualizuje aliasy czytane przez
6 +# /etc/grub.d/10_linux (initrd.img-<ver>, initramfs-<ver>.img). Wspólny plik
7 +# initramfs był przyczyną stanu „nowe moduły na starym jądrze” po `pag upgrade`.
8 +#
9 +# Kolejność builderów: dracut → mkinitcpio → mkinitramfs → własny busybox+cpio.
10 +# Opcjonalny argument: konkretna wersja jądra (np. 7.2.8-pagan).
11 +
12 +[ "$(id -u)" = "0" ] || { echo "Uruchom jako root" >&2; exit 1; }
13 +
14 +BOOT="${PAGAN_BOOT_DIR:-/boot}"
15 +MODS="${PAGAN_MODULES_DIR:-/usr/lib/modules}"
16 +
17 +# ── lista wersji jąder do przebudowy (argument albo wszystkie z /boot) ───────
18 +_versions() {
19 + if [ "$#" -gt 0 ] && [ -n "${1:-}" ]; then printf '%s\n' "$1"; return 0; fi
20 + for k in "$BOOT"/vmlinuz-*; do
21 + [ -e "$k" ] || continue
22 + b="$(basename "$k")"; v="${b#vmlinuz-}"
23 + [ "$v" != "$b" ] || continue
24 + printf '%s\n' "$v"
25 + done | sort -V
26 +}
27 +
28 +# ── fallback: minimalny initramfs (busybox + cpio), bez modułów jądra ────────
29 +# Moduły nie są potrzebne: jądro budowane przez Pagan ma dysk/FS/LUKS wbudowane
30 +# (initramfs ma tylko zamontować root i zrobić switch_root).
31 +_fallback_build() {
32 + local ver="$1" out="$2"
33 + echo "Fallback: busybox+cpio (initramfs dla $ver)..."
34 + local TMP; TMP="$(mktemp -d)" || return 1
35 + mkdir -p "$TMP"/bin "$TMP"/dev "$TMP"/proc "$TMP"/sys "$TMP"/run \
36 + "$TMP"/new_root "$TMP"/etc "$TMP"/usr/sbin "$TMP"/usr/lib "$TMP"/lib "$TMP"/lib64
37 +
38 + cat > "$TMP/init" <<'INITEOF'
39 +#!/bin/sh
40 +# Pagan Linux initramfs init (minimal: dysk + LUKS + deploymenty).
41 +mount -t proc proc /proc 2>/dev/null
42 +mount -t sysfs sysfs /sys 2>/dev/null
43 +mount -t devtmpfs dev /dev 2>/dev/null || mount -t tmpfs dev /dev 2>/dev/null
44 +mkdir -p /run /new_root /etc /usr/sbin /usr/bin /bin /sbin
45 +
46 +ROOT_DEV=""
47 +CRYPT_DEV_ARG=""
48 +for arg in $(cat /proc/cmdline 2>/dev/null); do
49 + case "$arg" in
50 + root=*) ROOT_DEV="${arg#root=}" ;;
51 + cryptdevice=*) CRYPT_DEV_ARG="${arg#cryptdevice=}" ;;
52 + esac
53 +done
54 +[ -n "$ROOT_DEV" ] || ROOT_DEV="/dev/sda1"
55 +
56 +# ── root=UUID=/PARTUUID=/LABEL= → konkretne urządzenie ──────────────────────
57 +# BusyBox `mount` NIE rozwiązuje UUID=/LABEL= (inaczej niż util-linux). Bez tego
58 +# po przebudowie initramfs system wisiał na starcie („nie można zamontować roota”).
59 +_blkid_get() {
60 + blkid "$1" 2>/dev/null | tr ' ' '\n' | grep "^$2=" | head -1 | cut -d= -f2- | tr -d '"'
61 +}
62 +_resolve_root() {
63 + local key="$1" val="$2" d
64 + for d in /dev/sd*[0-9] /dev/hd*[0-9] /dev/vd*[0-9] \
65 + /dev/nvme*n[0-9]*p[0-9]* /dev/mmcblk*p[0-9]* \
66 + /dev/dm-[0-9]* /dev/mapper/*; do
67 + [ -b "$d" ] || continue
68 + [ "$(_blkid_get "$d" "$key")" = "$val" ] && { printf '%s' "$d"; return 0; }
69 + done
70 + return 1
71 +}
72 +case "$ROOT_DEV" in
73 + UUID=*) _r="$(_resolve_root UUID "${ROOT_DEV#UUID=}")" && ROOT_DEV="$_r" ;;
74 + PARTUUID=*) _r="$(_resolve_root PARTUUID "${ROOT_DEV#PARTUUID=}")" && ROOT_DEV="$_r" ;;
75 + LABEL=*) _r="$(_resolve_root LABEL "${ROOT_DEV#LABEL=}")" && ROOT_DEV="$_r" ;;
76 +esac
77 +
78 +# ---- LUKS: odblokowanie roota (cryptdevice= lub wprost partycja LUKS) ----
79 +unlock_luks() {
80 + local dev="$1" name="$2" pass
81 + [ -n "$name" ] || name="cryptroot"
82 + mkdir -p /dev/mapper
83 + mknod /dev/mapper/control c 10 236 2>/dev/null
84 + modprobe dm-crypt 2>/dev/null || true
85 + if ! command -v cryptsetup >/dev/null 2>&1; then
86 + echo "[pagan-init] BŁĄD: brak cryptsetup w initramfs – nie odblokuję $dev"
87 + return 1
88 + fi
89 + stty -echo 2>/dev/null
90 + printf "Hasło (LUKS %s): " "$dev"; read -r pass; stty echo 2>/dev/null; echo
91 + if ! printf '%s\n' "$pass" | cryptsetup open "$dev" "$name" 2>/dev/null; then
92 + pass=""; echo "[pagan-init] BŁĄD: nie odblokowano $dev (złe hasło?)"; return 1
93 + fi
94 + pass=""; echo "[pagan-init] Odblokowano /dev/mapper/$name"; return 0
95 +}
96 +
97 +if [ -n "$CRYPT_DEV_ARG" ]; then
98 + crypt_src="${CRYPT_DEV_ARG%%:*}"; crypt_name="${CRYPT_DEV_ARG#*:}"; crypt_name="${crypt_name%%:*}"
99 + crypt_dev=""
100 + case "$crypt_src" in
101 + UUID=*)
102 + want="${crypt_src#UUID=}"
103 + for d in /dev/sd*[0-9] /dev/hd*[0-9] /dev/vd*[0-9] /dev/nvme*n[0-9]*p[0-9]* /dev/mmcblk*p[0-9]*; do
104 + [ -b "$d" ] || continue
105 + [ "$(cryptsetup luksUUID "$d" 2>/dev/null)" = "$want" ] && { crypt_dev="$d"; break; }
106 + done ;;
107 + /dev/*) crypt_dev="$crypt_src" ;;
108 + esac
109 + if [ -n "$crypt_dev" ] && [ -b "$crypt_dev" ]; then
110 + if unlock_luks "$crypt_dev" "$crypt_name"; then ROOT_DEV="/dev/mapper/$crypt_name"
111 + else echo "[pagan-init] Powłoka ratunkowa:"; exec /bin/sh; fi
112 + else
113 + echo "[pagan-init] BŁĄD: cryptdevice nie znaleziono ($crypt_src)"; exec /bin/sh
114 + fi
115 +fi
116 +
117 +i=0
118 +while [ ! -e "$ROOT_DEV" ] && [ "$i" -lt 10 ]; do sleep 1; i=$((i+1)); done
119 +
120 +# Fallback: root= wskazuje wprost na partycję LUKS. `cryptsetup isLuks` jest
121 +# jednoznaczne (BusyBox `blkid -t` ignoruje filtr i zawsze zwraca 0).
122 +if cryptsetup isLuks "$ROOT_DEV" 2>/dev/null; then
123 + echo "[pagan-init] Wykryto LUKS na root ($ROOT_DEV)"
124 + if unlock_luks "$ROOT_DEV" cryptroot; then ROOT_DEV="/dev/mapper/cryptroot"
125 + else echo "[pagan-init] Powłoka ratunkowa:"; exec /bin/sh; fi
126 +fi
127 +
128 +mount -t auto -o rw "$ROOT_DEV" /new_root 2>/dev/null || {
129 + echo "[pagan-init] BŁĄD: nie można zamontować roota ($ROOT_DEV)"; exec /bin/sh; }
130 +
131 +# Deploymenty PAG (immutable OS)
132 +ACTIVE="/new_root/.deployments/active"; DEP=""
133 +if [ -L "$ACTIVE" ]; then
134 + DEP=$(readlink "$ACTIVE"); [ -n "$DEP" ] && DEP="/new_root/.deployments/$DEP"
135 +elif [ -d "/new_root/.deployments" ]; then
136 + DEP=$(ls -1 /new_root/.deployments/ 2>/dev/null | grep -v active | sort -r | head -1)
137 + [ -n "$DEP" ] && DEP="/new_root/.deployments/$DEP"
138 +fi
139 +[ -n "$DEP" ] && [ -d "$DEP" ] && NEWROOT="$DEP" || NEWROOT="/new_root"
140 +
141 +mount --move /proc "$NEWROOT/proc" 2>/dev/null
142 +mount --move /sys "$NEWROOT/sys" 2>/dev/null
143 +mount --move /dev "$NEWROOT/dev" 2>/dev/null
144 +exec switch_root "$NEWROOT" /sbin/init
145 +INITEOF
146 + chmod +x "$TMP/init"
147 +
148 + # busybox (statyczny) lub kopie binarek HOSTA
149 + BB=""
150 + for p in /usr/bin/busybox /bin/busybox; do [ -x "$p" ] && BB="$p" && break; done
151 + if [ -n "$BB" ]; then
152 + cp "$BB" "$TMP/bin/busybox"; chmod 755 "$TMP/bin/busybox"
153 + for c in sh mount umount ls cat echo sleep readlink mkdir switch_root cp rm ln grep \
154 + poweroff reboot blkid mknod stty sed sort cut tr head vi; do
155 + ln -sf busybox "$TMP/bin/$c"
156 + done
157 + else
158 + for t in sh bash mount umount ls cat echo sleep readlink mkdir switch_root cp rm ln grep \
159 + blkid mknod stty sed sort cut tr head; do
160 + s="$(command -v "$t" 2>/dev/null)" && [ -n "$s" ] && [ -f "$s" ] && cp "$s" "$TMP/bin/"
161 + done
162 + fi
163 +
164 + # cryptsetup + biblioteki (obsługa LUKS) – jeśli system go ma
165 + CS=""
166 + for p in /usr/sbin/cryptsetup /usr/bin/cryptsetup /sbin/cryptsetup; do [ -x "$p" ] && CS="$p" && break; done
167 + if [ -n "$CS" ]; then
168 + cp "$CS" "$TMP/usr/sbin/cryptsetup"; chmod 755 "$TMP/usr/sbin/cryptsetup"
169 + for lib in $(ldd "$CS" 2>/dev/null | awk '/=>/ {print $3} /^[[:space:]]*\// {print $1}'); do
170 + [ -f "$lib" ] || continue
171 + d="${lib#"${PAGAN_ROOT:-}"}"; d="${d#/}"; [ -n "$d" ] || continue
172 + mkdir -p "$TMP/${d%/*}"; cp -fL "$lib" "$TMP/$d" 2>/dev/null || true
173 + done
174 + # Domknięcie zależności PRZECHODNICH (jedno ldd pomija np. libcrypto.so.3).
175 + for _pass in 1 2 3; do
176 + for f in "$TMP"/usr/lib/*.so* "$TMP"/lib/*.so*; do
177 + [ -f "$f" ] || continue
178 + for lib in $(ldd "$f" 2>/dev/null | awk '/=>[[:space:]]*\// {print $3}'); do
179 + [ -f "$lib" ] || continue
180 + d="${lib#"${PAGAN_ROOT:-}"}"; d="${d#/}"; [ -n "$d" ] || continue
181 + [ -e "$TMP/$d" ] && continue
182 + mkdir -p "$TMP/${d%/*}"; cp -fL "$lib" "$TMP/$d" 2>/dev/null || true
183 + done
184 + done
185 + done
186 + loader="$(ldd "$CS" 2>/dev/null | awk '/ld-linux/ {print $1}')"
187 + if [ -n "$loader" ] && [ -f "$loader" ]; then
188 + mkdir -p "$TMP${loader%/*}"; cp -fL "$loader" "$TMP$loader"
189 + fi
190 + fi
191 + [ -f /etc/pagan-release ] && cp /etc/pagan-release "$TMP/etc/"
192 +
193 + ( cd "$TMP" && find . | cpio -oH newc 2>/dev/null | gzip ) > "$out" || { rm -rf "$TMP"; return 1; }
194 + rm -rf "$TMP"
195 + return 0
196 +}
197 +
198 +# ── zbuduj initramfs dla jednej wersji jądra do pliku $out ───────────────────
199 +_build_one() {
200 + local ver="$1" out="$2"
201 + if [ ! -d "$MODS/$ver" ]; then
202 + echo "⚠ brak modułów dla $ver ($MODS/$ver) – pomijam"
203 + return 1
204 + fi
205 + if command -v dracut >/dev/null 2>&1; then
206 + dracut --force --kver "$ver" "$out" >/dev/null 2>&1 && return 0
207 + fi
208 + if command -v mkinitcpio >/dev/null 2>&1; then
209 + mkinitcpio -k "$ver" -g "$out" >/dev/null 2>&1 && return 0
210 + fi
211 + if command -v mkinitramfs >/dev/null 2>&1; then
212 + mkinitramfs -o "$out" -k "$ver" >/dev/null 2>&1 || mkinitramfs "$ver" >/dev/null 2>&1
213 + [ -s "$out" ] && return 0
214 + fi
215 + _fallback_build "$ver" "$out"
216 +}
217 +
218 +built_any=0
219 +for ver in $(_versions "${1:-}"); do
220 + out="$BOOT/initramfs-$ver.img"
221 + [ -L "$out" ] && rm -f "$out" # nie pisz „przez” stary symlink
222 + if _build_one "$ver" "$out"; then
223 + ln -sfn "initramfs-$ver.img" "$BOOT/initrd.img-$ver"
224 + built_any=1
225 + echo "✅ initramfs-$ver.img"
226 + else
227 + rm -f "$out"
228 + fi
229 +done
230 +
231 +if [ "$built_any" = "1" ]; then
232 + newest="$(for k in "$BOOT"/vmlinuz-*; do [ -e "$k" ] || continue; basename "$k"; done \
233 + | sed 's/^vmlinuz-//' | sort -V | tail -1)"
234 + [ -n "$newest" ] && ln -sfn "initramfs-$newest.img" "$BOOT/initramfs.img"
235 + exit 0
236 +fi
237 +echo "❌ Nie zbudowano żadnego initramfs (brak jąder w $BOOT?)" >&2
238 +exit 1