github.com/quay/claircore@v1.5.28/indexer/controller/state.go (about) 1 package controller 2 3 import ( 4 "context" 5 "encoding/json" 6 ) 7 8 // State is a specific state in the indexer fsm 9 type State int 10 11 // States and their explanations. 12 // Each state is implemented by a stateFunc implemented in their own files. 13 const ( 14 // Terminal is the state which halts the fsm and returns the current s.result to the caller 15 Terminal State = iota 16 // CheckManifest determines if the manifest should be scanned. 17 // if no Terminal is returned and we return the existing IndexReport. 18 // Transitions: FetchLayers, Terminal 19 CheckManifest 20 // FetchLayers retrieves all the layers in a manifest and stacks them the same obtain the file image contents. 21 // creates the "image" layer 22 // Transitions: ScanLayers 23 FetchLayers 24 // ScanLayers scans each image including the image layer and indexes the contents 25 // Transitions: Coalesce 26 ScanLayers 27 // Coalesce runs each provided ecosystem's coalescer and merges their scan results 28 // Transitions: IndexManifest 29 Coalesce 30 // IndexManifest evaluates a coalesced IndexReport and writes it's contents 31 // to the the persistence layer where it maybe searched. 32 // Transitions: IndexFinished 33 IndexManifest 34 // IndexError state indicates a impassable error has occurred. 35 // returns a ScanResult with the error field 36 // Transitions: Terminal 37 IndexError 38 // IndexFinished state is the terminal state and should return a IndexReport 39 // to the caller of Scan() 40 // Transitions: Terminal 41 IndexFinished 42 ) 43 44 func (ss State) String() string { 45 names := [...]string{ 46 "Terminal", 47 "CheckManifest", 48 "FetchLayers", 49 "ScanLayers", 50 "Coalesce", 51 "IndexManifest", 52 "IndexError", 53 "IndexFinished", 54 } 55 return names[ss] 56 } 57 58 func (ss *State) FromString(state string) { 59 switch state { 60 case "Terminal": 61 *ss = Terminal 62 case "CheckManifest": 63 *ss = CheckManifest 64 case "FetchLayers": 65 *ss = FetchLayers 66 case "ScanLayers": 67 *ss = ScanLayers 68 case "Coalesce": 69 *ss = Coalesce 70 case "IndexManifest": 71 *ss = IndexManifest 72 case "IndexError": 73 *ss = IndexError 74 case "IndexFinished": 75 *ss = IndexFinished 76 } 77 } 78 79 func (ss State) MarshalJSON() ([]byte, error) { 80 return json.Marshal(ss.String()) 81 } 82 83 func (ss *State) UnmarshalJSON(data []byte) error { 84 var temp string 85 if err := json.Unmarshal(data, &temp); err != nil { 86 return err 87 } 88 89 ss.FromString(temp) 90 return nil 91 } 92 93 // stateFunc implement the logic of our controller and map directly to States. 94 // returning an error will exit the controller in an error state. 95 // returning Terminal ends the controller in a non error state. 96 type stateFunc func(context.Context, *Controller) (State, error) 97 98 // provides a mapping of States to their implemented stateFunc methods 99 var stateToStateFunc = map[State]stateFunc{ 100 CheckManifest: checkManifest, 101 FetchLayers: fetchLayers, 102 ScanLayers: scanLayers, 103 Coalesce: coalesce, 104 IndexManifest: indexManifest, 105 IndexFinished: indexFinished, 106 }