mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-11 14:00:29 +00:00
fix(agent): surface the real cause when reviewed actions go unavailable
Two diagnosability gaps found by exercising the docker-update vertical
live with a real agent, each of which turns 'approved action cannot
execute' into a dead end with no visible cause:
- The durable operation-receipt store failing to open (e.g. unwritable
state dir) silently registered the agent with receipt version 0; the
only symptom was a server-side claim that the agent was too old. The
agent now logs the real cause and state dir loudly at startup.
- The server readiness copy asserted 'older agent version' for any
receipt-version mismatch. It now names both causes (old version or
unavailable state directory) and points at the agent logs.
(The related docker collect-cycle watchdog landed separately in
a0f75b1bb with a hung-daemon reproducer.)
Contract-Neutral: agent-side diagnosability: receipt-store failure warning + honest readiness copy; no public contract delta
This commit is contained in:
@@ -326,7 +326,7 @@ func (e dockerContainerActionExecutor) CheckActionAvailable(ctx context.Context,
|
||||
agentID, _ := e.connectedDockerCommandAgentID(resource)
|
||||
liveCapability, supported := e.agents.(agentOperationReceiptCapability)
|
||||
if !supported || liveCapability.AgentOperationReceiptVersion(agentID) != operationreceipt.ProtocolVersion {
|
||||
return unavailableDockerActionReadiness(operation, "operation_receipt_unsupported", "The Pulse agent on this host is still on an older version that cannot run reviewed actions. Wait for the agent to update itself or update it manually, then retry.")
|
||||
return unavailableDockerActionReadiness(operation, "operation_receipt_unsupported", "The Pulse agent on this host cannot run reviewed actions: it is on an older version, or its durable state directory is unavailable. Update the agent, or check the agent logs if it is already current, then retry.")
|
||||
}
|
||||
return readiness
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ func hostStorageCleanupUnavailableReason(err error) string {
|
||||
case "host_commands_disabled":
|
||||
return "Typed host operations are disabled for this agent."
|
||||
case "operation_receipt_unsupported":
|
||||
return "The Pulse agent on this host is still on an older version that cannot run reviewed actions. Wait for the agent to update itself or update it manually, then retry."
|
||||
return "The Pulse agent on this host cannot run reviewed actions: it is on an older version, or its durable state directory is unavailable. Update the agent, or check the agent logs if it is already current, then retry."
|
||||
case "unsupported_cleanup_provider":
|
||||
return "This host does not expose a supported package-cache cleanup provider."
|
||||
case "cleanup_inventory_error":
|
||||
|
||||
@@ -272,7 +272,7 @@ func hostUpdateUnavailableReason(err error) string {
|
||||
case "host_commands_disabled":
|
||||
return "Typed host operations are disabled for this agent."
|
||||
case "operation_receipt_unsupported":
|
||||
return "The Pulse agent on this host is still on an older version that cannot run reviewed actions. Wait for the agent to update itself or update it manually, then retry."
|
||||
return "The Pulse agent on this host cannot run reviewed actions: it is on an older version, or its durable state directory is unavailable. Update the agent, or check the agent logs if it is already current, then retry."
|
||||
case "unsupported_package_manager":
|
||||
return "This host does not expose a supported package manager."
|
||||
case "package_inventory_error":
|
||||
|
||||
@@ -132,6 +132,14 @@ func NewCommandClient(cfg Config, agentID, hostname, platform, version string) *
|
||||
}
|
||||
|
||||
receipts, receiptErr := operationreceipt.Open(filepath.Join(stateDir, "operation-receipts.db"), hostOperationReceiptConfig())
|
||||
if receiptErr != nil {
|
||||
// Without the durable receipt store the agent registers with operation
|
||||
// receipt version 0 and Pulse refuses every reviewed action for this
|
||||
// host. Surface the real cause loudly; otherwise the only symptom is a
|
||||
// misleading "agent is too old" readiness message on the server.
|
||||
logger.Warn().Err(receiptErr).Str("state_dir", stateDir).
|
||||
Msg("Operation receipt store unavailable — Pulse will refuse reviewed actions for this agent until its state directory is writable")
|
||||
}
|
||||
return &CommandClient{
|
||||
pulseURL: strings.TrimRight(cfg.PulseURL, "/"),
|
||||
apiToken: cfg.APIToken,
|
||||
|
||||
Reference in New Issue
Block a user