Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow signal bootstrap sends to commands on cancel to be customized #1390

Merged
merged 2 commits into from
Mar 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions agent/job_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,11 @@ func (r *JobRunner) createEnvironment() ([]string, error) {
env["BUILDKITE_AGENT_EXPERIMENT"] = strings.Join(experiments.Enabled(), ",")
env["BUILDKITE_REDACTED_VARS"] = strings.Join(r.conf.AgentConfiguration.RedactedVars, ",")

// propagate CancelSignal to bootstrap, unless it's the default SIGTERM
if r.conf.CancelSignal != process.SIGTERM {
env["BUILDKITE_CANCEL_SIGNAL"] = r.conf.CancelSignal.String()
}

// Whether to enable profiling in the bootstrap
if r.conf.AgentConfiguration.Profile != "" {
env["BUILDKITE_AGENT_PROFILE"] = r.conf.AgentConfiguration.Profile
Expand Down
1 change: 1 addition & 0 deletions bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func (b *Bootstrap) Run(ctx context.Context) (exitCode int) {

b.shell.PTY = b.Config.RunInPty
b.shell.Debug = b.Config.Debug
b.shell.InterruptSignal = b.Config.CancelSignal
}

// Listen for cancellation
Expand Down
4 changes: 4 additions & 0 deletions bootstrap/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"log"

"github.com/buildkite/agent/v3/env"
"github.com/buildkite/agent/v3/process"
)

// Config provides the configuration for the Bootstrap. Some of the keys are
Expand Down Expand Up @@ -127,6 +128,9 @@ type Config struct {
// Phases to execute, defaults to all phases
Phases []string

// What signal to use for command cancellation
CancelSignal process.Signal

// List of environment variable globs to redact from job output
RedactedVars []string

Expand Down
27 changes: 16 additions & 11 deletions bootstrap/shell/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ type Shell struct {
// Currently running command
cmd *command
cmdLock sync.Mutex

// The signal to use to interrupt the command
InterruptSignal process.Signal
}

// New returns a new Shell
Expand Down Expand Up @@ -102,12 +105,13 @@ func (s *Shell) WithStdin(r io.Reader) *Shell {
defer s.cmdLock.Unlock()
// Can't copy struct like `newsh := *s` because sync.Mutex can't be copied.
return &Shell{
Logger: s.Logger,
Env: s.Env,
stdin: r, // our new stdin
Writer: s.Writer,
wd: s.wd,
ctx: s.ctx,
Logger: s.Logger,
Env: s.Env,
stdin: r, // our new stdin
Writer: s.Writer,
wd: s.wd,
ctx: s.ctx,
InterruptSignal: s.InterruptSignal,
}
}

Expand Down Expand Up @@ -375,11 +379,12 @@ func (s *Shell) buildCommand(ctx context.Context, name string, arg ...string) (*
}

cfg := process.Config{
Path: absPath,
Args: arg,
Env: s.Env.ToSlice(),
Stdin: s.stdin,
Dir: s.wd,
Path: absPath,
Args: arg,
Env: s.Env.ToSlice(),
Stdin: s.stdin,
Dir: s.wd,
InterruptSignal: s.InterruptSignal,
}

// Create a sub-context so that shell.Cancel() can interrupt
Expand Down
14 changes: 14 additions & 0 deletions clicommand/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/buildkite/agent/v3/cliconfig"
"github.com/buildkite/agent/v3/experiments"
"github.com/buildkite/agent/v3/logger"
"github.com/buildkite/agent/v3/process"
"github.com/urfave/cli"
)

Expand Down Expand Up @@ -81,6 +82,7 @@ type BootstrapConfig struct {
Experiments []string `cli:"experiment" normalize:"list"`
Phases []string `cli:"phases" normalize:"list"`
Profile string `cli:"profile"`
CancelSignal string `cli:"cancel-signal"`
RedactedVars []string `cli:"redacted-vars" normalize:"list"`
TracingBackend string `cli:"tracing-backend"`
}
Expand Down Expand Up @@ -297,6 +299,12 @@ var BootstrapCommand = cli.Command{
Usage: "The specific phases to execute. The order they're defined is irrelevant.",
EnvVar: "BUILDKITE_BOOTSTRAP_PHASES",
},
cli.StringFlag{
Name: "cancel-signal",
Usage: "The signal to use for cancellation",
EnvVar: "BUILDKITE_CANCEL_SIGNAL",
Value: "SIGTERM",
},
cli.StringSliceFlag{
Name: "redacted-vars",
Usage: "Pattern of environment variable names containing sensitive values",
Expand Down Expand Up @@ -353,6 +361,11 @@ var BootstrapCommand = cli.Command{
}
}

cancelSig, err := process.ParseSignal(cfg.CancelSignal)
if err != nil {
l.Fatal("Failed to parse cancel-signal: %v", err)
}

// Configure the bootstraper
bootstrap := bootstrap.New(bootstrap.Config{
Command: cfg.Command,
Expand Down Expand Up @@ -392,6 +405,7 @@ var BootstrapCommand = cli.Command{
SSHKeyscan: cfg.SSHKeyscan,
Shell: cfg.Shell,
Phases: cfg.Phases,
CancelSignal: cancelSig,
RedactedVars: cfg.RedactedVars,
TracingBackend: cfg.TracingBackend,
})
Expand Down