From 8919bbf04d3222ed1e3135f6b9e9bb126f40998d Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Wed, 6 Mar 2019 12:07:04 +0000 Subject: [PATCH 1/3] dial-stdio: handle connections which lack CloseRead method. This happens on Windows when dialing a named pipe (a path which is used by CLI plugins), in that case some debugging shows: DEBU[0000] conn is a *winio.win32MessageBytePipe DEBU[0000] conn is a halfReadCloser: false DEBU[0000] conn is a halfWriteCloser: true the raw stream connection does not implement halfCloser In such cases we can simply wrap with a nop function since closing for read isn't too critical. Signed-off-by: Ian Campbell --- cli/command/system/dial_stdio.go | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/cli/command/system/dial_stdio.go b/cli/command/system/dial_stdio.go index 642d79505e..ceeac8223f 100644 --- a/cli/command/system/dial_stdio.go +++ b/cli/command/system/dial_stdio.go @@ -34,10 +34,17 @@ func runDialStdio(dockerCli command.Cli) error { if err != nil { return errors.Wrap(err, "failed to open the raw stream connection") } - connHalfCloser, ok := conn.(halfCloser) - if !ok { + + var connHalfCloser halfCloser + switch t := conn.(type) { + case halfCloser: + connHalfCloser = t + case halfReadWriteCloser: + connHalfCloser = &nopCloseReader{t} + default: return errors.New("the raw stream connection does not implement halfCloser") } + stdin2conn := make(chan error) conn2stdout := make(chan error) go func() { @@ -90,6 +97,19 @@ type halfCloser interface { halfWriteCloser } +type halfReadWriteCloser interface { + io.Reader + halfWriteCloser +} + +type nopCloseReader struct { + halfReadWriteCloser +} + +func (x *nopCloseReader) CloseRead() error { + return nil +} + type halfReadCloserWrapper struct { io.ReadCloser } From 186e7456ac6ddddf31716ca083a2742b132cc225 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 12 Mar 2019 14:52:22 +0000 Subject: [PATCH 2/3] dial-stdio: Close the connection This was leaking the fd. Signed-off-by: Ian Campbell --- cli/command/system/dial_stdio.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/command/system/dial_stdio.go b/cli/command/system/dial_stdio.go index ceeac8223f..017ed40ce3 100644 --- a/cli/command/system/dial_stdio.go +++ b/cli/command/system/dial_stdio.go @@ -34,6 +34,7 @@ func runDialStdio(dockerCli command.Cli) error { if err != nil { return errors.Wrap(err, "failed to open the raw stream connection") } + defer conn.Close() var connHalfCloser halfCloser switch t := conn.(type) { From 0449ad8d06829459f367e51e85aef36b14bdceac Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Mon, 11 Mar 2019 15:44:58 +0000 Subject: [PATCH 3/3] Revert "Disable `docker system dial-stdio` on Windows" This reverts commit c41c23813c15219a78e4c2451f83bcdb74c6e071. This case is now handled due to the previous commit. Signed-off-by: Ian Campbell --- cli-plugins/plugin/plugin.go | 7 +------ cli/command/system/cmd.go | 8 +------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/cli-plugins/plugin/plugin.go b/cli-plugins/plugin/plugin.go index c8e4f9f465..99ef36d845 100644 --- a/cli-plugins/plugin/plugin.go +++ b/cli-plugins/plugin/plugin.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "os" - "runtime" "sync" "github.com/docker/cli/cli" @@ -75,11 +74,7 @@ func PersistentPreRunE(cmd *cobra.Command, args []string) error { } // flags must be the original top-level command flags, not cmd.Flags() options.opts.Common.SetDefaultOptions(options.flags) - var initopts []command.InitializeOpt - if runtime.GOOS != "windows" { - initopts = append(initopts, withPluginClientConn(options.name)) - } - err = options.dockerCli.Initialize(options.opts, initopts...) + err = options.dockerCli.Initialize(options.opts, withPluginClientConn(options.name)) }) return err } diff --git a/cli/command/system/cmd.go b/cli/command/system/cmd.go index 1bb5374ccb..6accb98f0c 100644 --- a/cli/command/system/cmd.go +++ b/cli/command/system/cmd.go @@ -1,8 +1,6 @@ package system import ( - "runtime" - "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/spf13/cobra" @@ -21,12 +19,8 @@ func NewSystemCommand(dockerCli command.Cli) *cobra.Command { NewInfoCommand(dockerCli), newDiskUsageCommand(dockerCli), newPruneCommand(dockerCli), + newDialStdioCommand(dockerCli), ) - if runtime.GOOS != "windows" { - cmd.AddCommand( - newDialStdioCommand(dockerCli), - ) - } return cmd }