mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2026-10-24 22:07:40 -05:00
Address the final review findings
- management_ip() returned non-zero when no lease was active, which made wait_for_management_ip exit before its retry loop. It now always returns 0, filters on the ipv4 protocol column, and parses lease rows with bash instead of per-line awk subprocesses. - wait_for_cloud_init() treated exit 2 as 'disabled'; cloud-init returns 2 for recoverable errors and 0 when disabled, so a failed package install was silently accepted. Only 0 is accepted now, and the long status is printed on failure. - check-package now waits for cloud-init through the shared wait_for_guest_ready helper, asserts the guest OS, and reports the missing-package error instead of exiting silently under pipefail. - Resolve the guest OS and the expected os-release string once in lib/common.sh; configure.sh and check-package share the assertion. - Delete the unused package-list helper and warn when bpftool is missing after the best-effort extras install. - build_rust.sh stops when prerequisite installation fails, matching build_pkg_debian.sh. - Add a sync pointer above the harness UISP config block.
This commit is contained in:
1 parent
297cb9ea37
commit
14a7fca24c
6 files changed
+62
-62
No files matched your search
+6
-10
@@ -5,11 +5,7 @@ LAB_ROOT=$(cd -- "$(dirname -- "$0")" && pwd)
|
||||
source "$LAB_ROOT/lib/common.sh"
|
||||
source "$LAB_ROOT/lab.env"
|
||||
|
||||
GUEST_OS=${LAB_GUEST_OS:-}
|
||||
if [[ -z $GUEST_OS && -f $IMAGE_DIR/guest-os ]]; then
|
||||
GUEST_OS=$(<"$IMAGE_DIR/guest-os")
|
||||
fi
|
||||
GUEST_OS=${GUEST_OS:-ubuntu}
|
||||
GUEST_OS=$(resolve_guest_os)
|
||||
case "$GUEST_OS" in
|
||||
ubuntu)
|
||||
GUEST_IMAGE_URL=$UBUNTU_IMAGE_URL
|
||||
@@ -30,7 +26,6 @@ esac
|
||||
GUEST_OS_VARIANT=${LAB_OS_VARIANT:-$DEFAULT_GUEST_OS_VARIANT}
|
||||
|
||||
readonly GUEST_OS GUEST_IMAGE_URL GUEST_IMAGE_CHECKSUM GUEST_IMAGE_CHECKSUM_TOOL GUEST_OS_VARIANT
|
||||
export GUEST_OS
|
||||
readonly GUEST_BASE="$IMAGE_DIR/$(basename "$GUEST_IMAGE_URL")"
|
||||
readonly ROUTER_ARCHIVE="$IMAGE_DIR/chr-$ROUTEROS_VERSION.img.zip"
|
||||
readonly ROUTER_BASE="$IMAGE_DIR/chr-$ROUTEROS_VERSION.qcow2"
|
||||
@@ -171,17 +166,18 @@ cmd_check_package() {
|
||||
local package_path=${1:-} lqos_ip simulate_output
|
||||
require_host_tools
|
||||
if [[ -z $package_path ]]; then
|
||||
package_path=$(ls -1t "$REPO_ROOT"/src/dist/libreqos_*_amd64.deb 2>/dev/null | head -n 1)
|
||||
package_path=$(ls -1t "$REPO_ROOT"/src/dist/libreqos_*_amd64.deb 2>/dev/null | head -n 1) || true
|
||||
fi
|
||||
[[ -n $package_path && -f $package_path ]] || die "no LibreQoS package found; build one with src/build_pkg_debian.sh or pass a path"
|
||||
domain_exists "$LQOS_DOMAIN" || die "the lab is not running; use ./radius-harness/lab up first"
|
||||
lqos_ip=$(wait_for_management_ip 52:54:00:10:00:10)
|
||||
wait_for_ssh "$lqos_ip"
|
||||
lqos_ip=$(wait_for_guest_ready 52:54:00:10:00:10)
|
||||
note "verifying the LibreQoS guest operating system"
|
||||
assert_guest_os "$lqos_ip" "$GUEST_OS"
|
||||
note "checking package dependency resolution inside the $GUEST_OS guest"
|
||||
lab_scp "$package_path" "$lqos_ip" /tmp/
|
||||
if ! simulate_output=$(lab_ssh "$lqos_ip" "sudo apt-get install --simulate '/tmp/$(basename "$package_path")' 2>&1"); then
|
||||
printf '%s\n' "$simulate_output"
|
||||
die "package dependency resolution failed in the $GUEST_OS guest"
|
||||
die "package check failed in the $GUEST_OS guest"
|
||||
fi
|
||||
note "package dependency resolution passed"
|
||||
}
|
||||
|
||||
@@ -38,25 +38,42 @@ ensure_lab_stopped() {
|
||||
done
|
||||
}
|
||||
|
||||
# Prints the guest OS recorded for this lab: LAB_GUEST_OS, the images/guest-os
|
||||
# marker written by init, or the ubuntu default.
|
||||
resolve_guest_os() {
|
||||
local guest_os=${LAB_GUEST_OS:-}
|
||||
if [[ -z $guest_os && -f $IMAGE_DIR/guest-os ]]; then
|
||||
guest_os=$(<"$IMAGE_DIR/guest-os")
|
||||
fi
|
||||
printf '%s\n' "${guest_os:-ubuntu}"
|
||||
}
|
||||
|
||||
# Prints the /etc/os-release "ID VERSION_ID" string expected for a guest OS.
|
||||
guest_expected_os_release() {
|
||||
case "$1" in
|
||||
ubuntu) printf 'ubuntu 24.04\n' ;;
|
||||
debian) printf 'debian 13\n' ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
management_ip() {
|
||||
local mac=$1 now line expires epoch ip best_ip= best_expires=0
|
||||
local mac=$1 now line day time mac_field proto ip_field rest best_ip= best_expires=0 epoch
|
||||
now=$(date +%s)
|
||||
while IFS= read -r line; do
|
||||
if [[ ${line,,} != *"${mac,,}"* ]]; then
|
||||
read -r day time mac_field proto ip_field rest <<<"$line" || continue
|
||||
[[ ${mac_field,,} == "${mac,,}" ]] || continue
|
||||
[[ ${proto,,} == "ipv4" ]] || continue
|
||||
epoch=$(date -d "$day $time" +%s 2>/dev/null) || continue
|
||||
if (( epoch <= now )); then
|
||||
continue
|
||||
fi
|
||||
expires=$(awk '{ print $1 " " $2 }' <<<"$line")
|
||||
epoch=$(date -d "$expires" +%s 2>/dev/null) || continue
|
||||
if [[ $epoch -le $now ]]; then
|
||||
continue
|
||||
fi
|
||||
ip=$(awk '{ print $5 }' <<<"$line")
|
||||
if [[ $epoch -gt $best_expires ]]; then
|
||||
if (( epoch > best_expires )); then
|
||||
best_expires=$epoch
|
||||
best_ip=${ip%%/*}
|
||||
best_ip=${ip_field%%/*}
|
||||
fi
|
||||
done < <(virsh_lab net-dhcp-leases "$MANAGEMENT_NETWORK")
|
||||
[[ -n $best_ip ]] && printf '%s\n' "$best_ip"
|
||||
printf '%s\n' "$best_ip"
|
||||
}
|
||||
|
||||
wait_for_management_ip() {
|
||||
@@ -79,20 +96,29 @@ wait_for_ssh() {
|
||||
}
|
||||
|
||||
wait_for_cloud_init() {
|
||||
local host=$1 output status
|
||||
if output=$(lab_ssh "$host" 'sudo cloud-init status --wait' 2>&1); then
|
||||
return 0
|
||||
else
|
||||
status=$?
|
||||
fi
|
||||
# Exit code 2 means cloud-init is disabled, which is not a failure here.
|
||||
if [ "$status" -eq 2 ]; then
|
||||
local host=$1 output
|
||||
if output=$(lab_ssh "$host" 'sudo cloud-init status --wait --long' 2>&1); then
|
||||
return 0
|
||||
fi
|
||||
printf '%s\n' "$output"
|
||||
die "cloud-init did not complete successfully on $host"
|
||||
}
|
||||
|
||||
wait_for_guest_ready() {
|
||||
local mac=$1 ip
|
||||
ip=$(wait_for_management_ip "$mac")
|
||||
wait_for_ssh "$ip"
|
||||
wait_for_cloud_init "$ip"
|
||||
printf '%s\n' "$ip"
|
||||
}
|
||||
|
||||
assert_guest_os() {
|
||||
local host=$1 guest_os=$2 expected actual
|
||||
expected=$(guest_expected_os_release "$guest_os") || die "unsupported GUEST_OS '$guest_os'"
|
||||
actual=$(lab_ssh "$host" '. /etc/os-release && printf "%s %s" "$ID" "$VERSION_ID"')
|
||||
[[ $actual == "$expected" ]] || die "LibreQoS guest is '$actual', expected '$expected'"
|
||||
}
|
||||
|
||||
lab_ssh() { local host=$1; shift; ssh -i "$RUN_DIR/id_ed25519" -o IdentitiesOnly=yes -o BatchMode=yes -o UserKnownHostsFile="$RUN_DIR/known_hosts" -o StrictHostKeyChecking=accept-new "lab@$host" "$@"; }
|
||||
lab_scp() { local source=$1 host=$2 destination=$3; scp -i "$RUN_DIR/id_ed25519" -o IdentitiesOnly=yes -p -o BatchMode=yes -o UserKnownHostsFile="$RUN_DIR/known_hosts" -o StrictHostKeyChecking=accept-new -r "$source" "lab@$host:$destination"; }
|
||||
|
||||
|
||||
@@ -10,25 +10,14 @@ require_command sshpass
|
||||
require_lab_secret RADIUS_SHARED_SECRET
|
||||
require_lab_secret ROUTEROS_ADMIN_PASSWORD
|
||||
|
||||
note "discovering guest management addresses"
|
||||
lqos_ip=$(wait_for_management_ip 52:54:00:10:00:10)
|
||||
radius_ip=$(wait_for_management_ip 52:54:00:20:00:10)
|
||||
client_ip=$(wait_for_management_ip 52:54:00:30:00:10)
|
||||
note "waiting for the LibreQoS, FreeRADIUS, and PPPoE client guests"
|
||||
lqos_ip=$(wait_for_guest_ready 52:54:00:10:00:10)
|
||||
radius_ip=$(wait_for_guest_ready 52:54:00:20:00:10)
|
||||
client_ip=$(wait_for_guest_ready 52:54:00:30:00:10)
|
||||
router_ip=$(wait_for_management_ip 52:54:00:40:00:10)
|
||||
note "waiting for SSH on LibreQoS, FreeRADIUS, and PPPoE client guests"
|
||||
wait_for_ssh "$lqos_ip"; wait_for_ssh "$radius_ip"; wait_for_ssh "$client_ip"
|
||||
|
||||
note "waiting for cloud-init to finish on the lab guests"
|
||||
wait_for_cloud_init "$lqos_ip"; wait_for_cloud_init "$radius_ip"; wait_for_cloud_init "$client_ip"
|
||||
|
||||
note "verifying the LibreQoS guest operating system"
|
||||
case ${GUEST_OS:-ubuntu} in
|
||||
ubuntu) expected_os_release='ubuntu 24.04' ;;
|
||||
debian) expected_os_release='debian 13' ;;
|
||||
*) die "unsupported GUEST_OS '${GUEST_OS:-}'" ;;
|
||||
esac
|
||||
actual_os_release=$(lab_ssh "$lqos_ip" '. /etc/os-release && printf "%s %s" "$ID" "$VERSION_ID"')
|
||||
[[ $actual_os_release == "$expected_os_release" ]] || die "LibreQoS guest is '$actual_os_release', expected '$expected_os_release'"
|
||||
assert_guest_os "$lqos_ip" "$(resolve_guest_os)"
|
||||
|
||||
note "rendering isolated lab configuration"
|
||||
install -d -m 0700 "$RUN_DIR/config"
|
||||
|
||||
@@ -56,6 +56,7 @@ queue_refresh_interval_mins = 30
|
||||
use_mikrotik_ipv6 = false
|
||||
ethernet_port_limits_enabled = true
|
||||
|
||||
# Keep this block in sync with the [uisp_integration] section in src/lqos.example.
|
||||
[uisp_integration]
|
||||
enable_uisp = false
|
||||
token = ""
|
||||
|
||||
+4
-16
@@ -47,11 +47,6 @@ lqos_detect_distro() {
|
||||
printf 'unknown\n'
|
||||
}
|
||||
|
||||
# Prints the packages shared by all supported distributions.
|
||||
lqos_common_build_packages() {
|
||||
printf '%s\n' "${LQOS_COMMON_BUILD_PACKAGES[@]}"
|
||||
}
|
||||
|
||||
# Prints the distribution-specific build packages.
|
||||
# Returns non-zero for distributions without a known package set.
|
||||
lqos_distro_build_extras() {
|
||||
@@ -72,16 +67,6 @@ lqos_distro_build_extras() {
|
||||
esac
|
||||
}
|
||||
|
||||
# Prints the full build prerequisite package list for a distribution.
|
||||
lqos_build_packages() {
|
||||
local extras
|
||||
if ! extras=$(lqos_distro_build_extras "$1"); then
|
||||
return 1
|
||||
fi
|
||||
lqos_common_build_packages
|
||||
printf '%s\n' "$extras"
|
||||
}
|
||||
|
||||
# Installs the build prerequisites for the current or overridden distribution.
|
||||
# Side effects: refreshes apt package lists, installs packages, and prepends
|
||||
# /usr/sbin to PATH so the build can find bpftool on Debian.
|
||||
@@ -97,7 +82,7 @@ lqos_install_build_prerequisites() {
|
||||
if ! extras=$(lqos_distro_build_extras "$distro"); then
|
||||
echo "Unsupported distribution '$distro' for automatic prerequisite install."
|
||||
echo "Install these packages with your distribution's package manager:"
|
||||
lqos_common_build_packages | sed 's/^/ /'
|
||||
printf '%s\n' "${LQOS_COMMON_BUILD_PACKAGES[@]}" | sed 's/^/ /'
|
||||
echo "Also install bpftool (required to build lqos_sys) and, optionally, perf."
|
||||
return 1
|
||||
fi
|
||||
@@ -114,4 +99,7 @@ lqos_install_build_prerequisites() {
|
||||
echo "Warning: failed to install: $extras"
|
||||
echo "Install the distribution equivalents of bpftool (required by lqos_sys) and perf manually if the build fails."
|
||||
fi
|
||||
if ! command -v bpftool >/dev/null 2>&1; then
|
||||
echo "Warning: bpftool was not found; lqos_sys cannot build without it."
|
||||
fi
|
||||
}
|
||||
+1
-1
@@ -28,7 +28,7 @@ VENV_PYTHON="/opt/libreqos/venv/bin/python"
|
||||
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=build_prereqs.sh
|
||||
source "$SCRIPT_DIR/build_prereqs.sh"
|
||||
lqos_install_build_prerequisites
|
||||
lqos_install_build_prerequisites || exit 1
|
||||
|
||||
if ! rustup -V &> /dev/null
|
||||
then
|
||||
|
||||
Reference in new issue
Block a user