Files
system-spec/installer/patch-disk-config.sh

100 lines
2.7 KiB
Bash
Executable File

#!/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 <disk-device>"
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)"