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;