diff --git a/spn/captain/module.go b/spn/captain/module.go index c5279c4d..6ebee1a1 100644 --- a/spn/captain/module.go +++ b/spn/captain/module.go @@ -135,8 +135,9 @@ func start() error { crew.EnableConnecting(publicIdentity.Hub) } - // Initialize intel. - module.mgr.Go("start", func(wc *mgr.WorkerCtx) error { + // Initialize SPN intel. + // Do this synchronously to ensure everything is up to date before + err = module.mgr.Do("start", func(wc *mgr.WorkerCtx) error { if err := registerIntelUpdateHook(); err != nil { return err } @@ -145,6 +146,9 @@ func start() error { } return nil }) + if err != nil { + return err + } // Subscribe to updates of cranes. startDockHooks() diff --git a/spn/navigator/intel.go b/spn/navigator/intel.go index cd4501b4..43fff54a 100644 --- a/spn/navigator/intel.go +++ b/spn/navigator/intel.go @@ -67,14 +67,18 @@ func (m *Map) GetIntel() *hub.Intel { } func (m *Map) updateIntelStatuses(pin *Pin, trustNodes []string) { - // Reset all related states. - pin.removeStates(StateTrusted | StateUsageDiscouraged | StateUsageAsHomeDiscouraged | StateUsageAsDestinationDiscouraged) + // Reset all related states (StateSummaryStatusesAppliedFromIntel). + pin.stateIntelApplied.UnSet() + pin.removeStates(StateTrusted | StateUsageDiscouraged | StateUsageAsHomeDiscouraged | StateUsageAsDestinationDiscouraged) // same as: StateSummaryStatusesAppliedFromIntel // Check if Intel data is loaded. if m.intel == nil { return } + // Indicate that intel statuses have been applied to the pin + defer pin.stateIntelApplied.Set() + // Check Hub Intel hubIntel, ok := m.intel.Hubs[pin.Hub.ID] if ok { diff --git a/spn/navigator/options.go b/spn/navigator/options.go index 3e2407fa..708d7f7e 100644 --- a/spn/navigator/options.go +++ b/spn/navigator/options.go @@ -246,6 +246,14 @@ func (o *HubOptions) Matcher(hubType HubType, hubIntel *hub.Intel) PinMatcher { return false } + // Check if all required states from intel were applied. + if regard.HasAnyOf(StateSummaryStatusesAppliedFromIntel) || disregard.HasAnyOf(StateSummaryStatusesAppliedFromIntel) { + if pin.stateIntelApplied.IsNotSet() { + log.Warningf("spn/navigator: pin %s skipped as intel statuses were not applied", pin.Hub.ID) + return false + } + } + // Check verified owners. if len(o.RequireVerifiedOwners) > 0 { // Check if Pin has a verified owner at all. diff --git a/spn/navigator/pin.go b/spn/navigator/pin.go index 3c2b99bf..54571b6b 100644 --- a/spn/navigator/pin.go +++ b/spn/navigator/pin.go @@ -26,6 +26,10 @@ type Pin struct { //nolint:maligned // Hub Status State PinState + + // stateIntelApplied signifies that states from intel file were applied to the pin. + stateIntelApplied *abool.AtomicBool + // VerifiedOwner holds the name of the verified owner / operator of the Hub. VerifiedOwner string // HopDistance signifies the needed hops to reach this Hub. diff --git a/spn/navigator/state.go b/spn/navigator/state.go index 755e2895..dd260754 100644 --- a/spn/navigator/state.go +++ b/spn/navigator/state.go @@ -91,6 +91,12 @@ const ( StateOffline | StateUsageDiscouraged | StateIsHomeHub + + // StateSummaryStatusesAppliedFromIntel summarizes all states that are applied from the intel file. + StateSummaryStatusesAppliedFromIntel = StateTrusted | + StateUsageDiscouraged | + StateUsageAsHomeDiscouraged | + StateUsageAsDestinationDiscouraged ) var allStates = []PinState{ diff --git a/spn/navigator/update.go b/spn/navigator/update.go index f0b1a339..17b73ae3 100644 --- a/spn/navigator/update.go +++ b/spn/navigator/update.go @@ -168,9 +168,10 @@ func (m *Map) updateHub(h *hub.Hub, lockMap, lockHub bool) { pin.Hub = h } else { pin = &Pin{ - Hub: h, - ConnectedTo: make(map[string]*Lane), - pushChanges: abool.New(), + Hub: h, + ConnectedTo: make(map[string]*Lane), + stateIntelApplied: abool.New(), + pushChanges: abool.New(), } m.all[h.ID] = pin }