Refactor Debian 13 Trixie Packer templates for LUKS support

- Removed obsolete variable files: variables-common.pkr.hcl and variables.pkr.hcl.
- Updated debian-trixie.pkr.hcl to include local values for LUKS configuration.
- Modified boot command to include LUKS arguments based on the enable_luks variable.
- Enhanced initial-setup.sh to support LUKS detection and resizing.
- Replaced preseed.cfg with preseed.cfg.pkrtpl for dynamic LUKS configuration.
- Added enable_luks variable to control LUKS encryption during image build.
- Introduced luks.pkrvars.hcl for LUKS-specific variable settings.
- Updated mise.toml to support new variable file argument for Packer builds.
This commit is contained in:
Philip Henning 2026-05-11 19:13:11 +02:00
parent e57f2d977b
commit eded7180dc
20 changed files with 281 additions and 2445 deletions

View file

@ -5,12 +5,18 @@ IFS=$'\n\t'
SCRIPT_NAME="$(basename "$0")"
TASK_INDEX=0
TASK_TOTAL=0
TEMP_FILES=()
STORAGE_DETECTED=0
STORAGE_MODE=""
ROOT_SOURCE=""
VG_NAME=""
LV_NAME=""
PV_NAME=""
LUKS_DEV=""
LUKS_NAME=""
LUKS_PART=""
RESIZE_PART=""
DISK_DEV=""
PART_NUM=""
@ -56,6 +62,18 @@ section() {
echo "${DIM}------------------------------------------------------------${RESET}"
}
add_temp_file() {
TEMP_FILES+=("$1")
}
cleanup() {
local file
for file in "${TEMP_FILES[@]:-}"; do
[ -f "$file" ] && rm -f "$file"
done
}
trap cleanup EXIT
ensure_tty() {
if [ ! -t 0 ] || [ ! -t 1 ]; then
die "This setup must run interactively in a TTY."
@ -227,6 +245,29 @@ infer_disk_part_from_partition() {
return 1
}
resolve_luks_backing_partition() {
local mapper_path="$1"
local mapper_name="$2"
local mapper_name_alt="$3"
local part=""
if command -v cryptsetup >/dev/null 2>&1; then
part="$(cryptsetup status "$mapper_name" 2>/dev/null | awk '/^[[:space:]]*device:/ {print $2; exit}' | xargs || true)"
if [ -z "$part" ] && [ -n "$mapper_name_alt" ] && [ "$mapper_name_alt" != "$mapper_name" ]; then
part="$(cryptsetup status "$mapper_name_alt" 2>/dev/null | awk '/^[[:space:]]*device:/ {print $2; exit}' | xargs || true)"
fi
if [ -z "$part" ]; then
part="$(cryptsetup status "$mapper_path" 2>/dev/null | awk '/^[[:space:]]*device:/ {print $2; exit}' | xargs || true)"
fi
fi
if [ -z "$part" ]; then
part="$(lsblk -nro PATH,TYPE -s "$mapper_path" 2>/dev/null | awk '$2=="part" {print $1; exit}' | xargs || true)"
fi
printf '%s' "$part"
}
refresh_partition_table() {
local disk="$1"
if command -v partprobe >/dev/null 2>&1; then
@ -324,8 +365,20 @@ show_disk_layout() {
fi
}
resize_open_luks_mapping() {
if [ -n "$LUKS_NAME" ] && cryptsetup resize "$LUKS_NAME" >/dev/null 2>&1; then
return 0
fi
cryptsetup resize "$LUKS_DEV" >/dev/null 2>&1
}
detect_storage_stack() {
STORAGE_DETECTED=0
STORAGE_MODE=""
LUKS_DEV=""
LUKS_NAME=""
LUKS_PART=""
RESIZE_PART=""
DISK_DEV=""
PART_NUM=""
@ -358,10 +411,29 @@ detect_storage_stack() {
return 1
fi
local pv_type
pv_type="$(lsblk_attr "$PV_NAME" TYPE)"
if [ "$pv_type" = "crypt" ]; then
STORAGE_MODE="luks_lvm"
LUKS_DEV="$PV_NAME"
LUKS_NAME="$(basename "$LUKS_DEV")"
local mapper_name_alt
mapper_name_alt="$(lsblk_attr "$LUKS_DEV" NAME)"
LUKS_PART="$(resolve_luks_backing_partition "$LUKS_DEV" "$LUKS_NAME" "$mapper_name_alt")"
if [ -z "$LUKS_PART" ] || [ ! -b "$LUKS_PART" ]; then
log_warn "Unable to detect LUKS backing partition."
return 1
fi
RESIZE_PART="$LUKS_PART"
else
STORAGE_MODE="lvm"
RESIZE_PART="$PV_NAME"
fi
local inferred
local inferred_disk=""
local inferred_part=""
inferred="$(infer_disk_part_from_partition "$PV_NAME" || true)"
inferred="$(infer_disk_part_from_partition "$RESIZE_PART" || true)"
if [ -n "$inferred" ]; then
inferred_disk="$(printf '%s\n' "$inferred" | sed -n '1p')"
inferred_part="$(printf '%s\n' "$inferred" | sed -n '2p')"
@ -372,21 +444,21 @@ detect_storage_stack() {
if [ -z "$DISK_DEV" ]; then
local disk_parent
disk_parent="$(lsblk_attr "$PV_NAME" PKNAME)"
disk_parent="$(lsblk_attr "$RESIZE_PART" PKNAME)"
if [ -n "$disk_parent" ]; then
DISK_DEV="/dev/${disk_parent}"
else
DISK_DEV="$(lsblk -nro PATH,TYPE -s "$PV_NAME" 2>/dev/null | awk '$2=="disk" {print $1; exit}' | xargs || true)"
DISK_DEV="$(lsblk -nro PATH,TYPE -s "$RESIZE_PART" 2>/dev/null | awk '$2=="disk" {print $1; exit}' | xargs || true)"
fi
fi
if [ -z "$PART_NUM" ]; then
PART_NUM="$(lsblk_attr "$PV_NAME" PARTNUM)"
PART_NUM="$(lsblk_attr "$RESIZE_PART" PARTNUM)"
fi
if [ -z "$DISK_DEV" ] || [ ! -b "$DISK_DEV" ] || [ -z "$PART_NUM" ] || ! [[ "$PART_NUM" =~ ^[0-9]+$ ]]; then
log_warn "Unable to detect disk device or partition number."
log_warn "Detected values: PV_NAME=${PV_NAME:-<empty>} DISK_DEV=${DISK_DEV:-<empty>} PART_NUM=${PART_NUM:-<empty>}"
log_warn "Detected values: RESIZE_PART=${RESIZE_PART:-<empty>} DISK_DEV=${DISK_DEV:-<empty>} PART_NUM=${PART_NUM:-<empty>}"
return 1
fi
@ -394,7 +466,7 @@ detect_storage_stack() {
return 0
}
resize_lvm() {
resize_lvm_storage() {
if [ "$STORAGE_DETECTED" -ne 1 ]; then
log_warn "Storage layout not detected; skipping resize."
return 0
@ -402,12 +474,21 @@ resize_lvm() {
require_cmd parted || return 0
require_cmd blockdev || return 0
if [ "$STORAGE_MODE" = "luks_lvm" ]; then
require_cmd cryptsetup || return 0
fi
require_cmd pvresize || return 0
require_cmd lvextend || return 0
log_info "Root LV: ${ROOT_SOURCE}"
log_info "VG: ${VG_NAME} | LV: ${LV_NAME}"
log_info "Storage mode: ${STORAGE_MODE}"
log_info "LVM PV: ${PV_NAME}"
if [ "$STORAGE_MODE" = "luks_lvm" ]; then
log_info "LUKS device: ${LUKS_DEV}"
log_info "LUKS partition: ${LUKS_PART}"
[ -n "$LUKS_NAME" ] && log_info "LUKS mapper name: ${LUKS_NAME}"
fi
log_info "Disk: ${DISK_DEV} | Partition number: ${PART_NUM}"
if ! repair_gpt_backup_header "$DISK_DEV"; then
@ -422,7 +503,7 @@ resize_lvm() {
local part_size_before
local free_bytes
part_size_before="$(blockdev --getsize64 "$PV_NAME" 2>/dev/null || echo 0)"
part_size_before="$(blockdev --getsize64 "$RESIZE_PART" 2>/dev/null || echo 0)"
free_bytes="$(get_trailing_free_bytes "$DISK_DEV" "$PART_NUM" || true)"
if [ -z "$free_bytes" ]; then
log_warn "Unable to determine free disk space."
@ -436,22 +517,36 @@ resize_lvm() {
log_info "Unallocated space available: $(human_bytes "$free_bytes")"
show_disk_layout "$DISK_DEV"
if ! confirm "Extend partition, VG, and root LV now?" "yes"; then
local resize_prompt
if [ "$STORAGE_MODE" = "luks_lvm" ]; then
resize_prompt="Extend partition, LUKS device, VG, and root LV now?"
else
resize_prompt="Extend partition, VG, and root LV now?"
fi
if ! confirm "$resize_prompt" "yes"; then
log_warn "Skipped resize."
return 0
fi
log_info "Extending partition ${PV_NAME} to 100% of disk..."
log_info "Extending partition ${RESIZE_PART} to 100% of disk..."
if ! parted -s "$DISK_DEV" resizepart "$PART_NUM" 100%; then
log_warn "Partition resize failed."
return 0
fi
refresh_partition_table "$DISK_DEV"
if [ "$part_size_before" -gt 0 ] && ! wait_for_partition_growth "$PV_NAME" "$part_size_before"; then
if [ "$part_size_before" -gt 0 ] && ! wait_for_partition_growth "$RESIZE_PART" "$part_size_before"; then
log_warn "Kernel has not reported the new partition size yet; continuing anyway."
fi
if [ "$STORAGE_MODE" = "luks_lvm" ]; then
log_info "Resizing LUKS device..."
if ! resize_open_luks_mapping; then
log_warn "LUKS resize failed."
return 0
fi
fi
log_info "Resizing LVM physical volume..."
if ! pvresize "$PV_NAME"; then
log_warn "pvresize failed."
@ -549,6 +644,62 @@ setup_swap() {
log_ok "Swap enabled."
}
change_luks_passphrase() {
if [ "$STORAGE_MODE" != "luks_lvm" ]; then
log_info "Root storage is not LUKS-backed; skipping LUKS passphrase change."
return 0
fi
if [ -z "$LUKS_PART" ] || [ ! -e "$LUKS_PART" ]; then
log_warn "LUKS partition not found; skipping."
return 0
fi
require_cmd cryptsetup || return 0
if ! confirm "Change LUKS passphrase in slot 0 now?" "yes"; then
log_warn "Skipped LUKS passphrase change."
return 0
fi
local old_pass
local new_pass
local tmp_old
local tmp_new
old_pass="$(prompt_secret "Enter current LUKS passphrase")"
new_pass="$(prompt_secret_confirm "Enter new LUKS passphrase" "Confirm new LUKS passphrase")"
tmp_old="$(mktemp)"
tmp_new="$(mktemp)"
add_temp_file "$tmp_old"
add_temp_file "$tmp_new"
printf '%s' "$old_pass" >"$tmp_old"
printf '%s' "$new_pass" >"$tmp_new"
log_info "Updating LUKS passphrase in slot 0..."
if cryptsetup luksChangeKey --batch-mode --key-slot 0 --key-file "$tmp_old" "$LUKS_PART" "$tmp_new"; then
log_ok "LUKS passphrase updated."
else
log_warn "Failed to update LUKS passphrase."
fi
}
setup_clevis() {
if [ "$STORAGE_MODE" != "luks_lvm" ]; then
log_info "Root storage is not LUKS-backed; skipping Clevis/Tang setup."
return 0
fi
log_info "Clevis/Tang setup is not implemented in this template yet."
if confirm "Would you like to configure Clevis with a Tang server now? (will be skipped)" "no"; then
local tang
tang="$(prompt_input "Tang server URL" "http://tang.int.r3w.de")"
log_warn "Clevis setup for ${tang} is not implemented yet. Skipping."
else
log_info "Skipping Clevis setup."
fi
}
setup_tailscale() {
if ! require_cmd tailscale; then
log_warn "Tailscale is not installed; skipping."
@ -639,7 +790,7 @@ main() {
welcome
if detect_storage_stack; then
log_ok "Detected LVM storage layout."
log_ok "Detected ${STORAGE_MODE} storage layout."
else
log_warn "Storage layout detection incomplete; some steps may be skipped."
fi
@ -647,8 +798,12 @@ main() {
TASK_TITLES=()
TASK_FUNCS=()
add_task "Resize LVM (if free space exists)" resize_lvm
add_task "Resize LVM storage (if free space exists)" resize_lvm_storage
add_task "Configure swap file" setup_swap
if [ "$STORAGE_MODE" = "luks_lvm" ]; then
add_task "Change LUKS passphrase (slot 0)" change_luks_passphrase
add_task "Clevis/Tang setup (placeholder)" setup_clevis
fi
add_task "Configure Tailscale" setup_tailscale
add_task "Configure CrowdSec" setup_crowdsec
add_task "Reboot recommendation" prompt_reboot