Files
pulse/internal/monitoring/docker_identity_conflict.go
T
rcourtman 245177e531 Restore backend lint to green: real dedup + errcheck idiom fixes
golangci-lint had accumulated 12 findings since 5abb2d8f4. All fixed with
real dedup (no nolint suppressions) and the repo's existing errcheck idioms:

- dupl internal/monitoring: docker/host identity-conflict trackers were
  structural clones; extracted a shared identityFlapTracker core with a
  domain-neutral identityConflict result. Per-domain files now hold only
  the window const and the model translation. Tracker-behavior tests
  consolidated into identity_flap_tracker_test.go; Monitor-level
  translation and Apply*Report integration tests remain per domain.
- dupl internal/api/router.go: VM/container workload chart loops shared a
  16-line live-fallback block; extracted guestChartSeriesWithLiveFallback
  over a guestLiveMetricsView interface both views satisfy.
- dupl internal/storagehealth/risk.go: SMART attribute copying extracted
  into applySMARTAttributes shared by both assessors (same
  *models.SMARTAttributes type on both inputs).
- errcheck pkg/audit/sqlite_logger.go: three defer tx.Rollback() sites
  now use the repo-wide defer func() { _ = tx.Rollback() }() idiom.
- errcheck telemetry/notifications tests: send() errors now fail the
  test; queue.Stop() uses the package's _ = idiom.

Full test suites pass for all six touched packages.

Contract-Neutral: lint-hygiene restoration: dupl dedup (identical logic extracted to shared helpers) and errcheck idiom fixes; no public-contract or behavioral delta
2026-08-03 01:01:20 +01:00

39 lines
1.6 KiB
Go

package monitoring
import (
"time"
"github.com/rcourtman/pulse-go-rewrite/internal/models"
)
// dockerIdentityConflictWindow bounds how far apart two reports can be and
// still count as evidence that distinct machines share one identity. It also
// controls how long a detected conflict stays visible after the flapping
// stops (e.g. one of the clones was fixed or shut down). Sized to cover a few
// report cycles even for agents on multi-minute intervals.
const dockerIdentityConflictWindow = 15 * time.Minute
// trackDockerHostIdentity feeds one report's identity fields into the flap
// tracker for the resolved host identifier and returns the active conflict,
// if any. The secondary identity field is the reported machine ID: cloned
// VMs that share /etc/machine-id alternate hostnames every report cycle and
// trip the revisit detector immediately. Callers must not hold m.mu.
func (m *Monitor) trackDockerHostIdentity(identifier, hostname, machineID string, now time.Time) *models.DockerHostIdentityConflict {
conflict := m.observeIdentityFlap(&m.dockerIdentityFlaps, dockerIdentityConflictWindow, identifier, hostname, machineID, now)
if conflict == nil {
return nil
}
return &models.DockerHostIdentityConflict{
Hostnames: conflict.hostnames,
MachineIDs: conflict.secondaries,
FirstSeen: conflict.firstSeen,
LastSeen: conflict.lastSeen,
}
}
// clearDockerHostIdentityTrackingLocked drops flap state for a host identity,
// e.g. when the host is deliberately removed. Callers must hold m.mu.
func (m *Monitor) clearDockerHostIdentityTrackingLocked(hostID string) {
delete(m.dockerIdentityFlaps, hostID)
}