mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-02-18 23:41:48 +01:00
WIP: Fix temperature proxy registration persistence (incomplete)
This commit contains multiple fixes for temperature proxy registration, but the core issue remains unresolved. ## What's Fixed: 1. Added config pointer and reloadFunc to TemperatureProxyHandlers 2. Added SetConfig method to keep handler in sync with router config changes 3. Added config reload after registration to prevent monitor from overwriting 4. Fixed installer port conflict detection and duplicate YAML key issues 5. Added comprehensive debug logging throughout registration flow ## What's Still Broken: The TemperatureProxyURL, TemperatureProxyToken, and TemperatureProxyControlToken fields are NOT persisting to nodes.enc after SaveNodesConfig is called. Debug logs confirm: - HandleRegister correctly updates nodesConfig.PVEInstances[matchedIndex] - The correct data is passed to SaveNodesConfig (verified in logs) - SaveNodesConfig completes without errors - Config reload executes successfully - BUT after Pulse restart, the fields are empty when loaded from disk The bug is in SaveNodesConfig serialization or file writing logic itself. Related files: - internal/api/temperature_proxy.go: Registration handler - internal/config/persistence.go: SaveNodesConfig implementation - internal/config/config.go: PVEInstance struct definition
This commit is contained in:
@@ -3418,6 +3418,12 @@ echo " Pulse Monitoring Setup for Proxmox VE"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
|
||||
PULSE_URL="%s"
|
||||
SERVER_HOST="%s"
|
||||
TOKEN_NAME="%s"
|
||||
PULSE_TOKEN_ID="pulse-monitor@pam!${TOKEN_NAME}"
|
||||
SETUP_SCRIPT_URL="$PULSE_URL/api/setup-script?type=pve&host=$SERVER_HOST&pulse_url=$PULSE_URL"
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "Please run this script as root"
|
||||
@@ -3497,10 +3503,10 @@ case "$ENVIRONMENT" in
|
||||
# 1) Create or reuse the Pulse monitoring API token
|
||||
pveum user add pulse-monitor@pam --comment "Pulse monitoring service"
|
||||
pveum aclmod / -user pulse-monitor@pam -role PVEAuditor
|
||||
pveum user token add pulse-monitor@pam %s --privsep 0
|
||||
pveum user token add pulse-monitor@pam "$TOKEN_NAME" --privsep 0
|
||||
|
||||
# 2) Install or update pulse-sensor-proxy on the host
|
||||
curl -sSL "%s/api/install/install-sensor-proxy.sh" | bash -s -- --ctid ${CTID_DISPLAY} --pulse-server "%s"
|
||||
curl -sSL "$PULSE_URL/api/install/install-sensor-proxy.sh" | bash -s -- --ctid ${CTID_DISPLAY} --pulse-server "$PULSE_URL"
|
||||
|
||||
# 3) Ensure the proxy socket is mounted into this container
|
||||
NEXT_MP=\$(pct config ${CTID_DISPLAY} | awk '\$1 ~ /^mp[0-9]+:/ && index(\$0, "mp=/mnt/pulse-proxy") {gsub(":", "", \$1); print \$1; exit}')
|
||||
@@ -3510,7 +3516,7 @@ pct exec ${CTID_DISPLAY} -- test -S /mnt/pulse-proxy/pulse-sensor-proxy.sock &&
|
||||
|
||||
EOF
|
||||
echo "For the simplest experience, run this script on your Proxmox host instead:"
|
||||
echo " curl -sSL \"%s/api/setup-script?type=pve&host=%s&pulse_url=%s\" | bash"
|
||||
echo " curl -sSL \"$SETUP_SCRIPT_URL\" | bash"
|
||||
echo ""
|
||||
echo "Exiting without error. Re-run after completing the host steps."
|
||||
exit 0
|
||||
@@ -3519,23 +3525,23 @@ EOF
|
||||
echo "This script requires Proxmox host tooling (pveum)."
|
||||
echo ""
|
||||
echo "Run on your Proxmox host:"
|
||||
echo " curl -sSL \"%s/api/setup-script?type=pve&host=%s&pulse_url=%s\" | bash"
|
||||
echo " curl -sSL \"$SETUP_SCRIPT_URL\" | bash"
|
||||
echo ""
|
||||
echo "Manual setup steps:"
|
||||
echo " 1. On Proxmox host, create API token:"
|
||||
echo " pveum user add pulse-monitor@pam --comment \"Pulse monitoring service\""
|
||||
echo " pveum aclmod / -user pulse-monitor@pam -role PVEAuditor"
|
||||
echo " pveum user token add pulse-monitor@pam %s --privsep 0"
|
||||
echo " pveum user token add pulse-monitor@pam "$TOKEN_NAME" --privsep 0"
|
||||
echo ""
|
||||
echo " 2. In Pulse: Settings → Nodes → Add Node (enter token from above)"
|
||||
echo ""
|
||||
echo " 3. (Optional) For temperature monitoring on containerized Pulse:"
|
||||
echo ""
|
||||
echo " For LXC containers, run on Proxmox host:"
|
||||
echo " curl -sSL %s/api/install/install-sensor-proxy.sh | bash -s -- --ctid <CTID> --pulse-server %s"
|
||||
echo " curl -sSL $PULSE_URL/api/install/install-sensor-proxy.sh | bash -s -- --ctid <CTID> --pulse-server $PULSE_URL"
|
||||
echo ""
|
||||
echo " For Docker containers, run on Proxmox host:"
|
||||
echo " curl -sSL %s/api/install/install-sensor-proxy.sh | bash -s -- --standalone --pulse-server %s"
|
||||
echo " curl -sSL $PULSE_URL/api/install/install-sensor-proxy.sh | bash -s -- --standalone --pulse-server $PULSE_URL"
|
||||
echo " Then add to docker-compose.yml:"
|
||||
echo " volumes:"
|
||||
echo " - /run/pulse-sensor-proxy:/run/pulse-sensor-proxy:rw"
|
||||
@@ -3809,25 +3815,25 @@ echo "Generating API token..."
|
||||
|
||||
# Check if token already exists
|
||||
TOKEN_EXISTED=false
|
||||
if pveum user token list pulse-monitor@pam 2>/dev/null | grep -q "%s"; then
|
||||
if pveum user token list pulse-monitor@pam 2>/dev/null | grep -q "$TOKEN_NAME"; then
|
||||
TOKEN_EXISTED=true
|
||||
echo ""
|
||||
echo "================================================================"
|
||||
echo "WARNING: Token '%s' already exists!"
|
||||
echo "WARNING: Token '$TOKEN_NAME' already exists!"
|
||||
echo "================================================================"
|
||||
echo ""
|
||||
echo "To create a new token, first remove the existing one:"
|
||||
echo " pveum user token remove pulse-monitor@pam %s"
|
||||
echo " pveum user token remove pulse-monitor@pam $TOKEN_NAME"
|
||||
echo ""
|
||||
echo "Or create a token with a different name:"
|
||||
echo " pveum user token add pulse-monitor@pam %s-$(date +%%s) --privsep 0"
|
||||
echo " pveum user token add pulse-monitor@pam ${TOKEN_NAME}-$(date +%%s) --privsep 0"
|
||||
echo ""
|
||||
echo "Then use the new token ID in Pulse (e.g., pulse-monitor@pam!%s-1234567890)"
|
||||
echo "Then use the new token ID in Pulse (e.g., ${PULSE_TOKEN_ID}-1234567890)"
|
||||
echo "================================================================"
|
||||
echo ""
|
||||
else
|
||||
# Create token silently first
|
||||
TOKEN_OUTPUT=$(pveum user token add pulse-monitor@pam %s --privsep 0)
|
||||
TOKEN_OUTPUT=$(pveum user token add pulse-monitor@pam "$TOKEN_NAME" --privsep 0)
|
||||
|
||||
# Extract the token value for auto-registration
|
||||
TOKEN_VALUE=$(echo "$TOKEN_OUTPUT" | grep "│ value" | awk -F'│' '{print $3}' | tr -d ' ' | tail -1)
|
||||
@@ -3884,11 +3890,8 @@ else
|
||||
SERVER_HOSTNAME=$(hostname -s 2>/dev/null || hostname)
|
||||
SERVER_IP=$(hostname -I | awk '{print $1}')
|
||||
|
||||
# Send registration to Pulse
|
||||
PULSE_URL="%s"
|
||||
|
||||
# Check if host URL was provided
|
||||
HOST_URL="%s"
|
||||
HOST_URL="$SERVER_HOST"
|
||||
if [ "$HOST_URL" = "https://YOUR_PROXMOX_HOST:8006" ] || [ -z "$HOST_URL" ]; then
|
||||
echo ""
|
||||
echo "❌ ERROR: No Proxmox host URL provided!"
|
||||
@@ -3901,7 +3904,7 @@ else
|
||||
echo " curl -sSL \"$PULSE_URL/api/setup-script?type=pve&host=https://192.168.0.5:8006&pulse_url=$PULSE_URL\" | bash"
|
||||
echo ""
|
||||
echo "📝 For manual setup, use the token created above with:"
|
||||
echo " Token ID: pulse-monitor@pam!%s"
|
||||
echo " Token ID: $PULSE_TOKEN_ID"
|
||||
echo " Token Value: [See above]"
|
||||
echo ""
|
||||
exit 1
|
||||
@@ -3909,7 +3912,7 @@ else
|
||||
|
||||
# Construct registration request with setup code
|
||||
# Build JSON carefully to preserve the exclamation mark
|
||||
REGISTER_JSON='{"type":"pve","host":"'"$HOST_URL"'","serverName":"'"$SERVER_HOSTNAME"'","tokenId":"pulse-monitor@pam!%s","tokenValue":"'"$TOKEN_VALUE"'","authToken":"'"$AUTH_TOKEN"'"}'
|
||||
REGISTER_JSON='{"type":"pve","host":"'"$HOST_URL"'","serverName":"'"$SERVER_HOSTNAME"'","tokenId":"'"$PULSE_TOKEN_ID"'","tokenValue":"'"$TOKEN_VALUE"'","authToken":"'"$AUTH_TOKEN"'"}'
|
||||
|
||||
# Send registration with setup code
|
||||
REGISTER_RESPONSE=$(echo "$REGISTER_JSON" | curl -s -X POST "$PULSE_URL/api/auto-register" \
|
||||
@@ -4043,7 +4046,7 @@ SSH_SENSORS_KEY_ENTRY="command=\"sensors -j\",no-port-forwarding,no-X11-forwardi
|
||||
TEMPERATURE_ENABLED=false
|
||||
TEMP_MONITORING_AVAILABLE=true
|
||||
MIN_PROXY_VERSION="%s"
|
||||
PULSE_VERSION_ENDPOINT="%s/api/version"
|
||||
PULSE_VERSION_ENDPOINT="$PULSE_URL/api/version"
|
||||
STANDALONE_PROXY_DEPLOYED=false
|
||||
SKIP_TEMPERATURE_PROMPT=false
|
||||
PROXY_SOCKET_EXISTED_AT_START=false
|
||||
@@ -4067,7 +4070,7 @@ version_ge() {
|
||||
}
|
||||
|
||||
# Check if temperature proxy is available and override SSH key if it is
|
||||
PROXY_KEY_URL="%s/api/system/proxy-public-key"
|
||||
PROXY_KEY_URL="$PULSE_URL/api/system/proxy-public-key"
|
||||
TEMPERATURE_PROXY_KEY=$(curl -s -f "$PROXY_KEY_URL" 2>/dev/null || echo "")
|
||||
if [ -n "$TEMPERATURE_PROXY_KEY" ] && [[ "$TEMPERATURE_PROXY_KEY" =~ ^ssh-(rsa|ed25519) ]]; then
|
||||
# Proxy is available - use its key instead of container's key
|
||||
@@ -4080,7 +4083,7 @@ PULSE_CTID=""
|
||||
PULSE_IS_CONTAINERIZED=false
|
||||
if command -v pct >/dev/null 2>&1; then
|
||||
# Extract Pulse IP from URL
|
||||
PULSE_IP=$(echo "%s" | sed -E 's|^https?://([^:/]+).*|\1|')
|
||||
PULSE_IP=$(echo "$PULSE_URL" | sed -E 's|^https?://([^:/]+).*|\1|')
|
||||
|
||||
# Find container with this IP
|
||||
if [[ "$PULSE_IP" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
@@ -4199,7 +4202,7 @@ if [ "$TEMP_MONITORING_AVAILABLE" = true ] && [ "$PULSE_IS_CONTAINERIZED" = true
|
||||
if true; then
|
||||
# Download installer script from Pulse server
|
||||
PROXY_INSTALLER="/tmp/install-sensor-proxy-$$.sh"
|
||||
INSTALLER_URL="%s/api/install/install-sensor-proxy.sh"
|
||||
INSTALLER_URL="$PULSE_URL/api/install/install-sensor-proxy.sh"
|
||||
|
||||
echo "Installing pulse-sensor-proxy..."
|
||||
if curl --fail --silent --location \
|
||||
@@ -4208,7 +4211,7 @@ if [ "$TEMP_MONITORING_AVAILABLE" = true ] && [ "$PULSE_IS_CONTAINERIZED" = true
|
||||
chmod +x "$PROXY_INSTALLER"
|
||||
|
||||
# Run installer with Pulse server as fallback
|
||||
INSTALL_OUTPUT=$("$PROXY_INSTALLER" --ctid "$PULSE_CTID" --pulse-server "%s" 2>&1)
|
||||
INSTALL_OUTPUT=$("$PROXY_INSTALLER" --ctid "$PULSE_CTID" --pulse-server "$PULSE_URL" 2>&1)
|
||||
INSTALL_STATUS=$?
|
||||
|
||||
if [ -n "$INSTALL_OUTPUT" ]; then
|
||||
@@ -4311,7 +4314,7 @@ if [ "$SKIP_TEMPERATURE_PROMPT" = true ]; then
|
||||
|
||||
# Download and run installer to refresh config
|
||||
PROXY_INSTALLER="/tmp/install-sensor-proxy-repair-$$.sh"
|
||||
INSTALLER_URL="%s/api/install/install-sensor-proxy.sh"
|
||||
INSTALLER_URL="$PULSE_URL/api/install/install-sensor-proxy.sh"
|
||||
|
||||
if curl --fail --silent --location "$INSTALLER_URL" -o "$PROXY_INSTALLER" 2>/dev/null; then
|
||||
chmod +x "$PROXY_INSTALLER"
|
||||
@@ -4331,10 +4334,10 @@ if [ "$SKIP_TEMPERATURE_PROMPT" = true ]; then
|
||||
|
||||
if [ -n "$DETECTED_CTID" ]; then
|
||||
# Was deployed for containerized Pulse - use --ctid mode
|
||||
INSTALLER_ARGS="--ctid $DETECTED_CTID --pulse-server %s"
|
||||
INSTALLER_ARGS="--ctid $DETECTED_CTID --pulse-server $PULSE_URL"
|
||||
elif [ "$IS_STANDALONE_NODE" = true ]; then
|
||||
# Standalone node - use --standalone --http-mode
|
||||
INSTALLER_ARGS="--standalone --http-mode --pulse-server %s"
|
||||
INSTALLER_ARGS="--standalone --http-mode --pulse-server $PULSE_URL"
|
||||
else
|
||||
# Cannot determine deployment type - bail out
|
||||
echo ""
|
||||
@@ -4342,10 +4345,10 @@ if [ "$SKIP_TEMPERATURE_PROMPT" = true ]; then
|
||||
echo " Manual repair required. Run one of:"
|
||||
echo ""
|
||||
echo " • For container:"
|
||||
echo " curl -fsSL %s/api/install/install-sensor-proxy.sh | bash -s -- --ctid <CTID> --pulse-server %s"
|
||||
echo " curl -fsSL $PULSE_URL/api/install/install-sensor-proxy.sh | bash -s -- --ctid <CTID> --pulse-server $PULSE_URL"
|
||||
echo ""
|
||||
echo " • For standalone:"
|
||||
echo " curl -fsSL %s/api/install/install-sensor-proxy.sh | bash -s -- --standalone --http-mode --pulse-server %s"
|
||||
echo " curl -fsSL $PULSE_URL/api/install/install-sensor-proxy.sh | bash -s -- --standalone --http-mode --pulse-server $PULSE_URL"
|
||||
echo ""
|
||||
echo " Keeping existing proxy configuration"
|
||||
rm -f "$PROXY_INSTALLER"
|
||||
@@ -4353,7 +4356,15 @@ if [ "$SKIP_TEMPERATURE_PROMPT" = true ]; then
|
||||
fi
|
||||
|
||||
if [ -n "$INSTALLER_ARGS" ]; then
|
||||
# Run installer and capture output for diagnostics
|
||||
# Check if service is already running
|
||||
if systemctl is-active --quiet pulse-sensor-proxy 2>/dev/null; then
|
||||
echo "✓ pulse-sensor-proxy service is already running"
|
||||
echo " Refreshing configuration and token..."
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Run installer to refresh config and restart service
|
||||
# The installer handles stopping/restarting on its own
|
||||
INSTALL_OUTPUT=$("$PROXY_INSTALLER" $INSTALLER_ARGS 2>&1)
|
||||
REPAIR_STATUS=$?
|
||||
|
||||
@@ -4486,7 +4497,7 @@ elif [ "$TEMP_MONITORING_AVAILABLE" = true ]; then
|
||||
# SECURITY: Block SSH-based temperature monitoring for containerized Pulse (unless dev mode)
|
||||
if [ "$PULSE_IS_CONTAINERIZED" = true ]; then
|
||||
# Check for dev mode override (from Pulse server environment)
|
||||
DEV_MODE_RESPONSE=$(curl -s "%s/api/health" 2>/dev/null | grep -o '"devModeSSH"[[:space:]]*:[[:space:]]*true' || echo "")
|
||||
DEV_MODE_RESPONSE=$(curl -s "$PULSE_URL/api/health" 2>/dev/null | grep -o '"devModeSSH"[[:space:]]*:[[:space:]]*true' || echo "")
|
||||
|
||||
if [ -n "$DEV_MODE_RESPONSE" ]; then
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
@@ -4743,7 +4754,7 @@ Host ${NODE}
|
||||
|
||||
# Write SSH config to Pulse container
|
||||
# This will be written to /home/pulse/.ssh/config inside the container
|
||||
echo "$SSH_CONFIG" | curl -s -X POST "%s/api/system/ssh-config" \
|
||||
echo "$SSH_CONFIG" | curl -s -X POST "$PULSE_URL/api/system/ssh-config" \
|
||||
-H "Content-Type: text/plain" \
|
||||
-H "Authorization: Bearer $AUTH_TOKEN" \
|
||||
--data-binary @- > /dev/null 2>&1
|
||||
@@ -4932,7 +4943,7 @@ EOF
|
||||
CONFIGURED_NODES="$(hostname) ${CONFIGURED_NODES}"
|
||||
fi
|
||||
|
||||
VERIFY_RESPONSE=$(curl -s -X POST "%s/api/system/verify-temperature-ssh" \
|
||||
VERIFY_RESPONSE=$(curl -s -X POST "$PULSE_URL/api/system/verify-temperature-ssh" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $AUTH_TOKEN" \
|
||||
-d "{\"nodes\": \"$CONFIGURED_NODES\"}" 2>/dev/null || echo "")
|
||||
@@ -4975,7 +4986,7 @@ if [ "$IS_STANDALONE_NODE" = true ] && [ "$TEMPERATURE_ENABLED" = true ] && [ "$
|
||||
echo ""
|
||||
|
||||
# Try to fetch the proxy's public key from Pulse server
|
||||
PROXY_KEY_URL="%s/api/system/proxy-public-key"
|
||||
PROXY_KEY_URL="$PULSE_URL/api/system/proxy-public-key"
|
||||
echo "Fetching temperature proxy public key..."
|
||||
|
||||
PROXY_PUBLIC_KEY=$(curl -s -f "$PROXY_KEY_URL" 2>/dev/null || echo "")
|
||||
@@ -5035,7 +5046,7 @@ echo ""
|
||||
# Only show manual setup instructions if auto-registration failed
|
||||
if [ "$AUTO_REG_SUCCESS" != true ]; then
|
||||
echo "Manual setup instructions:"
|
||||
echo " Token ID: pulse-monitor@pam!%s"
|
||||
echo " Token ID: $PULSE_TOKEN_ID"
|
||||
if [ "$TOKEN_EXISTED" = true ]; then
|
||||
echo " Token Value: [Use your existing token or create a new one as shown above]"
|
||||
elif [ -n "$TOKEN_VALUE" ]; then
|
||||
@@ -5047,16 +5058,11 @@ if [ "$AUTO_REG_SUCCESS" != true ]; then
|
||||
echo ""
|
||||
fi
|
||||
`, serverName, time.Now().Format("2006-01-02 15:04:05"),
|
||||
tokenName, pulseURL, pulseURL,
|
||||
pulseURL, serverHost, pulseURL,
|
||||
pulseURL, serverHost, pulseURL,
|
||||
tokenName, pulseURL, pulseURL,
|
||||
pulseURL, pulseURL,
|
||||
pulseURL, serverHost, tokenName,
|
||||
pulseIP,
|
||||
tokenName, tokenName, tokenName, tokenName, tokenName, tokenName,
|
||||
authToken, pulseURL, serverHost, tokenName, tokenName, storagePerms,
|
||||
sshKeys.ProxyPublicKey, sshKeys.SensorsPublicKey, minProxyReadyVersion,
|
||||
pulseURL, pulseURL, pulseURL, pulseURL, pulseURL, pulseURL, pulseURL, pulseURL, pulseURL, pulseURL, pulseURL, pulseURL, pulseURL, pulseURL, pulseURL, pulseURL, tokenName)
|
||||
authToken,
|
||||
storagePerms,
|
||||
sshKeys.ProxyPublicKey, sshKeys.SensorsPublicKey, minProxyReadyVersion)
|
||||
|
||||
} else { // PBS
|
||||
script = fmt.Sprintf(`#!/bin/bash
|
||||
|
||||
@@ -69,6 +69,7 @@ func TestPVESetupScriptArgumentAlignment(t *testing.T) {
|
||||
script := rr.Body.String()
|
||||
|
||||
// Critical alignment checks to prevent fmt.Sprintf argument mismatch bugs
|
||||
// After refactor: script uses bash variables ($PULSE_URL, $TOKEN_NAME) instead of fmt.Sprintf substitutions
|
||||
tests := []struct {
|
||||
name string
|
||||
contains string
|
||||
@@ -76,13 +77,13 @@ func TestPVESetupScriptArgumentAlignment(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "repair_installer_url",
|
||||
contains: `INSTALLER_URL="http://SENTINEL_URL:7656/api/install/install-sensor-proxy.sh"`,
|
||||
desc: "Repair block INSTALLER_URL should get pulseURL, not authToken",
|
||||
contains: `INSTALLER_URL="$PULSE_URL/api/install/install-sensor-proxy.sh"`,
|
||||
desc: "Repair block INSTALLER_URL should use $PULSE_URL bash variable",
|
||||
},
|
||||
{
|
||||
name: "repair_ctid_pulse_server",
|
||||
contains: `--pulse-server http://SENTINEL_URL:7656`,
|
||||
desc: "Repair --ctid --pulse-server should get pulseURL, not authToken",
|
||||
contains: `--pulse-server $PULSE_URL`,
|
||||
desc: "Repair --ctid --pulse-server should use $PULSE_URL bash variable",
|
||||
},
|
||||
{
|
||||
name: "runtime_auth_token_ssh_config",
|
||||
@@ -91,8 +92,18 @@ func TestPVESetupScriptArgumentAlignment(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "token_id_uses_tokenname",
|
||||
contains: `Token ID: pulse-monitor@pam!pulse-`,
|
||||
desc: "Token ID should use tokenName (pulse-*), not pulseURL or authToken",
|
||||
contains: `Token ID: $PULSE_TOKEN_ID`,
|
||||
desc: "Token ID should use $PULSE_TOKEN_ID bash variable",
|
||||
},
|
||||
{
|
||||
name: "bash_variables_defined",
|
||||
contains: `PULSE_URL="http://SENTINEL_URL:7656"`,
|
||||
desc: "Bash variable PULSE_URL should be defined at top of script",
|
||||
},
|
||||
{
|
||||
name: "token_name_variable_defined",
|
||||
contains: `TOKEN_NAME="pulse-SENTINEL_URL-`,
|
||||
desc: "Bash variable TOKEN_NAME should be defined with correct format",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ func (r *Router) setupRoutes() {
|
||||
updateHandlers := NewUpdateHandlers(r.updateManager, r.updateHistory)
|
||||
r.dockerAgentHandlers = NewDockerAgentHandlers(r.monitor, r.wsHub)
|
||||
r.hostAgentHandlers = NewHostAgentHandlers(r.monitor, r.wsHub)
|
||||
r.temperatureProxyHandlers = NewTemperatureProxyHandlers(r.persistence)
|
||||
r.temperatureProxyHandlers = NewTemperatureProxyHandlers(r.config, r.persistence, r.reloadFunc)
|
||||
|
||||
// API routes
|
||||
r.mux.HandleFunc("/api/health", r.handleHealth)
|
||||
@@ -1208,6 +1208,9 @@ func (r *Router) SetConfig(cfg *config.Config) {
|
||||
if r.systemSettingsHandler != nil {
|
||||
r.systemSettingsHandler.SetConfig(r.config)
|
||||
}
|
||||
if r.temperatureProxyHandlers != nil {
|
||||
r.temperatureProxyHandlers.SetConfig(r.config)
|
||||
}
|
||||
}
|
||||
|
||||
// reloadSystemSettings loads system settings from disk and caches them
|
||||
|
||||
@@ -22,7 +22,9 @@ import (
|
||||
|
||||
// TemperatureProxyHandlers manages temperature proxy registration
|
||||
type TemperatureProxyHandlers struct {
|
||||
config *config.Config
|
||||
persistence *config.ConfigPersistence
|
||||
reloadFunc func() error
|
||||
syncMu sync.RWMutex
|
||||
syncStatus map[string]proxySyncState
|
||||
}
|
||||
@@ -41,13 +43,22 @@ type authorizedNode struct {
|
||||
}
|
||||
|
||||
// NewTemperatureProxyHandlers constructs a new handler set for temperature proxy
|
||||
func NewTemperatureProxyHandlers(persistence *config.ConfigPersistence) *TemperatureProxyHandlers {
|
||||
func NewTemperatureProxyHandlers(cfg *config.Config, persistence *config.ConfigPersistence, reloadFunc func() error) *TemperatureProxyHandlers {
|
||||
return &TemperatureProxyHandlers{
|
||||
config: cfg,
|
||||
persistence: persistence,
|
||||
reloadFunc: reloadFunc,
|
||||
syncStatus: make(map[string]proxySyncState),
|
||||
}
|
||||
}
|
||||
|
||||
// SetConfig updates the configuration reference used by the handler.
|
||||
func (h *TemperatureProxyHandlers) SetConfig(cfg *config.Config) {
|
||||
if h != nil {
|
||||
h.config = cfg
|
||||
}
|
||||
}
|
||||
|
||||
func (h *TemperatureProxyHandlers) recordSync(instance string, refreshSeconds int) {
|
||||
if h == nil {
|
||||
return
|
||||
@@ -278,11 +289,28 @@ func (h *TemperatureProxyHandlers) HandleRegister(w http.ResponseWriter, r *http
|
||||
nodesConfig.PVEInstances[matchedIndex].TemperatureProxyControlToken = ctrlToken
|
||||
|
||||
// Save updated configuration
|
||||
log.Debug().
|
||||
Int("matchedIndex", matchedIndex).
|
||||
Str("saving_url", nodesConfig.PVEInstances[matchedIndex].TemperatureProxyURL).
|
||||
Bool("saving_has_token", nodesConfig.PVEInstances[matchedIndex].TemperatureProxyToken != "").
|
||||
Str("instance_name", nodesConfig.PVEInstances[matchedIndex].Name).
|
||||
Msg("About to save nodes config with proxy registration")
|
||||
if err := h.persistence.SaveNodesConfig(nodesConfig.PVEInstances, nodesConfig.PBSInstances, nodesConfig.PMGInstances); err != nil {
|
||||
writeErrorResponse(w, http.StatusInternalServerError, "config_save_failed", "Failed to save configuration", map[string]string{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Reload the entire config to ensure all components (router, monitor, handlers) get the fresh config
|
||||
// This prevents the monitor from later overwriting nodes.enc with stale data
|
||||
if h.reloadFunc != nil {
|
||||
if err := h.reloadFunc(); err != nil {
|
||||
log.Error().Err(err).Msg("Failed to reload config after temperature proxy registration")
|
||||
// Don't fail the request - the save succeeded, reload is best-effort
|
||||
} else {
|
||||
log.Info().Str("instance", matchedInstance.Name).Msg("Config reloaded after temperature proxy registration")
|
||||
}
|
||||
}
|
||||
|
||||
log.Info().
|
||||
Str("hostname", hostname).
|
||||
Str("proxy_url", proxyURL).
|
||||
|
||||
@@ -1738,17 +1738,35 @@ if [[ "$HTTP_MODE" == true ]]; then
|
||||
# Check if port is already in use
|
||||
PORT_NUMBER="${HTTP_ADDR#:}"
|
||||
if ss -ltn | grep -q ":${PORT_NUMBER} "; then
|
||||
print_error "Port ${PORT_NUMBER} is already in use"
|
||||
print_error ""
|
||||
print_error "Currently using port ${PORT_NUMBER}:"
|
||||
ss -ltnp | grep ":${PORT_NUMBER} " || true
|
||||
print_error ""
|
||||
print_error "Options:"
|
||||
print_error " 1. Stop the conflicting service"
|
||||
print_error " 2. Use a different port: --http-addr :PORT"
|
||||
print_error " 3. If this is a previous sensor-proxy, uninstall first:"
|
||||
print_error " $0 --uninstall"
|
||||
exit 1
|
||||
# Port is in use - check if it's our own service (refresh scenario)
|
||||
if systemctl is-active --quiet pulse-sensor-proxy 2>/dev/null; then
|
||||
# Check if the process using the port is pulse-sensor-proxy
|
||||
PORT_OWNER=$(ss -ltnp | grep ":${PORT_NUMBER} " | grep -o 'pulse-sensor-pr' || true)
|
||||
if [[ -n "$PORT_OWNER" ]]; then
|
||||
# Our service is using the port - this is a refresh, continue
|
||||
print_info "Existing pulse-sensor-proxy detected on port ${PORT_NUMBER} - will refresh configuration"
|
||||
else
|
||||
# Service is active but something else is using the port
|
||||
print_error "Port ${PORT_NUMBER} is already in use by another process"
|
||||
print_error ""
|
||||
print_error "Currently using port ${PORT_NUMBER}:"
|
||||
ss -ltnp | grep ":${PORT_NUMBER} " || true
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# Service not active, port conflict with something else
|
||||
print_error "Port ${PORT_NUMBER} is already in use"
|
||||
print_error ""
|
||||
print_error "Currently using port ${PORT_NUMBER}:"
|
||||
ss -ltnp | grep ":${PORT_NUMBER} " || true
|
||||
print_error ""
|
||||
print_error "Options:"
|
||||
print_error " 1. Stop the conflicting service"
|
||||
print_error " 2. Use a different port: --http-addr :PORT"
|
||||
print_error " 3. If this is a previous sensor-proxy, uninstall first:"
|
||||
print_error " $0 --uninstall"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Setup TLS certificates
|
||||
@@ -1814,12 +1832,19 @@ if [[ "$HTTP_MODE" == true ]]; then
|
||||
chmod 600 /etc/pulse-sensor-proxy/.http-auth-token
|
||||
chown pulse-sensor-proxy:pulse-sensor-proxy /etc/pulse-sensor-proxy/.http-auth-token
|
||||
|
||||
# Backup config before modifying
|
||||
# Backup config and token files before modifying
|
||||
if [[ -f /etc/pulse-sensor-proxy/config.yaml ]]; then
|
||||
BACKUP_CONFIG="/etc/pulse-sensor-proxy/config.yaml.backup.$(date +%s)"
|
||||
BACKUP_TIMESTAMP="$(date +%s)"
|
||||
BACKUP_CONFIG="/etc/pulse-sensor-proxy/config.yaml.backup.$BACKUP_TIMESTAMP"
|
||||
cp /etc/pulse-sensor-proxy/config.yaml "$BACKUP_CONFIG"
|
||||
print_info "Config backed up to: $BACKUP_CONFIG"
|
||||
|
||||
# Also backup token files so rollback restores matching secrets
|
||||
if [[ -f /etc/pulse-sensor-proxy/.pulse-control-token ]]; then
|
||||
BACKUP_CONTROL_TOKEN="/etc/pulse-sensor-proxy/.pulse-control-token.backup.$BACKUP_TIMESTAMP"
|
||||
cp /etc/pulse-sensor-proxy/.pulse-control-token "$BACKUP_CONTROL_TOKEN"
|
||||
fi
|
||||
|
||||
# Remove any existing HTTP configuration to prevent duplicates
|
||||
if grep -q "^# HTTP Mode Configuration" /etc/pulse-sensor-proxy/config.yaml; then
|
||||
print_info "Removing existing HTTP configuration..."
|
||||
@@ -1841,9 +1866,15 @@ if [[ "$HTTP_MODE" == true ]]; then
|
||||
|
||||
print_info "Pulse server detected at: $PULSE_IP"
|
||||
|
||||
# Append HTTP configuration to config.yaml
|
||||
# Configure HTTP mode - check if already configured to avoid duplicates
|
||||
print_info "Configuring HTTP mode..."
|
||||
cat >> /etc/pulse-sensor-proxy/config.yaml << EOF
|
||||
if grep -q "^http_enabled:" /etc/pulse-sensor-proxy/config.yaml 2>/dev/null; then
|
||||
# HTTP mode already configured - only update the token (avoid duplicates)
|
||||
sed -i "s|^http_auth_token:.*|http_auth_token: $HTTP_AUTH_TOKEN|" /etc/pulse-sensor-proxy/config.yaml
|
||||
print_info "Updated HTTP auth token (existing HTTP mode configuration kept)"
|
||||
else
|
||||
# Fresh HTTP mode configuration - append to file
|
||||
cat >> /etc/pulse-sensor-proxy/config.yaml << EOF
|
||||
|
||||
# HTTP Mode Configuration (External PVE Host)
|
||||
http_enabled: true
|
||||
@@ -1857,6 +1888,7 @@ allowed_source_subnets:
|
||||
- $PULSE_IP/32
|
||||
- 127.0.0.1/32
|
||||
EOF
|
||||
fi
|
||||
chown pulse-sensor-proxy:pulse-sensor-proxy /etc/pulse-sensor-proxy/config.yaml
|
||||
chmod 0644 /etc/pulse-sensor-proxy/config.yaml
|
||||
|
||||
@@ -1876,7 +1908,10 @@ fi
|
||||
# Stop existing service if running (for upgrades)
|
||||
if systemctl is-active --quiet pulse-sensor-proxy 2>/dev/null; then
|
||||
print_info "Stopping existing service for upgrade..."
|
||||
systemctl stop pulse-sensor-proxy
|
||||
# Tolerate timeout from slow HTTPS shutdown (can take 30s)
|
||||
systemctl stop pulse-sensor-proxy || true
|
||||
# Clear any failed state from the stop
|
||||
systemctl reset-failed pulse-sensor-proxy 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Install hardened systemd service
|
||||
@@ -2031,7 +2066,7 @@ if ! systemctl enable pulse-sensor-proxy.service; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! systemctl restart pulse-sensor-proxy.service; then
|
||||
if ! systemctl start pulse-sensor-proxy.service; then
|
||||
print_error "Failed to start pulse-sensor-proxy service"
|
||||
print_error ""
|
||||
|
||||
@@ -2040,7 +2075,14 @@ if ! systemctl restart pulse-sensor-proxy.service; then
|
||||
print_warn "Attempting to rollback to previous configuration..."
|
||||
if cp "$BACKUP_CONFIG" /etc/pulse-sensor-proxy/config.yaml; then
|
||||
print_info "Config restored from backup"
|
||||
if systemctl restart pulse-sensor-proxy.service; then
|
||||
# Also restore token files to match the old config
|
||||
if [[ -n "$BACKUP_CONTROL_TOKEN" && -f "$BACKUP_CONTROL_TOKEN" ]]; then
|
||||
cp "$BACKUP_CONTROL_TOKEN" /etc/pulse-sensor-proxy/.pulse-control-token
|
||||
print_info "Control plane token restored from backup"
|
||||
fi
|
||||
# Clear failed state before attempting rollback start
|
||||
systemctl reset-failed pulse-sensor-proxy 2>/dev/null || true
|
||||
if systemctl start pulse-sensor-proxy.service; then
|
||||
print_success "Service restarted with previous configuration"
|
||||
print_error ""
|
||||
print_error "HTTP mode installation failed but previous config restored"
|
||||
|
||||
Reference in New Issue
Block a user