#!/usr/bin/env bash # This wrapper script dynamically adapts the archinstall configuration to the target machine. # # The target disk MUST be provided as a parameter (e.g. /dev/nvme0n1 or a # /dev/disk/by-id/* path) # # This avoids hardcoding device names (e.g. /dev/sda, /dev/nvme0n1) and disk sizes, # making the same archinstall config usable across multiple devices. # Usage: # ./patch-disk-config.sh /dev/nvme0n1 set -euo pipefail CFG_IN="user_config_base.json" CFG_OUT="user_config.json" MIN_GIB=80 die() { echo "Error: $*" >&2 exit 1 } if [[ $# -ne 1 ]]; then echo "Usage: $0 " exit 1 fi DISK="$1" # Basic validation [[ -b "$DISK" ]] || die "'$DISK' is not a block device." # Refuse removable devices [[ "$(lsblk -dn -o RM "$DISK")" == "0" ]] || die "'$DISK' is removable. Refusing." # Minimum size check (bytes) SIZE_BYTES="$(lsblk -dn -o SIZE -b "$DISK")" ((SIZE_BYTES >= MIN_GIB * 1024 * 1024 * 1024)) || die "'$DISK' is smaller than ${MIN_GIB}GiB." read -r BOOT_SIZE_UNIT BOOT_SIZE_VALUE ROOT_START_BYTES ROOT_SIZE_BYTES < <( python3 - "$DISK" "$SIZE_BYTES" "$CFG_IN" "$CFG_OUT" <<'PY' import json, sys disk = sys.argv[1] size_bytes = int(sys.argv[2]) cfg_in = sys.argv[3] cfg_out = sys.argv[4] with open(cfg_in, "r", encoding="utf-8") as f: cfg = json.load(f) # Sanity: ensure expected JSON structure exists try: dm0 = cfg["disk_config"]["device_modifications"][0] parts = dm0["partitions"] if not (isinstance(parts, list) and len(parts) >= 2): raise TypeError("partitions not length >= 2") p0 = parts[0] p1 = parts[1] root_start = p1["start"]["value"] if isinstance(root_start, float) and root_start.is_integer(): root_start = int(root_start) if not isinstance(root_start, int): raise TypeError(f"start.value not int: {root_start!r}") except Exception as e: raise SystemExit(f"Unexpected JSON structure in {cfg_in}: {e}") # Compute "root = remaining space" in bytes based on the configured root partition start offset root_size = size_bytes - root_start if root_size <= 0: raise SystemExit("Computed root size is not positive.") # Patch: # - set target disk # - set root partition size to fill to end of disk (bytes) dm0["device"] = disk p1["size"]["unit"] = "B" p1["size"]["value"] = int(root_size) with open(cfg_out, "w", encoding="utf-8") as f: json.dump(cfg, f, indent=4) f.write("\n") # Report boot = p0["size"] print(boot["unit"], boot["value"], p1["start"]["value"], p1["size"]["value"]) PY ) echo "Prepared archinstall config: $CFG_OUT" echo " Disk : $DISK" echo " Disk bytes : $SIZE_BYTES" echo " /boot size : ${BOOT_SIZE_VALUE}${BOOT_SIZE_UNIT}" echo " Root start : $ROOT_START_BYTES B" echo " Root size : $ROOT_SIZE_BYTES B (fills remaining space)"