2022-03-12 05:05:55 -05:00
|
|
|
package container // import "github.com/docker/docker/integration/container"
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2022-03-12 09:32:18 -05:00
|
|
|
"github.com/docker/docker/api/types"
|
2022-03-12 05:05:55 -05:00
|
|
|
containertypes "github.com/docker/docker/api/types/container"
|
|
|
|
"github.com/docker/docker/integration/internal/container"
|
|
|
|
"gotest.tools/v3/assert"
|
|
|
|
"gotest.tools/v3/poll"
|
|
|
|
"gotest.tools/v3/skip"
|
|
|
|
)
|
|
|
|
|
|
|
|
// TestWindowsDevices that Windows Devices are correctly propagated
|
|
|
|
// via HostConfig.Devices through to the implementation in hcsshim.
|
|
|
|
func TestWindowsDevices(t *testing.T) {
|
|
|
|
skip.If(t, testEnv.DaemonInfo.OSType != "windows")
|
|
|
|
defer setupTest(t)()
|
|
|
|
client := testEnv.APIClient()
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
testData := []struct {
|
2022-03-12 09:32:18 -05:00
|
|
|
doc string
|
|
|
|
devices []string
|
|
|
|
isolation containertypes.Isolation
|
|
|
|
expectedStartFailure bool
|
|
|
|
expectedStartFailureMessage string
|
|
|
|
expectedExitCode int
|
|
|
|
expectedStdout string
|
|
|
|
expectedStderr string
|
2022-03-12 05:05:55 -05:00
|
|
|
}{
|
|
|
|
{
|
2022-03-12 09:32:18 -05:00
|
|
|
doc: "process/no device mounted",
|
|
|
|
isolation: containertypes.IsolationProcess,
|
2022-03-12 05:05:55 -05:00
|
|
|
expectedExitCode: 1,
|
|
|
|
},
|
|
|
|
{
|
2022-03-12 09:32:18 -05:00
|
|
|
doc: "process/class/5B45201D-F2F2-4F3B-85BB-30FF1F953599 mounted",
|
2022-03-12 05:05:55 -05:00
|
|
|
devices: []string{"class/5B45201D-F2F2-4F3B-85BB-30FF1F953599"},
|
2022-03-12 09:32:18 -05:00
|
|
|
isolation: containertypes.IsolationProcess,
|
2022-03-12 05:05:55 -05:00
|
|
|
expectedStdout: "/Windows/System32/HostDriverStore/FileRepository",
|
|
|
|
},
|
2022-03-13 01:01:28 -05:00
|
|
|
{
|
|
|
|
doc: "process/class://5B45201D-F2F2-4F3B-85BB-30FF1F953599 mounted",
|
|
|
|
devices: []string{"class://5B45201D-F2F2-4F3B-85BB-30FF1F953599"},
|
|
|
|
isolation: containertypes.IsolationProcess,
|
|
|
|
expectedStdout: "/Windows/System32/HostDriverStore/FileRepository",
|
|
|
|
},
|
|
|
|
{
|
2022-03-13 05:00:22 -04:00
|
|
|
doc: "process/vpci-class-guid://5B45201D-F2F2-4F3B-85BB-30FF1F953599 mounted",
|
|
|
|
devices: []string{"vpci-class-guid://5B45201D-F2F2-4F3B-85BB-30FF1F953599"},
|
|
|
|
isolation: containertypes.IsolationProcess,
|
|
|
|
expectedStdout: "/Windows/System32/HostDriverStore/FileRepository",
|
2022-03-13 01:01:28 -05:00
|
|
|
},
|
2022-03-12 09:32:18 -05:00
|
|
|
{
|
|
|
|
doc: "hyperv/no device mounted",
|
|
|
|
isolation: containertypes.IsolationHyperV,
|
|
|
|
expectedExitCode: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
doc: "hyperv/class/5B45201D-F2F2-4F3B-85BB-30FF1F953599 mounted",
|
|
|
|
devices: []string{"class/5B45201D-F2F2-4F3B-85BB-30FF1F953599"},
|
|
|
|
isolation: containertypes.IsolationHyperV,
|
2022-03-13 01:01:28 -05:00
|
|
|
expectedStartFailure: !testEnv.RuntimeIsWindowsContainerd(),
|
|
|
|
expectedStartFailureMessage: "device assignment is not supported for HyperV containers",
|
|
|
|
expectedStdout: "/Windows/System32/HostDriverStore/FileRepository",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
doc: "hyperv/class://5B45201D-F2F2-4F3B-85BB-30FF1F953599 mounted",
|
|
|
|
devices: []string{"class://5B45201D-F2F2-4F3B-85BB-30FF1F953599"},
|
|
|
|
isolation: containertypes.IsolationHyperV,
|
|
|
|
expectedStartFailure: !testEnv.RuntimeIsWindowsContainerd(),
|
|
|
|
expectedStartFailureMessage: "device assignment is not supported for HyperV containers",
|
|
|
|
expectedStdout: "/Windows/System32/HostDriverStore/FileRepository",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
doc: "hyperv/vpci-class-guid://5B45201D-F2F2-4F3B-85BB-30FF1F953599 mounted",
|
|
|
|
devices: []string{"vpci-class-guid://5B45201D-F2F2-4F3B-85BB-30FF1F953599"},
|
|
|
|
isolation: containertypes.IsolationHyperV,
|
2022-03-12 09:32:18 -05:00
|
|
|
expectedStartFailure: !testEnv.RuntimeIsWindowsContainerd(),
|
|
|
|
expectedStartFailureMessage: "device assignment is not supported for HyperV containers",
|
|
|
|
expectedStdout: "/Windows/System32/HostDriverStore/FileRepository",
|
|
|
|
},
|
2022-03-12 05:05:55 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, d := range testData {
|
|
|
|
d := d
|
|
|
|
t.Run(d.doc, func(t *testing.T) {
|
|
|
|
t.Parallel()
|
2022-03-12 09:32:18 -05:00
|
|
|
deviceOptions := []func(*container.TestContainerConfig){container.WithIsolation(d.isolation)}
|
2022-03-12 05:05:55 -05:00
|
|
|
for _, deviceName := range d.devices {
|
|
|
|
deviceOptions = append(deviceOptions, container.WithWindowsDevice(deviceName))
|
|
|
|
}
|
2022-03-12 09:32:18 -05:00
|
|
|
|
|
|
|
id := container.Create(ctx, t, client, deviceOptions...)
|
|
|
|
|
|
|
|
// Hyper-V isolation is failing even with no actual devices added.
|
|
|
|
// TODO: Once https://github.com/moby/moby/issues/43395 is resolved,
|
|
|
|
// remove this skip.If and validate the expected behaviour under Hyper-V.
|
|
|
|
skip.If(t, d.isolation == containertypes.IsolationHyperV && !d.expectedStartFailure, "FIXME. HyperV isolation setup is probably incorrect in the test")
|
|
|
|
|
|
|
|
err := client.ContainerStart(ctx, id, types.ContainerStartOptions{})
|
|
|
|
if d.expectedStartFailure {
|
|
|
|
assert.ErrorContains(t, err, d.expectedStartFailureMessage)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.NilError(t, err)
|
2022-03-12 05:05:55 -05:00
|
|
|
|
|
|
|
poll.WaitOn(t, container.IsInState(ctx, client, id, "running"), poll.WithDelay(100*time.Millisecond))
|
|
|
|
|
|
|
|
// /Windows/System32/HostDriverStore is mounted from the host when class GUID 5B45201D-F2F2-4F3B-85BB-30FF1F953599
|
|
|
|
// is mounted. See `C:\windows\System32\containers\devices.def` on a Windows host for (slightly more) details.
|
|
|
|
res, err := container.Exec(ctx, client, id, []string{"sh", "-c",
|
|
|
|
"ls -d /Windows/System32/HostDriverStore/* | grep /Windows/System32/HostDriverStore/FileRepository"})
|
|
|
|
assert.NilError(t, err)
|
|
|
|
assert.Equal(t, d.expectedExitCode, res.ExitCode)
|
|
|
|
if d.expectedExitCode == 0 {
|
|
|
|
assert.Equal(t, d.expectedStdout, strings.TrimSpace(res.Stdout()))
|
|
|
|
assert.Equal(t, d.expectedStderr, strings.TrimSpace(res.Stderr()))
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|