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 controlling the stop signal for drivers #3591

Merged
merged 14 commits into from
Dec 7, 2017
Merged

Conversation

chelseakomlo
Copy link
Contributor

@chelseakomlo chelseakomlo commented Nov 27, 2017

See initial issue: #1755

This feature is only supported by drivers which accept signals.

This excludes rkt- we first need this PR to merge before extending support: rkt/rkt#3732

@nugend
Copy link

nugend commented Nov 29, 2017

Barring said idiomatic translation could you please expand the subset to include HUP, QUIT, and TERM

That should cover all the sane process termination signals.

edit: Sorry, I see now that QUIT is being used as the default. Does that mean that if someone accidentally typed "SIGTRM" as the value to use it would send SIGQUIT?

Copy link
Member

@schmichael schmichael left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few things to get this one merged:

  • Broke the Windows build. (see code comment)
  • Missing raw_exec support.
  • Need to update driver's Validate method to make sure a valid signal is specified. (thanks @nugend!)

case "SIGUSR2":
return syscall.SIGUSR2
default:
return syscall.SIGQUIT
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not all of these signals are available on every platform: https://ci.appveyor.com/project/hashicorp/nomad/build/build-b-1755-stop-1969/job/tt7wpyqorw9lvf7e

Oddly both executor_unix.go and executor_basic.go include windows in their build tags... It might be best to see if you can make executor_unix.go actually Unix-only and add a executor_windows.go for the Windows implementation of this function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. What do you think about validating on a per-platform basis then, against the subset of signals that are supported for that platform?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah! We already fingerprint signals. Looks like consul-template already has the list we need: https://github.com/hashicorp/nomad/blob/master/client/fingerprint/signal.go

@chelseakomlo chelseakomlo force-pushed the b-1755-stop branch 5 times, most recently from 2585f3e to d2e5ca7 Compare December 6, 2017 16:25
@chelseakomlo chelseakomlo changed the title Allow controlling the stop signal in exec/raw_exec Allow controlling the stop signal for drivers Dec 6, 2017
@chelseakomlo chelseakomlo force-pushed the b-1755-stop branch 5 times, most recently from 7f1d929 to 4adf93a Compare December 6, 2017 19:26
// specified. If it is not supported on the platform, returns an error.
func getTaskKillSignal(signal string) (os.Signal, error) {
if signal == "" {
return nil, nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not have it default to SIGINT

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was debating whether it should be here or in executor.go- having the default here would be good; changing.

@@ -201,6 +201,7 @@ type DockerDriverConfig struct {
MacAddress string `mapstructure:"mac_address"` // Pin mac address to container
SecurityOpt []string `mapstructure:"security_opt"` // Flags to pass directly to security-opt
Devices []DockerDevice `mapstructure:"devices"` // To allow mounting USB or other serial control devices
StopSignal string `mapstructure:"stop_signal"` // allow passing through a specific stop signal
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be removed since it is specified at the task level now

@@ -676,6 +678,7 @@ func ApiTaskToStructsTask(apiTask *api.Task, structsTask *structs.Task) {
structsTask.Meta = apiTask.Meta
structsTask.KillTimeout = *apiTask.KillTimeout
structsTask.ShutdownDelay = apiTask.ShutdownDelay
structsTask.KillSignal = apiTask.KillSignal
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add to test

jobspec/parse.go Outdated
@@ -623,6 +624,13 @@ func parseTasks(jobName string, taskGroupName string, result *[]*api.Task, list
WeaklyTypedInput: true,
Result: &t,
})

// this needs to be manually assigned
killsig := m["kill_signal"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this the case? The mapstructure decode should get this?


// getTaskKillSignal looks up the signal specified for the task if it has been
// specified. If it is not supported on the platform, returns an error.
func getTaskKillSignal(signal string) (os.Signal, error) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this same validation be used for signals to docker/other containers?

@@ -3221,6 +3226,10 @@ type Task struct {
// ShutdownDelay is the duration of the delay between deregistering a
// task from Consul and sending it a signal to shutdown. See #2441
ShutdownDelay time.Duration

// The kill signal to use for the task. This is an optional specification,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KillSignal is the kill signal to use for the task. See: https://github.com/golang/go/wiki/Comments

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -1978,6 +1978,11 @@ func (j *Job) RequiredSignals() map[string]map[string][]string {
taskSignals[task.Vault.ChangeSignal] = struct{}{}
}

// If a user has specified a KillSignal, add it to required signals
if task.KillSignal != "" {
taskSignals[task.KillSignal] = struct{}{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add to test

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

execCmd := &executor.ExecCommand{
Cmd: command,
Args: driverConfig.Args,
TaskKillSignal: taskKillSignal,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Java driver too

Copy link
Contributor Author

@chelseakomlo chelseakomlo Dec 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See 27b666e

@@ -496,9 +499,11 @@ func (e *UniversalExecutor) ShutDown() error {
}
return nil
}
if err = proc.Signal(os.Interrupt); err != nil && err.Error() != finishedErr {

if err = proc.Signal(e.command.TaskKillSignal); err != nil && err.Error() != finishedErr {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you will still need to default since it isn't being set on rkt

@@ -54,6 +54,11 @@ job "docs" {
[`max_kill_timeout`][max_kill] on the agent running the task, which has a
default value of 30 seconds.

- `kill_signal` `(string)` - Specifies a configurable kill signal for a task,
where the default is SIGINT. Note tha this is only supported for drivers
which accept sending signals (currently docker, exec, raw_exec, and java
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capitalize Docker and Java.

CHANGELOG.md Outdated
@@ -11,6 +11,8 @@ __BACKWARDS INCOMPATIBILITIES:__
IMPROVEMENTS:
* core: Allow operators to reload TLS certificate and key files via SIGHUP
[GH-3479]
* core: allow configurable stop signals for a task, when drivers support
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capitalize allow. Remove period before [GH-

@@ -1055,6 +1056,10 @@ func (d *DockerDriver) createContainerConfig(ctx *ExecContext, task *structs.Tas
StopTimeout: int(task.KillTimeout.Seconds()),
}

if task.KillSignal != "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this become:

config := &docker.Config{
  ...
  StopTimeout: int(task.KillTimeout.Seconds()),
  StopSignal: task.KillSignal,
}

@nugend
Copy link

nugend commented Dec 7, 2017

@chelseakomlo Thank you so much for working on this!

@chelseakomlo chelseakomlo merged commit dfb95fd into master Dec 7, 2017
@chelseakomlo chelseakomlo deleted the b-1755-stop branch December 7, 2017 22:06
@github-actions
Copy link

I'm going to lock this pull request because it has been closed for 120 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants