← recipes

Commit e19edc32

5
files
+590
added
-0
deleted
@@ -0,0 +1,21 @@
1 +MIT License
2 +
3 +Copyright (c) 2026 Pagan Linux
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in all
13 +copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 +SOFTWARE.
0 22 new file mode 100644
@@ -0,0 +1,37 @@
1 +pkgname: pagan-mkiso
2 +pkgver: '1.0'
3 +pkgrel: '1'
4 +pkgdesc: 'PaganLinux – generator bootowalnego ISO z uruchomionego systemu (squashfs + hybrydowe BIOS/UEFI)'
5 +url: 'https://paganlinux.eu'
6 +arch: x86_64
7 +license:
8 +- MIT
9 +# Narzędzia budowy ISO. Sprawdzane tez przez `pagan-mkiso --check`.
10 +depends:
11 +- squashfs-tools
12 +- libisoburn
13 +- busybox
14 +- mtools
15 +- dosfstools
16 +- syslinux
17 +makedepends: []
18 +source:
19 +- 'pagan-mkiso'
20 +- 'pagan-mkiso-gui.py'
21 +- 'pagan-mkiso.desktop'
22 +- 'mkiso.conf.example'
23 +- 'LICENSE'
24 +sha256sums:
25 +- SKIP
26 +- SKIP
27 +- SKIP
28 +- SKIP
29 +- SKIP
30 +build: |
31 + install -Dm755 pagan-mkiso ${PKGDIR}/usr/bin/pagan-mkiso
32 + install -Dm644 pagan-mkiso-gui.py ${PKGDIR}/usr/lib/pagan/pagan-mkiso-gui.py
33 + install -Dm644 pagan-mkiso.desktop ${PKGDIR}/usr/share/applications/pagan-mkiso.desktop
34 + install -Dm644 mkiso.conf.example ${PKGDIR}/usr/share/pagan/mkiso.conf.example
35 + install -Dm644 LICENSE ${PKGDIR}/usr/share/licenses/pagan-mkiso/LICENSE
36 +package: |
37 + true
0 38 new file mode 100644
@@ -0,0 +1,33 @@
1 +# =============================================================================
2 +# pagan-mkiso — konfiguracja (skopiuj do /etc/pagan/mkiso.conf i dostosuj)
3 +# =============================================================================
4 +# Ten plik jest wczytywany (source) przez /usr/bin/pagan-mkiso. Opcje z linii
5 +# poleceń mają pierwszeństwo.
6 +
7 +# Ścieżka wyjściowa ISO (domyślnie: ~/Pagan-Linux-<data>-live.iso).
8 +MKISO_OUT=""
9 +
10 +# Etykieta wolumenu ISO (bez spacji).
11 +MKISO_LABEL="PAGANLIVE"
12 +
13 +# Jądro i initramfs. Puste = autodetekcja:
14 +# jądro: /boot/vmlinuz-linux → /boot/vmlinuz-$(uname -r) → pierwsze vmlinuz-*
15 +# initramfs: /boot/initramfs.img → /boot/initramfs-$(uname -r).img → najnowszy
16 +# Gdy initramfs nie zostanie znaleziony, pagan-mkiso zbuduje WŁASNY (live).
17 +MKISO_KERNEL=""
18 +MKISO_INITRAMFS=""
19 +
20 +# Kompresja squashfs (mksquashfs). Domyślnie: xz z dużym słownikiem.
21 +MKISO_COMP="xz -b 1M -Xdict-size 100% -noappend"
22 +# Szybsza/wieksza alternatywa: MKISO_COMP="zstd -Xcompression-level 15 -noappend"
23 +
24 +# Liczba wątków mksquashfs (puste = nproc).
25 +MKISO_JOBS=""
26 +
27 +# Desktop (informacyjnie) i przełączniki bootloaderów.
28 +MKISO_DE="xfce"
29 +MKISO_DO_BIOS=1
30 +MKISO_DO_UEFI=1
31 +
32 +# Zachowaj katalog roboczy (debug): ustaw na 1.
33 +KEEP_WORK=0
0 34 new file mode 100755
@@ -0,0 +1,487 @@
1 +#!/bin/bash
2 +# =============================================================================
3 +# pagan-mkiso — zamróz uruchomiony PaganOS w bootowalne, hybrydowe ISO
4 +# =============================================================================
5 +# Robi squashfs z działającego systemu i opakowuje go w ISO startujące przez
6 +# BIOS (isolinux) ORAZ UEFI (GRUB). Nadaje się do postawienia kolejnej maszyny
7 +# albo jako baza własnej dystrybucji.
8 +#
9 +# Samowystarczalny: sam buduje LIVE-initramfs (busybox + własny /init obsługujący
10 +# squashfs + overlay + findiso), więc nie zależy od initramfsu dyskowego.
11 +#
12 +# Użycie:
13 +# sudo pagan-mkiso # ISO z uruchomionego systemu
14 +# sudo pagan-mkiso -o ~/Pagan.iso # własna ścieżka wyjścia
15 +# sudo pagan-mkiso --initramfs FILE # użyj gotowego (live) initramfs
16 +# sudo pagan-mkiso --check # sprawdź narzędzia, nic nie buduj
17 +# sudo pagan-mkiso --gui # proste okno GTK (jeśli dostępne)
18 +# pagan-mkiso --help
19 +#
20 +# Konfiguracja: /etc/pagan/mkiso.conf (wzór: /usr/share/pagan/mkiso.conf.example)
21 +# =============================================================================
22 +set -uo pipefail
23 +
24 +# ---------- kolory / logi ----------
25 +if [[ -t 1 ]]; then
26 + R=$'\033[91m'; G=$'\033[92m'; Y=$'\033[93m'; B=$'\033[94m'; BOLD=$'\033[1m'; N=$'\033[0m'
27 +else
28 + R=""; G=""; Y=""; B=""; BOLD=""; N=""
29 +fi
30 +info() { printf '%s[pagan-mkiso]%s %s\n' "$B" "$N" "$*"; }
31 +ok() { printf '%s[pagan-mkiso]%s %s✅%s %s\n' "$B" "$N" "$G" "$N" "$*"; }
32 +warn() { printf '%s[pagan-mkiso]%s %s⚠%s %s\n' "$B" "$N" "$Y" "$N" "$*" >&2; }
33 +die() { printf '%s[pagan-mkiso]%s BŁĄD: %s\n' "$B" "$R$N" "$*" >&2; exit 1; }
34 +
35 +# ---------- domyślne / konfiguracja ----------
36 +MKISO_OUT=""
37 +MKISO_LABEL="PAGANLIVE"
38 +MKISO_KERNEL=""
39 +MKISO_INITRAMFS=""
40 +MKISO_COMP="xz -b 1M -Xdict-size 100% -noappend"
41 +MKISO_DE=""
42 +MKISO_DO_BIOS=1
43 +MKISO_DO_UEFI=1
44 +MKISO_ASSUME_YES=0
45 +# shellcheck disable=SC1091
46 +[[ -r /etc/pagan/mkiso.conf ]] && source /etc/pagan/mkiso.conf
47 +
48 +# ---------- argumenty ----------
49 +DO_CHECK=0
50 +DO_GUI=0
51 +while [[ $# -gt 0 ]]; do
52 + case "$1" in
53 + -o|--output) MKISO_OUT="$2"; shift 2 ;;
54 + -l|--label) MKISO_LABEL="$2"; shift 2 ;;
55 + -k|--kernel) MKISO_KERNEL="$2"; shift 2 ;;
56 + -i|--initramfs) MKISO_INITRAMFS="$2"; shift 2 ;;
57 + -c|--compress) MKISO_COMP="$2"; shift 2 ;;
58 + --de) MKISO_DE="$2"; shift 2 ;;
59 + --no-bios) MKISO_DO_BIOS=0; shift ;;
60 + --no-uefi) MKISO_DO_UEFI=0; shift ;;
61 + --check) DO_CHECK=1; shift ;;
62 + --gui) DO_GUI=1; shift ;;
63 + -y|--yes) MKISO_ASSUME_YES=1; shift ;;
64 + -h|--help) sed -n '2,20p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
65 + *) die "Nieznana opcja: $1 (użyj --help)" ;;
66 + esac
67 +done
68 +
69 +# ---------- GUI (opcjonalne) ----------
70 +if [[ $DO_GUI -eq 1 ]]; then
71 + for _g in /usr/lib/pagan/pagan-mkiso-gui.py /usr/share/pagan/pagan-mkiso-gui.py; do
72 + if [[ -f "$_g" ]]; then exec python3 "$_g" "$@"; fi
73 + done
74 + warn "brak pagan-mkiso-gui.py – uruchamiam tryb tekstowy"
75 +fi
76 +
77 +[[ "$(id -u)" = "0" ]] || die "Uruchom jako root (sudo pagan-mkiso)"
78 +
79 +# ---------- wymagane narzędzia ----------
80 +_have() { command -v "$1" >/dev/null 2>&1; }
81 +_missing_tools() {
82 + local _m=""
83 + for t in mksquashfs xorriso; do _have "$t" || _m="$_m $t"; done
84 + # busybox do zbudowania initramfs; jeśli brak, spróbujemy kopii binarek hosta
85 + _have busybox || _have /usr/bin/busybox || _m="$_m busybox"
86 + printf '%s' "$_m"
87 +}
88 +_find_syslinux() {
89 + local f="$1" d
90 + for d in /usr/lib/syslinux/bios /usr/lib/syslinux /usr/lib/syslinux/modules/bios \
91 + /usr/share/syslinux /usr/lib/ISOLINUX /usr/lib/syslinux/mbr; do
92 + [[ -f "$d/$f" ]] && { printf '%s' "$d/$f"; return 0; }
93 + done
94 + return 1
95 +}
96 +
97 +if [[ $DO_CHECK -eq 1 ]]; then
98 + MISSING="$(_missing_tools)"
99 + if [[ -n "$MISSING" ]]; then
100 + warn "brakujące narzędzia:$MISSING"
101 + die "doinstaluj: sudo pag install pagan-mkiso (albo squashfs-tools libisoburn busybox)"
102 + fi
103 + for f in isolinux.bin ldlinux.c32 isohdpfx.bin; do
104 + _find_syslinux "$f" >/dev/null || warn "brak pliku syslinux: $f (BIOS ISO nie powstanie)"
105 + done
106 + [[ -e /usr/lib/grub/x86_64-efi ]] || warn "brak /usr/lib/grub/x86_64-efi (UEFI pominięte)"
107 + ok "narzędzia obecne"
108 + exit 0
109 +fi
110 +
111 +MISSING="$(_missing_tools)"
112 +[[ -z "$MISSING" ]] || die "brak narzędzi:$MISSING — doinstaluj: sudo pag install pagan-mkiso"
113 +
114 +# ---------- wykrycie jądra i initramfs (FIX: per-wersja) ----------
115 +KREL="$(uname -r)"
116 +_detect_kernel() {
117 + [[ -n "$MKISO_KERNEL" ]] && { printf '%s' "$MKISO_KERNEL"; return; }
118 + local c
119 + for c in /boot/vmlinuz-linux "/boot/vmlinuz-$KREL" /boot/vmlinuz-*; do
120 + [[ -f "$c" || -L "$c" ]] && { printf '%s' "$c"; return; }
121 + done
122 +}
123 +_detect_initramfs() {
124 + [[ -n "$MKISO_INITRAMFS" ]] && { printf '%s' "$MKISO_INITRAMFS"; return; }
125 + # 1) klasyczny pojedynczy plik, 2) per-wersja dla działającego jądra,
126 + # 3) najnowszy per-wersja. (pagan-initramfs tworzy /boot/initramfs-<ver>.img.)
127 + if [[ -e /boot/initramfs.img ]]; then printf '%s' /boot/initramfs.img; return; fi
128 + if [[ -e "/boot/initramfs-$KREL.img" ]]; then printf '%s' "/boot/initramfs-$KREL.img"; return; fi
129 + local newest="" k
130 + for k in /boot/initramfs-*.img; do
131 + [[ -e "$k" ]] || continue
132 + newest="$k" # glob sortuje leksykalnie; wystarczy „jakiś istniejący”
133 + done
134 + [[ -n "$newest" ]] && printf '%s' "$newest"
135 +}
136 +
137 +KERNEL="$(_detect_kernel)"
138 +[[ -n "$KERNEL" && -e "$KERNEL" ]] || die "Nie znalazłem jądra (--kernel PLIK). Sprawdź /boot/vmlinuz-linux."
139 +KERNEL="$(readlink -f "$KERNEL")"
140 +
141 +INITRAMFS="$(_detect_initramfs)"
142 +# Nie przerywamy, gdy brak initramfs — zbudujemy własny LIVE poniżej.
143 +
144 +# ---------- wykrycie rozmiaru / punktu pracy ----------
145 +host_arch="$(uname -m)"
146 +[[ "$host_arch" = "x86_64" || "$host_arch" = "i686" ]] || die "Obsługiwane tylko x86/x86_64 (jest: $host_arch)"
147 +
148 +# ---------- przygotowanie katalogu pracy ----------
149 +WORK="$(mktemp -d /var/tmp/pagan-mkiso.XXXXXX)" || die "nie mogę utworzyć katalogu pracy"
150 +cleanup() { [[ "${KEEP_WORK:-0}" = "1" ]] || rm -rf "$WORK"; }
151 +trap cleanup EXIT
152 +ISODIR="$WORK/iso"
153 +mkdir -p "$ISODIR/boot" "$ISODIR/live" "$ISODIR/isolinux"
154 +
155 +[[ -n "$MKISO_OUT" ]] || MKISO_OUT="$HOME/Pagan-Linux-$(date +%Y.%m.%d)-live.iso"
156 +
157 +info "jądro: $KERNEL"
158 +[[ -n "$INITRAMFS" ]] && info "initramfs: $INITRAMFS" || info "initramfs: (brak — zbuduję LIVE)"
159 +
160 +# =============================================================================
161 +# 1) LIVE-initramfs (jeśli nie podano) — busybox + własny /init (squashfs+overlay)
162 +# =============================================================================
163 +build_live_initramfs() {
164 + local idir="$WORK/initramfs" out="$WORK/initramfs.img"
165 + info "buduję LIVE-initramfs (busybox + live init)..."
166 + rm -rf "$idir"; mkdir -p "$idir"/{bin,sbin,usr/bin,usr/sbin,dev,proc,sys,run,etc,new_root,lower,overlay,mnt}
167 +
168 + # --- /init ---
169 + cat > "$idir/init" <<'INITEOF'
170 +#!/bin/sh
171 +export PATH=/usr/sbin:/usr/bin:/sbin:/bin
172 +mount -t proc proc /proc 2>/dev/null
173 +mount -t sysfs sysfs /sys 2>/dev/null
174 +mount -t devtmpfs dev /dev 2>/dev/null || mount -t tmpfs dev /dev 2>/dev/null
175 +mkdir -p /run /new_root /lower /overlay /mnt /etc
176 +
177 +LIVE=0; ROOT_DEV=""; CRYPT_DEV_ARG=""; FINDISO=""; IMG_DEV=""; _join=""
178 +set -- $(cat /proc/cmdline 2>/dev/null)
179 +for arg in "$@"; do
180 + if [ -n "$_join" ]; then
181 + case "$arg" in
182 + *=*) _join="" ;;
183 + *) case "$_join" in
184 + FINDISO) FINDISO="$FINDISO $arg" ;;
185 + IMG_DEV) IMG_DEV="$IMG_DEV $arg" ;;
186 + esac
187 + continue ;;
188 + esac
189 + fi
190 + case "$arg" in
191 + pagan.live|live) LIVE=1 ;;
192 + root=*) ROOT_DEV="${arg#root=}" ;;
193 + cryptdevice=*) CRYPT_DEV_ARG="${arg#cryptdevice=}" ;;
194 + findiso=*) FINDISO="${arg#findiso=}"; _join=FINDISO ;;
195 + iso-scan/filename=*) FINDISO="${arg#iso-scan/filename=}"; _join=FINDISO ;;
196 + img_dev=*) IMG_DEV="${arg#img_dev=}"; _join=IMG_DEV ;;
197 + esac
198 +done
199 +[ -n "$FINDISO" ] && command -v sed >/dev/null 2>&1 && FINDISO="$(printf '%s' "$FINDISO" | sed 's/\\ / /g')"
200 +
201 +SFS="live/filesystem.squashfs"
202 +
203 +_ro_mount() { # $1=dev $2=punkt
204 + case "$1" in
205 + /dev/sr*|/dev/cdrom)
206 + for t in iso9660 udf; do mount -t "$t" -o ro "$1" "$2" 2>/dev/null && return 0; done ;;
207 + *)
208 + mount -t auto -o ro "$1" "$2" 2>/dev/null && return 0
209 + for t in exfat vfat ntfs3 ntfs iso9660; do mount -t "$t" -o ro "$1" "$2" 2>/dev/null && return 0; done ;;
210 + esac
211 + return 1
212 +}
213 +_try_medium() { # $1=dev; sukces: LIVE_DEV/LIVE_ISO ustawione
214 + [ -b "$1" ] || return 1
215 + _ro_mount "$1" /mnt || return 1
216 + if [ -f "/mnt/$SFS" ]; then LIVE_DEV="$1"; LIVE_ISO=""; umount /mnt 2>/dev/null; return 0; fi
217 + if [ -n "$FINDISO" ] && [ -f "/mnt/$FINDISO" ]; then LIVE_DEV="$1"; LIVE_ISO="$FINDISO"; umount /mnt 2>/dev/null; return 0; fi
218 + umount /mnt 2>/dev/null; return 1
219 +}
220 +
221 +LIVE_DEV=""; LIVE_ISO=""
222 +if [ "$LIVE" = "1" ]; then
223 + echo "[pagan-init] Tryb LIVE"
224 + # kolejność: dm/Ventoy, CD, nośniki wymienne, na końcu img_dev
225 + for _d in $IMG_DEV /dev/sr* /dev/dm-* /dev/mapper/*; do
226 + [ -e "$_d" ] || continue
227 + _try_medium "$_d" && break
228 + done
229 + if [ -z "$LIVE_DEV" ]; then
230 + for _s in /sys/block/*; do
231 + [ "$(cat "$_s/removable" 2>/dev/null)" = "1" ] || continue
232 + _b="/dev/${_s##*/}"
233 + for _p in "$_b"?* "$_b"; do [ -e "$_p" ] && { _try_medium "$_p" && break; }; done
234 + [ -n "$LIVE_DEV" ] && break
235 + done
236 + fi
237 + [ -n "$LIVE_DEV" ] || { echo "[pagan-init] BŁĄD: nie znalazłem nośnika live. Powłoka:"; exec /bin/sh; }
238 +
239 + mkdir -p /run/media
240 + _ro_mount "$LIVE_DEV" /run/media || { echo "[pagan-init] BŁĄD: nie mogę zamontować $LIVE_DEV"; exec /bin/sh; }
241 + SFSFILE="/run/media/$SFS"
242 + if [ -n "$LIVE_ISO" ]; then
243 + # nośnik danych z plikiem ISO -> losetup + iso9660
244 + for L in /dev/loop0 /dev/loop1 /dev/loop2 /dev/loop3; do
245 + [ -e "$L" ] || mknod "$L" b 7 "${L#/dev/loop}" 2>/dev/null
246 + if losetup "$L" "/run/media/$LIVE_ISO" 2>/dev/null; then
247 + mkdir -p /run/iso
248 + mount -t iso9660 -o ro "$L" /run/iso 2>/dev/null && { SFSFILE="/run/iso/$SFS"; break; }
249 + losetup -d "$L" 2>/dev/null
250 + fi
251 + done
252 + fi
253 + [ -f "$SFSFILE" ] || { echo "[pagan-init] BŁĄD: brak $SFS na nośniku. Powłoka:"; exec /bin/sh; }
254 +
255 + # squashfs (loop) + overlay (tmpfs) + switch_root
256 + mount -t squashfs -o loop,ro "$SFSFILE" /lower 2>/dev/null || \
257 + { LOS=$(losetup -f 2>/dev/null); losetup "$LOS" "$SFSFILE" 2>/dev/null; mount -t squashfs -o ro "$LOS" /lower; }
258 + mount -t tmpfs -o mode=0755 tmpfs /overlay
259 + mkdir -p /overlay/upper /overlay/work
260 + mount -t overlay overlay -o lowerdir=/lower,upperdir=/overlay/upper,workdir=/overlay/work /new_root || \
261 + { echo "[pagan-init] BŁĄD: overlay na /new_root"; exec /bin/sh; }
262 + mount --move /proc /new_root/proc 2>/dev/null
263 + mount --move /sys /new_root/sys 2>/dev/null
264 + mount --move /dev /new_root/dev 2>/dev/null
265 + echo "[pagan-init] LIVE gotowy – switch_root"
266 + exec switch_root /new_root /sbin/init
267 +fi
268 +
269 +# ================= TRYB DYSK =================
270 +[ -n "$ROOT_DEV" ] || ROOT_DEV="/dev/sda1"
271 +_blkid_get() { blkid "$1" 2>/dev/null | tr ' ' '\n' | grep "^$2=" | head -1 | cut -d= -f2- | tr -d '"'; }
272 +_resolve_root() {
273 + local key="$1" val="$2" d
274 + 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]* /dev/dm-[0-9]* /dev/mapper/*; do
275 + [ -b "$d" ] || continue
276 + [ "$(_blkid_get "$d" "$key")" = "$val" ] && { printf '%s' "$d"; return 0; }
277 + done
278 + return 1
279 +}
280 +case "$ROOT_DEV" in
281 + UUID=*) _r="$(_resolve_root UUID "${ROOT_DEV#UUID=}")" && ROOT_DEV="$_r" ;;
282 + PARTUUID=*) _r="$(_resolve_root PARTUUID "${ROOT_DEV#PARTUUID=}")" && ROOT_DEV="$_r" ;;
283 + LABEL=*) _r="$(_resolve_root LABEL "${ROOT_DEV#LABEL=}")" && ROOT_DEV="$_r" ;;
284 +esac
285 +if command -v cryptsetup >/dev/null 2>&1 && cryptsetup isLuks "$ROOT_DEV" 2>/dev/null; then
286 + modprobe dm-crypt 2>/dev/null || true
287 + stty -echo 2>/dev/null; printf "Hasło (LUKS %s): " "$ROOT_DEV"; read -r _p; stty echo 2>/dev/null; echo
288 + printf '%s\n' "$_p" | cryptsetup open "$ROOT_DEV" cryptroot 2>/dev/null && ROOT_DEV="/dev/mapper/cryptroot"
289 + _p=""
290 +fi
291 +i=0; while [ ! -e "$ROOT_DEV" ] && [ "$i" -lt 10 ]; do sleep 1; i=$((i+1)); done
292 +mount -t auto -o rw "$ROOT_DEV" /new_root 2>/dev/null || { echo "[pagan-init] BŁĄD: nie zamontuję $ROOT_DEV"; exec /bin/sh; }
293 +ACTIVE="/new_root/.deployments/active"; NEWROOT="/new_root"
294 +if [ -L "$ACTIVE" ]; then _d=$(readlink "$ACTIVE"); [ -n "$_d" ] && NEWROOT="/new_root/.deployments/$_d"; fi
295 +mount --move /proc "$NEWROOT/proc" 2>/dev/null
296 +mount --move /sys "$NEWROOT/sys" 2>/dev/null
297 +mount --move /dev "$NEWROOT/dev" 2>/dev/null
298 +exec switch_root "$NEWROOT" /sbin/init
299 +INITEOF
300 + chmod 755 "$idir/init"
301 +
302 + # busybox + applety
303 + local BB=""
304 + for p in /usr/bin/busybox /bin/busybox /sbin/busybox; do [[ -x "$p" ]] && BB="$p" && break; done
305 + [[ -n "$BB" ]] || die "brak busybox — doinstaluj: sudo pag install busybox"
306 + cp "$BB" "$idir/bin/busybox"; chmod 755 "$idir/bin/busybox"
307 + local c
308 + for c in sh mount umount ls cat echo sleep readlink mkdir switch_root cp rm ln grep \
309 + poweroff reboot blkid mknod stty sed sort cut tr head losetup find; do
310 + ln -sf busybox "$idir/bin/$c"
311 + done
312 +
313 + # opcjonalnie cryptsetup (LUKS) + jego biblioteki
314 + local CS=""
315 + for p in /usr/sbin/cryptsetup /usr/bin/cryptsetup /sbin/cryptsetup; do [[ -x "$p" ]] && CS="$p" && break; done
316 + if [[ -n "$CS" ]]; then
317 + cp "$CS" "$idir/usr/sbin/cryptsetup"; chmod 755 "$idir/usr/sbin/cryptsetup"
318 + local lib d
319 + for lib in $(ldd "$CS" 2>/dev/null | awk '/=>[[:space:]]*\// {print $3}'); do
320 + [[ -f "$lib" ]] || continue; d="${lib#/}"; mkdir -p "$idir/${d%/*}"; cp -fL "$lib" "$idir/$d" 2>/dev/null || true
321 + done
322 + fi
323 +
324 + # moduły jądra dla DZIAŁAJĄCEGO jądra (best-effort; squashfs/overlay/iso9660/loop
325 + # są wbudowane w jądro Pagan, ale kopiujemy moduły na wypadek LUKS/USB itd.)
326 + local kver="$KREL"
327 + if [[ -d "/usr/lib/modules/$kver" ]] && command -v busybox >/dev/null 2>&1; then
328 + # świadomie NIE kopiujemy całego drzewa modułów (rozmiar) – live i tak używa
329 + # tego, co wbudowane; cryptsetup/dm-crypt doładowywane z jądra.
330 + mkdir -p "$idir/lib/modules/$kver"
331 + for m in kernel/drivers/md/dm-crypt.ko* kernel/crypto/*/*.ko* kernel/fs/squashfs/squashfs.ko*; do
332 + [[ -e "/usr/lib/modules/$kver/$m" ]] || continue
333 + mkdir -p "$idir/lib/modules/$kver/$(dirname "$m")"
334 + cp -f "/usr/lib/modules/$kver/$m" "$idir/lib/modules/$kver/$m" 2>/dev/null || true
335 + done
336 + fi
337 +
338 + ( cd "$idir" && find . | cpio -oH newc 2>/dev/null | gzip -1 ) > "$out" || die "budowa initramfs nieudana"
339 + [[ -s "$out" ]] || die "initramfs pusty"
340 + INITRAMFS="$out"
341 + ok "LIVE-initramfs: $out ($(du -h "$out" | cut -f1))"
342 +}
343 +
344 +if [[ -z "$INITRAMFS" || ! -e "$INITRAMFS" ]]; then
345 + build_live_initramfs
346 +fi
347 +
348 +# =============================================================================
349 +# 2) squashfs uruchomionego systemu
350 +# =============================================================================
351 +info "buduję squashfs systemu (to trwa)…"
352 +SQUASHFS="$ISODIR/live/filesystem.squashfs"
353 +EXCLUDES="$WORK/excludes"
354 +cat > "$EXCLUDES" <<'EXC'
355 +/proc/*
356 +/sys/*
357 +/dev/*
358 +/run/*
359 +/tmp/*
360 +/var/tmp/*
361 +/var/cache/*
362 +/var/lib/pagan-sync/cache/*
363 +/mnt/*
364 +/media/*
365 +/swapfile
366 +/lost+found
367 +/.pag_staging/*
368 +/boot/initramfs-*.img
369 +/usr/src/kernel
370 +EXC
371 +# Wyklucz katalog roboczy oraz cel ISO, by nie zamrozić samego procesu budowy.
372 +printf '%s/*\n' "$WORK" >> "$EXCLUDES"
373 +if [[ -n "$MKISO_OUT" ]]; then
374 + _out_abs="$(readlink -f "$MKISO_OUT" 2>/dev/null || printf '%s' "$MKISO_OUT")"
375 + [[ "$_out_abs" == /* ]] && printf '%s\n' "$_out_abs" >> "$EXCLUDES"
376 +fi
377 +
378 +JOBS="${MKISO_JOBS:-$(nproc)}"
379 +mksquashfs / "$SQUASHFS" -wildcards -ef "$EXCLUDES" -noappend -comp "${MKISO_COMP%% *}" \
380 + ${MKISO_COMP#"${MKISO_COMP%% *}"} -processors "$JOBS" || die "mksquashfs nie powiódł się"
381 +ok "squashfs: $(du -h "$SQUASHFS" | cut -f1)"
382 +
383 +# =============================================================================
384 +# 3) drzewo ISO: jądro + initramfs + loading
385 +# =============================================================================
386 +cp -fL "$KERNEL" "$ISODIR/boot/vmlinuz-linux"
387 +cp -fL "$INITRAMFS" "$ISODIR/boot/initramfs.img"
388 +
389 +# =============================================================================
390 +# 4) BIOS (isolinux)
391 +# =============================================================================
392 +ISO_MBR=""
393 +if [[ $MKISO_DO_BIOS -eq 1 ]]; then
394 + ISO_BIN="$(_find_syslinux isolinux.bin || true)"
395 + LDLINUX="$(_find_syslinux ldlinux.c32 || true)"
396 + MBR_BIN="$(_find_syslinux isohdpfx.bin || true)"
397 + if [[ -n "$ISO_BIN" && -n "$MBR_BIN" ]]; then
398 + cp -f "$ISO_BIN" "$ISODIR/isolinux/isolinux.bin"
399 + [[ -n "$LDLINUX" ]] && cp -f "$LDLINUX" "$ISODIR/isolinux/ldlinux.c32"
400 + for m in libcom32.c32 libutil.c32 menu.c32; do
401 + mf="$(_find_syslinux "$m" || true)"; [[ -n "$mf" ]] && cp -f "$mf" "$ISODIR/isolinux/$m"
402 + done
403 + cat > "$ISODIR/isolinux/isolinux.cfg" <<EOF
404 +DEFAULT pagan
405 +TIMEOUT 100
406 +PROMPT 0
407 +
408 +LABEL pagan
409 + MENU LABEL ^Pagan Linux Live
410 + KERNEL /boot/vmlinuz-linux
411 + APPEND initrd=/boot/initramfs.img pagan.live rw quiet splash
412 +
413 +LABEL pagan-fallback
414 + MENU LABEL Pagan Linux (tryb awaryjny)
415 + KERNEL /boot/vmlinuz-linux
416 + APPEND initrd=/boot/initramfs.img pagan.live rw noacpi nomodeset
417 +
418 +LABEL pagan-debug
419 + MENU LABEL Pagan Linux (debug – powłoka)
420 + KERNEL /boot/vmlinuz-linux
421 + APPEND initrd=/boot/initramfs.img pagan.live break
422 +EOF
423 + ISO_MBR="$MBR_BIN"
424 + else
425 + warn "brak isolinux.bin/isohdpfx.bin – pomijam boot BIOS"
426 + fi
427 +fi
428 +
429 +# =============================================================================
430 +# 5) UEFI (GRUB) — efiboot.img
431 +# =============================================================================
432 +EFI_IMG=""
433 +if [[ $MKISO_DO_UEFI -eq 1 ]]; then
434 + if [[ -d /usr/lib/grub/x86_64-efi ]] && _have grub-mkstandalone && _have mkfs.fat && _have mcopy; then
435 + info "buduję EFI (GRUB standalone)..."
436 + mkdir -p "$ISODIR/boot/grub" "$WORK/efi/EFI/BOOT"
437 + cat > "$WORK/grub-efi.cfg" <<'GEOF'
438 +set default=0
439 +set timeout=10
440 +menuentry "Pagan Linux (LIVE)" {
441 + linux /boot/vmlinuz-linux pagan.live rw quiet splash
442 + initrd /boot/initramfs.img
443 +}
444 +menuentry "Pagan Linux (verbose)" {
445 + linux /boot/vmlinuz-linux pagan.live rw
446 + initrd /boot/initramfs.img
447 +}
448 +GEOF
449 + if grub-mkstandalone -O x86_64-efi -o "$WORK/efi/EFI/BOOT/BOOTX64.EFI" \
450 + --modules="iso9660 part_gpt part_msdos normal linux echo" \
451 + "boot/grub/grub.cfg=$WORK/grub-efi.cfg" >/dev/null 2>&1; then
452 + dd if=/dev/zero of="$WORK/efi.img" bs=1M count=8 status=none
453 + mkfs.fat -F12 "$WORK/efi.img" >/dev/null 2>&1
454 + mcopy -s -i "$WORK/efi.img" "$WORK/efi/EFI" ::/ 2>/dev/null || mcopy -s -i "$WORK/efi.img" "$WORK/efi/EFI" ::
455 + EFI_IMG="$WORK/efi.img"
456 + else
457 + warn "grub-mkstandalone nie powiódł się – pomijam UEFI"
458 + fi
459 + else
460 + warn "brak narzędzi GRUB/EFI (grub-mkstandalone, mkfs.fat, mtools) – pomijam boot UEFI"
461 + fi
462 +fi
463 +
464 +# =============================================================================
465 +# 6) xorriso — hybrydowe ISO
466 +# =============================================================================
467 +info "buduję ISO (xorriso)…"
468 +XORRISO_ARGS=(-as mkisofs -iso-level 3 -full-iso9660-filenames -joliet -joliet-long
469 + -rational-rock -volid "$MKISO_LABEL")
470 +if [[ -n "$ISO_MBR" ]]; then
471 + XORRISO_ARGS+=(-eltorito-boot isolinux/isolinux.bin -no-emul-boot -boot-load-size 4
472 + -boot-info-table -isohybrid-mbr "$ISO_MBR")
473 +fi
474 +if [[ -n "$EFI_IMG" ]]; then
475 + cp -f "$EFI_IMG" "$ISODIR/boot/efiboot.img"
476 + XORRISO_ARGS+=(-eltorito-alt-boot -e boot/efiboot.img -no-emul-boot -isohybrid-gpt-basdat)
477 +fi
478 +XORRISO_ARGS+=(-o "$MKISO_OUT" "$ISODIR")
479 +
480 +xorriso "${XORRISO_ARGS[@]}" >/dev/null 2>&1 || die "xorriso nie powiódł się"
481 +[[ -s "$MKISO_OUT" ]] || die "ISO nie powstało"
482 +
483 +ok "ISO gotowe: $MKISO_OUT ($(du -h "$MKISO_OUT" | cut -f1))"
484 +[[ -n "$ISO_MBR" ]] && info " boot: BIOS (isolinux) hybrydowy"
485 +[[ -n "$EFI_IMG" ]] && info " boot: UEFI (GRUB)"
486 +info " Wypal/wgraj: sudo dd if='$MKISO_OUT' of=/dev/sdX bs=4M status=progress oflag=sync"
487 +exit 0
0 488 new file mode 100644
@@ -0,0 +1,12 @@
1 +[Desktop Entry]
2 +Type=Application
3 +Version=1.0
4 +Name=Pagan ISO Maker
5 +Name[pl]=Generator ISO Pagan
6 +Comment=Freeze the running PaganOS into a bootable ISO
7 +Comment[pl]=Zamroź uruchomiony PaganOS w bootowalne ISO
8 +Exec=pkexec pagan-mkiso --gui
9 +Icon=application-x-cd-image
10 +Terminal=false
11 +Categories=System;Settings;Utility;
12 +Keywords=iso;live;snapshot;mkiso;