Files
docker-cli/components/engine/integration-cli/docker_api_containers_windows_test.go
John Starks fae0c281b6 Windows: Add named pipe mount support
Current insider builds of Windows have support for mounting individual
named pipe servers from the host to the guest. This allows, for example,
exposing the docker engine's named pipe to a container.

This change allows the user to request such a mount via the normal bind
mount syntax in the CLI:

  docker run -v \\.\pipe\docker_engine:\\.\pipe\docker_engine <args>

Signed-off-by: John Starks <jostarks@microsoft.com>
Upstream-commit: 54354db850664783918a1fc9d208bcfcf47c28e2
Component: engine
2017-08-07 11:34:36 -07:00

72 lines
2.0 KiB
Go

// +build windows
package main
import (
"fmt"
"io/ioutil"
"math/rand"
"net/http"
"strings"
winio "github.com/Microsoft/go-winio"
"github.com/docker/docker/integration-cli/checker"
"github.com/docker/docker/integration-cli/request"
"github.com/go-check/check"
)
func (s *DockerSuite) TestContainersAPICreateMountsBindNamedPipe(c *check.C) {
testRequires(c, SameHostDaemon, DaemonIsWindowsAtLeastBuild(16210)) // Named pipe support was added in RS3
// Create a host pipe to map into the container
hostPipeName := fmt.Sprintf(`\\.\pipe\docker-cli-test-pipe-%x`, rand.Uint64())
pc := &winio.PipeConfig{
SecurityDescriptor: "D:P(A;;GA;;;AU)", // Allow all users access to the pipe
}
l, err := winio.ListenPipe(hostPipeName, pc)
if err != nil {
c.Fatal(err)
}
defer l.Close()
// Asynchronously read data that the container writes to the mapped pipe.
var b []byte
ch := make(chan error)
go func() {
conn, err := l.Accept()
if err == nil {
b, err = ioutil.ReadAll(conn)
conn.Close()
}
ch <- err
}()
containerPipeName := `\\.\pipe\docker-cli-test-pipe`
text := "hello from a pipe"
cmd := fmt.Sprintf("echo %s > %s", text, containerPipeName)
name := "test-bind-npipe"
data := map[string]interface{}{
"Image": testEnv.MinimalBaseImage(),
"Cmd": []string{"cmd", "/c", cmd},
"HostConfig": map[string]interface{}{"Mounts": []map[string]interface{}{{"Type": "npipe", "Source": hostPipeName, "Target": containerPipeName}}},
}
status, resp, err := request.SockRequest("POST", "/containers/create?name="+name, data, daemonHost())
c.Assert(err, checker.IsNil, check.Commentf(string(resp)))
c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(resp)))
status, _, err = request.SockRequest("POST", "/containers/"+name+"/start", nil, daemonHost())
c.Assert(err, checker.IsNil)
c.Assert(status, checker.Equals, http.StatusNoContent)
err = <-ch
if err != nil {
c.Fatal(err)
}
result := strings.TrimSpace(string(b))
if result != text {
c.Errorf("expected pipe to contain %s, got %s", text, result)
}
}