in executors/kubernetes/kubernetes.go [748:812]
func (s *executor) runWithAttach(cmd common.ExecutorCommand) error {
ctx := cmd.Context
err := s.ensurePodsConfigured(ctx)
if err != nil {
return err
}
ctx, cancel := context.WithCancel(ctx)
defer cancel()
containerName, containerCommand := s.getContainerInfo(cmd)
err = s.saveScriptOnEmptyDir(ctx, s.scriptName(string(cmd.Stage)), containerName, cmd.Script)
if err != nil {
return err
}
s.BuildLogger.Debugln(fmt.Sprintf(
"Starting in container %q the command %q with script: %s",
containerName,
containerCommand,
cmd.Script,
))
podStatusCh := s.watchPodStatus(ctx, &podContainerStatusChecker{shouldCheckContainerFilter: isNotServiceContainer})
select {
case err := <-s.runInContainer(ctx, cmd.Stage, containerName, containerCommand):
s.BuildLogger.Debugln(fmt.Sprintf("Container %q exited with error: %v", containerName, err))
var terminatedError *commandTerminatedError
if err != nil && errors.As(err, &terminatedError) {
return &common.BuildError{Inner: err, ExitCode: terminatedError.exitCode}
}
return err
case err := <-podStatusCh:
if IsKubernetesPodNotFoundError(err) || IsKubernetesPodFailedError(err) || IsKubernetesPodContainerError(err) {
return err
}
return &common.BuildError{Inner: err}
case err := <-s.podWatcher.Errors():
// if we observe terminal pod errors via the pod watcher, we can exit immediately
return err
case <-ctx.Done():
s.remoteStageStatusMutex.Lock()
defer s.remoteStageStatusMutex.Unlock()
script := s.stageCancellationScript(string(cmd.Stage))
s.BuildLogger.Debugln("Running job cancellation script:", script)
if !s.remoteStageStatus.IsExited() {
err := <-s.runInContainerWithExec(
s.Context,
containerName,
s.BuildShell.DockerCommand,
script,
nil, nil,
)
s.BuildLogger.Debugln("Job cancellation script exited with error:", err)
}
return fmt.Errorf("build aborted")
}
}