manjaro-arm/manjaro-arm-installer.patch

118 lines
4.9 KiB
Diff

--- /home/claude/work/arm-installer/manjaro-arm/manjaro-arm-installer 2026-04-25 00:04:54.000000000 +0000
+++ /home/claude/work/manjaro-arm-installer-patched 2026-04-25 00:08:21.126014412 +0000
@@ -48,6 +48,43 @@
HOSTNAME=""
CRYPT=""
+# ─── image-output mode (added) ────────────────────────────────────────────────
+# When IMG_OUTPUT is set, the installer writes to a sparse image file via
+# losetup -fP instead of asking the user to pick a block device.
+#
+# Set via environment OR via --output-image / -o flag, e.g.:
+# sudo IMG_OUTPUT=manjaro.img IMG_SIZE=8G ./manjaro-arm-installer
+# sudo ./manjaro-arm-installer --output-image manjaro.img --image-size 8G
+#
+# Defaults: IMG_SIZE=8G, IMG_COMPRESS=0
+IMG_OUTPUT="${IMG_OUTPUT:-}"
+IMG_SIZE="${IMG_SIZE:-8G}"
+IMG_COMPRESS="${IMG_COMPRESS:-0}"
+IMG_LOOPDEV=""
+
+# parse our own flags out of $@ before the script's branch-detection logic
+# (which only inspects $1) sees them
+_filtered_args=()
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ -o|--output-image) IMG_OUTPUT="$2"; shift 2 ;;
+ --image-size) IMG_SIZE="$2"; shift 2 ;;
+ --compress) IMG_COMPRESS=1; shift ;;
+ *) _filtered_args+=("$1"); shift ;;
+ esac
+done
+set -- "${_filtered_args[@]}"
+
+# cleanup hook — detaches the loop device on exit/interrupt so we don't leak
+_img_cleanup() {
+ if [[ -n "$IMG_LOOPDEV" ]] && losetup "$IMG_LOOPDEV" &>/dev/null; then
+ sync
+ losetup -d "$IMG_LOOPDEV" 2>/dev/null || true
+ fi
+}
+trap _img_cleanup EXIT INT TERM
+# ─── end image-output mode ────────────────────────────────────────────────────
+
# check if root
if [ "$EUID" -ne 0 ]; then
echo "*******************************************************************************************"
@@ -951,6 +988,25 @@
then
# simple command to put the results of lsblk (just the names of the devices) into an array and make that array populate the options
+ if [[ -n "$IMG_OUTPUT" ]]; then
+ # ─── image-output branch (added) ──────────────────────────────────────
+ msg "Image-output mode: writing to $IMG_OUTPUT (size $IMG_SIZE)"
+ if [[ -e "$IMG_OUTPUT" ]]; then
+ info "removing existing $IMG_OUTPUT"
+ rm -f "$IMG_OUTPUT" || { msg "could not remove existing image"; exit 1; }
+ fi
+ # create sparse file
+ truncate -s "$IMG_SIZE" "$IMG_OUTPUT" \
+ || { msg "truncate failed"; exit 1; }
+ # losetup with -P enables partition device nodes (loopNp1, loopNp2)
+ IMG_LOOPDEV=$(losetup -fP --show "$IMG_OUTPUT") \
+ || { msg "losetup failed"; exit 1; }
+ info "attached as $IMG_LOOPDEV"
+ SDCARD="$IMG_LOOPDEV"
+ DEV_NAME="${IMG_LOOPDEV#/dev/}"
+ SDTYP="${SDCARD:5:2}" # will be "lo" — handled below
+ # ─── end image-output branch ──────────────────────────────────────────
+ else
let i=0
W=()
while read -r line; do
@@ -966,6 +1022,7 @@
DEV_NAME=$SDCARD
SDCARD=/dev/$SDCARD
SDTYP=${SDCARD:5:2}
+ fi
else
clear
exit 1
@@ -973,7 +1030,8 @@
if [[ "$SDTYP" = "sd" ]]; then
SDDEV=""
-elif [[ "$SDTYP" = "mm" || "$SDTYP" = "nv" ]]; then
+elif [[ "$SDTYP" = "mm" || "$SDTYP" = "nv" || "$SDTYP" = "lo" ]]; then
+ # loop devices use /dev/loopNp1 partition naming, same as mmcblk/nvme
SDDEV="p"
else
clear
@@ -1148,3 +1206,26 @@
cleanup
show_elapsed_time "${FUNCNAME}" "${timer_start}"
sync
+
+# ─── image-output finalization (added) ────────────────────────────────────────
+if [[ -n "$IMG_OUTPUT" ]]; then
+ msg "Detaching loop device $IMG_LOOPDEV"
+ sync
+ losetup -d "$IMG_LOOPDEV" 2>/dev/null || true
+ IMG_LOOPDEV=""
+
+ if [[ "$IMG_COMPRESS" = "1" ]]; then
+ msg "Compressing $IMG_OUTPUT (this may take a while)"
+ if command -v xz &>/dev/null; then
+ xz -T0 -v "$IMG_OUTPUT"
+ msg "Compressed: ${IMG_OUTPUT}.xz"
+ elif command -v zstd &>/dev/null; then
+ zstd -T0 -19 --rm "$IMG_OUTPUT" -o "${IMG_OUTPUT}.zst"
+ msg "Compressed: ${IMG_OUTPUT}.zst"
+ else
+ info "Neither xz nor zstd found — leaving image uncompressed"
+ fi
+ fi
+ msg "Image build complete: ${IMG_OUTPUT}$([[ "$IMG_COMPRESS" = "1" ]] && echo ".xz")"
+fi
+# ─── end image-output finalization ────────────────────────────────────────────