fix: address Copilot review — validation, error handling, MAC case

- Add ValidateSet('8','9','all') to dev.ps1 -Version parameter
- Fix Shell warning to reference $DevContainer not $InfraContainer
- Fix Skip-IfNoNodeB to check $PasswordB not $Password
- Pass PVE_TARGET_NODE to wait-for-pve.sh instead of auto-discovering
- Add error default cases to all pve_* helper functions
- Lowercase MAC addresses for answer server matching
- Create answer file paths before terraform destroy in cleanup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Clint Branham
2026-03-25 15:50:07 -05:00
parent 7cb64811b7
commit 7ffc57e16f
4 changed files with 21 additions and 14 deletions
@@ -81,7 +81,7 @@ function script:Skip-IfNoOva {
function script:Skip-IfNoNodeB {
if (Skip-IfNoTarget) { return $true }
if (-not $script:HostB -or -not $script:Password) {
if (-not $script:HostB -or -not $script:PasswordB) {
Set-ItResult -Skipped -Because 'Multi-node env vars not set (PVETEST_HOST_B, PVETEST_PASSWORD)'
return $true
}
+2 -1
View File
@@ -103,6 +103,7 @@ param(
[string[]] $Tests,
[Alias('PveVersion')]
[ValidateSet('8', '9', 'all')]
[string] $Version = 'all',
[string] $DockerHost,
@@ -214,7 +215,7 @@ if ($Rebuild) {
if ($Shell) {
if ($DockerHost) {
Write-Warning "Interactive shell over remote Docker is not supported. Use: ssh $DockerHost 'docker exec -it $InfraContainer pwsh -NoProfile'"
Write-Warning "Interactive shell over remote Docker is not supported. Use: ssh $DockerHost 'docker exec -it $DevContainer pwsh -NoProfile'"
return
}
Start-DevContainer
@@ -64,6 +64,7 @@ pve_iso() {
case "$ver" in
9) echo "${PVE9_ISO:-proxmox-ve_9.1-1.iso}" ;;
8) echo "${PVE8_ISO:-proxmox-ve_8.4-1.iso}" ;;
*) echo "ERROR: unknown PVE version '$ver'" >&2; exit 1 ;;
esac
}
@@ -71,6 +72,7 @@ pve_vmid() {
case "$1" in
9a) echo "${PVE9A_VMID:-99091}" ;; 9b) echo "${PVE9B_VMID:-99092}" ;;
8a) echo "${PVE8A_VMID:-99081}" ;; 8b) echo "${PVE8B_VMID:-99082}" ;;
*) echo "ERROR: unknown node '$1'" >&2; exit 1 ;;
esac
}
@@ -78,6 +80,7 @@ pve_vmname() {
case "$1" in
9a) echo "pve-test-9a" ;; 9b) echo "pve-test-9b" ;;
8a) echo "pve-test-8a" ;; 8b) echo "pve-test-8b" ;;
*) echo "ERROR: unknown node '$1'" >&2; exit 1 ;;
esac
}
@@ -85,15 +88,16 @@ pve_fqdn() {
case "$1" in
9a) echo "pve9a.test.local" ;; 9b) echo "pve9b.test.local" ;;
8a) echo "pve8a.test.local" ;; 8b) echo "pve8b.test.local" ;;
*) echo "ERROR: unknown node '$1'" >&2; exit 1 ;;
esac
}
# Deterministic MAC addresses for each node.
# Scheme: AA:BB:CC:00:<version-hex>:<node-hex>
# Deterministic MAC addresses for each node (lowercase for answer server matching).
pve_mac() {
case "$1" in
9a) echo "AA:BB:CC:00:09:1A" ;; 9b) echo "AA:BB:CC:00:09:1B" ;;
8a) echo "AA:BB:CC:00:08:1A" ;; 8b) echo "AA:BB:CC:00:08:1B" ;;
9a) echo "aa:bb:cc:00:09:1a" ;; 9b) echo "aa:bb:cc:00:09:1b" ;;
8a) echo "aa:bb:cc:00:08:1a" ;; 8b) echo "aa:bb:cc:00:08:1b" ;;
*) echo "ERROR: unknown node '$1'" >&2; exit 1 ;;
esac
}
@@ -299,7 +303,7 @@ cmd_provision() {
log "Waiting for $node to boot..."
local output
output=$(bash "$SCRIPT_DIR/wait-for-pve.sh" \
"$PVE_ENDPOINT" "$PVE_API_TOKEN" \
"$PVE_ENDPOINT" "$PVE_API_TOKEN" "$PVE_TARGET_NODE" \
"$(pve_vmid "$node")" "$PVE_PASSWORD" 900)
local ip node_name
ip=$(echo "$output" | grep "^IP=" | cut -d= -f2)
@@ -552,6 +556,10 @@ cmd_cleanup() {
(cd "$INFRA_DIR" && terraform init -input=false 2>/dev/null)
# Ensure answer file paths exist (terraform destroy validates host_path mounts)
mkdir -p "$WORK_DIR/answers"
touch "$WORK_DIR/default-answer.toml"
# Build -target flags when destroying a subset
local tf_targets=""
if [[ "$requested" != "all" ]]; then
+5 -7
View File
@@ -2,7 +2,7 @@
# Wait for a fresh nested PVE instance to boot, discover its IP via the QEMU guest agent,
# then wait for the PVE API to become responsive.
#
# Usage: wait-for-pve.sh <parent-pve-endpoint> <parent-api-token> <vm-id> <root-password> [max-wait-seconds]
# Usage: wait-for-pve.sh <parent-pve-endpoint> <parent-api-token> <parent-node> <vm-id> <root-password> [max-wait-seconds]
# Outputs:
# IP=<discovered-ip>
# NODE=<pve-hostname>
@@ -10,14 +10,12 @@ set -euo pipefail
PARENT_ENDPOINT="${1%/}"
PARENT_TOKEN="$2"
VM_ID="$3"
ROOT_PASSWORD="$4"
MAX_WAIT="${5:-600}"
PARENT_NODE="$3"
VM_ID="$4"
ROOT_PASSWORD="$5"
MAX_WAIT="${6:-600}"
INTERVAL=10
PARENT_API="${PARENT_ENDPOINT}/api2/json"
NODES_JSON=$(curl -sk -H "Authorization: PVEAPIToken=${PARENT_TOKEN}" \
"${PARENT_API}/nodes")
PARENT_NODE=$(echo "$NODES_JSON" | python3 -c "import json,sys; print(json.load(sys.stdin)['data'][0]['node'])")
# --- Phase 1: Discover IP via QEMU guest agent ---
echo "Waiting for guest agent on VM ${VM_ID} (node: ${PARENT_NODE})..."