update
This commit is contained in:
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
action="${1:-}"
|
action="${1:-}"
|
||||||
FOLDER='/opt/idssys/ta-proxmenu'
|
FOLDER='/opt/idssys/ta-proxmenu'
|
||||||
VERS='2026.7.25-63'
|
VERS='2026.7.25-64'
|
||||||
|
|
||||||
noupdate=' '
|
noupdate=' '
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
TAPM_HA_NODE_IN_MAINTENANCE() {
|
||||||
|
local node="${1:-}"
|
||||||
|
local status_file="${2:-/etc/pve/ha/manager_status}"
|
||||||
|
|
||||||
|
[[ "$node" =~ ^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$ ]] || return 2
|
||||||
|
[[ -r "$status_file" ]] || return 2
|
||||||
|
TAPM_HA_NODE="$node" python3 - "$status_file" <<'PY'
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(sys.argv[1], encoding="utf-8") as status_handle:
|
||||||
|
status = json.load(status_handle)
|
||||||
|
except (OSError, TypeError, ValueError):
|
||||||
|
raise SystemExit(2)
|
||||||
|
|
||||||
|
node = os.environ["TAPM_HA_NODE"].strip().lower()
|
||||||
|
|
||||||
|
def contains_maintenance(value):
|
||||||
|
if isinstance(value, str):
|
||||||
|
return "maintenance" in value.lower()
|
||||||
|
if isinstance(value, dict):
|
||||||
|
return any(contains_maintenance(item) for item in value.values())
|
||||||
|
if isinstance(value, list):
|
||||||
|
return any(contains_maintenance(item) for item in value)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def node_is_in_maintenance(value):
|
||||||
|
if isinstance(value, dict):
|
||||||
|
for key, item in value.items():
|
||||||
|
if str(key).strip().lower() == node and contains_maintenance(item):
|
||||||
|
return True
|
||||||
|
identity = next(
|
||||||
|
(
|
||||||
|
value.get(key)
|
||||||
|
for key in ("node", "name", "id")
|
||||||
|
if isinstance(value.get(key), str)
|
||||||
|
),
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
if identity.strip().lower() == node and contains_maintenance(value):
|
||||||
|
return True
|
||||||
|
return any(node_is_in_maintenance(item) for item in value.values())
|
||||||
|
if isinstance(value, list):
|
||||||
|
return any(node_is_in_maintenance(item) for item in value)
|
||||||
|
return False
|
||||||
|
|
||||||
|
raise SystemExit(0 if node_is_in_maintenance(status) else 1)
|
||||||
|
PY
|
||||||
|
}
|
||||||
+13
-1
@@ -6,6 +6,7 @@
|
|||||||
source /opt/idssys/defaults/default.inc
|
source /opt/idssys/defaults/default.inc
|
||||||
source /opt/idssys/ta-proxmenu/defaults.inc
|
source /opt/idssys/ta-proxmenu/defaults.inc
|
||||||
source /opt/idssys/ta-proxmenu/inc/git-update.inc
|
source /opt/idssys/ta-proxmenu/inc/git-update.inc
|
||||||
|
source /opt/idssys/ta-proxmenu/inc/ha-status.inc
|
||||||
source /opt/idssys/ta-proxmenu/inc/deploy-iso-nfs-lxc.sh
|
source /opt/idssys/ta-proxmenu/inc/deploy-iso-nfs-lxc.sh
|
||||||
source /opt/idssys/ta-proxmenu/inc/deploy-pulse-lxc.sh
|
source /opt/idssys/ta-proxmenu/inc/deploy-pulse-lxc.sh
|
||||||
source /opt/idssys/ta-proxmenu/inc/virtio-helpers.inc
|
source /opt/idssys/ta-proxmenu/inc/virtio-helpers.inc
|
||||||
@@ -1948,9 +1949,20 @@ MONITORING_MENU() {
|
|||||||
CLUSTER_MENU() {
|
CLUSTER_MENU() {
|
||||||
local -a labels
|
local -a labels
|
||||||
local -a values=("maintenance" "services" "keepalived" "iso_nfs")
|
local -a values=("maintenance" "services" "keepalived" "iso_nfs")
|
||||||
|
local maintenance_status
|
||||||
|
local node
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
if ha-manager status | grep -F "$(hostname -s)" | grep -q "maintenance mode"; then
|
node="$(hostname -s)"
|
||||||
|
TAPM_HA_NODE_IN_MAINTENANCE "$node"
|
||||||
|
maintenance_status=$?
|
||||||
|
if (( maintenance_status == 2 )); then
|
||||||
|
ha-manager status |
|
||||||
|
grep -F "$node" |
|
||||||
|
grep -q "maintenance mode"
|
||||||
|
maintenance_status=$?
|
||||||
|
fi
|
||||||
|
if (( maintenance_status == 0 )); then
|
||||||
labels=("Take this host out of maintenance mode")
|
labels=("Take this host out of maintenance mode")
|
||||||
else
|
else
|
||||||
labels=("Put this host into maintenance mode and evacuate guests")
|
labels=("Put this host into maintenance mode and evacuate guests")
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -u -o pipefail
|
||||||
|
|
||||||
|
TEST_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
source "${TEST_ROOT}/tests/testlib.sh"
|
||||||
|
source "${TEST_ROOT}/inc/ha-status.inc"
|
||||||
|
|
||||||
|
STATUS_FILE="$(mktemp /tmp/tapm-ha-status.XXXXXX)"
|
||||||
|
cleanup_ha_status_test() {
|
||||||
|
[[ "$STATUS_FILE" == /tmp/tapm-ha-status.* ]] && rm -f -- "$STATUS_FILE"
|
||||||
|
}
|
||||||
|
trap cleanup_ha_status_test EXIT
|
||||||
|
|
||||||
|
printf '%s\n' \
|
||||||
|
'{"node_status":{"pve1":"online","pve2":"maintenance mode"}}' \
|
||||||
|
>"$STATUS_FILE"
|
||||||
|
assert_success "maintenance node detected in HA manager state" \
|
||||||
|
TAPM_HA_NODE_IN_MAINTENANCE pve2 "$STATUS_FILE"
|
||||||
|
assert_failure "active node is not reported as maintenance" \
|
||||||
|
TAPM_HA_NODE_IN_MAINTENANCE pve1 "$STATUS_FILE"
|
||||||
|
|
||||||
|
printf '%s\n' \
|
||||||
|
'{"nodes":[{"node":"pve3","state":"maintenance"}]}' \
|
||||||
|
>"$STATUS_FILE"
|
||||||
|
assert_success "structured HA node state detected" \
|
||||||
|
TAPM_HA_NODE_IN_MAINTENANCE pve3 "$STATUS_FILE"
|
||||||
|
|
||||||
|
printf '%s\n' 'not-json' >"$STATUS_FILE"
|
||||||
|
assert_failure "malformed HA state is rejected" \
|
||||||
|
TAPM_HA_NODE_IN_MAINTENANCE pve1 "$STATUS_FILE"
|
||||||
|
|
||||||
|
finish_tests
|
||||||
Reference in New Issue
Block a user