@@ -165,6 +165,9 @@ const (
165165 PodReasonForceDelete IntervalReason = "ForceDelete"
166166 PodReasonDeleted IntervalReason = "Deleted"
167167 PodReasonScheduled IntervalReason = "Scheduled"
168+ PodReasonEvicted IntervalReason = "Evicted"
169+ PodReasonPreempted IntervalReason = "Preempted"
170+ PodReasonFailed IntervalReason = "Failed"
168171
169172 ContainerReasonContainerExit IntervalReason = "ContainerExit"
170173 ContainerReasonContainerStart IntervalReason = "ContainerStart"
@@ -184,6 +187,9 @@ const (
184187 NodeNotReadyReason IntervalReason = "NotReady"
185188 NodeFailedLease IntervalReason = "FailedToUpdateLease"
186189
190+ MachineConfigChangeReason IntervalReason = "MachineConfigChange"
191+ MachineConfigReachedReason IntervalReason = "MachineConfigReached"
192+
187193 Timeout IntervalReason = "Timeout"
188194
189195 E2ETestStarted IntervalReason = "E2ETestStarted"
@@ -196,6 +202,7 @@ const (
196202 AnnotationReason AnnotationKey = "reason"
197203 AnnotationContainerExitCode AnnotationKey = "code"
198204 AnnotationCause AnnotationKey = "cause"
205+ AnnotationConfig AnnotationKey = "config"
199206 AnnotationNode AnnotationKey = "node"
200207 AnnotationEtcdLocalMember AnnotationKey = "local-member-id"
201208 AnnotationEtcdTerm AnnotationKey = "term"
@@ -207,10 +214,18 @@ const (
207214 // TODO this looks wrong. seems like it ought to be set in the to/from
208215 AnnotationDuration AnnotationKey = "duration"
209216 AnnotationRequestAuditID AnnotationKey = "request-audit-id"
217+ AnnotationRoles AnnotationKey = "roles"
210218 AnnotationStatus AnnotationKey = "status"
211219 AnnotationCondition AnnotationKey = "condition"
212220)
213221
222+ // ConstructionOwner was originally meant to signify that an interval was derived from other intervals.
223+ // This allowed for the possibility of testing interval generation by feeding in only source intervals,
224+ // and checking what was generated.
225+ // TODO: likely want to drop this concept in favor of Source, plus a flag automatically applied to any
226+ // intervals coming back from the monitor test call to generate calculated intervals. Source
227+ // will replace the use of what constructed the interval, and the flag will allow us to see what is derived
228+ // and what isn't.
214229type ConstructionOwner string
215230
216231const (
@@ -229,6 +244,9 @@ type Message struct {
229244 Annotations map [AnnotationKey ]string `json:"annotations"`
230245}
231246
247+ // IntervalSource is used to type/categorize all intervals based on what created them.
248+ // This is intended to be used to group, and when combined with the display flag, signal that
249+ // they should be visible by default in the UIs that render interval charts.
232250type IntervalSource string
233251
234252const (
@@ -238,13 +256,16 @@ const (
238256 SourceE2ETest IntervalSource = "E2ETest"
239257 SourceNetworkManagerLog IntervalSource = "NetworkMangerLog"
240258 SourceNodeMonitor IntervalSource = "NodeMonitor"
259+ SourceSystemJournalScanner IntervalSource = "KubeletLogScanner"
241260 SourcePodLog IntervalSource = "PodLog"
242261 SourcePodMonitor IntervalSource = "PodMonitor"
243262 SourceKubeEvent IntervalSource = "KubeEvent"
244263 SourceTestData IntervalSource = "TestData" // some tests have no real source to assign
245264 SourcePathologicalEventMarker IntervalSource = "PathologicalEventMarker" // not sure if this is really helpful since the events all have a different origin
246265 SourceClusterOperatorMonitor IntervalSource = "ClusterOperatorMonitor"
247266 SourceOperatorState IntervalSource = "OperatorState"
267+ SourceNodeState = "NodeState"
268+ SourcePodState = "PodState"
248269)
249270
250271type Interval struct {
@@ -303,25 +324,73 @@ func (i Message) OldMessage() string {
303324}
304325
305326func (i Locator ) OldLocator () string {
306- keys := sets . NewString ()
327+ keys := [] string {}
307328 for k := range i .Keys {
308- keys . Insert ( string (k ))
329+ keys = append ( keys , string (k ))
309330 }
310331
332+ keys = sortKeys (keys )
333+
311334 annotations := []string {}
312- for _ , k := range keys . List () {
335+ for _ , k := range keys {
313336 v := i .Keys [LocatorKey (k )]
314337 if LocatorKey (k ) == LocatorE2ETestKey {
315338 annotations = append (annotations , fmt .Sprintf ("%v/%q" , k , v ))
316339 } else {
317340 annotations = append (annotations , fmt .Sprintf ("%v/%v" , k , v ))
318341 }
319342 }
343+
320344 annotationString := strings .Join (annotations , " " )
321345
322346 return annotationString
323347}
324348
349+ // sortKeys ensures that some keys appear in the order we require (least specific to most), so rows with locators
350+ // are grouped together. (i.e. keeping containers within the same pod together, or rows for a specific container)
351+ // Blindly going through the keys results in alphabetical ordering, container comes first, and then we've
352+ // got container events separated from their pod events on the intervals chart.
353+ // This will hopefully eventually go away but for now we need it.
354+ // Courtesy of ChatGPT but unit tested.
355+ func sortKeys (keys []string ) []string {
356+
357+ // Ensure these keys appear in this order. Other keys can be mixed in and will appear at the end in alphabetical
358+ // order.
359+ orderedKeys := []string {"namespace" , "node" , "pod" , "uid" , "server" , "container" , "shutdown" }
360+
361+ // Create a map to store the indices of keys in the orderedKeys array.
362+ // This will allow us to efficiently check if a key is in orderedKeys and find its position.
363+ orderedKeyIndices := make (map [string ]int )
364+
365+ for i , key := range orderedKeys {
366+ orderedKeyIndices [key ] = i
367+ }
368+
369+ // Define a custom sorting function that orders the keys based on the orderedKeys array.
370+ sort .Slice (keys , func (i , j int ) bool {
371+ // Get the indices of keys i and j in orderedKeys.
372+ indexI , existsI := orderedKeyIndices [keys [i ]]
373+ indexJ , existsJ := orderedKeyIndices [keys [j ]]
374+
375+ // If both keys exist in orderedKeys, sort them based on their order.
376+ if existsI && existsJ {
377+ return indexI < indexJ
378+ }
379+
380+ // If only one of the keys exists in orderedKeys, move it to the front.
381+ if existsI {
382+ return true
383+ } else if existsJ {
384+ return false
385+ }
386+
387+ // If neither key is in orderedKeys, sort alphabetically so we have predictable ordering
388+ return keys [i ] < keys [j ]
389+ })
390+
391+ return keys
392+ }
393+
325394type IntervalFilter func (i Interval ) bool
326395
327396type IntervalFilters []IntervalFilter
0 commit comments