docker_api_containers_windows_test.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. //go:build windows
  2. // +build windows
  3. package main
  4. import (
  5. "context"
  6. "fmt"
  7. "io"
  8. "math/rand"
  9. "strings"
  10. "testing"
  11. winio "github.com/Microsoft/go-winio"
  12. "github.com/Microsoft/hcsshim/osversion"
  13. "github.com/docker/docker/api/types"
  14. "github.com/docker/docker/api/types/container"
  15. "github.com/docker/docker/api/types/mount"
  16. "github.com/pkg/errors"
  17. "gotest.tools/v3/assert"
  18. is "gotest.tools/v3/assert/cmp"
  19. )
  20. func (s *DockerSuite) TestContainersAPICreateMountsBindNamedPipe(c *testing.T) {
  21. testRequires(c, testEnv.IsLocalDaemon, DaemonIsWindowsAtLeastBuild(osversion.RS3)) // Named pipe support was added in RS3
  22. // Create a host pipe to map into the container
  23. hostPipeName := fmt.Sprintf(`\\.\pipe\docker-cli-test-pipe-%x`, rand.Uint64())
  24. pc := &winio.PipeConfig{
  25. SecurityDescriptor: "D:P(A;;GA;;;AU)", // Allow all users access to the pipe
  26. }
  27. l, err := winio.ListenPipe(hostPipeName, pc)
  28. if err != nil {
  29. c.Fatal(err)
  30. }
  31. defer l.Close()
  32. // Asynchronously read data that the container writes to the mapped pipe.
  33. var b []byte
  34. ch := make(chan error)
  35. go func() {
  36. conn, err := l.Accept()
  37. if err == nil {
  38. b, err = io.ReadAll(conn)
  39. conn.Close()
  40. }
  41. ch <- err
  42. }()
  43. containerPipeName := `\\.\pipe\docker-cli-test-pipe`
  44. text := "hello from a pipe"
  45. cmd := fmt.Sprintf("echo %s > %s", text, containerPipeName)
  46. name := "test-bind-npipe"
  47. ctx := context.Background()
  48. client := testEnv.APIClient()
  49. _, err = client.ContainerCreate(ctx,
  50. &container.Config{
  51. Image: testEnv.PlatformDefaults.BaseImage,
  52. Cmd: []string{"cmd", "/c", cmd},
  53. }, &container.HostConfig{
  54. Mounts: []mount.Mount{
  55. {
  56. Type: "npipe",
  57. Source: hostPipeName,
  58. Target: containerPipeName,
  59. },
  60. },
  61. },
  62. nil, nil, name)
  63. assert.NilError(c, err)
  64. err = client.ContainerStart(ctx, name, types.ContainerStartOptions{})
  65. assert.NilError(c, err)
  66. err = <-ch
  67. assert.NilError(c, err)
  68. assert.Check(c, is.Equal(text, strings.TrimSpace(string(b))))
  69. }
  70. func mountWrapper(device, target, mType, options string) error {
  71. // This should never be called.
  72. return errors.Errorf("there is no implementation of Mount on this platform")
  73. }