gitlab.com/jfprevost/gitlab-runner-notlscheck@v11.11.4+incompatible/common/executor.go (about) 1 package common 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 8 "github.com/sirupsen/logrus" 9 ) 10 11 type ExecutorData interface{} 12 13 type ExecutorCommand struct { 14 Script string 15 Stage BuildStage 16 Predefined bool 17 Context context.Context 18 } 19 20 type ExecutorStage string 21 22 const ( 23 ExecutorStageCreated ExecutorStage = "created" 24 ExecutorStagePrepare ExecutorStage = "prepare" 25 ExecutorStageFinish ExecutorStage = "finish" 26 ExecutorStageCleanup ExecutorStage = "cleanup" 27 ) 28 29 type ExecutorPrepareOptions struct { 30 Config *RunnerConfig 31 Build *Build 32 Trace JobTrace 33 User string 34 Context context.Context 35 } 36 37 type Executor interface { 38 Shell() *ShellScriptInfo 39 Prepare(options ExecutorPrepareOptions) error 40 Run(cmd ExecutorCommand) error 41 Finish(err error) 42 Cleanup() 43 GetCurrentStage() ExecutorStage 44 SetCurrentStage(stage ExecutorStage) 45 } 46 47 type ExecutorProvider interface { 48 CanCreate() bool 49 Create() Executor 50 Acquire(config *RunnerConfig) (ExecutorData, error) 51 Release(config *RunnerConfig, data ExecutorData) 52 GetFeatures(features *FeaturesInfo) error 53 GetDefaultShell() string 54 } 55 56 type BuildError struct { 57 Inner error 58 FailureReason JobFailureReason 59 } 60 61 func (b *BuildError) Error() string { 62 if b.Inner == nil { 63 return "error" 64 } 65 66 return b.Inner.Error() 67 } 68 69 func MakeBuildError(format string, args ...interface{}) error { 70 return &BuildError{ 71 Inner: fmt.Errorf(format, args...), 72 } 73 } 74 75 var executors map[string]ExecutorProvider 76 77 func validateExecutorProvider(provider ExecutorProvider) error { 78 if provider.GetDefaultShell() == "" { 79 return errors.New("default shell not implemented") 80 } 81 82 if !provider.CanCreate() { 83 return errors.New("cannot create executor") 84 } 85 86 if err := provider.GetFeatures(&FeaturesInfo{}); err != nil { 87 return fmt.Errorf("cannot get features: %v", err) 88 } 89 90 return nil 91 } 92 93 func RegisterExecutor(executor string, provider ExecutorProvider) { 94 logrus.Debugln("Registering", executor, "executor...") 95 96 if err := validateExecutorProvider(provider); err != nil { 97 panic("Executor cannot be registered: " + err.Error()) 98 } 99 100 if executors == nil { 101 executors = make(map[string]ExecutorProvider) 102 } 103 if _, ok := executors[executor]; ok { 104 panic("Executor already exist: " + executor) 105 } 106 executors[executor] = provider 107 } 108 109 func GetExecutor(executor string) ExecutorProvider { 110 if executors == nil { 111 return nil 112 } 113 114 provider, _ := executors[executor] 115 return provider 116 } 117 118 func GetExecutors() []string { 119 names := []string{} 120 if executors != nil { 121 for name := range executors { 122 names = append(names, name) 123 } 124 } 125 return names 126 } 127 128 func GetExecutorProviders() (providers []ExecutorProvider) { 129 if executors != nil { 130 for _, executorProvider := range executors { 131 providers = append(providers, executorProvider) 132 } 133 } 134 return 135 } 136 137 func NewExecutor(executor string) Executor { 138 provider := GetExecutor(executor) 139 if provider != nil { 140 return provider.Create() 141 } 142 143 return nil 144 }