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

#507 - make docker run handle SIGINT/SIGTERM #1249

Conversation

unclejack
Copy link
Contributor

This PR adds SIGTERM and SIGINT handling to docker run. When any of the two signals is received by a docker run process, docker stop will be run to try to stop the container. If the container fails to stop graciously in 4 seconds, it's killed by docker stop.

Observations:

  1. docker stop isn't called, the CmdStop function is called instead to avoid duplicating any code.
  2. Running things under a process monitoring solution will also require proper return codes, otherwise processes will always seem to be exiting cleanly.
  3. This PR doesn't break signal handling for bash running in a container (e.g.: `docker run -i -t ubuntu bash.. ^c).
  4. There's an issue with sending a SIGTERM/SIGINT to something which has set up a TTY:
$ docker run -i -t ubuntu bash
root@8158df67a66a:/# 
                     Received signal: interrupt; cleaning up
                                                            bk@bkm:~$

Questions:

  1. What SIGKILL timeout should be set for docker stop?
  2. How should the TTY output formatting issue be fixed?
  3. What other changes should be made?
  4. How could we test this?

This PR fixes #507.

@unclejack
Copy link
Contributor Author

It's time to cc a few persons who might want to review this and provide feedback.

/cc @shykes @creack @vieux @gabrtv @progrium

@vieux
Copy link
Contributor

vieux commented Jul 22, 2013

I know this PR produce the right behaviour, but I think many people, myself included, are used to do ctrl-c to exit the client and not the process. I think we should add a hint somewhere the the keystroke combination to detach. ( I can't remember it, as I always use ctrl+c ;) )

Maybe we could have a longer timeout, but if you press a second time ctrc+c, it call cmdKill ?

@unclejack
Copy link
Contributor Author

@vieux If you type ctrl-c, the signal will still be sent to the process you're running, e.g.: bash or something else.

ctrl+p ctrl-q detaches and SIGINT is still handled by the process running in the container. SIGTERM/SIGINT has to be sent to the docker process itself in order to stop it.

In my opinion, this PR only changes the behavior of the docker process spawned by docker run, not the behavior of anything else which may be running in the docker container.

Concerning the second signal, yes, we could do that.

@vieux
Copy link
Contributor

vieux commented Jul 23, 2013

ping @shykes @creack

signals := make(chan os.Signal, 1)
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
go func() {
for {
Copy link
Contributor

Choose a reason for hiding this comment

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

the for { loop is not really necessary, is it?. The goroutine should wait for any of the signals in the line below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There's a reason for having the for, we want to ask the container to stop more than just once if SIGINT/SIGTERM is received more than once.

@creack
Copy link
Contributor

creack commented Aug 9, 2013

LGTM, /cc @vieux @crosbymichael

@crosbymichael
Copy link
Contributor

LGTM

signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
go func() {
for {
sig := <-signals
Copy link
Contributor

Choose a reason for hiding this comment

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

This can be simplified to for sig := range signals {.

@ghost
Copy link

ghost commented Aug 12, 2013

I wanted to have signal handling very badly, so I wrote this little wrapper script, which handles INT/TERM/HUP and translates it to stop and restart. Have a look: https://github.com/lgierth/docker-exec

I knew this PR here is in the works, but solving the problem with a wrapping shell script seemed like a fun thing to do. It might also take a bit of pressure off this PR, since anybody who badly wants this feature can just use the script, and then switch to the official support once this PR is released.

@vieux
Copy link
Contributor

vieux commented Aug 12, 2013

LGTM

1 similar comment
@crosbymichael
Copy link
Contributor

LGTM

crosbymichael added a commit that referenced this pull request Aug 14, 2013
…ng_to_docker_run

#507 - make docker run handle SIGINT/SIGTERM
@crosbymichael crosbymichael merged commit 84a0274 into moby:master Aug 14, 2013
@unclejack unclejack deleted the 507-add_sigterm_sigint_handling_to_docker_run branch August 15, 2013 06:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Foreground containers should die gracefully when sent a kill signal
6 participants