diff --git a/cli/cmd/serve.go b/cli/cmd/serve.go index 59fc8441b..6ea6c0793 100644 --- a/cli/cmd/serve.go +++ b/cli/cmd/serve.go @@ -2,7 +2,6 @@ package cmd import ( "context" - "net" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -39,10 +38,12 @@ func ServeCommand() *cobra.Command { func runServe(ctx context.Context, opts serveOpts) error { s := server.New() - listener, err := net.Listen("unix", opts.address) + listener, err := server.CreateListener(opts.address) + if err != nil { - return errors.Wrap(err, "listen unix socket") + return errors.Wrap(err, "listen address "+opts.address) } + // nolint errcheck defer listener.Close() diff --git a/go.mod b/go.mod index 5b03523af..1bb974af6 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/Azure/go-autorest/autorest/date v0.2.0 github.com/Azure/go-autorest/autorest/to v0.3.0 github.com/Azure/go-autorest/autorest/validation v0.2.0 // indirect - github.com/Microsoft/go-winio v0.4.14 // indirect + github.com/Microsoft/go-winio v0.4.14 github.com/buger/goterm v0.0.0-20200322175922-2f3e71b85129 github.com/compose-spec/compose-go v0.0.0-20200423124427-63dcf8c22cae github.com/containerd/console v1.0.0 diff --git a/server/server.go b/server/server.go index c24bfc871..b24e2c206 100644 --- a/server/server.go +++ b/server/server.go @@ -30,6 +30,8 @@ package server import ( "context" "errors" + "net" + "strings" grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "google.golang.org/grpc" @@ -57,6 +59,15 @@ func New() *grpc.Server { return s } + +//CreateListener creates a listener either on tcp://, or local listener, supporting unix:// for unix socket or npipe:// for named pipes on windows +func CreateListener(address string) (net.Listener, error) { + if strings.HasPrefix(address, "tcp://") { + return net.Listen("tcp", strings.TrimPrefix(address, "tcp://")) + } + return createLocalListener(address) +} + func unary(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { return grpc_prometheus.UnaryServerInterceptor(ctx, req, info, handler) } diff --git a/server/socket_unix.go b/server/socket_unix.go new file mode 100644 index 000000000..49b095c50 --- /dev/null +++ b/server/socket_unix.go @@ -0,0 +1,16 @@ +// +build !windows + +package server + +import ( + "errors" + "net" + "strings" +) + +func createLocalListener(address string) (net.Listener, error) { + if !strings.HasPrefix(address, "unix://") { + return nil, errors.New("Cannot parse address, must start with unix:// or tcp:// : " + address) + } + return net.Listen("unix", strings.TrimPrefix(address, "unix://")) +} diff --git a/server/socket_windows.go b/server/socket_windows.go new file mode 100644 index 000000000..fbcba0d12 --- /dev/null +++ b/server/socket_windows.go @@ -0,0 +1,22 @@ +// +build windows + +package server + +import ( + "errors" + "net" + "strings" + + "github.com/Microsoft/go-winio" +) + +func createLocalListener(address string) (net.Listener, error) { + if !strings.HasPrefix(address, "npipe://") { + return nil, errors.New("Cannot parse address, must start with npipe:// or tcp:// : " + address) + } + return winio.ListenPipe(strings.TrimPrefix(address, "npipe://"), &winio.PipeConfig{ + MessageMode: true, // Use message mode so that CloseWrite() is supported + InputBufferSize: 65536, // Use 64KB buffers to improve performance + OutputBufferSize: 65536, + }) +} diff --git a/tests/framework/exec.go b/tests/framework/exec.go index 36866e44f..d84a83128 100644 --- a/tests/framework/exec.go +++ b/tests/framework/exec.go @@ -46,7 +46,7 @@ func NewCommand(command string, args ...string) *CmdContext { func dockerExecutable() string { if runtime.GOOS == "windows" { - return "./bin/windows/docker.exe" + return "./bin/docker.exe" } return "./bin/docker" }