github.com/alloyci/alloy-runner@v1.0.1-0.20180222164613-925503ccafd6/executors/docker/executor_docker_command.go (about)

     1  package docker
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  
     7  	"github.com/docker/docker/api/types"
     8  	"gitlab.com/gitlab-org/gitlab-runner/common"
     9  	"gitlab.com/gitlab-org/gitlab-runner/executors"
    10  )
    11  
    12  type commandExecutor struct {
    13  	executor
    14  	buildContainer *types.ContainerJSON
    15  }
    16  
    17  func (s *commandExecutor) Prepare(options common.ExecutorPrepareOptions) error {
    18  	err := s.executor.Prepare(options)
    19  	if err != nil {
    20  		return err
    21  	}
    22  
    23  	s.Debugln("Starting Docker command...")
    24  
    25  	if len(s.BuildShell.DockerCommand) == 0 {
    26  		return errors.New("Script is not compatible with Docker")
    27  	}
    28  
    29  	_, err = s.getPrebuiltImage()
    30  	if err != nil {
    31  		return err
    32  	}
    33  
    34  	_, err = s.getBuildImage()
    35  	if err != nil {
    36  		return err
    37  	}
    38  	return nil
    39  }
    40  
    41  func (s *commandExecutor) requestNewPredefinedContainer() (*types.ContainerJSON, error) {
    42  	prebuildImage, err := s.getPrebuiltImage()
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  
    47  	buildImage := common.Image{
    48  		Name: prebuildImage.ID,
    49  	}
    50  
    51  	containerJSON, err := s.createContainer("predefined", buildImage, common.ContainerCommandBuild, []string{prebuildImage.ID})
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  
    56  	return containerJSON, err
    57  }
    58  
    59  func (s *commandExecutor) requestBuildContainer() (*types.ContainerJSON, error) {
    60  	if s.buildContainer == nil {
    61  		var err error
    62  
    63  		// Start build container which will run actual build
    64  		s.buildContainer, err = s.createContainer("build", s.Build.Image, s.BuildShell.DockerCommand, []string{})
    65  		if err != nil {
    66  			return nil, err
    67  		}
    68  	}
    69  
    70  	return s.buildContainer, nil
    71  }
    72  
    73  func (s *commandExecutor) Run(cmd common.ExecutorCommand) error {
    74  	var runOn *types.ContainerJSON
    75  	var err error
    76  	if cmd.Predefined {
    77  		runOn, err = s.requestNewPredefinedContainer()
    78  	} else {
    79  		runOn, err = s.requestBuildContainer()
    80  	}
    81  	if err != nil {
    82  		return err
    83  	}
    84  
    85  	s.Debugln("Executing on", runOn.Name, "the", cmd.Script)
    86  
    87  	s.SetCurrentStage(DockerExecutorStageRun)
    88  
    89  	return s.watchContainer(cmd.Context, runOn.ID, bytes.NewBufferString(cmd.Script))
    90  }
    91  
    92  func init() {
    93  	options := executors.ExecutorOptions{
    94  		DefaultBuildsDir: "/builds",
    95  		DefaultCacheDir:  "/cache",
    96  		SharedBuildsDir:  false,
    97  		Shell: common.ShellScriptInfo{
    98  			Shell:         "bash",
    99  			Type:          common.NormalShell,
   100  			RunnerCommand: "/usr/bin/gitlab-runner-helper",
   101  		},
   102  		ShowHostname: true,
   103  	}
   104  
   105  	creator := func() common.Executor {
   106  		e := &commandExecutor{
   107  			executor: executor{
   108  				AbstractExecutor: executors.AbstractExecutor{
   109  					ExecutorOptions: options,
   110  				},
   111  			},
   112  		}
   113  		e.SetCurrentStage(common.ExecutorStageCreated)
   114  		return e
   115  	}
   116  
   117  	featuresUpdater := func(features *common.FeaturesInfo) {
   118  		features.Variables = true
   119  		features.Image = true
   120  		features.Services = true
   121  	}
   122  
   123  	common.RegisterExecutor("docker", executors.DefaultExecutorProvider{
   124  		Creator:         creator,
   125  		FeaturesUpdater: featuresUpdater,
   126  	})
   127  }