Fix version tracking deadlock - allow old agents to check in for updates
Problem: Version check middleware blocked old agents from checking in to receive update commands, creating a deadlock where agents couldn't upgrade because they were blocked from checking in. Solution: Modified MachineBindingMiddleware to allow old agents checking in for commands to proceed IF they have a pending update_agent command. This allows agents to receive the update command even when below minimum version. Changes: - Added grace period logic in middleware for command endpoints - Check if agent has pending update command before blocking - If update pending, allow check-in and log it - Added HasPendingUpdateCommand() to AgentQueries for checking pending updates - Also added same method to CommandQueries for completeness This prevents the version tracking deadlock while maintaining security for agents without pending updates. NOTE: Need to test that old agents can actually receive and execute update commands when allowed through this path.
This commit is contained in:
@@ -45,6 +45,20 @@ func (q *CommandQueries) GetPendingCommands(agentID uuid.UUID) ([]models.AgentCo
|
||||
return commands, err
|
||||
}
|
||||
|
||||
|
||||
// GetCommandsByAgentID retrieves all commands for a specific agent
|
||||
func (q *CommandQueries) GetCommandsByAgentID(agentID uuid.UUID) ([]models.AgentCommand, error) {
|
||||
var commands []models.AgentCommand
|
||||
query := `
|
||||
SELECT * FROM agent_commands
|
||||
WHERE agent_id = $1
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 100
|
||||
`
|
||||
err := q.db.Select(&commands, query, agentID)
|
||||
return commands, err
|
||||
}
|
||||
|
||||
// MarkCommandSent updates a command's status to sent
|
||||
func (q *CommandQueries) MarkCommandSent(id uuid.UUID) error {
|
||||
now := time.Now()
|
||||
@@ -460,3 +474,28 @@ func (q *CommandQueries) VerifyCommandsCompleted(commandIDs []string) ([]string,
|
||||
|
||||
return completedIDs, nil
|
||||
}
|
||||
|
||||
// HasPendingUpdateCommand checks if an agent has a pending update_agent command
|
||||
// This is used to allow old agents to check in and receive updates even if they're below minimum version
|
||||
func (q *CommandQueries) HasPendingUpdateCommand(agentID string) (bool, error) {
|
||||
var count int
|
||||
query := `
|
||||
SELECT COUNT(*)
|
||||
FROM agent_commands
|
||||
WHERE agent_id = $1
|
||||
AND command_type = 'update_agent'
|
||||
AND status = 'pending'
|
||||
`
|
||||
|
||||
agentUUID, err := uuid.Parse(agentID)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("invalid agent ID: %w", err)
|
||||
}
|
||||
|
||||
err = q.db.Get(&count, query, agentUUID)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to check for pending update commands: %w", err)
|
||||
}
|
||||
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user