func()

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")
	}
}