-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Conversation
845904a
to
70324a1
Compare
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? |
There was a problem hiding this 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!)
client/driver/executor/executor.go
Outdated
case "SIGUSR2": | ||
return syscall.SIGUSR2 | ||
default: | ||
return syscall.SIGQUIT |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
2585f3e
to
d2e5ca7
Compare
d2e5ca7
to
a9ad4f8
Compare
7f1d929
to
4adf93a
Compare
add conversion for KillSignal for api/struct representation of task
4adf93a
to
359613e
Compare
client/driver/utils.go
Outdated
// specified. If it is not supported on the platform, returns an error. | ||
func getTaskKillSignal(signal string) (os.Signal, error) { | ||
if signal == "" { | ||
return nil, nil |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
client/driver/docker.go
Outdated
@@ -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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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"] |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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{}{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add to test
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Java driver too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See 27b666e
client/driver/executor/executor.go
Outdated
@@ -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 { |
There was a problem hiding this comment.
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
21e10d1
to
1b65853
Compare
1b65853
to
7d8dda8
Compare
@@ -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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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-
client/driver/docker.go
Outdated
@@ -1055,6 +1056,10 @@ func (d *DockerDriver) createContainerConfig(ctx *ExecContext, task *structs.Tas | |||
StopTimeout: int(task.KillTimeout.Seconds()), | |||
} | |||
|
|||
if task.KillSignal != "" { |
There was a problem hiding this comment.
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,
}
@chelseakomlo Thank you so much for working on this! |
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. |
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