100 lines
2.7 KiB
Bash
Executable File
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)"
|