mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
Compare commits
6 Commits
v1.10.3-rc
...
v1.10.3-rc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9968dd63a4 | ||
|
|
20f81dde9b | ||
|
|
320d17b2a2 | ||
|
|
0dbbaf76ab | ||
|
|
0e4f9457c0 | ||
|
|
f4dd90f40a |
@@ -11,8 +11,6 @@ be found.
|
||||
|
||||
- Fix Docker client exiting with an "Unrecognized input header" error [#20706](https://github.com/docker/docker/pull/20706)
|
||||
- Fix Docker exiting if Exec is started with both `AttachStdin` and `Detach` [#20647](https://github.com/docker/docker/pull/20647)
|
||||
- Fix loss of output in short-lived containers [#20729](https://github.com/docker/docker/pull/20729)
|
||||
- Fix an issue that caused the client to hang if the container process died [#20967](https://github.com/docker/docker/pull/20967)
|
||||
|
||||
### Distribution
|
||||
|
||||
|
||||
@@ -1093,9 +1093,7 @@ func killProcessDirectly(container *container.Container) error {
|
||||
if err != syscall.ESRCH {
|
||||
return err
|
||||
}
|
||||
e := errNoSuchProcess{pid, 9}
|
||||
logrus.Debug(e)
|
||||
return e
|
||||
logrus.Debugf("Cannot kill process (pid=%d) with signal 9: no such process.", pid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,9 +149,7 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd
|
||||
User: c.ProcessConfig.User,
|
||||
}
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
writers, err := setupPipes(container, &c.ProcessConfig, p, pipes, &wg)
|
||||
if err != nil {
|
||||
if err := setupPipes(container, &c.ProcessConfig, p, pipes); err != nil {
|
||||
return execdriver.ExitStatus{ExitCode: -1}, err
|
||||
}
|
||||
|
||||
@@ -173,10 +171,6 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd
|
||||
return execdriver.ExitStatus{ExitCode: -1}, err
|
||||
}
|
||||
|
||||
//close the write end of any opened pipes now that they are dup'ed into the container
|
||||
for _, writer := range writers {
|
||||
writer.Close()
|
||||
}
|
||||
// 'oom' is used to emit 'oom' events to the eventstream, 'oomKilled' is used
|
||||
// to set the 'OOMKilled' flag in state
|
||||
oom := notifyOnOOM(cont)
|
||||
@@ -205,9 +199,6 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd
|
||||
}
|
||||
ps = execErr.ProcessState
|
||||
}
|
||||
// wait for all IO goroutine copiers to finish
|
||||
wg.Wait()
|
||||
|
||||
cont.Destroy()
|
||||
destroyed = true
|
||||
// oomKilled will have an oom event if any process within the container was
|
||||
@@ -494,26 +485,24 @@ func (t *TtyConsole) Close() error {
|
||||
return t.console.Close()
|
||||
}
|
||||
|
||||
func setupPipes(container *configs.Config, processConfig *execdriver.ProcessConfig, p *libcontainer.Process, pipes *execdriver.Pipes, wg *sync.WaitGroup) ([]io.WriteCloser, error) {
|
||||
|
||||
writers := []io.WriteCloser{}
|
||||
func setupPipes(container *configs.Config, processConfig *execdriver.ProcessConfig, p *libcontainer.Process, pipes *execdriver.Pipes) error {
|
||||
|
||||
rootuid, err := container.HostUID()
|
||||
if err != nil {
|
||||
return writers, err
|
||||
return err
|
||||
}
|
||||
|
||||
if processConfig.Tty {
|
||||
cons, err := p.NewConsole(rootuid)
|
||||
if err != nil {
|
||||
return writers, err
|
||||
return err
|
||||
}
|
||||
term, err := NewTtyConsole(cons, pipes)
|
||||
if err != nil {
|
||||
return writers, err
|
||||
return err
|
||||
}
|
||||
processConfig.Terminal = term
|
||||
return writers, nil
|
||||
return nil
|
||||
}
|
||||
// not a tty--set up stdio pipes
|
||||
term := &execdriver.StdConsole{}
|
||||
@@ -528,7 +517,7 @@ func setupPipes(container *configs.Config, processConfig *execdriver.ProcessConf
|
||||
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
return writers, err
|
||||
return err
|
||||
}
|
||||
if pipes.Stdin != nil {
|
||||
go func() {
|
||||
@@ -537,32 +526,23 @@ func setupPipes(container *configs.Config, processConfig *execdriver.ProcessConf
|
||||
}()
|
||||
p.Stdin = r
|
||||
}
|
||||
return writers, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// if we have user namespaces enabled (rootuid != 0), we will set
|
||||
// up os pipes for stderr, stdout, stdin so we can chown them to
|
||||
// the proper ownership to allow for proper access to the underlying
|
||||
// fds
|
||||
var fds []uintptr
|
||||
|
||||
copyPipes := func(out io.Writer, in io.ReadCloser) {
|
||||
defer wg.Done()
|
||||
io.Copy(out, in)
|
||||
in.Close()
|
||||
}
|
||||
var fds []int
|
||||
|
||||
//setup stdout
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
w.Close()
|
||||
return writers, err
|
||||
return err
|
||||
}
|
||||
writers = append(writers, w)
|
||||
fds = append(fds, r.Fd(), w.Fd())
|
||||
fds = append(fds, int(r.Fd()), int(w.Fd()))
|
||||
if pipes.Stdout != nil {
|
||||
wg.Add(1)
|
||||
go copyPipes(pipes.Stdout, r)
|
||||
go io.Copy(pipes.Stdout, r)
|
||||
}
|
||||
term.Closers = append(term.Closers, r)
|
||||
p.Stdout = w
|
||||
@@ -570,14 +550,11 @@ func setupPipes(container *configs.Config, processConfig *execdriver.ProcessConf
|
||||
//setup stderr
|
||||
r, w, err = os.Pipe()
|
||||
if err != nil {
|
||||
w.Close()
|
||||
return writers, err
|
||||
return err
|
||||
}
|
||||
writers = append(writers, w)
|
||||
fds = append(fds, r.Fd(), w.Fd())
|
||||
fds = append(fds, int(r.Fd()), int(w.Fd()))
|
||||
if pipes.Stderr != nil {
|
||||
wg.Add(1)
|
||||
go copyPipes(pipes.Stderr, r)
|
||||
go io.Copy(pipes.Stderr, r)
|
||||
}
|
||||
term.Closers = append(term.Closers, r)
|
||||
p.Stderr = w
|
||||
@@ -585,10 +562,9 @@ func setupPipes(container *configs.Config, processConfig *execdriver.ProcessConf
|
||||
//setup stdin
|
||||
r, w, err = os.Pipe()
|
||||
if err != nil {
|
||||
r.Close()
|
||||
return writers, err
|
||||
return err
|
||||
}
|
||||
fds = append(fds, r.Fd(), w.Fd())
|
||||
fds = append(fds, int(r.Fd()), int(w.Fd()))
|
||||
if pipes.Stdin != nil {
|
||||
go func() {
|
||||
io.Copy(w, pipes.Stdin)
|
||||
@@ -597,11 +573,11 @@ func setupPipes(container *configs.Config, processConfig *execdriver.ProcessConf
|
||||
p.Stdin = r
|
||||
}
|
||||
for _, fd := range fds {
|
||||
if err := syscall.Fchown(int(fd), rootuid, rootuid); err != nil {
|
||||
return writers, fmt.Errorf("Failed to chown pipes fd: %v", err)
|
||||
if err := syscall.Fchown(fd, rootuid, rootuid); err != nil {
|
||||
return fmt.Errorf("Failed to chown pipes fd: %v", err)
|
||||
}
|
||||
}
|
||||
return writers, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// SupportsHooks implements the execdriver Driver interface.
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
@@ -53,19 +52,13 @@ func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessCo
|
||||
}
|
||||
|
||||
config := active.Config()
|
||||
wg := sync.WaitGroup{}
|
||||
writers, err := setupPipes(&config, processConfig, p, pipes, &wg)
|
||||
if err != nil {
|
||||
if err := setupPipes(&config, processConfig, p, pipes); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
if err := active.Start(p); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
//close the write end of any opened pipes now that they are dup'ed into the container
|
||||
for _, writer := range writers {
|
||||
writer.Close()
|
||||
}
|
||||
|
||||
if hooks.Start != nil {
|
||||
pid, err := p.Pid()
|
||||
@@ -90,7 +83,5 @@ func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessCo
|
||||
}
|
||||
ps = exitErr.ProcessState
|
||||
}
|
||||
// wait for all IO goroutine copiers to finish
|
||||
wg.Wait()
|
||||
return utils.ExitStatus(ps.Sys().(syscall.WaitStatus)), nil
|
||||
}
|
||||
|
||||
@@ -12,22 +12,6 @@ import (
|
||||
"github.com/docker/docker/pkg/signal"
|
||||
)
|
||||
|
||||
type errNoSuchProcess struct {
|
||||
pid int
|
||||
signal int
|
||||
}
|
||||
|
||||
func (e errNoSuchProcess) Error() string {
|
||||
return fmt.Sprintf("Cannot kill process (pid=%d) with signal %d: no such process.", e.pid, e.signal)
|
||||
}
|
||||
|
||||
// isErrNoSuchProcess returns true if the error
|
||||
// is an instance of errNoSuchProcess.
|
||||
func isErrNoSuchProcess(err error) bool {
|
||||
_, ok := err.(errNoSuchProcess)
|
||||
return ok
|
||||
}
|
||||
|
||||
// ContainerKill send signal to the container
|
||||
// If no signal is given (sig 0), then Kill with SIGKILL and wait
|
||||
// for the container to exit.
|
||||
@@ -103,9 +87,6 @@ func (daemon *Daemon) Kill(container *container.Container) error {
|
||||
// So, instead we'll give it up to 2 more seconds to complete and if
|
||||
// by that time the container is still running, then the error
|
||||
// we got is probably valid and so we return it to the caller.
|
||||
if isErrNoSuchProcess(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if container.IsRunning() {
|
||||
container.WaitStop(2 * time.Second)
|
||||
@@ -117,9 +98,6 @@ func (daemon *Daemon) Kill(container *container.Container) error {
|
||||
|
||||
// 2. Wait for the process to die, in last resort, try to kill the process directly
|
||||
if err := killProcessDirectly(container); err != nil {
|
||||
if isErrNoSuchProcess(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -131,9 +109,8 @@ func (daemon *Daemon) Kill(container *container.Container) error {
|
||||
func (daemon *Daemon) killPossiblyDeadProcess(container *container.Container, sig int) error {
|
||||
err := daemon.killWithSignal(container, sig)
|
||||
if err == syscall.ESRCH {
|
||||
e := errNoSuchProcess{container.GetPID(), sig}
|
||||
logrus.Debug(e)
|
||||
return e
|
||||
logrus.Debugf("Cannot kill process (pid=%d) with signal %d: no such process.", container.GetPID(), sig)
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -25,12 +25,6 @@ set -e
|
||||
|
||||
url='https://get.docker.com/'
|
||||
|
||||
key_servers="
|
||||
ha.pool.sks-keyservers.net
|
||||
pgp.mit.edu
|
||||
keyserver.ubuntu.com
|
||||
"
|
||||
|
||||
command_exists() {
|
||||
command -v "$@" > /dev/null 2>&1
|
||||
}
|
||||
@@ -105,10 +99,7 @@ rpm_import_repository_key() {
|
||||
local key=$1; shift
|
||||
local tmpdir=$(mktemp -d)
|
||||
chmod 600 "$tmpdir"
|
||||
for key_server in $key_servers ; do
|
||||
gpg --homedir "$tmpdir" --keyserver "$key_server" --recv-keys "$key" && break
|
||||
done
|
||||
gpg --homedir "$tmpdir" -k "$key" >/dev/null
|
||||
gpg --homedir "$tmpdir" --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"
|
||||
gpg --homedir "$tmpdir" --export --armor "$key" > "$tmpdir"/repo.key
|
||||
rpm --import "$tmpdir"/repo.key
|
||||
rm -rf "$tmpdir"
|
||||
@@ -418,10 +409,7 @@ do_install() {
|
||||
fi
|
||||
(
|
||||
set -x
|
||||
for key_server in $key_servers ; do
|
||||
$sh_c "apt-key adv --keyserver hkp://${key_server}:80 --recv-keys ${gpg_fingerprint}" && break
|
||||
done
|
||||
$sh_c "apt-key adv -k ${gpg_fingerprint} >/dev/null"
|
||||
$sh_c "apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D"
|
||||
$sh_c "mkdir -p /etc/apt/sources.list.d"
|
||||
$sh_c "echo deb [arch=$(dpkg --print-architecture)] https://apt.dockerproject.org/repo ${lsb_dist}-${dist_version} ${repo} > /etc/apt/sources.list.d/docker.list"
|
||||
$sh_c 'sleep 3; apt-get update; apt-get install -y -q docker-engine'
|
||||
|
||||
Reference in New Issue
Block a user