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  }