Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package docker for openSUSE:Factory checked in at 2023-07-09 20:39:06 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/docker (Old) and /work/SRC/openSUSE:Factory/.docker.new.23466 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "docker" Sun Jul 9 20:39:06 2023 rev:134 rq:1097636 version:24.0.4_ce Changes: -------- --- /work/SRC/openSUSE:Factory/docker/docker.changes 2023-06-30 19:58:07.741378236 +0200 +++ /work/SRC/openSUSE:Factory/.docker.new.23466/docker.changes 2023-07-09 20:39:08.216695696 +0200 @@ -1,0 +2,14 @@ +Fri Jul 7 21:29:05 UTC 2023 - Aleksa Sarai <[email protected]> + +- Update to Docker 24.0.4-ce. See upstream changelog online at + <https://docs.docker.com/engine/release-notes/24.0/#2404>. + +------------------------------------------------------------------- +Fri Jul 7 02:35:02 UTC 2023 - Aleksa Sarai <[email protected]> + +- Update to Docker 24.0.3-ce. See upstream changelog online at + <https://docs.docker.com/engine/release-notes/24.0/#2403>. bsc#1213120 +- Rebase patches: + * cli-0001-docs-include-required-tools-in-source-tree.patch + +------------------------------------------------------------------- Old: ---- docker-24.0.2_ce_659604f9ee60.tar.xz docker-cli-24.0.2_ce.tar.xz New: ---- docker-24.0.4_ce_4ffc61430bbe.tar.xz docker-cli-24.0.4_ce.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ docker.spec ++++++ --- /var/tmp/diff_new_pack.rRJntR/_old 2023-07-09 20:39:09.600704024 +0200 +++ /var/tmp/diff_new_pack.rRJntR/_new 2023-07-09 20:39:09.604704048 +0200 @@ -31,9 +31,9 @@ # helpfully injects into our build environment from the changelog). If you want # to generate a new git_commit_epoch, use this: # $ date --date="$(git show --format=fuller --date=iso $COMMIT_ID | grep -oP '(?<=^CommitDate: ).*')" '+%s' -%define real_version 24.0.2 -%define git_version 659604f9ee60 -%define git_commit_epoch 1685049742 +%define real_version 24.0.4 +%define git_version 4ffc61430bbe +%define git_commit_epoch 1688740946 Name: docker Version: %{real_version}_ce @@ -86,7 +86,7 @@ BuildRequires: go-go-md2man BuildRequires: pkgconfig(libsystemd) BuildRequires: sysuser-tools -BuildRequires: golang(API) = 1.19 +BuildRequires: golang(API) = 1.20 %if 0%{?sle_version} >= 150000 # This conditional only works on rpm>=4.13, which SLE 12 doesn't have. But we # don't need to support Docker+selinux for SLE 12 anyway. ++++++ _service ++++++ --- /var/tmp/diff_new_pack.rRJntR/_old 2023-07-09 20:39:09.668704433 +0200 +++ /var/tmp/diff_new_pack.rRJntR/_new 2023-07-09 20:39:09.672704457 +0200 @@ -3,16 +3,16 @@ <param name="url">https://github.com/moby/moby.git</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="versionformat">24.0.2_ce_%h</param> - <param name="revision">v24.0.2</param> + <param name="versionformat">24.0.4_ce_%h</param> + <param name="revision">v24.0.4</param> <param name="filename">docker</param> </service> <service name="tar_scm" mode="disabled"> <param name="url">https://github.com/docker/cli.git</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="versionformat">24.0.2_ce</param> - <param name="revision">v24.0.2</param> + <param name="versionformat">24.0.4_ce</param> + <param name="revision">v24.0.4</param> <param name="filename">docker-cli</param> </service> <service name="recompress" mode="disabled"> ++++++ cli-0001-docs-include-required-tools-in-source-tree.patch ++++++ --- /var/tmp/diff_new_pack.rRJntR/_old 2023-07-09 20:39:09.688704553 +0200 +++ /var/tmp/diff_new_pack.rRJntR/_new 2023-07-09 20:39:09.692704578 +0200 @@ -1,4 +1,4 @@ -From c46107746f7676a09590008584a17d3f907f7926 Mon Sep 17 00:00:00 2001 +From 3461d391fcee06e89b3bb4768bc15779d92388b8 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai <[email protected]> Date: Wed, 26 Apr 2023 10:13:48 +1000 Subject: [PATCH] docs: include required tools in source tree @@ -395,7 +395,7 @@ mkdir -p docs/yaml set -x diff --git a/vendor.mod b/vendor.mod -index 9b171b28e5b3..0aeec6f36cc5 100644 +index 93b252033bb8..694d6bb790e9 100644 --- a/vendor.mod +++ b/vendor.mod @@ -8,7 +8,9 @@ go 1.18 @@ -406,7 +406,7 @@ github.com/creack/pty v1.1.18 + github.com/docker/cli-docs-tool v0.5.1 github.com/docker/distribution v2.8.2+incompatible - github.com/docker/docker v24.0.1+incompatible + github.com/docker/docker v24.0.2+incompatible github.com/docker/docker-credential-helpers v0.7.0 @@ -67,6 +69,7 @@ require ( github.com/prometheus/common v0.37.0 // indirect @@ -423,7 +423,7 @@ + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/vendor.sum b/vendor.sum -index adb8ce424999..b577d7bb7242 100644 +index 15bc7cd703d3..55870c81da53 100644 --- a/vendor.sum +++ b/vendor.sum @@ -85,6 +85,7 @@ github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u9 @@ -23717,7 +23717,7 @@ + +} diff --git a/vendor/modules.txt b/vendor/modules.txt -index 5fc4fe641043..8dfd03ef0dd2 100644 +index 1baed2ba4d14..c3e1679730a4 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -18,9 +18,17 @@ github.com/containerd/containerd/errdefs @@ -23766,6 +23766,6 @@ ## explicit; go 1.13 gotest.tools/v3/assert -- -2.40.1 +2.41.0 ++++++ docker-24.0.2_ce_659604f9ee60.tar.xz -> docker-24.0.4_ce_4ffc61430bbe.tar.xz ++++++ /work/SRC/openSUSE:Factory/docker/docker-24.0.2_ce_659604f9ee60.tar.xz /work/SRC/openSUSE:Factory/.docker.new.23466/docker-24.0.4_ce_4ffc61430bbe.tar.xz differ: char 15, line 1 ++++++ docker-cli-24.0.2_ce.tar.xz -> docker-cli-24.0.4_ce.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/.github/workflows/test.yml new/docker-cli-24.0.4_ce/.github/workflows/test.yml --- old/docker-cli-24.0.2_ce/.github/workflows/test.yml 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/.github/workflows/test.yml 2023-06-30 19:55:44.000000000 +0200 @@ -63,7 +63,7 @@ name: Set up Go uses: actions/setup-go@v4 with: - go-version: 1.20.4 + go-version: 1.20.5 - name: Test run: | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/Dockerfile new/docker-cli-24.0.4_ce/Dockerfile --- old/docker-cli-24.0.2_ce/Dockerfile 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/Dockerfile 2023-06-30 19:55:44.000000000 +0200 @@ -1,12 +1,12 @@ # syntax=docker/dockerfile:1 ARG BASE_VARIANT=alpine -ARG GO_VERSION=1.20.4 -ARG ALPINE_VERSION=3.16 +ARG GO_VERSION=1.20.5 +ARG ALPINE_VERSION=3.17 ARG XX_VERSION=1.1.1 ARG GOVERSIONINFO_VERSION=v1.3.0 -ARG GOTESTSUM_VERSION=v1.8.2 -ARG BUILDX_VERSION=0.10.4 +ARG GOTESTSUM_VERSION=v1.10.0 +ARG BUILDX_VERSION=0.11.0 FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/cli/command/cli.go new/docker-cli-24.0.4_ce/cli/command/cli.go --- old/docker-cli-24.0.2_ce/cli/command/cli.go 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/cli/command/cli.go 2023-06-30 19:55:44.000000000 +0200 @@ -8,7 +8,6 @@ "path/filepath" "runtime" "strconv" - "strings" "sync" "time" @@ -327,13 +326,8 @@ func (cli *DockerCli) initializeFromClient() { ctx := context.Background() - if !strings.HasPrefix(cli.dockerEndpoint.Host, "ssh://") { - // @FIXME context.WithTimeout doesn't work with connhelper / ssh connections - // time="2020-04-10T10:16:26Z" level=warning msg="commandConn.CloseWrite: commandconn: failed to wait: signal: killed" - var cancel func() - ctx, cancel = context.WithTimeout(ctx, cli.getInitTimeout()) - defer cancel() - } + ctx, cancel := context.WithTimeout(ctx, cli.getInitTimeout()) + defer cancel() ping, err := cli.client.Ping(ctx) if err != nil { @@ -381,7 +375,7 @@ // the "default" context is used if: // // - The "--host" option is set -// - The "DOCKER_HOST" ([DefaultContextName]) environment variable is set +// - The "DOCKER_HOST" ([client.EnvOverrideHost]) environment variable is set // to a non-empty value. // // In these cases, the default context is used, which uses the host as diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/cli/command/context/use_test.go new/docker-cli-24.0.4_ce/cli/command/context/use_test.go --- old/docker-cli-24.0.2_ce/cli/command/context/use_test.go 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/cli/command/context/use_test.go 2023-06-30 19:55:44.000000000 +0200 @@ -6,6 +6,7 @@ "io" "os" "path/filepath" + "runtime" "testing" "github.com/docker/cli/cli/command" @@ -13,7 +14,6 @@ "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/flags" "github.com/docker/docker/errdefs" - "github.com/docker/docker/pkg/homedir" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" ) @@ -57,7 +57,11 @@ // the _default_ configuration file. If we specify a custom configuration // file, the CLI produces an error if the file doesn't exist. tmpHomeDir := t.TempDir() - t.Setenv(homedir.Key(), tmpHomeDir) + if runtime.GOOS == "windows" { + t.Setenv("USERPROFILE", tmpHomeDir) + } else { + t.Setenv("HOME", tmpHomeDir) + } configDir := filepath.Join(tmpHomeDir, ".docker") configFilePath := filepath.Join(configDir, "config.json") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/cli/command/system/info.go new/docker-cli-24.0.4_ce/cli/command/system/info.go --- old/docker-cli-24.0.2_ce/cli/command/system/info.go 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/cli/command/system/info.go 2023-06-30 19:55:44.000000000 +0200 @@ -313,7 +313,12 @@ fprintln(output, " Docker Root Dir:", info.DockerRootDir) fprintln(output, " Debug Mode:", info.Debug) - if info.Debug { + // The daemon collects this information regardless if "debug" is + // enabled. Print the debugging information if either the daemon, + // or the client has debug enabled. We should probably improve this + // logic and print any of these if set (but some special rules are + // needed for file-descriptors, which may use "-1". + if info.Debug || debug.IsEnabled() { fprintln(output, " File Descriptors:", info.NFd) fprintln(output, " Goroutines:", info.NGoroutines) fprintln(output, " System Time:", info.SystemTime) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/cli/connhelper/commandconn/commandconn.go new/docker-cli-24.0.4_ce/cli/connhelper/commandconn/commandconn.go --- old/docker-cli-24.0.2_ce/cli/connhelper/commandconn/commandconn.go 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/cli/connhelper/commandconn/commandconn.go 2023-06-30 19:55:44.000000000 +0200 @@ -23,6 +23,7 @@ "runtime" "strings" "sync" + "sync/atomic" "syscall" "time" @@ -64,81 +65,68 @@ // commandConn implements net.Conn type commandConn struct { - cmd *exec.Cmd - cmdExited bool - cmdWaitErr error - cmdMutex sync.Mutex - stdin io.WriteCloser - stdout io.ReadCloser - stderrMu sync.Mutex - stderr bytes.Buffer - stdioClosedMu sync.Mutex // for stdinClosed and stdoutClosed - stdinClosed bool - stdoutClosed bool - localAddr net.Addr - remoteAddr net.Addr -} - -// killIfStdioClosed kills the cmd if both stdin and stdout are closed. -func (c *commandConn) killIfStdioClosed() error { - c.stdioClosedMu.Lock() - stdioClosed := c.stdoutClosed && c.stdinClosed - c.stdioClosedMu.Unlock() - if !stdioClosed { - return nil + cmdMutex sync.Mutex // for cmd, cmdWaitErr + cmd *exec.Cmd + cmdWaitErr error + cmdExited atomic.Bool + stdin io.WriteCloser + stdout io.ReadCloser + stderrMu sync.Mutex // for stderr + stderr bytes.Buffer + stdinClosed atomic.Bool + stdoutClosed atomic.Bool + closing atomic.Bool + localAddr net.Addr + remoteAddr net.Addr +} + +// kill terminates the process. On Windows it kills the process directly, +// whereas on other platforms, a SIGTERM is sent, before forcefully terminating +// the process after 3 seconds. +func (c *commandConn) kill() { + if c.cmdExited.Load() { + return } - return c.kill() -} - -// killAndWait tries sending SIGTERM to the process before sending SIGKILL. -func killAndWait(cmd *exec.Cmd) error { + c.cmdMutex.Lock() var werr error if runtime.GOOS != "windows" { werrCh := make(chan error) - go func() { werrCh <- cmd.Wait() }() - cmd.Process.Signal(syscall.SIGTERM) + go func() { werrCh <- c.cmd.Wait() }() + _ = c.cmd.Process.Signal(syscall.SIGTERM) select { case werr = <-werrCh: case <-time.After(3 * time.Second): - cmd.Process.Kill() + _ = c.cmd.Process.Kill() werr = <-werrCh } } else { - cmd.Process.Kill() - werr = cmd.Wait() + _ = c.cmd.Process.Kill() + werr = c.cmd.Wait() } - return werr + c.cmdWaitErr = werr + c.cmdMutex.Unlock() + c.cmdExited.Store(true) } -// kill returns nil if the command terminated, regardless to the exit status. -func (c *commandConn) kill() error { - var werr error - c.cmdMutex.Lock() - if c.cmdExited { - werr = c.cmdWaitErr - } else { - werr = killAndWait(c.cmd) - c.cmdWaitErr = werr - c.cmdExited = true - } - c.cmdMutex.Unlock() - if werr == nil { - return nil +// handleEOF handles io.EOF errors while reading or writing from the underlying +// command pipes. +// +// When we've received an EOF we expect that the command will +// be terminated soon. As such, we call Wait() on the command +// and return EOF or the error depending on whether the command +// exited with an error. +// +// If Wait() does not return within 10s, an error is returned +func (c *commandConn) handleEOF(err error) error { + if err != io.EOF { + return err } - wExitErr, ok := werr.(*exec.ExitError) - if ok { - if wExitErr.ProcessState.Exited() { - return nil - } - } - return errors.Wrapf(werr, "commandconn: failed to wait") -} -func (c *commandConn) onEOF(eof error) error { - // when we got EOF, the command is going to be terminated - var werr error c.cmdMutex.Lock() - if c.cmdExited { + defer c.cmdMutex.Unlock() + + var werr error + if c.cmdExited.Load() { werr = c.cmdWaitErr } else { werrCh := make(chan error) @@ -146,18 +134,17 @@ select { case werr = <-werrCh: c.cmdWaitErr = werr - c.cmdExited = true + c.cmdExited.Store(true) case <-time.After(10 * time.Second): - c.cmdMutex.Unlock() c.stderrMu.Lock() stderr := c.stderr.String() c.stderrMu.Unlock() - return errors.Errorf("command %v did not exit after %v: stderr=%q", c.cmd.Args, eof, stderr) + return errors.Errorf("command %v did not exit after %v: stderr=%q", c.cmd.Args, err, stderr) } } - c.cmdMutex.Unlock() + if werr == nil { - return eof + return err } c.stderrMu.Lock() stderr := c.stderr.String() @@ -166,71 +153,86 @@ } func ignorableCloseError(err error) bool { - errS := err.Error() - ss := []string{ - os.ErrClosed.Error(), - } - for _, s := range ss { - if strings.Contains(errS, s) { - return true - } + return strings.Contains(err.Error(), os.ErrClosed.Error()) +} + +func (c *commandConn) Read(p []byte) (int, error) { + n, err := c.stdout.Read(p) + // check after the call to Read, since + // it is blocking, and while waiting on it + // Close might get called + if c.closing.Load() { + // If we're currently closing the connection + // we don't want to call onEOF + return n, err + } + + return n, c.handleEOF(err) +} + +func (c *commandConn) Write(p []byte) (int, error) { + n, err := c.stdin.Write(p) + // check after the call to Write, since + // it is blocking, and while waiting on it + // Close might get called + if c.closing.Load() { + // If we're currently closing the connection + // we don't want to call onEOF + return n, err } - return false + + return n, c.handleEOF(err) } +// CloseRead allows commandConn to implement halfCloser func (c *commandConn) CloseRead() error { // NOTE: maybe already closed here if err := c.stdout.Close(); err != nil && !ignorableCloseError(err) { - logrus.Warnf("commandConn.CloseRead: %v", err) - } - c.stdioClosedMu.Lock() - c.stdoutClosed = true - c.stdioClosedMu.Unlock() - if err := c.killIfStdioClosed(); err != nil { - logrus.Warnf("commandConn.CloseRead: %v", err) + return err } - return nil -} + c.stdoutClosed.Store(true) -func (c *commandConn) Read(p []byte) (int, error) { - n, err := c.stdout.Read(p) - if err == io.EOF { - err = c.onEOF(err) + if c.stdinClosed.Load() { + c.kill() } - return n, err + + return nil } +// CloseWrite allows commandConn to implement halfCloser func (c *commandConn) CloseWrite() error { // NOTE: maybe already closed here if err := c.stdin.Close(); err != nil && !ignorableCloseError(err) { - logrus.Warnf("commandConn.CloseWrite: %v", err) + return err } - c.stdioClosedMu.Lock() - c.stdinClosed = true - c.stdioClosedMu.Unlock() - if err := c.killIfStdioClosed(); err != nil { - logrus.Warnf("commandConn.CloseWrite: %v", err) - } - return nil -} + c.stdinClosed.Store(true) -func (c *commandConn) Write(p []byte) (int, error) { - n, err := c.stdin.Write(p) - if err == io.EOF { - err = c.onEOF(err) + if c.stdoutClosed.Load() { + c.kill() } - return n, err + return nil } +// Close is the net.Conn func that gets called +// by the transport when a dial is cancelled +// due to it's context timing out. Any blocked +// Read or Write calls will be unblocked and +// return errors. It will block until the underlying +// command has terminated. func (c *commandConn) Close() error { - var err error - if err = c.CloseRead(); err != nil { + c.closing.Store(true) + defer c.closing.Store(false) + + if err := c.CloseRead(); err != nil { logrus.Warnf("commandConn.Close: CloseRead: %v", err) + return err } - if err = c.CloseWrite(); err != nil { + if err := c.CloseWrite(); err != nil { logrus.Warnf("commandConn.Close: CloseWrite: %v", err) + return err } - return err + + return nil } func (c *commandConn) LocalAddr() net.Addr { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/cli/connhelper/commandconn/commandconn_unix_test.go new/docker-cli-24.0.4_ce/cli/connhelper/commandconn/commandconn_unix_test.go --- old/docker-cli-24.0.2_ce/cli/connhelper/commandconn/commandconn_unix_test.go 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/cli/connhelper/commandconn/commandconn_unix_test.go 2023-06-30 19:55:44.000000000 +0200 @@ -6,8 +6,11 @@ import ( "context" "io" + "io/fs" "testing" + "time" + "github.com/docker/docker/pkg/process" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" ) @@ -43,3 +46,170 @@ assert.Check(t, is.Equal(0, n)) assert.Check(t, is.Equal(io.EOF, err)) } + +func TestCloseRunningCommand(t *testing.T) { + cmd := "sh" + args := []string{"-c", "while true; sleep 1; done"} + + done := make(chan struct{}) + defer close(done) + + go func() { + c, err := New(context.TODO(), cmd, args...) + assert.NilError(t, err) + cmdConn := c.(*commandConn) + assert.Check(t, process.Alive(cmdConn.cmd.Process.Pid)) + + n, err := c.Write([]byte("hello")) + assert.Check(t, is.Equal(len("hello"), n)) + assert.NilError(t, err) + assert.Check(t, process.Alive(cmdConn.cmd.Process.Pid)) + + err = cmdConn.Close() + assert.NilError(t, err) + assert.Check(t, !process.Alive(cmdConn.cmd.Process.Pid)) + done <- struct{}{} + }() + + select { + case <-time.After(5 * time.Second): + t.Error("test did not finish in time") + case <-done: + break + } +} + +func TestCloseTwice(t *testing.T) { + cmd := "sh" + args := []string{"-c", "echo hello; sleep 1; exit 0"} + + done := make(chan struct{}) + go func() { + c, err := New(context.TODO(), cmd, args...) + assert.NilError(t, err) + cmdConn := c.(*commandConn) + assert.Check(t, process.Alive(cmdConn.cmd.Process.Pid)) + + b := make([]byte, 32) + n, err := c.Read(b) + assert.Check(t, is.Equal(len("hello\n"), n)) + assert.NilError(t, err) + + err = cmdConn.Close() + assert.NilError(t, err) + assert.Check(t, !process.Alive(cmdConn.cmd.Process.Pid)) + + err = cmdConn.Close() + assert.NilError(t, err) + assert.Check(t, !process.Alive(cmdConn.cmd.Process.Pid)) + done <- struct{}{} + }() + + select { + case <-time.After(10 * time.Second): + t.Error("test did not finish in time") + case <-done: + break + } +} + +func TestEOFTimeout(t *testing.T) { + cmd := "sh" + args := []string{"-c", "sleep 20"} + + done := make(chan struct{}) + go func() { + c, err := New(context.TODO(), cmd, args...) + assert.NilError(t, err) + cmdConn := c.(*commandConn) + assert.Check(t, process.Alive(cmdConn.cmd.Process.Pid)) + + cmdConn.stdout = mockStdoutEOF{} + + b := make([]byte, 32) + n, err := c.Read(b) + assert.Check(t, is.Equal(0, n)) + assert.ErrorContains(t, err, "did not exit after EOF") + + done <- struct{}{} + }() + + // after receiving an EOF, we try to kill the command + // if it doesn't exit after 10s, we throw an error + select { + case <-time.After(12 * time.Second): + t.Error("test did not finish in time") + case <-done: + break + } +} + +type mockStdoutEOF struct{} + +func (mockStdoutEOF) Read(_ []byte) (int, error) { + return 0, io.EOF +} + +func (mockStdoutEOF) Close() error { + return nil +} + +func TestCloseWhileWriting(t *testing.T) { + cmd := "sh" + args := []string{"-c", "while true; sleep 1; done"} + + c, err := New(context.TODO(), cmd, args...) + assert.NilError(t, err) + cmdConn := c.(*commandConn) + assert.Check(t, process.Alive(cmdConn.cmd.Process.Pid)) + + writeErrC := make(chan error) + go func() { + for { + n, err := c.Write([]byte("hello")) + if err != nil { + writeErrC <- err + return + } + assert.Equal(t, n, len("hello")) + } + }() + + err = c.Close() + assert.NilError(t, err) + assert.Check(t, !process.Alive(cmdConn.cmd.Process.Pid)) + + writeErr := <-writeErrC + assert.ErrorContains(t, writeErr, "file already closed") + assert.Check(t, is.ErrorIs(writeErr, fs.ErrClosed)) +} + +func TestCloseWhileReading(t *testing.T) { + cmd := "sh" + args := []string{"-c", "while true; sleep 1; done"} + + c, err := New(context.TODO(), cmd, args...) + assert.NilError(t, err) + cmdConn := c.(*commandConn) + assert.Check(t, process.Alive(cmdConn.cmd.Process.Pid)) + + readErrC := make(chan error) + go func() { + for { + b := make([]byte, 32) + n, err := c.Read(b) + if err != nil { + readErrC <- err + return + } + assert.Check(t, is.Equal(0, n)) + } + }() + + err = cmdConn.Close() + assert.NilError(t, err) + assert.Check(t, !process.Alive(cmdConn.cmd.Process.Pid)) + + readErr := <-readErrC + assert.Check(t, is.ErrorIs(readErr, fs.ErrClosed)) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/cli/connhelper/connhelper.go new/docker-cli-24.0.4_ce/cli/connhelper/connhelper.go --- old/docker-cli-24.0.2_ce/cli/connhelper/connhelper.go 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/cli/connhelper/connhelper.go 2023-06-30 19:55:44.000000000 +0200 @@ -5,6 +5,7 @@ "context" "net" "net/url" + "strings" "github.com/docker/cli/cli/connhelper/commandconn" "github.com/docker/cli/cli/connhelper/ssh" @@ -51,6 +52,7 @@ if sp.Path != "" { args = append(args, "--host", "unix://"+sp.Path) } + sshFlags = addSSHTimeout(sshFlags) args = append(args, "system", "dial-stdio") return commandconn.New(ctx, "ssh", append(sshFlags, sp.Args(args...)...)...) }, @@ -71,3 +73,10 @@ Host: "http://docker.example.com", }, nil } + +func addSSHTimeout(sshFlags []string) []string { + if !strings.Contains(strings.Join(sshFlags, ""), "ConnectTimeout") { + sshFlags = append(sshFlags, "-o ConnectTimeout=30") + } + return sshFlags +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/cli/connhelper/connhelper_test.go new/docker-cli-24.0.4_ce/cli/connhelper/connhelper_test.go --- old/docker-cli-24.0.2_ce/cli/connhelper/connhelper_test.go 1970-01-01 01:00:00.000000000 +0100 +++ new/docker-cli-24.0.4_ce/cli/connhelper/connhelper_test.go 2023-06-30 19:55:44.000000000 +0200 @@ -0,0 +1,31 @@ +package connhelper + +import ( + "testing" + + "gotest.tools/v3/assert" +) + +func TestSSHFlags(t *testing.T) { + testCases := []struct { + in []string + out []string + }{ + { + in: []string{}, + out: []string{"-o ConnectTimeout=30"}, + }, + { + in: []string{"option", "-o anotherOption"}, + out: []string{"option", "-o anotherOption", "-o ConnectTimeout=30"}, + }, + { + in: []string{"-o ConnectTimeout=5", "anotherOption"}, + out: []string{"-o ConnectTimeout=5", "anotherOption"}, + }, + } + + for _, tc := range testCases { + assert.DeepEqual(t, addSSHTimeout(tc.in), tc.out) + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/docker-bake.hcl new/docker-cli-24.0.4_ce/docker-bake.hcl --- old/docker-cli-24.0.2_ce/docker-bake.hcl 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/docker-bake.hcl 2023-06-30 19:55:44.000000000 +0200 @@ -1,5 +1,5 @@ variable "GO_VERSION" { - default = "1.20.4" + default = "1.20.5" } variable "VERSION" { default = "" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/dockerfiles/Dockerfile.authors new/docker-cli-24.0.4_ce/dockerfiles/Dockerfile.authors --- old/docker-cli-24.0.2_ce/dockerfiles/Dockerfile.authors 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/dockerfiles/Dockerfile.authors 2023-06-30 19:55:44.000000000 +0200 @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -ARG ALPINE_VERSION=3.16 +ARG ALPINE_VERSION=3.17 FROM alpine:${ALPINE_VERSION} AS gen RUN apk add --no-cache bash git diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/dockerfiles/Dockerfile.dev new/docker-cli-24.0.4_ce/dockerfiles/Dockerfile.dev --- old/docker-cli-24.0.2_ce/dockerfiles/Dockerfile.dev 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/dockerfiles/Dockerfile.dev 2023-06-30 19:55:44.000000000 +0200 @@ -1,9 +1,9 @@ # syntax=docker/dockerfile:1 -ARG GO_VERSION=1.20.4 -ARG ALPINE_VERSION=3.16 +ARG GO_VERSION=1.20.5 +ARG ALPINE_VERSION=3.17 -ARG BUILDX_VERSION=0.10.4 +ARG BUILDX_VERSION=0.11.0 FROM docker/buildx-bin:${BUILDX_VERSION} AS buildx FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS golang @@ -18,7 +18,7 @@ && gofumpt --version FROM golang AS gotestsum -ARG GOTESTSUM_VERSION=v1.8.2 +ARG GOTESTSUM_VERSION=v1.10.0 RUN --mount=type=cache,target=/root/.cache/go-build \ --mount=type=cache,target=/go/pkg/mod \ --mount=type=tmpfs,target=/go/src/ \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/dockerfiles/Dockerfile.lint new/docker-cli-24.0.4_ce/dockerfiles/Dockerfile.lint --- old/docker-cli-24.0.2_ce/dockerfiles/Dockerfile.lint 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/dockerfiles/Dockerfile.lint 2023-06-30 19:55:44.000000000 +0200 @@ -1,7 +1,7 @@ # syntax=docker/dockerfile:1 -ARG GO_VERSION=1.20.4 -ARG ALPINE_VERSION=3.16 +ARG GO_VERSION=1.20.5 +ARG ALPINE_VERSION=3.17 ARG GOLANGCI_LINT_VERSION=v1.52.2 FROM golangci/golangci-lint:${GOLANGCI_LINT_VERSION}-alpine AS golangci-lint diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/dockerfiles/Dockerfile.vendor new/docker-cli-24.0.4_ce/dockerfiles/Dockerfile.vendor --- old/docker-cli-24.0.2_ce/dockerfiles/Dockerfile.vendor 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/dockerfiles/Dockerfile.vendor 2023-06-30 19:55:44.000000000 +0200 @@ -1,7 +1,7 @@ # syntax=docker/dockerfile:1 -ARG GO_VERSION=1.20.4 -ARG ALPINE_VERSION=3.16 +ARG GO_VERSION=1.20.5 +ARG ALPINE_VERSION=3.17 ARG MODOUTDATED_VERSION=v0.8.0 FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS base @@ -9,7 +9,7 @@ WORKDIR /src FROM base AS vendored -ENV GOPROXY=direct +ENV GOPROXY=https://proxy.golang.org|direct RUN --mount=target=/context \ --mount=target=.,type=tmpfs \ --mount=target=/go/pkg/mod,type=cache <<EOT diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/docs/reference/commandline/attach.md new/docker-cli-24.0.4_ce/docs/reference/commandline/attach.md --- old/docker-cli-24.0.2_ce/docs/reference/commandline/attach.md 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/docs/reference/commandline/attach.md 2023-06-30 19:55:44.000000000 +0200 @@ -9,11 +9,11 @@ ### Options -| Name | Type | Default | Description | -|:----------------|:---------|:--------|:----------------------------------------------------| -| `--detach-keys` | `string` | | Override the key sequence for detaching a container | -| `--no-stdin` | | | Do not attach STDIN | -| `--sig-proxy` | | | Proxy all received signals to the process | +| Name | Type | Default | Description | +|:--------------------------------|:---------|:--------|:----------------------------------------------------| +| [`--detach-keys`](#detach-keys) | `string` | | Override the key sequence for detaching a container | +| `--no-stdin` | | | Do not attach STDIN | +| `--sig-proxy` | | | Proxy all received signals to the process | <!---MARKER_GEN_END--> @@ -56,30 +56,6 @@ foreground over a slow client connection. Instead, users should use the `docker logs` command to get access to the logs. -### Override the detach sequence - -If you want, you can configure an override the Docker key sequence for detach. -This is useful if the Docker default sequence conflicts with key sequence you -use for other applications. There are two ways to define your own detach key -sequence, as a per-container override or as a configuration property on your -entire configuration. - -To override the sequence for an individual container, use the -`--detach-keys="<sequence>"` flag with the `docker attach` command. The format of -the `<sequence>` is either a letter [a-Z], or the `ctrl-` combined with any of -the following: - -* `a-z` (a single lowercase alpha character ) -* `@` (at sign) -* `[` (left bracket) -* `\\` (two backward slashes) -* `_` (underscore) -* `^` (caret) - -These `a`, `ctrl-a`, `X`, or `ctrl-\\` values are all examples of valid key -sequences. To configure a different configuration default key sequence for all -containers, see [**Configuration file** section](cli.md#configuration-files). - ## Examples ### Attach to and detach from a running container @@ -168,3 +144,27 @@ CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a2fe3fd886db alpine "/bin/sh" About a minute ago Exited (13) 40 seconds ago test ``` + +### <a name="detach-keys"></a> Override the detach sequence (--detach-keys) + +Use the `--detach-keys` option to override the Docker key sequence for detach. +This is useful if the Docker default sequence conflicts with key sequence you +use for other applications. There are two ways to define your own detach key +sequence, as a per-container override or as a configuration property on your +entire configuration. + +To override the sequence for an individual container, use the +`--detach-keys="<sequence>"` flag with the `docker attach` command. The format of +the `<sequence>` is either a letter [a-Z], or the `ctrl-` combined with any of +the following: + +* `a-z` (a single lowercase alpha character ) +* `@` (at sign) +* `[` (left bracket) +* `\\` (two backward slashes) +* `_` (underscore) +* `^` (caret) + +These `a`, `ctrl-a`, `X`, or `ctrl-\\` values are all examples of valid key +sequences. To configure a different configuration default key sequence for all +containers, see [**Configuration file** section](cli.md#configuration-files). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/docs/reference/commandline/dockerd.md new/docker-cli-24.0.4_ce/docs/reference/commandline/dockerd.md --- old/docker-cli-24.0.2_ce/docs/reference/commandline/dockerd.md 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/docs/reference/commandline/dockerd.md 2023-06-30 19:55:44.000000000 +0200 @@ -828,36 +828,197 @@ C:\> dockerd --storage-opt size=40G ``` -### Docker runtime execution options +### Runtime options The Docker daemon relies on a [OCI](https://github.com/opencontainers/runtime-spec) compliant runtime (invoked via the `containerd` daemon) as its interface to the Linux kernel `namespaces`, `cgroups`, and `SELinux`. -By default, the Docker daemon automatically starts `containerd`. If you want to -control `containerd` startup, manually start `containerd` and pass the path to -the `containerd` socket using the `--containerd` flag. For example: +#### Configure container runtimes + +By default, the Docker daemon uses runc as a container runtime. +You can configure the daemon to add additional runtimes. + +containerd shims installed on `PATH` can be used directly, without the need +to edit the daemon's configuration. For example, if you install the Kata +Containers shim (`containerd-shim-kata-v2`) on `PATH`, then you can select that +runtime with `docker run` without having to edit the daemon's configuration: + +```console +$ docker run --runtime io.containerd.kata.v2 +``` + +Container runtimes that don't implement containerd shims, or containerd shims +installed outside of `PATH`, must be registered with the daemon, either via the +configuration file or using the `--add-runtime` command line flag. + +For examples on how to use other container runtimes, see +[Alternative container runtimes](https://docs.docker.com/engine/alternative-runtimes/) + +##### Configure runtimes using `daemon.json` + +To register and configure container runtimes using the daemon's configuration +file, add the runtimes as entries under `runtimes`: + +```json +{ + "runtimes": { + "<runtime>": {} + } +} +``` + +The key of the entry (`<runtime>` in the previous example) represents the name +of the runtime. This is the name that you reference when you run a container, +using `docker run --runtime <runtime>`. + +The runtime entry contains an object specifying the configuration for your +runtime. The properties of the object depends on what kind of runtime you're +looking to register: + +- If the runtime implements its own containerd shim, the object shall contain + a `runtimeType` field and an optional `options` field. + + ```json + { + "runtimes": { + "<runtime>": { + "runtimeType": "<name-or-path>", + "options": {} + } + } + } + ``` + + See [Configure shims](#configure-containerd-shims). + +- If the runtime is designed to be a drop-in replacement for runc, + the object contains a `path` field, and an optional `runtimeArgs` field. + + ```json + { + "runtimes": { + "<runtime>": { + "path": "/path/to/bin", + "runtimeArgs": ["...args"] + } + } + } + ``` + + See [Configure runc drop-in replacements](#configure-runc-drop-in-replacements). + +After changing the runtimes configuration in the configuration file, +you must reload or restart the daemon for changes to take effect: ```console -$ sudo dockerd --containerd /var/run/dev/docker-containerd.sock +$ sudo systemctl reload dockerd +``` + +##### Configure containerd shims + +If the runtime that you want to register implements a containerd shim, +or if you want to register a runtime which uses the runc shim, +use the following format for the runtime entry: + +```json +{ + "runtimes": { + "<runtime>": { + "runtimeType": "<name-or-path>", + "options": {} + } + } +} ``` -Runtimes can be registered with the daemon either via the -configuration file or using the `--add-runtime` command line argument. +`runtimeType` refers to either: + +- A fully qualified name of a containerd shim. + + The fully qualified name of a shim is the same as the `runtime_type` used to + register the runtime in containerd's CRI configuration. + For example, `io.containerd.runsc.v1`. + +- The path of a containerd shim binary. -The following is an example adding 2 runtimes via the configuration: + This option is useful if you installed the containerd shim binary outside of + `PATH`. + +`options` is optional. It lets you specify the runtime configuration that you +want to use for the shim. The configuration parameters that you can specify in +`options` depends on the runtime you're registering. For most shims, +the supported configuration options are `TypeUrl` and `ConfigPath`. +For example: ```json { - "default-runtime": "runc", "runtimes": { - "custom": { - "path": "/usr/local/bin/my-runc-replacement", - "runtimeArgs": [ - "--debug" - ] + "gvisor": { + "runtimeType": "io.containerd.runsc.v1", + "options": { + "TypeUrl": "io.containerd.runsc.v1.options", + "ConfigPath": "/etc/containerd/runsc.toml", + } + } + } +} +``` + +You can configure multiple runtimes using the same runtimeType. For example: + +```json +{ + "runtimes": { + "gvisor-foo": { + "runtimeType": "io.containerd.runsc.v1", + "options": { + "TypeUrl": "io.containerd.runsc.v1.options", + "ConfigPath": "/etc/containerd/runsc-foo.toml" + } }, + "gvisor-bar": { + "runtimeType": "io.containerd.runsc.v1", + "options": { + "TypeUrl": "io.containerd.runsc.v1.options", + "ConfigPath": "/etc/containerd/runsc-bar.toml" + } + } + } +} +``` + +The `options` field takes a special set of configuration parameters when used +with `"runtimeType": "io.containerd.runc.v2"`. For more information about runc +parameters, refer to the runc configuration section in +[CRI Plugin Config Guide](https://github.com/containerd/containerd/blob/v1.7.2/docs/cri/config.md#full-configuration). + +##### Configure runc drop-in replacements + +If the runtime that you want to register can act as a drop-in replacement for +runc, you can register the runtime either using the daemon configuration file, +or using the `--add-runtime` flag for the `dockerd` cli. + +When you use the configuration file, the entry uses the following format: + +```json +{ + "runtimes": { + "<runtime>": { + "path": "/path/to/binary", + "runtimeArgs": ["...args"] + } + } +} +``` + +Where `path` is either the absolute path to the runtime executable, or the name +of an executable installed on `PATH`: + +```json +{ + "runtimes": { "runc": { "path": "runc" } @@ -865,24 +1026,58 @@ } ``` -This is the same example via the command line: +And `runtimeArgs` lets you optionally pass additional arguments to the runtime. +Entries with this format use the containerd runc shim to invoke a custom +runtime binary. + +When you use the `--add-runtime` CLI flag, use the following format: ```console -$ sudo dockerd --add-runtime runc=runc --add-runtime custom=/usr/local/bin/my-runc-replacement +$ sudo dockerd --add-runtime <runtime>=<path> ``` -> **Note** -> -> Defining runtime arguments via the command line is not supported. +Defining runtime arguments via the command line is not supported. -#### Options for the runtime +For an example configuration for a runc drop-in replacment, see +[Alternative container runtimes > youki](https://docs.docker.com/engine/alternative-runtimes/#youki) -You can configure the runtime using options specified -with the `--exec-opt` flag. All the flag's options have the `native` prefix. A -single `native.cgroupdriver` option is available. +##### Configure the default container runtime -The `native.cgroupdriver` option specifies the management of the container's -cgroups. You can only specify `cgroupfs` or `systemd`. If you specify +You can specify either the name of a fully qualified containerd runtime shim, +or the name of a registered runtime. You can specify the default runtime either +using the daemon configuration file, or using the `--default-runtime` flag for +the `dockerd` cli. + +When you use the configuration file, the entry uses the following format: + +```json +{ + "default-runtime": "io.containerd.runsc.v1" +} +``` + +When you use the `--default-runtime` CLI flag, use the following format: + +```console +$ dockerd --default-runtime io.containerd.runsc.v1 +``` + +#### Run containerd standalone + +By default, the Docker daemon automatically starts `containerd`. If you want to +control `containerd` startup, manually start `containerd` and pass the path to +the `containerd` socket using the `--containerd` flag. For example: + +```console +$ sudo dockerd --containerd /run/containerd/containerd.sock +``` + +#### Configure cgroup driver + +You can configure how the runtime should manage container cgroups, using the +`--exec-opt native.cgroupdriver` CLI flag. + +You can only specify `cgroupfs` or `systemd`. If you specify `systemd` and it is not available, the system errors out. If you omit the `native.cgroupdriver` option,` cgroupfs` is used on cgroup v1 hosts, `systemd` is used on cgroup v2 hosts with systemd available. @@ -895,16 +1090,19 @@ Setting this option applies to all containers the daemon launches. -Also Windows Container makes use of `--exec-opt` for special purpose. Docker user -can specify default container isolation technology with this, for example: +#### Configure container isolation technology (Windows) + +For Windows containers, you can specify the default container isolation +technology to use, using the `--exec-opt isolation` flag. + +The following example makes `hyperv` the default isolation technology: ```console > dockerd --exec-opt isolation=hyperv ``` -Will make `hyperv` the default isolation technology on Windows. If no isolation -value is specified on daemon start, on Windows client, the default is -`hyperv`, and on Windows server, the default is `process`. +If no isolation value is specified on daemon start, on Windows client, +the default is `hyperv`, and on Windows server, the default is `process`. ### Daemon DNS options diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/docs/reference/commandline/run.md new/docker-cli-24.0.4_ce/docs/reference/commandline/run.md --- old/docker-cli-24.0.2_ce/docs/reference/commandline/run.md 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/docs/reference/commandline/run.md 2023-06-30 19:55:44.000000000 +0200 @@ -32,7 +32,7 @@ | `--cpuset-cpus` | `string` | | CPUs in which to allow execution (0-3, 0,1) | | `--cpuset-mems` | `string` | | MEMs in which to allow execution (0-3, 0,1) | | `-d`, `--detach` | | | Run container in background and print container ID | -| `--detach-keys` | `string` | | Override the key sequence for detaching a container | +| [`--detach-keys`](#detach-keys) | `string` | | Override the key sequence for detaching a container | | [`--device`](#device) | `list` | | Add a host device to the container | | [`--device-cgroup-rule`](#device-cgroup-rule) | `list` | | Add a rule to the cgroup allowed devices list | | `--device-read-bps` | `list` | | Limit read rate (bytes per second) from a device | @@ -485,10 +485,12 @@ ``` You can also choose the IP addresses for the container with `--ip` and `--ip6` -flags when you start the container on a user-defined network. +flags when you start the container on a user-defined network. To assign a +static IP to containers, you must specify subnet block for the network. ```console -$ docker run -itd --network=my-net --ip=10.10.9.75 busybox +$ docker network create --subnet 192.0.2.0/24 my-net +$ docker run -itd --network=my-net --ip=192.0.2.69 busybox ``` If you want to add a running container to a network use the `docker network connect` subcommand. @@ -569,6 +571,30 @@ See also [the `docker cp` command](cp.md). +### <a name="detach-keys"></a> Override the detach sequence (--detach-keys) + +Use the `--detach-keys` option to override the Docker key sequence for detach. +This is useful if the Docker default sequence conflicts with key sequence you +use for other applications. There are two ways to define your own detach key +sequence, as a per-container override or as a configuration property on your +entire configuration. + +To override the sequence for an individual container, use the +`--detach-keys="<sequence>"` flag with the `docker attach` command. The format of +the `<sequence>` is either a letter [a-Z], or the `ctrl-` combined with any of +the following: + +* `a-z` (a single lowercase alpha character ) +* `@` (at sign) +* `[` (left bracket) +* `\\` (two backward slashes) +* `_` (underscore) +* `^` (caret) + +These `a`, `ctrl-a`, `X`, or `ctrl-\\` values are all examples of valid key +sequences. To configure a different configuration default key sequence for all +containers, see [**Configuration file** section](cli.md#configuration-files). + ### <a name="device"></a> Add host device to container (--device) ```console @@ -948,4 +974,4 @@ - If that call returns a 404 (image not found), and depending on the `--pull` option ("always", "missing", "never") the call can trigger a `docker pull <image>`. - `/containers/create` again after pulling the image. - `/containers/(id)/start` to start the container. -- `/containers/(id)/attach` to attach to the container when starting with the `-it` flags for interactive containers. \ No newline at end of file +- `/containers/(id)/attach` to attach to the container when starting with the `-it` flags for interactive containers. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/docs/reference/commandline/service_create.md new/docker-cli-24.0.4_ce/docs/reference/commandline/service_create.md --- old/docker-cli-24.0.2_ce/docs/reference/commandline/service_create.md 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/docs/reference/commandline/service_create.md 2023-06-30 19:55:44.000000000 +0200 @@ -916,7 +916,7 @@ The swarm extends my-network to each node running the service. Containers on the same network can access each other using -[service discovery](https://docs.docker.com/network/overlay/#container-discovery). +[service discovery](https://docs.docker.com/network/drivers/overlay/#container-discovery). Long form syntax of `--network` allows to specify list of aliases and driver options: `--network name=my-network,alias=web1,driver-opt=field1=value1` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/e2e/testdata/Dockerfile.gencerts new/docker-cli-24.0.4_ce/e2e/testdata/Dockerfile.gencerts --- old/docker-cli-24.0.2_ce/e2e/testdata/Dockerfile.gencerts 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/e2e/testdata/Dockerfile.gencerts 2023-06-30 19:55:44.000000000 +0200 @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -ARG GO_VERSION=1.20.4 +ARG GO_VERSION=1.20.5 FROM golang:${GO_VERSION}-alpine AS generated RUN go install github.com/dmcgowan/quicktls@master diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/man/src/container/attach.md new/docker-cli-24.0.4_ce/man/src/container/attach.md --- old/docker-cli-24.0.2_ce/man/src/container/attach.md 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/man/src/container/attach.md 2023-06-30 19:55:44.000000000 +0200 @@ -13,9 +13,29 @@ It is forbidden to redirect the standard input of a **docker attach** command while attaching to a TTY-enabled container (i.e., launched with `-i` and `-t`). -# Override the detach sequence +# EXAMPLES + +## Attaching to a container + +In this example the top command is run inside a container from an ubuntu image, +in detached mode, then attaches to it, and then terminates the container +with `CTRL-c`: + + $ docker run -d --name topdemo ubuntu:20.04 /usr/bin/top -b + $ docker attach topdemo + top - 00:07:01 up 4:54, 0 users, load average: 0.83, 0.91, 0.82 + Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie + %Cpu(s): 2.3 us, 1.6 sy, 0.0 ni, 95.9 id, 0.0 wa, 0.1 hi, 0.1 si, 0.0 st + MiB Mem : 15846.2 total, 5729.2 free, 2592.5 used, 7524.4 buff/cache + MiB Swap: 16384.0 total, 16384.0 free, 0.0 used. 12097.3 avail Mem + + PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND + 1 root 20 0 5976 3256 2828 R 0.0 0.0 0:00.04 top + ^C + +## Override the detach sequence -If you want, you can configure an override the Docker key sequence for detach. +Use the **--detach-keys** option to override the Docker key sequence for detach. This is useful if the Docker default sequence conflicts with key sequence you use for other applications. There are two ways to define your own detach key sequence, as a per-container override or as a configuration property on your @@ -37,22 +57,3 @@ sequences. To configure a different configuration default key sequence for all containers, see **docker(1)**. -# EXAMPLES - -## Attaching to a container - -In this example the top command is run inside a container from an ubuntu image, -in detached mode, then attaches to it, and then terminates the container -with `CTRL-c`: - - $ docker run -d --name topdemo ubuntu:20.04 /usr/bin/top -b - $ docker attach topdemo - top - 00:07:01 up 4:54, 0 users, load average: 0.83, 0.91, 0.82 - Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie - %Cpu(s): 2.3 us, 1.6 sy, 0.0 ni, 95.9 id, 0.0 wa, 0.1 hi, 0.1 si, 0.0 st - MiB Mem : 15846.2 total, 5729.2 free, 2592.5 used, 7524.4 buff/cache - MiB Swap: 16384.0 total, 16384.0 free, 0.0 used. 12097.3 avail Mem - - PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND - 1 root 20 0 5976 3256 2828 R 0.0 0.0 0:00.04 top - ^C diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/vendor/modules.txt new/docker-cli-24.0.4_ce/vendor/modules.txt --- old/docker-cli-24.0.2_ce/vendor/modules.txt 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/vendor/modules.txt 2023-06-30 19:55:44.000000000 +0200 @@ -40,7 +40,7 @@ github.com/docker/distribution/registry/storage/cache github.com/docker/distribution/registry/storage/cache/memory github.com/docker/distribution/uuid -# github.com/docker/docker v24.0.1+incompatible +# github.com/docker/docker v24.0.2+incompatible ## explicit github.com/docker/docker/api github.com/docker/docker/api/types diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/vendor.mod new/docker-cli-24.0.4_ce/vendor.mod --- old/docker-cli-24.0.2_ce/vendor.mod 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/vendor.mod 2023-06-30 19:55:44.000000000 +0200 @@ -10,7 +10,7 @@ github.com/containerd/containerd v1.6.21 github.com/creack/pty v1.1.18 github.com/docker/distribution v2.8.2+incompatible - github.com/docker/docker v24.0.1+incompatible + github.com/docker/docker v24.0.2+incompatible github.com/docker/docker-credential-helpers v0.7.0 github.com/docker/go-connections v0.4.0 github.com/docker/go-units v0.5.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/docker-cli-24.0.2_ce/vendor.sum new/docker-cli-24.0.4_ce/vendor.sum --- old/docker-cli-24.0.2_ce/vendor.sum 2023-05-25 22:26:27.000000000 +0200 +++ new/docker-cli-24.0.4_ce/vendor.sum 2023-06-30 19:55:44.000000000 +0200 @@ -96,8 +96,8 @@ github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.1+incompatible h1:NxN81beIxDlUaVt46iUQrYHD9/W3u9EGl52r86O/IGw= -github.com/docker/docker v24.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.2+incompatible h1:eATx+oLz9WdNVkQrr0qjQ8HvRJ4bOOxfzEo8R+dA3cg= +github.com/docker/docker v24.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
