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  }