parent
c5ef7684a7
commit
6b5ae18dfe
2 changed files with 179 additions and 2 deletions
|
|
@ -50,3 +50,35 @@ allowed_nodes:
|
||||||
t.Fatalf("expected config to remain unchanged")
|
t.Fatalf("expected config to remain unchanged")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSanitizeDuplicateAllowedNodesBlocks_WithCommentBlocks(t *testing.T) {
|
||||||
|
raw := `
|
||||||
|
allowed_source_subnets:
|
||||||
|
- 192.168.1.0/24
|
||||||
|
|
||||||
|
# Cluster nodes (auto-discovered during installation)
|
||||||
|
# These nodes are allowed to request temperature data when cluster IPC validation is unavailable
|
||||||
|
allowed_nodes:
|
||||||
|
- delly
|
||||||
|
- minipc
|
||||||
|
|
||||||
|
# Cluster nodes (auto-discovered during installation)
|
||||||
|
# These nodes are allowed to request temperature data when cluster IPC validation is unavailable
|
||||||
|
allowed_nodes:
|
||||||
|
- delly
|
||||||
|
- minipc
|
||||||
|
`
|
||||||
|
|
||||||
|
sanitized, out := sanitizeDuplicateAllowedNodesBlocks("", []byte(raw))
|
||||||
|
if !sanitized {
|
||||||
|
t.Fatalf("expected sanitizer to run for duplicate comment blocks")
|
||||||
|
}
|
||||||
|
|
||||||
|
result := string(out)
|
||||||
|
if strings.Count(result, "allowed_nodes:") != 1 {
|
||||||
|
t.Fatalf("expected a single allowed_nodes block, got %q", result)
|
||||||
|
}
|
||||||
|
if strings.Count(result, "# Cluster nodes") != 1 {
|
||||||
|
t.Fatalf("expected duplicate comments to collapse, got %q", result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3098,12 +3098,146 @@ INSTALLER="/opt/pulse/sensor-proxy/install-sensor-proxy.sh"
|
||||||
CTID_FILE="/etc/pulse-sensor-proxy/ctid"
|
CTID_FILE="/etc/pulse-sensor-proxy/ctid"
|
||||||
PENDING_FILE="/etc/pulse-sensor-proxy/pending-control-plane.env"
|
PENDING_FILE="/etc/pulse-sensor-proxy/pending-control-plane.env"
|
||||||
TOKEN_FILE="/etc/pulse-sensor-proxy/.pulse-control-token"
|
TOKEN_FILE="/etc/pulse-sensor-proxy/.pulse-control-token"
|
||||||
|
CONFIG_FILE="/etc/pulse-sensor-proxy/config.yaml"
|
||||||
LOG_TAG="pulse-sensor-proxy-selfheal"
|
LOG_TAG="pulse-sensor-proxy-selfheal"
|
||||||
|
|
||||||
log() {
|
log() {
|
||||||
logger -t "$LOG_TAG" "$1"
|
logger -t "$LOG_TAG" "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sanitize_allowed_nodes() {
|
||||||
|
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if ! command -v python3 >/dev/null 2>&1; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local result
|
||||||
|
if ! result=$(python3 - "$CONFIG_FILE" <<'PY'
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
path = Path(sys.argv[1])
|
||||||
|
lines = path.read_text().splitlines()
|
||||||
|
blocks = []
|
||||||
|
i = 0
|
||||||
|
while i < len(lines):
|
||||||
|
line = lines[i]
|
||||||
|
stripped = line.lstrip()
|
||||||
|
if stripped.startswith("allowed_nodes:"):
|
||||||
|
start = i
|
||||||
|
entries = []
|
||||||
|
j = i + 1
|
||||||
|
while j < len(lines):
|
||||||
|
nxt = lines[j]
|
||||||
|
nxt_stripped = nxt.lstrip()
|
||||||
|
if nxt_stripped.startswith("-"):
|
||||||
|
entries.append(nxt_stripped[1:].strip())
|
||||||
|
j += 1
|
||||||
|
continue
|
||||||
|
if (
|
||||||
|
nxt_stripped.startswith("#")
|
||||||
|
or nxt_stripped == ""
|
||||||
|
or nxt.startswith((" ", "\t"))
|
||||||
|
):
|
||||||
|
j += 1
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
|
||||||
|
comment_indices = set()
|
||||||
|
comment_text = []
|
||||||
|
k = start - 1
|
||||||
|
while k >= 0 and lines[k].strip() == "":
|
||||||
|
comment_indices.add(k)
|
||||||
|
k -= 1
|
||||||
|
while k >= 0 and lines[k].lstrip().startswith("#"):
|
||||||
|
comment_indices.add(k)
|
||||||
|
comment_text.append(lines[k])
|
||||||
|
k -= 1
|
||||||
|
comment_text.reverse()
|
||||||
|
|
||||||
|
blocks.append(
|
||||||
|
{
|
||||||
|
"start": start,
|
||||||
|
"end": j,
|
||||||
|
"comment_indices": comment_indices,
|
||||||
|
"comment_text": comment_text,
|
||||||
|
"entries": entries,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
i = j
|
||||||
|
continue
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
if len(blocks) <= 1:
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
seen = set()
|
||||||
|
merged = []
|
||||||
|
for block in blocks:
|
||||||
|
for entry in block["entries"]:
|
||||||
|
key = entry.lower()
|
||||||
|
if not key or key in seen:
|
||||||
|
continue
|
||||||
|
seen.add(key)
|
||||||
|
merged.append(entry)
|
||||||
|
|
||||||
|
if not merged:
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
first_block = blocks[0]
|
||||||
|
insert_at = min(
|
||||||
|
[first_block["start"]] + list(first_block["comment_indices"])
|
||||||
|
) if first_block["comment_indices"] else first_block["start"]
|
||||||
|
|
||||||
|
def build_comment():
|
||||||
|
if first_block["comment_text"]:
|
||||||
|
return first_block["comment_text"]
|
||||||
|
return ["# Cluster nodes (auto-discovered during installation)"]
|
||||||
|
|
||||||
|
comment_block = build_comment()
|
||||||
|
replacement = []
|
||||||
|
replacement.extend(comment_block)
|
||||||
|
if replacement and replacement[-1].strip() != "":
|
||||||
|
replacement.append("")
|
||||||
|
replacement.append("allowed_nodes:")
|
||||||
|
for entry in merged:
|
||||||
|
replacement.append(f" - {entry}")
|
||||||
|
replacement.append("")
|
||||||
|
|
||||||
|
indices_to_remove = set()
|
||||||
|
for block in blocks:
|
||||||
|
indices_to_remove.update(range(block["start"], block["end"]))
|
||||||
|
indices_to_remove.update(block["comment_indices"])
|
||||||
|
|
||||||
|
result = []
|
||||||
|
inserted = False
|
||||||
|
for idx, line in enumerate(lines):
|
||||||
|
if not inserted and idx == insert_at:
|
||||||
|
result.extend(replacement)
|
||||||
|
inserted = True
|
||||||
|
if idx in indices_to_remove:
|
||||||
|
continue
|
||||||
|
result.append(line)
|
||||||
|
|
||||||
|
if not inserted:
|
||||||
|
if result and result[-1].strip() != "":
|
||||||
|
result.append("")
|
||||||
|
result.extend(replacement)
|
||||||
|
|
||||||
|
path.write_text("\n".join(result).rstrip() + "\n")
|
||||||
|
print(f"Sanitized duplicate allowed_nodes blocks ({len(blocks) - 1} removed)")
|
||||||
|
PY
|
||||||
|
); then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$result" ]]; then
|
||||||
|
log "$result"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
attempt_control_plane_reconcile() {
|
attempt_control_plane_reconcile() {
|
||||||
if [[ ! -f "$PENDING_FILE" ]]; then
|
if [[ ! -f "$PENDING_FILE" ]]; then
|
||||||
return
|
return
|
||||||
|
|
@ -3141,11 +3275,14 @@ attempt_control_plane_reconcile() {
|
||||||
|
|
||||||
if PULSE_SENSOR_PROXY_SELFHEAL=1 bash "$INSTALLER" "${cmd[@]}"; then
|
if PULSE_SENSOR_PROXY_SELFHEAL=1 bash "$INSTALLER" "${cmd[@]}"; then
|
||||||
rm -f "$PENDING_FILE"
|
rm -f "$PENDING_FILE"
|
||||||
|
sanitize_allowed_nodes
|
||||||
else
|
else
|
||||||
log "Control-plane reconciliation failed"
|
log "Control-plane reconciliation failed"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sanitize_allowed_nodes
|
||||||
|
|
||||||
if ! command -v systemctl >/dev/null 2>&1; then
|
if ! command -v systemctl >/dev/null 2>&1; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
@ -3153,7 +3290,11 @@ fi
|
||||||
if ! systemctl list-unit-files 2>/dev/null | grep -q "^${SERVICE}\\.service"; then
|
if ! systemctl list-unit-files 2>/dev/null | grep -q "^${SERVICE}\\.service"; then
|
||||||
if [[ -x "$INSTALLER" && -f "$CTID_FILE" ]]; then
|
if [[ -x "$INSTALLER" && -f "$CTID_FILE" ]]; then
|
||||||
log "Service unit missing; attempting reinstall"
|
log "Service unit missing; attempting reinstall"
|
||||||
PULSE_SENSOR_PROXY_SELFHEAL=1 bash "$INSTALLER" --ctid "$(cat "$CTID_FILE")" --skip-restart --quiet || log "Reinstall attempt failed"
|
if PULSE_SENSOR_PROXY_SELFHEAL=1 bash "$INSTALLER" --ctid "$(cat "$CTID_FILE")" --skip-restart --quiet; then
|
||||||
|
sanitize_allowed_nodes
|
||||||
|
else
|
||||||
|
log "Reinstall attempt failed"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
@ -3166,7 +3307,11 @@ fi
|
||||||
if ! systemctl is-active --quiet "${SERVICE}.service"; then
|
if ! systemctl is-active --quiet "${SERVICE}.service"; then
|
||||||
if [[ -x "$INSTALLER" && -f "$CTID_FILE" ]]; then
|
if [[ -x "$INSTALLER" && -f "$CTID_FILE" ]]; then
|
||||||
log "Service failed to start; attempting reinstall"
|
log "Service failed to start; attempting reinstall"
|
||||||
PULSE_SENSOR_PROXY_SELFHEAL=1 bash "$INSTALLER" --ctid "$(cat "$CTID_FILE")" --skip-restart --quiet || log "Reinstall attempt failed"
|
if PULSE_SENSOR_PROXY_SELFHEAL=1 bash "$INSTALLER" --ctid "$(cat "$CTID_FILE")" --skip-restart --quiet; then
|
||||||
|
sanitize_allowed_nodes
|
||||||
|
else
|
||||||
|
log "Reinstall attempt failed"
|
||||||
|
fi
|
||||||
systemctl start "${SERVICE}.service" || true
|
systemctl start "${SERVICE}.service" || true
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue