mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 10:03:42 +08:00 
			
		
		
		
	vendor: github.com/docker/cli v24.0.4
full diff: https://github.com/docker/cli/compare/v24.0.2...v24.0.4 notable changes: - ssh: fix error on commandconn close, add ping and default - commandconn: return original error while closing Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
		
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							@@ -11,7 +11,7 @@ require (
 | 
				
			|||||||
	github.com/containerd/continuity v0.4.1
 | 
						github.com/containerd/continuity v0.4.1
 | 
				
			||||||
	github.com/containerd/typeurl/v2 v2.1.1
 | 
						github.com/containerd/typeurl/v2 v2.1.1
 | 
				
			||||||
	github.com/creack/pty v1.1.18
 | 
						github.com/creack/pty v1.1.18
 | 
				
			||||||
	github.com/docker/cli v24.0.2+incompatible
 | 
						github.com/docker/cli v24.0.4+incompatible
 | 
				
			||||||
	github.com/docker/cli-docs-tool v0.6.0
 | 
						github.com/docker/cli-docs-tool v0.6.0
 | 
				
			||||||
	github.com/docker/distribution v2.8.2+incompatible
 | 
						github.com/docker/distribution v2.8.2+incompatible
 | 
				
			||||||
	github.com/docker/docker v24.0.5-0.20230714235725-36e9e796c6fc+incompatible // 24.0
 | 
						github.com/docker/docker v24.0.5-0.20230714235725-36e9e796c6fc+incompatible // 24.0
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.sum
									
									
									
									
									
								
							@@ -150,8 +150,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
 | 
				
			|||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
					github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
				
			||||||
github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa h1:L9Ay/slwQ4ERSPaurC+TVkZrM0K98GNrEEo1En3e8as=
 | 
					github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa h1:L9Ay/slwQ4ERSPaurC+TVkZrM0K98GNrEEo1En3e8as=
 | 
				
			||||||
github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI=
 | 
					github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI=
 | 
				
			||||||
github.com/docker/cli v24.0.2+incompatible h1:QdqR7znue1mtkXIJ+ruQMGQhpw2JzMJLRXp6zpzF6tM=
 | 
					github.com/docker/cli v24.0.4+incompatible h1:Y3bYF9ekNTm2VFz5U/0BlMdJy73D+Y1iAAZ8l63Ydzw=
 | 
				
			||||||
github.com/docker/cli v24.0.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
 | 
					github.com/docker/cli v24.0.4+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
 | 
				
			||||||
github.com/docker/cli-docs-tool v0.6.0 h1:Z9x10SaZgFaB6jHgz3OWooynhSa40CsWkpe5hEnG/qA=
 | 
					github.com/docker/cli-docs-tool v0.6.0 h1:Z9x10SaZgFaB6jHgz3OWooynhSa40CsWkpe5hEnG/qA=
 | 
				
			||||||
github.com/docker/cli-docs-tool v0.6.0/go.mod h1:zMjqTFCU361PRh8apiXzeAZ1Q/xupbIwTusYpzCXS/o=
 | 
					github.com/docker/cli-docs-tool v0.6.0/go.mod h1:zMjqTFCU361PRh8apiXzeAZ1Q/xupbIwTusYpzCXS/o=
 | 
				
			||||||
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
 | 
					github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								vendor/github.com/docker/cli/cli/command/cli.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/docker/cli/cli/command/cli.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -8,7 +8,6 @@ import (
 | 
				
			|||||||
	"path/filepath"
 | 
						"path/filepath"
 | 
				
			||||||
	"runtime"
 | 
						"runtime"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -327,13 +326,8 @@ func (cli *DockerCli) getInitTimeout() time.Duration {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (cli *DockerCli) initializeFromClient() {
 | 
					func (cli *DockerCli) initializeFromClient() {
 | 
				
			||||||
	ctx := context.Background()
 | 
						ctx := context.Background()
 | 
				
			||||||
	if !strings.HasPrefix(cli.dockerEndpoint.Host, "ssh://") {
 | 
						ctx, cancel := context.WithTimeout(ctx, cli.getInitTimeout())
 | 
				
			||||||
		// @FIXME context.WithTimeout doesn't work with connhelper / ssh connections
 | 
						defer cancel()
 | 
				
			||||||
		// 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()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ping, err := cli.client.Ping(ctx)
 | 
						ping, err := cli.client.Ping(ctx)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -381,7 +375,7 @@ func (cli *DockerCli) ContextStore() store.Store {
 | 
				
			|||||||
// the "default" context is used if:
 | 
					// the "default" context is used if:
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
//   - The "--host" option is set
 | 
					//   - 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.
 | 
					//     to a non-empty value.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// In these cases, the default context is used, which uses the host as
 | 
					// In these cases, the default context is used, which uses the host as
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										222
									
								
								vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										222
									
								
								vendor/github.com/docker/cli/cli/connhelper/commandconn/commandconn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -23,6 +23,7 @@ import (
 | 
				
			|||||||
	"runtime"
 | 
						"runtime"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
						"sync/atomic"
 | 
				
			||||||
	"syscall"
 | 
						"syscall"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -64,81 +65,68 @@ func New(_ context.Context, cmd string, args ...string) (net.Conn, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// commandConn implements net.Conn
 | 
					// commandConn implements net.Conn
 | 
				
			||||||
type commandConn struct {
 | 
					type commandConn struct {
 | 
				
			||||||
	cmd           *exec.Cmd
 | 
						cmdMutex     sync.Mutex // for cmd, cmdWaitErr
 | 
				
			||||||
	cmdExited     bool
 | 
						cmd          *exec.Cmd
 | 
				
			||||||
	cmdWaitErr    error
 | 
						cmdWaitErr   error
 | 
				
			||||||
	cmdMutex      sync.Mutex
 | 
						cmdExited    atomic.Bool
 | 
				
			||||||
	stdin         io.WriteCloser
 | 
						stdin        io.WriteCloser
 | 
				
			||||||
	stdout        io.ReadCloser
 | 
						stdout       io.ReadCloser
 | 
				
			||||||
	stderrMu      sync.Mutex
 | 
						stderrMu     sync.Mutex // for stderr
 | 
				
			||||||
	stderr        bytes.Buffer
 | 
						stderr       bytes.Buffer
 | 
				
			||||||
	stdioClosedMu sync.Mutex // for stdinClosed and stdoutClosed
 | 
						stdinClosed  atomic.Bool
 | 
				
			||||||
	stdinClosed   bool
 | 
						stdoutClosed atomic.Bool
 | 
				
			||||||
	stdoutClosed  bool
 | 
						closing      atomic.Bool
 | 
				
			||||||
	localAddr     net.Addr
 | 
						localAddr    net.Addr
 | 
				
			||||||
	remoteAddr    net.Addr
 | 
						remoteAddr   net.Addr
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// killIfStdioClosed kills the cmd if both stdin and stdout are closed.
 | 
					// kill terminates the process. On Windows it kills the process directly,
 | 
				
			||||||
func (c *commandConn) killIfStdioClosed() error {
 | 
					// whereas on other platforms, a SIGTERM is sent, before forcefully terminating
 | 
				
			||||||
	c.stdioClosedMu.Lock()
 | 
					// the process after 3 seconds.
 | 
				
			||||||
	stdioClosed := c.stdoutClosed && c.stdinClosed
 | 
					func (c *commandConn) kill() {
 | 
				
			||||||
	c.stdioClosedMu.Unlock()
 | 
						if c.cmdExited.Load() {
 | 
				
			||||||
	if !stdioClosed {
 | 
							return
 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return c.kill()
 | 
						c.cmdMutex.Lock()
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// killAndWait tries sending SIGTERM to the process before sending SIGKILL.
 | 
					 | 
				
			||||||
func killAndWait(cmd *exec.Cmd) error {
 | 
					 | 
				
			||||||
	var werr error
 | 
						var werr error
 | 
				
			||||||
	if runtime.GOOS != "windows" {
 | 
						if runtime.GOOS != "windows" {
 | 
				
			||||||
		werrCh := make(chan error)
 | 
							werrCh := make(chan error)
 | 
				
			||||||
		go func() { werrCh <- cmd.Wait() }()
 | 
							go func() { werrCh <- c.cmd.Wait() }()
 | 
				
			||||||
		cmd.Process.Signal(syscall.SIGTERM)
 | 
							_ = c.cmd.Process.Signal(syscall.SIGTERM)
 | 
				
			||||||
		select {
 | 
							select {
 | 
				
			||||||
		case werr = <-werrCh:
 | 
							case werr = <-werrCh:
 | 
				
			||||||
		case <-time.After(3 * time.Second):
 | 
							case <-time.After(3 * time.Second):
 | 
				
			||||||
			cmd.Process.Kill()
 | 
								_ = c.cmd.Process.Kill()
 | 
				
			||||||
			werr = <-werrCh
 | 
								werr = <-werrCh
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		cmd.Process.Kill()
 | 
							_ = c.cmd.Process.Kill()
 | 
				
			||||||
		werr = cmd.Wait()
 | 
							werr = c.cmd.Wait()
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return werr
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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.cmdWaitErr = werr
 | 
				
			||||||
	c.cmdMutex.Unlock()
 | 
						c.cmdMutex.Unlock()
 | 
				
			||||||
	if werr == nil {
 | 
						c.cmdExited.Store(true)
 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	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 {
 | 
					// handleEOF handles io.EOF errors while reading or writing from the underlying
 | 
				
			||||||
	// when we got EOF, the command is going to be terminated
 | 
					// command pipes.
 | 
				
			||||||
	var werr error
 | 
					//
 | 
				
			||||||
 | 
					// 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
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.cmdMutex.Lock()
 | 
						c.cmdMutex.Lock()
 | 
				
			||||||
	if c.cmdExited {
 | 
						defer c.cmdMutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var werr error
 | 
				
			||||||
 | 
						if c.cmdExited.Load() {
 | 
				
			||||||
		werr = c.cmdWaitErr
 | 
							werr = c.cmdWaitErr
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		werrCh := make(chan error)
 | 
							werrCh := make(chan error)
 | 
				
			||||||
@@ -146,18 +134,17 @@ func (c *commandConn) onEOF(eof error) error {
 | 
				
			|||||||
		select {
 | 
							select {
 | 
				
			||||||
		case werr = <-werrCh:
 | 
							case werr = <-werrCh:
 | 
				
			||||||
			c.cmdWaitErr = werr
 | 
								c.cmdWaitErr = werr
 | 
				
			||||||
			c.cmdExited = true
 | 
								c.cmdExited.Store(true)
 | 
				
			||||||
		case <-time.After(10 * time.Second):
 | 
							case <-time.After(10 * time.Second):
 | 
				
			||||||
			c.cmdMutex.Unlock()
 | 
					 | 
				
			||||||
			c.stderrMu.Lock()
 | 
								c.stderrMu.Lock()
 | 
				
			||||||
			stderr := c.stderr.String()
 | 
								stderr := c.stderr.String()
 | 
				
			||||||
			c.stderrMu.Unlock()
 | 
								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 {
 | 
						if werr == nil {
 | 
				
			||||||
		return eof
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	c.stderrMu.Lock()
 | 
						c.stderrMu.Lock()
 | 
				
			||||||
	stderr := c.stderr.String()
 | 
						stderr := c.stderr.String()
 | 
				
			||||||
@@ -166,71 +153,86 @@ func (c *commandConn) onEOF(eof error) error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ignorableCloseError(err error) bool {
 | 
					func ignorableCloseError(err error) bool {
 | 
				
			||||||
	errS := err.Error()
 | 
						return strings.Contains(err.Error(), os.ErrClosed.Error())
 | 
				
			||||||
	ss := []string{
 | 
					 | 
				
			||||||
		os.ErrClosed.Error(),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, s := range ss {
 | 
					 | 
				
			||||||
		if strings.Contains(errS, s) {
 | 
					 | 
				
			||||||
			return true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *commandConn) Read(p []byte) (int, error) {
 | 
					func (c *commandConn) Read(p []byte) (int, error) {
 | 
				
			||||||
	n, err := c.stdout.Read(p)
 | 
						n, err := c.stdout.Read(p)
 | 
				
			||||||
	if err == io.EOF {
 | 
						// check after the call to Read, since
 | 
				
			||||||
		err = c.onEOF(err)
 | 
						// 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, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *commandConn) CloseWrite() error {
 | 
						return n, c.handleEOF(err)
 | 
				
			||||||
	// NOTE: maybe already closed here
 | 
					 | 
				
			||||||
	if err := c.stdin.Close(); err != nil && !ignorableCloseError(err) {
 | 
					 | 
				
			||||||
		logrus.Warnf("commandConn.CloseWrite: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	c.stdioClosedMu.Lock()
 | 
					 | 
				
			||||||
	c.stdinClosed = true
 | 
					 | 
				
			||||||
	c.stdioClosedMu.Unlock()
 | 
					 | 
				
			||||||
	if err := c.killIfStdioClosed(); err != nil {
 | 
					 | 
				
			||||||
		logrus.Warnf("commandConn.CloseWrite: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *commandConn) Write(p []byte) (int, error) {
 | 
					func (c *commandConn) Write(p []byte) (int, error) {
 | 
				
			||||||
	n, err := c.stdin.Write(p)
 | 
						n, err := c.stdin.Write(p)
 | 
				
			||||||
	if err == io.EOF {
 | 
						// check after the call to Write, since
 | 
				
			||||||
		err = c.onEOF(err)
 | 
						// 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, err
 | 
					
 | 
				
			||||||
 | 
						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) {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						c.stdoutClosed.Store(true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if c.stdinClosed.Load() {
 | 
				
			||||||
 | 
							c.kill()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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) {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						c.stdinClosed.Store(true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if c.stdoutClosed.Load() {
 | 
				
			||||||
 | 
							c.kill()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						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 {
 | 
					func (c *commandConn) Close() error {
 | 
				
			||||||
	var err error
 | 
						c.closing.Store(true)
 | 
				
			||||||
	if err = c.CloseRead(); err != nil {
 | 
						defer c.closing.Store(false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := c.CloseRead(); err != nil {
 | 
				
			||||||
		logrus.Warnf("commandConn.Close: CloseRead: %v", err)
 | 
							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)
 | 
							logrus.Warnf("commandConn.Close: CloseWrite: %v", err)
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return err
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *commandConn) LocalAddr() net.Addr {
 | 
					func (c *commandConn) LocalAddr() net.Addr {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										9
									
								
								vendor/github.com/docker/cli/cli/connhelper/connhelper.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/docker/cli/cli/connhelper/connhelper.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -5,6 +5,7 @@ import (
 | 
				
			|||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/docker/cli/cli/connhelper/commandconn"
 | 
						"github.com/docker/cli/cli/connhelper/commandconn"
 | 
				
			||||||
	"github.com/docker/cli/cli/connhelper/ssh"
 | 
						"github.com/docker/cli/cli/connhelper/ssh"
 | 
				
			||||||
@@ -51,6 +52,7 @@ func getConnectionHelper(daemonURL string, sshFlags []string) (*ConnectionHelper
 | 
				
			|||||||
				if sp.Path != "" {
 | 
									if sp.Path != "" {
 | 
				
			||||||
					args = append(args, "--host", "unix://"+sp.Path)
 | 
										args = append(args, "--host", "unix://"+sp.Path)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									sshFlags = addSSHTimeout(sshFlags)
 | 
				
			||||||
				args = append(args, "system", "dial-stdio")
 | 
									args = append(args, "system", "dial-stdio")
 | 
				
			||||||
				return commandconn.New(ctx, "ssh", append(sshFlags, sp.Args(args...)...)...)
 | 
									return commandconn.New(ctx, "ssh", append(sshFlags, sp.Args(args...)...)...)
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
@@ -71,3 +73,10 @@ func GetCommandConnectionHelper(cmd string, flags ...string) (*ConnectionHelper,
 | 
				
			|||||||
		Host: "http://docker.example.com",
 | 
							Host: "http://docker.example.com",
 | 
				
			||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func addSSHTimeout(sshFlags []string) []string {
 | 
				
			||||||
 | 
						if !strings.Contains(strings.Join(sshFlags, ""), "ConnectTimeout") {
 | 
				
			||||||
 | 
							sshFlags = append(sshFlags, "-o ConnectTimeout=30")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return sshFlags
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							@@ -209,7 +209,7 @@ github.com/davecgh/go-spew/spew
 | 
				
			|||||||
# github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa
 | 
					# github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa
 | 
				
			||||||
## explicit; go 1.18
 | 
					## explicit; go 1.18
 | 
				
			||||||
github.com/distribution/distribution/v3/reference
 | 
					github.com/distribution/distribution/v3/reference
 | 
				
			||||||
# github.com/docker/cli v24.0.2+incompatible
 | 
					# github.com/docker/cli v24.0.4+incompatible
 | 
				
			||||||
## explicit
 | 
					## explicit
 | 
				
			||||||
github.com/docker/cli/cli
 | 
					github.com/docker/cli/cli
 | 
				
			||||||
github.com/docker/cli/cli-plugins/manager
 | 
					github.com/docker/cli/cli-plugins/manager
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user