Skip to content

Commit 4acf043

Browse files
committed
Merge branch 'ajwalker/refactor-steps-connector' into 'main'
Refactor Connector to allow setup before connection See merge request https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/6359 Merged-by: Arran Walker <ajwalker@gitlab.com> Approved-by: Cameron Swords <cswords@gitlab.com> Reviewed-by: Cameron Swords <cswords@gitlab.com> Reviewed-by: GitLab Duo <gitlab-duo@gitlab.com> Reviewed-by: Emmanuel 326 <nyariboemmanuel8@gmail.com>
2 parents a37676b + da9e60d commit 4acf043

14 files changed

Lines changed: 455 additions & 160 deletions

File tree

commands/steps/steps.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import (
2727

2828
const (
2929
SubCommandName = "steps"
30+
31+
readyMessage = "step-runner is ready."
3032
)
3133

3234
type IOStreams struct {
@@ -69,6 +71,7 @@ func Bootstrap(destination string) error {
6971
return os.Chmod(destination, 0o755)
7072
}
7173

74+
//nolint:gocognit
7275
func Serve(ctx context.Context, sockPath string, ioStreams IOStreams, cmdAndArgs ...string) error {
7376
listener, err := net.ListenUnix("unix", api.SocketAddr(sockPath))
7477
if err != nil {
@@ -87,6 +90,9 @@ func Serve(ctx context.Context, sockPath string, ioStreams IOStreams, cmdAndArgs
8790
srv := grpc.NewServer()
8891
proto.RegisterStepRunnerServer(srv, service)
8992

93+
ctx, cancel := context.WithCancel(ctx)
94+
defer cancel()
95+
9096
wg, ctx := errgroup.WithContext(ctx)
9197

9298
go func() {
@@ -102,8 +108,13 @@ func Serve(ctx context.Context, sockPath string, ioStreams IOStreams, cmdAndArgs
102108
return nil
103109
})
104110

111+
fmt.Fprintln(os.Stderr, readyMessage)
112+
105113
if len(cmdAndArgs) > 0 {
106114
wg.Go(func() error {
115+
// on script exit, we cancel() so that the step-runner serve also terminates
116+
defer cancel()
117+
107118
stdin := bufio.NewReader(ioStreams.Stdin)
108119

109120
stdinCheck := make(chan error, 1)

common/build.go

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ func (b *Build) StartBuild(
418418
return nil
419419
}
420420

421+
//nolint:gocognit
421422
func (b *Build) executeStepStage(ctx context.Context, connector steps.Connector, buildStage BuildStage, req []schema.Step) error {
422423
if ctx.Err() != nil {
423424
return ctx.Err()
@@ -453,30 +454,46 @@ func (b *Build) executeStepStage(ctx context.Context, connector steps.Connector,
453454
Variables: b.GetAllVariables(),
454455
}
455456

456-
err := steps.Execute(ctx, connector, info, req, stdout)
457-
if err != nil {
458-
berr := &BuildError{Inner: err}
459-
460-
var cserr *steps.ClientStatusError
461-
if errors.As(err, &cserr) {
462-
switch cserr.Status.State {
463-
case client.StateUnspecified:
464-
berr.FailureReason = UnknownFailure
465-
case client.StateFailure:
466-
berr.FailureReason = ScriptFailure
467-
}
468-
}
469-
470-
return berr
471-
}
472-
473-
return err
457+
return wrapStepStageErr(steps.Execute(ctx, connector, info, req, stdout))
474458
},
475459
}
476460

477461
return section.Execute(&b.logger)
478462
}
479463

464+
func wrapStepStageErr(err error) error {
465+
if err == nil {
466+
return nil
467+
}
468+
469+
if errors.Is(err, steps.ErrNoStepRunnerButOkay) {
470+
return nil
471+
}
472+
473+
berr := &BuildError{Inner: err}
474+
475+
var cserr *steps.ClientStatusError
476+
if errors.As(err, &cserr) {
477+
switch cserr.Status.State {
478+
case client.StateUnspecified:
479+
berr.FailureReason = UnknownFailure
480+
case client.StateFailure:
481+
berr.FailureReason = ScriptFailure
482+
}
483+
}
484+
485+
// hack: for now, we parse the exit code from the error response
486+
// later we might want to introduce a proper exit code from the step-runner
487+
// https://gitlab.com/gitlab-org/step-runner/-/work_items/349
488+
if _, code, ok := strings.Cut(err.Error(), "exit status"); ok {
489+
if exitCode, err := strconv.Atoi(strings.TrimSpace(code)); err == nil {
490+
berr.ExitCode = exitCode
491+
}
492+
}
493+
494+
return berr
495+
}
496+
480497
//nolint:gocognit
481498
func (b *Build) executeStage(ctx context.Context, buildStage BuildStage, executor Executor) error {
482499
if b.UseNativeSteps() {

common/mocks.go

Lines changed: 0 additions & 89 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

executors/docker/docker.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -883,19 +883,20 @@ func (e *executor) createContainerConfig(
883883
OpenStdin: true,
884884
StdinOnce: true,
885885
Entrypoint: e.overwriteEntrypoint(&imageDefinition),
886+
Env: e.Build.GetAllVariables().StringList(),
886887
}
887888

888-
// We should never really need to set the environment variables on the container,
889-
// as these are exported via the abstract shell.
890-
//
891-
// Adding these variables interferes with steps. Given this situation, when native
892-
// steps is enabled, we no longer add the env vars to the container.
893-
if !e.Build.UseNativeSteps() {
894-
config.Env = e.Build.GetAllVariables().StringList()
895-
}
896-
897-
// user config should only be set in build containers
889+
//nolint:nestif
898890
if containerType == buildContainerType {
891+
if e.Build.UseNativeSteps() {
892+
config.Cmd = append([]string{bootstrappedBinary, "steps", "serve"}, config.Cmd...)
893+
894+
// Environment variables interferes with steps. Given this situation, when
895+
// native steps are enabled, we no longer add the env vars to the container.
896+
config.Env = nil
897+
}
898+
899+
// user config should only be set in build containers
899900
if user, err := e.getBuildContainerUser(imageDefinition); err != nil {
900901
return nil, err
901902
} else {

executors/docker/docker_command.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -204,18 +204,12 @@ func (s *commandExecutor) requestBuildContainer() (*container.InspectResponse, e
204204
return s.buildContainer, nil
205205
}
206206

207-
// Overwrite the build container command if using steps
208-
cmd := s.BuildShell.DockerCommand
209-
if s.Build.UseNativeSteps() {
210-
cmd = append([]string{bootstrappedBinary, "steps", "serve"}, s.BuildShell.DockerCommand...)
211-
}
212-
213207
var err error
214208
s.buildContainer, err = s.createContainer(
215209
buildContainerType,
216210
s.Build.Image,
217211
[]string{},
218-
newDefaultContainerConfigurator(&s.executor, buildContainerType, s.Build.Image, cmd, []string{}),
212+
newDefaultContainerConfigurator(&s.executor, buildContainerType, s.Build.Image, s.BuildShell.DockerCommand, []string{}),
219213
)
220214
if err != nil {
221215
return nil, err

executors/docker/machine/machine.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ func (e *machineExecutor) GetMetricsSelector() string {
171171
return refereed.GetMetricsSelector()
172172
}
173173

174-
func (s *machineExecutor) Connect(ctx context.Context) (io.ReadWriteCloser, error) {
174+
func (s *machineExecutor) Connect(ctx context.Context) (func() (io.ReadWriteCloser, error), error) {
175175
if connector, ok := s.executor.(steps.Connector); ok {
176176
return connector.Connect(ctx)
177177
}

executors/docker/machine/machine_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"gitlab.com/gitlab-org/gitlab-runner/common"
1313
"gitlab.com/gitlab-org/gitlab-runner/helpers/docker"
1414
"gitlab.com/gitlab-org/gitlab-runner/session/terminal"
15+
"gitlab.com/gitlab-org/gitlab-runner/steps"
1516
)
1617

1718
func getRunnerConfig() *common.RunnerConfig {
@@ -135,7 +136,7 @@ func TestMachineCredentialsUsage(t *testing.T) {
135136
type mockDockerExecutor struct {
136137
*common.MockExecutor
137138
*terminal.MockInteractiveTerminal
138-
*common.MockConnector
139+
*steps.MockConnector
139140
}
140141

141142
func TestMachineExecutor_WithoutInteractiveTerminal(t *testing.T) {
@@ -177,7 +178,7 @@ func TestMachineExecutor_WithInteractiveTerminal(t *testing.T) {
177178
func TestMachineExecutor_Connect(t *testing.T) {
178179
mock := mockDockerExecutor{
179180
MockExecutor: common.NewMockExecutor(t),
180-
MockConnector: common.NewMockConnector(t),
181+
MockConnector: steps.NewMockConnector(t),
181182
}
182183
e := machineExecutor{
183184
executor: &mock,

0 commit comments

Comments
 (0)