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