github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/store/kubernetesdiscoverys/reducers.go (about) 1 package kubernetesdiscoverys 2 3 import ( 4 "time" 5 6 "github.com/tilt-dev/tilt/internal/controllers/apicmp" 7 "github.com/tilt-dev/tilt/internal/store" 8 "github.com/tilt-dev/tilt/internal/store/k8sconv" 9 "github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1" 10 "github.com/tilt-dev/tilt/pkg/model" 11 ) 12 13 func HandleKubernetesDiscoveryUpsertAction(state *store.EngineState, action KubernetesDiscoveryUpsertAction) { 14 n := action.KubernetesDiscovery.Name 15 oldState := state.KubernetesDiscoverys[n] 16 state.KubernetesDiscoverys[n] = action.KubernetesDiscovery 17 18 // We only refresh when the K8sDiscovery is changed. 19 // 20 // This is really only needed for tests - we have tests that wait until we've 21 // reached a steady state, then change some fields on EngineState. 22 // 23 // K8s controllers assume everything is idempotent, and will wipe out our changes 24 // later with duplicate events. 25 isChanged := oldState == nil || 26 !apicmp.DeepEqual(oldState.Status, action.KubernetesDiscovery.Status) || 27 !apicmp.DeepEqual(oldState.Spec, action.KubernetesDiscovery.Spec) 28 if isChanged { 29 RefreshKubernetesResource(state, n) 30 } 31 } 32 33 func HandleKubernetesDiscoveryDeleteAction(state *store.EngineState, action KubernetesDiscoveryDeleteAction) { 34 oldState := state.KubernetesDiscoverys[action.Name] 35 delete(state.KubernetesDiscoverys, action.Name) 36 37 isChanged := oldState != nil 38 if isChanged { 39 RefreshKubernetesResource(state, action.Name) 40 } 41 } 42 43 func filterForResource(state *store.EngineState, name string) (*k8sconv.KubernetesApplyFilter, error) { 44 a := state.KubernetesApplys[name] 45 if a == nil { 46 return nil, nil 47 } 48 49 // if the yaml matches the existing resource, use its filter to save re-parsing 50 // (https://github.com/tilt-dev/tilt/issues/5837) 51 if prevResource, ok := state.KubernetesResources[name]; ok { 52 if prevResource.ApplyStatus != nil && a.Status.ResultYAML == prevResource.ApplyStatus.ResultYAML { 53 return prevResource.ApplyFilter, nil 54 } 55 } 56 57 return k8sconv.NewKubernetesApplyFilter(a.Status.ResultYAML) 58 } 59 60 func RefreshKubernetesResource(state *store.EngineState, name string) { 61 var aStatus *v1alpha1.KubernetesApplyStatus 62 a := state.KubernetesApplys[name] 63 if a != nil { 64 aStatus = &(a.Status) 65 } 66 67 d := state.KubernetesDiscoverys[name] 68 filter, err := filterForResource(state, name) 69 if err != nil { 70 return 71 } 72 r := k8sconv.NewKubernetesResourceWithFilter(d, aStatus, filter) 73 state.KubernetesResources[name] = r 74 75 if a != nil { 76 mn := model.ManifestName(a.Annotations[v1alpha1.AnnotationManifest]) 77 ms, ok := state.ManifestState(mn) 78 if ok { 79 krs := ms.K8sRuntimeState() 80 81 if d == nil { 82 // if the KubernetesDiscovery goes away, we no longer know about any pods 83 krs.FilteredPods = nil 84 ms.RuntimeState = krs 85 return 86 } 87 88 krs.FilteredPods = r.FilteredPods 89 krs.Conditions = r.ApplyStatus.Conditions 90 91 if krs.RuntimeStatus() == v1alpha1.RuntimeStatusOK { 92 // NOTE(nick): It doesn't seem right to update this timestamp everytime 93 // we get a new event, but it's what the old code did. 94 krs.LastReadyOrSucceededTime = time.Now() 95 } 96 97 ms.RuntimeState = krs 98 } 99 } 100 }