blob: 10a4242cd395e078c1ff577dea66b0ccbe10a190 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
#!/usr/bin/env bash
# tests/pve/_lib.sh — source-only helpers for the PVE e2e harness.
#
# Public surface:
# pve_load_env [path] load tests/pve/.env (or argument) and validate
# pve_require_reachable fail unless `ssh $PVE_SSH_TARGET true` works
# pve_ssh "cmd..." run a command on the PVE host
# pve_qm args... shorthand for `pve_ssh qm args...`
# pve_scp src dst copy a local file to the PVE host
# pve_template_phase echo: missing | running | stopped | template
# hdr "title" print a section header to stderr
#
# Refuses direct execution.
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
echo "ERR: tests/pve/_lib.sh is source-only; do not execute it." >&2
exit 1
fi
set -euo pipefail
PVE_LIB_REQUIRED_VARS=(
PVE_SSH_TARGET
PVE_NODE
PVE_STORAGE
PVE_BRIDGE
PVE_IMAGE_DIR
VYOS_ISO_PATH
VYOS_TEMPLATE_VMID
VYOS_TEMPLATE_NAME
VYOS_E2E_VMID
VYOS_E2E_VM_NAME
VYOS_E2E_IP
VYOS_E2E_CIDR
VYOS_E2E_GATEWAY
VYDEVICE_APIKEY
)
pve_load_env() {
local env_file="${1:-}"
if [[ -z "$env_file" ]]; then
env_file="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/.env"
fi
if [[ ! -f "$env_file" ]]; then
echo "ERR: missing env file: $env_file" >&2
echo " copy tests/pve/.env.example to tests/pve/.env and fill it in." >&2
return 1
fi
set -a
# shellcheck disable=SC1090
source "$env_file"
set +a
local missing=()
local v
for v in "${PVE_LIB_REQUIRED_VARS[@]}"; do
if [[ -z "${!v:-}" ]]; then
missing+=("$v")
fi
done
if (( ${#missing[@]} > 0 )); then
echo "ERR: env file $env_file is missing values for: ${missing[*]}" >&2
return 1
fi
}
pve_ssh() {
# ssh joins remaining args with spaces and hands the result to the
# remote login shell, so any unquoted `;`, `&`, `|`, `$`, glob, etc.
# would be re-interpreted there. When the caller passes a single
# argument we treat it as a verbatim remote script. When several are
# passed we shell-escape each one with `printf %q` so the remote
# shell sees exactly one argv per local argv.
if (( $# == 1 )); then
ssh -o BatchMode=yes -o ConnectTimeout=10 "$PVE_SSH_TARGET" "$1"
else
local cmd
# shellcheck disable=SC2059
cmd="$(printf '%q ' "$@")"
ssh -o BatchMode=yes -o ConnectTimeout=10 "$PVE_SSH_TARGET" "$cmd"
fi
}
pve_qm() {
pve_ssh qm "$@"
}
pve_scp() {
local src="$1" dst="$2"
scp -o BatchMode=yes -o ConnectTimeout=10 "$src" "$PVE_SSH_TARGET:$dst"
}
pve_require_reachable() {
if ! pve_ssh true >/dev/null 2>&1; then
echo "ERR: cannot ssh to PVE host '$PVE_SSH_TARGET'." >&2
echo " check ~/.ssh/config, your key, and that the host is up." >&2
return 1
fi
}
# Echo one of:
# missing — VMID not registered in PVE
# running — VM exists and is running
# stopped — VM exists, not a template, currently stopped
# template — VM exists and is flagged as a template
pve_template_phase() {
local vmid="$1"
if ! pve_qm status "$vmid" >/dev/null 2>&1; then
echo missing
return
fi
if pve_qm config "$vmid" | grep -q '^template: 1'; then
echo template
return
fi
# `qm status <vmid>` prints e.g. "status: running"
local s
s="$(pve_qm status "$vmid" | awk '{print $2}')"
if [[ "$s" == "running" ]]; then
echo running
else
echo stopped
fi
}
hdr() {
printf '\n=== %s ===\n' "$*" >&2
}
|