Fix Docker host display bug when multiple agents share API tokens (related to #658)

Root cause: findMatchingDockerHost() was matching hosts by token ID alone,
causing multiple Docker agents using the same API token to overwrite each
other in state. This resulted in only N visible hosts (where N = number of
unique tokens) instead of all M agents, with hosts "rotating" as each agent
reported every 10 seconds.

Example: 4 agents using 2 tokens would show only 2 hosts, rotating between
agents 1↔2 (token A) and agents 3↔4 (token B).

Fix: Remove token-only matching from findMatchingDockerHost(). Hosts should
only match by:
1. Agent ID (unique per agent)
2. Machine ID + hostname combination (with optional token validation)
3. Machine ID or hostname alone (only for tokenless agents)

This allows multiple agents to share the same API token without colliding.

Additional fix: UpsertDockerHost() now preserves Hidden, PendingUninstall,
and Command fields from existing hosts, preventing these flags from being
reset to defaults on every agent report.
This commit is contained in:
rcourtman 2025-11-07 13:46:35 +00:00
parent 9199892115
commit 7ee252bd84
2 changed files with 7 additions and 8 deletions

View file

@ -1136,6 +1136,13 @@ func (s *State) UpsertDockerHost(host DockerHost) {
if existing.CustomDisplayName != "" {
host.CustomDisplayName = existing.CustomDisplayName
}
// Preserve Hidden and PendingUninstall flags
host.Hidden = existing.Hidden
host.PendingUninstall = existing.PendingUninstall
// Preserve Command if it exists
if existing.Command != nil {
host.Command = existing.Command
}
s.DockerHosts[i] = host
updated = true
break

View file

@ -1304,14 +1304,6 @@ func findMatchingDockerHost(hosts []models.DockerHost, report agentsdocker.Repor
}
}
if tokenID != "" {
for _, host := range hosts {
if strings.TrimSpace(host.TokenID) == tokenID {
return host, true
}
}
}
if machineID != "" && hostname != "" {
for _, host := range hosts {
if strings.TrimSpace(host.MachineID) == machineID && strings.TrimSpace(host.Hostname) == hostname {