Refactor and extract TestRequire functionality
This will help when extracting suites in their own package. Signed-off-by: Vincent Demeester <vincent@sbr.pm>
This commit is contained in:
parent
ba1c20f8d6
commit
930a9869f6
|
@ -1665,7 +1665,7 @@ func (s *DockerSuite) TestContainersAPICreateMountsValidation(c *check.C) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if SameHostDaemon.Condition() {
|
if SameHostDaemon() {
|
||||||
tmpDir, err := ioutils.TempDir("", "test-mounts-api")
|
tmpDir, err := ioutils.TempDir("", "test-mounts-api")
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
|
@ -1696,7 +1696,7 @@ func (s *DockerSuite) TestContainersAPICreateMountsValidation(c *check.C) {
|
||||||
}...)
|
}...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if DaemonIsLinux.Condition() {
|
if DaemonIsLinux() {
|
||||||
cases = append(cases, []testCase{
|
cases = append(cases, []testCase{
|
||||||
{
|
{
|
||||||
config: cfg{
|
config: cfg{
|
||||||
|
@ -1823,7 +1823,7 @@ func (s *DockerSuite) TestContainersAPICreateMountsCreate(c *check.C) {
|
||||||
{mounttypes.Mount{Type: "volume", Target: destPath, Source: "test3", VolumeOptions: &mounttypes.VolumeOptions{DriverConfig: &mounttypes.Driver{Name: volume.DefaultDriverName}}}, types.MountPoint{Driver: volume.DefaultDriverName, Type: "volume", Name: "test3", RW: true, Destination: destPath}},
|
{mounttypes.Mount{Type: "volume", Target: destPath, Source: "test3", VolumeOptions: &mounttypes.VolumeOptions{DriverConfig: &mounttypes.Driver{Name: volume.DefaultDriverName}}}, types.MountPoint{Driver: volume.DefaultDriverName, Type: "volume", Name: "test3", RW: true, Destination: destPath}},
|
||||||
}
|
}
|
||||||
|
|
||||||
if SameHostDaemon.Condition() {
|
if SameHostDaemon() {
|
||||||
// setup temp dir for testing binds
|
// setup temp dir for testing binds
|
||||||
tmpDir1, err := ioutil.TempDir("", "test-mounts-api-1")
|
tmpDir1, err := ioutil.TempDir("", "test-mounts-api-1")
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
@ -1834,7 +1834,7 @@ func (s *DockerSuite) TestContainersAPICreateMountsCreate(c *check.C) {
|
||||||
}...)
|
}...)
|
||||||
|
|
||||||
// for modes only supported on Linux
|
// for modes only supported on Linux
|
||||||
if DaemonIsLinux.Condition() {
|
if DaemonIsLinux() {
|
||||||
tmpDir3, err := ioutils.TempDir("", "test-mounts-api-3")
|
tmpDir3, err := ioutils.TempDir("", "test-mounts-api-3")
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
defer os.RemoveAll(tmpDir3)
|
defer os.RemoveAll(tmpDir3)
|
||||||
|
|
|
@ -289,7 +289,7 @@ func containerStartOutputEquals(c *check.C, containerID, contents string) (err e
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultVolumes(tmpDir string) []string {
|
func defaultVolumes(tmpDir string) []string {
|
||||||
if SameHostDaemon.Condition() {
|
if SameHostDaemon() {
|
||||||
return []string{
|
return []string{
|
||||||
"/vol1",
|
"/vol1",
|
||||||
fmt.Sprintf("%s:/vol2", tmpDir),
|
fmt.Sprintf("%s:/vol2", tmpDir),
|
||||||
|
|
|
@ -40,7 +40,7 @@ func (s *DockerSuite) TestInfoEnsureSucceeds(c *check.C) {
|
||||||
stringsToCheck = append(stringsToCheck, "Init Binary:", "Security Options:", "containerd version:", "runc version:", "init version:")
|
stringsToCheck = append(stringsToCheck, "Init Binary:", "Security Options:", "containerd version:", "runc version:", "init version:")
|
||||||
}
|
}
|
||||||
|
|
||||||
if DaemonIsLinux.Condition() {
|
if DaemonIsLinux() {
|
||||||
stringsToCheck = append(stringsToCheck, "Runtimes:", "Default Runtime: runc")
|
stringsToCheck = append(stringsToCheck, "Runtimes:", "Default Runtime: runc")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -749,7 +749,7 @@ func (s *DockerSuite) TestPsShowMounts(c *check.C) {
|
||||||
// bind mount container
|
// bind mount container
|
||||||
var bindMountSource string
|
var bindMountSource string
|
||||||
var bindMountDestination string
|
var bindMountDestination string
|
||||||
if DaemonIsWindows.Condition() {
|
if DaemonIsWindows() {
|
||||||
bindMountSource = "c:\\"
|
bindMountSource = "c:\\"
|
||||||
bindMountDestination = "c:\\t"
|
bindMountDestination = "c:\\t"
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -13,9 +13,7 @@ import (
|
||||||
"github.com/go-check/check"
|
"github.com/go-check/check"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
func macvlanKernelSupport() bool {
|
||||||
MacvlanKernelSupport = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
const macvlanKernelVer = 3 // minimum macvlan kernel support
|
const macvlanKernelVer = 3 // minimum macvlan kernel support
|
||||||
const macvlanMajorVer = 9 // minimum macvlan major kernel support
|
const macvlanMajorVer = 9 // minimum macvlan major kernel support
|
||||||
kv, err := kernel.GetKernelVersion()
|
kv, err := kernel.GetKernelVersion()
|
||||||
|
@ -27,11 +25,9 @@ var (
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
},
|
|
||||||
"kernel version failed to meet the minimum macvlan kernel requirement of 3.9",
|
|
||||||
}
|
}
|
||||||
IpvlanKernelSupport = testRequirement{
|
|
||||||
func() bool {
|
func ipvlanKernelSupport() bool {
|
||||||
const ipvlanKernelVer = 4 // minimum ipvlan kernel support
|
const ipvlanKernelVer = 4 // minimum ipvlan kernel support
|
||||||
const ipvlanMajorVer = 2 // minimum ipvlan major kernel support
|
const ipvlanMajorVer = 2 // minimum ipvlan major kernel support
|
||||||
kv, err := kernel.GetKernelVersion()
|
kv, err := kernel.GetKernelVersion()
|
||||||
|
@ -43,14 +39,11 @@ var (
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
},
|
|
||||||
"kernel version failed to meet the minimum ipvlan kernel requirement of 4.0.0",
|
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
func (s *DockerNetworkSuite) TestDockerNetworkMacvlanPersistance(c *check.C) {
|
func (s *DockerNetworkSuite) TestDockerNetworkMacvlanPersistance(c *check.C) {
|
||||||
// verify the driver automatically provisions the 802.1q link (dm-dummy0.60)
|
// verify the driver automatically provisions the 802.1q link (dm-dummy0.60)
|
||||||
testRequires(c, DaemonIsLinux, MacvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||||
|
|
||||||
// master dummy interface 'dm' abbreviation represents 'docker macvlan'
|
// master dummy interface 'dm' abbreviation represents 'docker macvlan'
|
||||||
master := "dm-dummy0"
|
master := "dm-dummy0"
|
||||||
|
@ -70,7 +63,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanPersistance(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerNetworkSuite) TestDockerNetworkIpvlanPersistance(c *check.C) {
|
func (s *DockerNetworkSuite) TestDockerNetworkIpvlanPersistance(c *check.C) {
|
||||||
// verify the driver automatically provisions the 802.1q link (di-dummy0.70)
|
// verify the driver automatically provisions the 802.1q link (di-dummy0.70)
|
||||||
testRequires(c, DaemonIsLinux, IpvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||||
// master dummy interface 'di' notation represent 'docker ipvlan'
|
// master dummy interface 'di' notation represent 'docker ipvlan'
|
||||||
master := "di-dummy0"
|
master := "di-dummy0"
|
||||||
// simulate the master link the vlan tagged subinterface parent link will use
|
// simulate the master link the vlan tagged subinterface parent link will use
|
||||||
|
@ -89,7 +82,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanPersistance(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerNetworkSuite) TestDockerNetworkMacvlanSubIntCreate(c *check.C) {
|
func (s *DockerNetworkSuite) TestDockerNetworkMacvlanSubIntCreate(c *check.C) {
|
||||||
// verify the driver automatically provisions the 802.1q link (dm-dummy0.50)
|
// verify the driver automatically provisions the 802.1q link (dm-dummy0.50)
|
||||||
testRequires(c, DaemonIsLinux, MacvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||||
// master dummy interface 'dm' abbreviation represents 'docker macvlan'
|
// master dummy interface 'dm' abbreviation represents 'docker macvlan'
|
||||||
master := "dm-dummy0"
|
master := "dm-dummy0"
|
||||||
// simulate the master link the vlan tagged subinterface parent link will use
|
// simulate the master link the vlan tagged subinterface parent link will use
|
||||||
|
@ -104,7 +97,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanSubIntCreate(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerNetworkSuite) TestDockerNetworkIpvlanSubIntCreate(c *check.C) {
|
func (s *DockerNetworkSuite) TestDockerNetworkIpvlanSubIntCreate(c *check.C) {
|
||||||
// verify the driver automatically provisions the 802.1q link (di-dummy0.50)
|
// verify the driver automatically provisions the 802.1q link (di-dummy0.50)
|
||||||
testRequires(c, DaemonIsLinux, IpvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||||
// master dummy interface 'dm' abbreviation represents 'docker ipvlan'
|
// master dummy interface 'dm' abbreviation represents 'docker ipvlan'
|
||||||
master := "di-dummy0"
|
master := "di-dummy0"
|
||||||
// simulate the master link the vlan tagged subinterface parent link will use
|
// simulate the master link the vlan tagged subinterface parent link will use
|
||||||
|
@ -119,7 +112,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanSubIntCreate(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerNetworkSuite) TestDockerNetworkMacvlanOverlapParent(c *check.C) {
|
func (s *DockerNetworkSuite) TestDockerNetworkMacvlanOverlapParent(c *check.C) {
|
||||||
// verify the same parent interface cannot be used if already in use by an existing network
|
// verify the same parent interface cannot be used if already in use by an existing network
|
||||||
testRequires(c, DaemonIsLinux, MacvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||||
// master dummy interface 'dm' abbreviation represents 'docker macvlan'
|
// master dummy interface 'dm' abbreviation represents 'docker macvlan'
|
||||||
master := "dm-dummy0"
|
master := "dm-dummy0"
|
||||||
out, err := createMasterDummy(c, master)
|
out, err := createMasterDummy(c, master)
|
||||||
|
@ -139,7 +132,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanOverlapParent(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerNetworkSuite) TestDockerNetworkIpvlanOverlapParent(c *check.C) {
|
func (s *DockerNetworkSuite) TestDockerNetworkIpvlanOverlapParent(c *check.C) {
|
||||||
// verify the same parent interface cannot be used if already in use by an existing network
|
// verify the same parent interface cannot be used if already in use by an existing network
|
||||||
testRequires(c, DaemonIsLinux, IpvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||||
// master dummy interface 'dm' abbreviation represents 'docker ipvlan'
|
// master dummy interface 'dm' abbreviation represents 'docker ipvlan'
|
||||||
master := "di-dummy0"
|
master := "di-dummy0"
|
||||||
out, err := createMasterDummy(c, master)
|
out, err := createMasterDummy(c, master)
|
||||||
|
@ -159,7 +152,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanOverlapParent(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerNetworkSuite) TestDockerNetworkMacvlanMultiSubnet(c *check.C) {
|
func (s *DockerNetworkSuite) TestDockerNetworkMacvlanMultiSubnet(c *check.C) {
|
||||||
// create a dual stack multi-subnet Macvlan bridge mode network and validate connectivity between four containers, two on each subnet
|
// create a dual stack multi-subnet Macvlan bridge mode network and validate connectivity between four containers, two on each subnet
|
||||||
testRequires(c, DaemonIsLinux, IPv6, MacvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, IPv6, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||||
dockerCmd(c, "network", "create", "--driver=macvlan", "--ipv6", "--subnet=172.28.100.0/24", "--subnet=172.28.102.0/24", "--gateway=172.28.102.254",
|
dockerCmd(c, "network", "create", "--driver=macvlan", "--ipv6", "--subnet=172.28.100.0/24", "--subnet=172.28.102.0/24", "--gateway=172.28.102.254",
|
||||||
"--subnet=2001:db8:abc2::/64", "--subnet=2001:db8:abc4::/64", "--gateway=2001:db8:abc4::254", "dualstackbridge")
|
"--subnet=2001:db8:abc2::/64", "--subnet=2001:db8:abc4::/64", "--gateway=2001:db8:abc4::254", "dualstackbridge")
|
||||||
// Ensure the network was created
|
// Ensure the network was created
|
||||||
|
@ -214,7 +207,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanMultiSubnet(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerNetworkSuite) TestDockerNetworkIpvlanL2MultiSubnet(c *check.C) {
|
func (s *DockerNetworkSuite) TestDockerNetworkIpvlanL2MultiSubnet(c *check.C) {
|
||||||
// create a dual stack multi-subnet Ipvlan L2 network and validate connectivity within the subnets, two on each subnet
|
// create a dual stack multi-subnet Ipvlan L2 network and validate connectivity within the subnets, two on each subnet
|
||||||
testRequires(c, DaemonIsLinux, IPv6, IpvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, IPv6, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||||
dockerCmd(c, "network", "create", "--driver=ipvlan", "--ipv6", "--subnet=172.28.200.0/24", "--subnet=172.28.202.0/24", "--gateway=172.28.202.254",
|
dockerCmd(c, "network", "create", "--driver=ipvlan", "--ipv6", "--subnet=172.28.200.0/24", "--subnet=172.28.202.0/24", "--gateway=172.28.202.254",
|
||||||
"--subnet=2001:db8:abc8::/64", "--subnet=2001:db8:abc6::/64", "--gateway=2001:db8:abc6::254", "dualstackl2")
|
"--subnet=2001:db8:abc8::/64", "--subnet=2001:db8:abc6::/64", "--gateway=2001:db8:abc6::254", "dualstackl2")
|
||||||
// Ensure the network was created
|
// Ensure the network was created
|
||||||
|
@ -268,7 +261,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanL2MultiSubnet(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerNetworkSuite) TestDockerNetworkIpvlanL3MultiSubnet(c *check.C) {
|
func (s *DockerNetworkSuite) TestDockerNetworkIpvlanL3MultiSubnet(c *check.C) {
|
||||||
// create a dual stack multi-subnet Ipvlan L3 network and validate connectivity between all four containers per L3 mode
|
// create a dual stack multi-subnet Ipvlan L3 network and validate connectivity between all four containers per L3 mode
|
||||||
testRequires(c, DaemonIsLinux, IPv6, IpvlanKernelSupport, NotUserNamespace, NotArm, IPv6, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, IPv6, ipvlanKernelSupport, NotUserNamespace, NotArm, IPv6, ExperimentalDaemon)
|
||||||
dockerCmd(c, "network", "create", "--driver=ipvlan", "--ipv6", "--subnet=172.28.10.0/24", "--subnet=172.28.12.0/24", "--gateway=172.28.12.254",
|
dockerCmd(c, "network", "create", "--driver=ipvlan", "--ipv6", "--subnet=172.28.10.0/24", "--subnet=172.28.12.0/24", "--gateway=172.28.12.254",
|
||||||
"--subnet=2001:db8:abc9::/64", "--subnet=2001:db8:abc7::/64", "--gateway=2001:db8:abc7::254", "-o", "ipvlan_mode=l3", "dualstackl3")
|
"--subnet=2001:db8:abc9::/64", "--subnet=2001:db8:abc7::/64", "--gateway=2001:db8:abc7::254", "-o", "ipvlan_mode=l3", "dualstackl3")
|
||||||
// Ensure the network was created
|
// Ensure the network was created
|
||||||
|
@ -327,7 +320,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanL3MultiSubnet(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerNetworkSuite) TestDockerNetworkIpvlanAddressing(c *check.C) {
|
func (s *DockerNetworkSuite) TestDockerNetworkIpvlanAddressing(c *check.C) {
|
||||||
// Ensure the default gateways, next-hops and default dev devices are properly set
|
// Ensure the default gateways, next-hops and default dev devices are properly set
|
||||||
testRequires(c, DaemonIsLinux, IPv6, IpvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, IPv6, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||||
dockerCmd(c, "network", "create", "--driver=macvlan", "--ipv6", "--subnet=172.28.130.0/24",
|
dockerCmd(c, "network", "create", "--driver=macvlan", "--ipv6", "--subnet=172.28.130.0/24",
|
||||||
"--subnet=2001:db8:abca::/64", "--gateway=2001:db8:abca::254", "-o", "macvlan_mode=bridge", "dualstackbridge")
|
"--subnet=2001:db8:abca::/64", "--gateway=2001:db8:abca::254", "-o", "macvlan_mode=bridge", "dualstackbridge")
|
||||||
assertNwIsAvailable(c, "dualstackbridge")
|
assertNwIsAvailable(c, "dualstackbridge")
|
||||||
|
@ -373,7 +366,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanAddressing(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerSuite) TestDockerNetworkMacVlanBridgeNilParent(c *check.C) {
|
func (s *DockerSuite) TestDockerNetworkMacVlanBridgeNilParent(c *check.C) {
|
||||||
// macvlan bridge mode - dummy parent interface is provisioned dynamically
|
// macvlan bridge mode - dummy parent interface is provisioned dynamically
|
||||||
testRequires(c, DaemonIsLinux, MacvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||||
dockerCmd(c, "network", "create", "--driver=macvlan", "dm-nil-parent")
|
dockerCmd(c, "network", "create", "--driver=macvlan", "dm-nil-parent")
|
||||||
assertNwIsAvailable(c, "dm-nil-parent")
|
assertNwIsAvailable(c, "dm-nil-parent")
|
||||||
|
|
||||||
|
@ -390,7 +383,7 @@ func (s *DockerSuite) TestDockerNetworkMacVlanBridgeNilParent(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerSuite) TestDockerNetworkMacVlanBridgeInternalMode(c *check.C) {
|
func (s *DockerSuite) TestDockerNetworkMacVlanBridgeInternalMode(c *check.C) {
|
||||||
// macvlan bridge mode --internal containers can communicate inside the network but not externally
|
// macvlan bridge mode --internal containers can communicate inside the network but not externally
|
||||||
testRequires(c, DaemonIsLinux, MacvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||||
dockerCmd(c, "network", "create", "--driver=macvlan", "--internal", "dm-internal")
|
dockerCmd(c, "network", "create", "--driver=macvlan", "--internal", "dm-internal")
|
||||||
assertNwIsAvailable(c, "dm-internal")
|
assertNwIsAvailable(c, "dm-internal")
|
||||||
nr := getNetworkResource(c, "dm-internal")
|
nr := getNetworkResource(c, "dm-internal")
|
||||||
|
@ -413,7 +406,7 @@ func (s *DockerSuite) TestDockerNetworkMacVlanBridgeInternalMode(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerSuite) TestDockerNetworkIpvlanL2NilParent(c *check.C) {
|
func (s *DockerSuite) TestDockerNetworkIpvlanL2NilParent(c *check.C) {
|
||||||
// ipvlan l2 mode - dummy parent interface is provisioned dynamically
|
// ipvlan l2 mode - dummy parent interface is provisioned dynamically
|
||||||
testRequires(c, DaemonIsLinux, IpvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||||
dockerCmd(c, "network", "create", "--driver=ipvlan", "di-nil-parent")
|
dockerCmd(c, "network", "create", "--driver=ipvlan", "di-nil-parent")
|
||||||
assertNwIsAvailable(c, "di-nil-parent")
|
assertNwIsAvailable(c, "di-nil-parent")
|
||||||
|
|
||||||
|
@ -430,7 +423,7 @@ func (s *DockerSuite) TestDockerNetworkIpvlanL2NilParent(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerSuite) TestDockerNetworkIpvlanL2InternalMode(c *check.C) {
|
func (s *DockerSuite) TestDockerNetworkIpvlanL2InternalMode(c *check.C) {
|
||||||
// ipvlan l2 mode --internal containers can communicate inside the network but not externally
|
// ipvlan l2 mode --internal containers can communicate inside the network but not externally
|
||||||
testRequires(c, DaemonIsLinux, IpvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||||
dockerCmd(c, "network", "create", "--driver=ipvlan", "--internal", "di-internal")
|
dockerCmd(c, "network", "create", "--driver=ipvlan", "--internal", "di-internal")
|
||||||
assertNwIsAvailable(c, "di-internal")
|
assertNwIsAvailable(c, "di-internal")
|
||||||
nr := getNetworkResource(c, "di-internal")
|
nr := getNetworkResource(c, "di-internal")
|
||||||
|
@ -452,7 +445,7 @@ func (s *DockerSuite) TestDockerNetworkIpvlanL2InternalMode(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerSuite) TestDockerNetworkIpvlanL3NilParent(c *check.C) {
|
func (s *DockerSuite) TestDockerNetworkIpvlanL3NilParent(c *check.C) {
|
||||||
// ipvlan l3 mode - dummy parent interface is provisioned dynamically
|
// ipvlan l3 mode - dummy parent interface is provisioned dynamically
|
||||||
testRequires(c, DaemonIsLinux, IpvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||||
dockerCmd(c, "network", "create", "--driver=ipvlan", "--subnet=172.28.230.0/24",
|
dockerCmd(c, "network", "create", "--driver=ipvlan", "--subnet=172.28.230.0/24",
|
||||||
"--subnet=172.28.220.0/24", "-o", "ipvlan_mode=l3", "di-nil-parent-l3")
|
"--subnet=172.28.220.0/24", "-o", "ipvlan_mode=l3", "di-nil-parent-l3")
|
||||||
assertNwIsAvailable(c, "di-nil-parent-l3")
|
assertNwIsAvailable(c, "di-nil-parent-l3")
|
||||||
|
@ -470,7 +463,7 @@ func (s *DockerSuite) TestDockerNetworkIpvlanL3NilParent(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerSuite) TestDockerNetworkIpvlanL3InternalMode(c *check.C) {
|
func (s *DockerSuite) TestDockerNetworkIpvlanL3InternalMode(c *check.C) {
|
||||||
// ipvlan l3 mode --internal containers can communicate inside the network but not externally
|
// ipvlan l3 mode --internal containers can communicate inside the network but not externally
|
||||||
testRequires(c, DaemonIsLinux, IpvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||||
dockerCmd(c, "network", "create", "--driver=ipvlan", "--subnet=172.28.230.0/24",
|
dockerCmd(c, "network", "create", "--driver=ipvlan", "--subnet=172.28.230.0/24",
|
||||||
"--subnet=172.28.220.0/24", "-o", "ipvlan_mode=l3", "--internal", "di-internal-l3")
|
"--subnet=172.28.220.0/24", "-o", "ipvlan_mode=l3", "--internal", "di-internal-l3")
|
||||||
assertNwIsAvailable(c, "di-internal-l3")
|
assertNwIsAvailable(c, "di-internal-l3")
|
||||||
|
@ -493,7 +486,7 @@ func (s *DockerSuite) TestDockerNetworkIpvlanL3InternalMode(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerSuite) TestDockerNetworkMacVlanExistingParent(c *check.C) {
|
func (s *DockerSuite) TestDockerNetworkMacVlanExistingParent(c *check.C) {
|
||||||
// macvlan bridge mode - empty parent interface containers can reach each other internally but not externally
|
// macvlan bridge mode - empty parent interface containers can reach each other internally but not externally
|
||||||
testRequires(c, DaemonIsLinux, MacvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||||
netName := "dm-parent-exists"
|
netName := "dm-parent-exists"
|
||||||
out, err := createMasterDummy(c, "dm-dummy0")
|
out, err := createMasterDummy(c, "dm-dummy0")
|
||||||
//out, err := createVlanInterface(c, "dm-parent", "dm-slave", "macvlan", "bridge")
|
//out, err := createVlanInterface(c, "dm-parent", "dm-slave", "macvlan", "bridge")
|
||||||
|
@ -513,7 +506,7 @@ func (s *DockerSuite) TestDockerNetworkMacVlanExistingParent(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerSuite) TestDockerNetworkMacVlanSubinterface(c *check.C) {
|
func (s *DockerSuite) TestDockerNetworkMacVlanSubinterface(c *check.C) {
|
||||||
// macvlan bridge mode - empty parent interface containers can reach each other internally but not externally
|
// macvlan bridge mode - empty parent interface containers can reach each other internally but not externally
|
||||||
testRequires(c, DaemonIsLinux, MacvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||||
netName := "dm-subinterface"
|
netName := "dm-subinterface"
|
||||||
out, err := createMasterDummy(c, "dm-dummy0")
|
out, err := createMasterDummy(c, "dm-dummy0")
|
||||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package requirement
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
type skipT interface {
|
||||||
|
Skip(reason string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test represent a function that can be used as a requirement validation.
|
||||||
|
type Test func() bool
|
||||||
|
|
||||||
|
// Is checks if the environment satisfies the requirements
|
||||||
|
// for the test to run or skips the tests.
|
||||||
|
func Is(s skipT, requirements ...Test) {
|
||||||
|
for _, r := range requirements {
|
||||||
|
isValid := r()
|
||||||
|
if !isValid {
|
||||||
|
requirementFunc := runtime.FuncForPC(reflect.ValueOf(r).Pointer()).Name()
|
||||||
|
s.Skip(fmt.Sprintf("unmatched requirement %s", requirementFunc))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,237 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/go-check/check"
|
|
||||||
)
|
|
||||||
|
|
||||||
type testCondition func() bool
|
|
||||||
|
|
||||||
type testRequirement struct {
|
|
||||||
Condition testCondition
|
|
||||||
SkipMessage string
|
|
||||||
}
|
|
||||||
|
|
||||||
// List test requirements
|
|
||||||
var (
|
|
||||||
DaemonIsWindows = testRequirement{
|
|
||||||
func() bool { return daemonPlatform == "windows" },
|
|
||||||
"Test requires a Windows daemon",
|
|
||||||
}
|
|
||||||
DaemonIsLinux = testRequirement{
|
|
||||||
func() bool { return daemonPlatform == "linux" },
|
|
||||||
"Test requires a Linux daemon",
|
|
||||||
}
|
|
||||||
ExperimentalDaemon = testRequirement{
|
|
||||||
func() bool { return experimentalDaemon },
|
|
||||||
"Test requires an experimental daemon",
|
|
||||||
}
|
|
||||||
NotExperimentalDaemon = testRequirement{
|
|
||||||
func() bool { return !experimentalDaemon },
|
|
||||||
"Test requires a non experimental daemon",
|
|
||||||
}
|
|
||||||
IsAmd64 = testRequirement{
|
|
||||||
func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") == "amd64" },
|
|
||||||
"Test requires a daemon running on amd64",
|
|
||||||
}
|
|
||||||
NotArm = testRequirement{
|
|
||||||
func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") != "arm" },
|
|
||||||
"Test requires a daemon not running on ARM",
|
|
||||||
}
|
|
||||||
NotArm64 = testRequirement{
|
|
||||||
func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") != "arm64" },
|
|
||||||
"Test requires a daemon not running on arm64",
|
|
||||||
}
|
|
||||||
NotPpc64le = testRequirement{
|
|
||||||
func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") != "ppc64le" },
|
|
||||||
"Test requires a daemon not running on ppc64le",
|
|
||||||
}
|
|
||||||
NotS390X = testRequirement{
|
|
||||||
func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") != "s390x" },
|
|
||||||
"Test requires a daemon not running on s390x",
|
|
||||||
}
|
|
||||||
SameHostDaemon = testRequirement{
|
|
||||||
func() bool { return isLocalDaemon },
|
|
||||||
"Test requires docker daemon to run on the same machine as CLI",
|
|
||||||
}
|
|
||||||
UnixCli = testRequirement{
|
|
||||||
func() bool { return isUnixCli },
|
|
||||||
"Test requires posix utilities or functionality to run.",
|
|
||||||
}
|
|
||||||
ExecSupport = testRequirement{
|
|
||||||
func() bool { return supportsExec },
|
|
||||||
"Test requires 'docker exec' capabilities on the tested daemon.",
|
|
||||||
}
|
|
||||||
Network = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
// Set a timeout on the GET at 15s
|
|
||||||
var timeout = time.Duration(15 * time.Second)
|
|
||||||
var url = "https://hub.docker.com"
|
|
||||||
|
|
||||||
client := http.Client{
|
|
||||||
Timeout: timeout,
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := client.Get(url)
|
|
||||||
if err != nil && strings.Contains(err.Error(), "use of closed network connection") {
|
|
||||||
panic(fmt.Sprintf("Timeout for GET request on %s", url))
|
|
||||||
}
|
|
||||||
if resp != nil {
|
|
||||||
resp.Body.Close()
|
|
||||||
}
|
|
||||||
return err == nil
|
|
||||||
},
|
|
||||||
"Test requires network availability, environment variable set to none to run in a non-network enabled mode.",
|
|
||||||
}
|
|
||||||
Apparmor = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled")
|
|
||||||
return err == nil && len(buf) > 1 && buf[0] == 'Y'
|
|
||||||
},
|
|
||||||
"Test requires apparmor is enabled.",
|
|
||||||
}
|
|
||||||
RegistryHosting = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
// for now registry binary is built only if we're running inside
|
|
||||||
// container through `make test`. Figure that out by testing if
|
|
||||||
// registry binary is in PATH.
|
|
||||||
_, err := exec.LookPath(v2binary)
|
|
||||||
return err == nil
|
|
||||||
},
|
|
||||||
fmt.Sprintf("Test requires an environment that can host %s in the same host", v2binary),
|
|
||||||
}
|
|
||||||
NotaryHosting = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
// for now notary binary is built only if we're running inside
|
|
||||||
// container through `make test`. Figure that out by testing if
|
|
||||||
// notary-server binary is in PATH.
|
|
||||||
_, err := exec.LookPath(notaryServerBinary)
|
|
||||||
return err == nil
|
|
||||||
},
|
|
||||||
fmt.Sprintf("Test requires an environment that can host %s in the same host", notaryServerBinary),
|
|
||||||
}
|
|
||||||
NotaryServerHosting = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
// for now notary-server binary is built only if we're running inside
|
|
||||||
// container through `make test`. Figure that out by testing if
|
|
||||||
// notary-server binary is in PATH.
|
|
||||||
_, err := exec.LookPath(notaryServerBinary)
|
|
||||||
return err == nil
|
|
||||||
},
|
|
||||||
fmt.Sprintf("Test requires an environment that can host %s in the same host", notaryServerBinary),
|
|
||||||
}
|
|
||||||
NotOverlay = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return !strings.HasPrefix(daemonStorageDriver, "overlay")
|
|
||||||
},
|
|
||||||
"Test requires underlying root filesystem not be backed by overlay.",
|
|
||||||
}
|
|
||||||
|
|
||||||
Devicemapper = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return strings.HasPrefix(daemonStorageDriver, "devicemapper")
|
|
||||||
},
|
|
||||||
"Test requires underlying root filesystem to be backed by devicemapper.",
|
|
||||||
}
|
|
||||||
|
|
||||||
IPv6 = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
cmd := exec.Command("test", "-f", "/proc/net/if_inet6")
|
|
||||||
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
"Test requires support for IPv6",
|
|
||||||
}
|
|
||||||
UserNamespaceROMount = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
// quick case--userns not enabled in this test run
|
|
||||||
if os.Getenv("DOCKER_REMAP_ROOT") == "" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if _, _, err := dockerCmdWithError("run", "--rm", "--read-only", "busybox", "date"); err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
"Test cannot be run if user namespaces enabled but readonly mounts fail on this kernel.",
|
|
||||||
}
|
|
||||||
UserNamespaceInKernel = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
if _, err := os.Stat("/proc/self/uid_map"); os.IsNotExist(err) {
|
|
||||||
/*
|
|
||||||
* This kernel-provided file only exists if user namespaces are
|
|
||||||
* supported
|
|
||||||
*/
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need extra check on redhat based distributions
|
|
||||||
if f, err := os.Open("/sys/module/user_namespace/parameters/enable"); err == nil {
|
|
||||||
defer f.Close()
|
|
||||||
b := make([]byte, 1)
|
|
||||||
_, _ = f.Read(b)
|
|
||||||
return string(b) != "N"
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
"Kernel must have user namespaces configured and enabled.",
|
|
||||||
}
|
|
||||||
NotUserNamespace = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
root := os.Getenv("DOCKER_REMAP_ROOT")
|
|
||||||
return root == ""
|
|
||||||
},
|
|
||||||
"Test cannot be run when remapping root",
|
|
||||||
}
|
|
||||||
IsPausable = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
if daemonPlatform == "windows" {
|
|
||||||
return isolation == "hyperv"
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
"Test requires containers are pausable.",
|
|
||||||
}
|
|
||||||
NotPausable = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
if daemonPlatform == "windows" {
|
|
||||||
return isolation == "process"
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
"Test requires containers are not pausable.",
|
|
||||||
}
|
|
||||||
IsolationIsHyperv = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return daemonPlatform == "windows" && isolation == "hyperv"
|
|
||||||
},
|
|
||||||
"Test requires a Windows daemon running default isolation mode of hyperv.",
|
|
||||||
}
|
|
||||||
IsolationIsProcess = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return daemonPlatform == "windows" && isolation == "process"
|
|
||||||
},
|
|
||||||
"Test requires a Windows daemon running default isolation mode of process.",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// testRequires checks if the environment satisfies the requirements
|
|
||||||
// for the test to run or skips the tests.
|
|
||||||
func testRequires(c *check.C, requirements ...testRequirement) {
|
|
||||||
for _, r := range requirements {
|
|
||||||
if !r.Condition() {
|
|
||||||
c.Skip(r.SkipMessage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,211 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/docker/docker/integration-cli/requirement"
|
||||||
|
"github.com/go-check/check"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PlatformIs(platform string) bool {
|
||||||
|
return daemonPlatform == platform
|
||||||
|
}
|
||||||
|
|
||||||
|
func ArchitectureIs(arch string) bool {
|
||||||
|
return os.Getenv("DOCKER_ENGINE_GOARCH") == arch
|
||||||
|
}
|
||||||
|
|
||||||
|
func ArchitectureIsNot(arch string) bool {
|
||||||
|
return os.Getenv("DOCKER_ENGINE_GOARCH") != arch
|
||||||
|
}
|
||||||
|
|
||||||
|
func StorageDriverIs(storageDriver string) bool {
|
||||||
|
return strings.HasPrefix(daemonStorageDriver, storageDriver)
|
||||||
|
}
|
||||||
|
|
||||||
|
func StorageDriverIsNot(storageDriver string) bool {
|
||||||
|
return !strings.HasPrefix(daemonStorageDriver, storageDriver)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DaemonIsWindows() bool {
|
||||||
|
return PlatformIs("windows")
|
||||||
|
}
|
||||||
|
|
||||||
|
func DaemonIsLinux() bool {
|
||||||
|
return PlatformIs("linux")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExperimentalDaemon() bool {
|
||||||
|
return experimentalDaemon
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotExperimentalDaemon() bool {
|
||||||
|
return !experimentalDaemon
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsAmd64() bool {
|
||||||
|
return ArchitectureIs("amd64")
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotArm() bool {
|
||||||
|
return ArchitectureIsNot("arm")
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotArm64() bool {
|
||||||
|
return ArchitectureIsNot("arm64")
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotPpc64le() bool {
|
||||||
|
return ArchitectureIsNot("ppc64le")
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotS390X() bool {
|
||||||
|
return ArchitectureIsNot("s390x")
|
||||||
|
}
|
||||||
|
|
||||||
|
func SameHostDaemon() bool {
|
||||||
|
return isLocalDaemon
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnixCli() bool {
|
||||||
|
return isUnixCli
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExecSupport() bool {
|
||||||
|
return supportsExec
|
||||||
|
}
|
||||||
|
|
||||||
|
func Network() bool {
|
||||||
|
// Set a timeout on the GET at 15s
|
||||||
|
var timeout = time.Duration(15 * time.Second)
|
||||||
|
var url = "https://hub.docker.com"
|
||||||
|
|
||||||
|
client := http.Client{
|
||||||
|
Timeout: timeout,
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.Get(url)
|
||||||
|
if err != nil && strings.Contains(err.Error(), "use of closed network connection") {
|
||||||
|
panic(fmt.Sprintf("Timeout for GET request on %s", url))
|
||||||
|
}
|
||||||
|
if resp != nil {
|
||||||
|
resp.Body.Close()
|
||||||
|
}
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Apparmor() bool {
|
||||||
|
buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled")
|
||||||
|
return err == nil && len(buf) > 1 && buf[0] == 'Y'
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegistryHosting() bool {
|
||||||
|
// for now registry binary is built only if we're running inside
|
||||||
|
// container through `make test`. Figure that out by testing if
|
||||||
|
// registry binary is in PATH.
|
||||||
|
_, err := exec.LookPath(v2binary)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotaryHosting() bool {
|
||||||
|
// for now notary binary is built only if we're running inside
|
||||||
|
// container through `make test`. Figure that out by testing if
|
||||||
|
// notary-server binary is in PATH.
|
||||||
|
_, err := exec.LookPath(notaryServerBinary)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotaryServerHosting() bool {
|
||||||
|
// for now notary-server binary is built only if we're running inside
|
||||||
|
// container through `make test`. Figure that out by testing if
|
||||||
|
// notary-server binary is in PATH.
|
||||||
|
_, err := exec.LookPath(notaryServerBinary)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotOverlay() bool {
|
||||||
|
return StorageDriverIsNot("overlay")
|
||||||
|
}
|
||||||
|
|
||||||
|
func Devicemapper() bool {
|
||||||
|
return StorageDriverIs("devicemapper")
|
||||||
|
}
|
||||||
|
|
||||||
|
func IPv6() bool {
|
||||||
|
cmd := exec.Command("test", "-f", "/proc/net/if_inet6")
|
||||||
|
return cmd.Run() != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UserNamespaceROMount() bool {
|
||||||
|
// quick case--userns not enabled in this test run
|
||||||
|
if os.Getenv("DOCKER_REMAP_ROOT") == "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if _, _, err := dockerCmdWithError("run", "--rm", "--read-only", "busybox", "date"); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotUserNamespace() bool {
|
||||||
|
root := os.Getenv("DOCKER_REMAP_ROOT")
|
||||||
|
return root == ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func UserNamespaceInKernel() bool {
|
||||||
|
if _, err := os.Stat("/proc/self/uid_map"); os.IsNotExist(err) {
|
||||||
|
/*
|
||||||
|
* This kernel-provided file only exists if user namespaces are
|
||||||
|
* supported
|
||||||
|
*/
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need extra check on redhat based distributions
|
||||||
|
if f, err := os.Open("/sys/module/user_namespace/parameters/enable"); err == nil {
|
||||||
|
defer f.Close()
|
||||||
|
b := make([]byte, 1)
|
||||||
|
_, _ = f.Read(b)
|
||||||
|
return string(b) != "N"
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsPausable() bool {
|
||||||
|
if daemonPlatform == "windows" {
|
||||||
|
return isolation == "hyperv"
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotPausable() bool {
|
||||||
|
if daemonPlatform == "windows" {
|
||||||
|
return isolation == "process"
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsolationIs(expectedIsolation string) bool {
|
||||||
|
return daemonPlatform == "windows" && string(isolation) == expectedIsolation
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsolationIsHyperv() bool {
|
||||||
|
return IsolationIs("hyperv")
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsolationIsProcess() bool {
|
||||||
|
return IsolationIs("process")
|
||||||
|
}
|
||||||
|
|
||||||
|
// testRequires checks if the environment satisfies the requirements
|
||||||
|
// for the test to run or skips the tests.
|
||||||
|
func testRequires(c *check.C, requirements ...requirement.Test) {
|
||||||
|
requirement.Is(c, requirements...)
|
||||||
|
}
|
|
@ -1,159 +0,0 @@
|
||||||
// +build !windows
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io/ioutil"
|
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/parsers/kernel"
|
|
||||||
"github.com/docker/docker/pkg/sysinfo"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// SysInfo stores information about which features a kernel supports.
|
|
||||||
SysInfo *sysinfo.SysInfo
|
|
||||||
cpuCfsPeriod = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return SysInfo.CPUCfsPeriod
|
|
||||||
},
|
|
||||||
"Test requires an environment that supports cgroup cfs period.",
|
|
||||||
}
|
|
||||||
cpuCfsQuota = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return SysInfo.CPUCfsQuota
|
|
||||||
},
|
|
||||||
"Test requires an environment that supports cgroup cfs quota.",
|
|
||||||
}
|
|
||||||
cpuShare = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return SysInfo.CPUShares
|
|
||||||
},
|
|
||||||
"Test requires an environment that supports cgroup cpu shares.",
|
|
||||||
}
|
|
||||||
oomControl = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return SysInfo.OomKillDisable
|
|
||||||
},
|
|
||||||
"Test requires Oom control enabled.",
|
|
||||||
}
|
|
||||||
pidsLimit = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return SysInfo.PidsLimit
|
|
||||||
},
|
|
||||||
"Test requires pids limit enabled.",
|
|
||||||
}
|
|
||||||
kernelMemorySupport = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return SysInfo.KernelMemory
|
|
||||||
},
|
|
||||||
"Test requires an environment that supports cgroup kernel memory.",
|
|
||||||
}
|
|
||||||
memoryLimitSupport = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return SysInfo.MemoryLimit
|
|
||||||
},
|
|
||||||
"Test requires an environment that supports cgroup memory limit.",
|
|
||||||
}
|
|
||||||
memoryReservationSupport = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return SysInfo.MemoryReservation
|
|
||||||
},
|
|
||||||
"Test requires an environment that supports cgroup memory reservation.",
|
|
||||||
}
|
|
||||||
swapMemorySupport = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return SysInfo.SwapLimit
|
|
||||||
},
|
|
||||||
"Test requires an environment that supports cgroup swap memory limit.",
|
|
||||||
}
|
|
||||||
memorySwappinessSupport = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return SysInfo.MemorySwappiness
|
|
||||||
},
|
|
||||||
"Test requires an environment that supports cgroup memory swappiness.",
|
|
||||||
}
|
|
||||||
blkioWeight = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return SysInfo.BlkioWeight
|
|
||||||
},
|
|
||||||
"Test requires an environment that supports blkio weight.",
|
|
||||||
}
|
|
||||||
cgroupCpuset = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return SysInfo.Cpuset
|
|
||||||
},
|
|
||||||
"Test requires an environment that supports cgroup cpuset.",
|
|
||||||
}
|
|
||||||
seccompEnabled = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return supportsSeccomp && SysInfo.Seccomp
|
|
||||||
},
|
|
||||||
"Test requires that seccomp support be enabled in the daemon.",
|
|
||||||
}
|
|
||||||
bridgeNfIptables = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return !SysInfo.BridgeNFCallIPTablesDisabled
|
|
||||||
},
|
|
||||||
"Test requires that bridge-nf-call-iptables support be enabled in the daemon.",
|
|
||||||
}
|
|
||||||
bridgeNfIP6tables = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
return !SysInfo.BridgeNFCallIP6TablesDisabled
|
|
||||||
},
|
|
||||||
"Test requires that bridge-nf-call-ip6tables support be enabled in the daemon.",
|
|
||||||
}
|
|
||||||
unprivilegedUsernsClone = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
content, err := ioutil.ReadFile("/proc/sys/kernel/unprivileged_userns_clone")
|
|
||||||
if err == nil && strings.Contains(string(content), "0") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
"Test cannot be run with 'sysctl kernel.unprivileged_userns_clone' = 0",
|
|
||||||
}
|
|
||||||
ambientCapabilities = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
content, err := ioutil.ReadFile("/proc/self/status")
|
|
||||||
if err == nil && strings.Contains(string(content), "CapAmb:") {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
"Test cannot be run without a kernel (4.3+) supporting ambient capabilities",
|
|
||||||
}
|
|
||||||
overlayFSSupported = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
cmd := exec.Command(dockerBinary, "run", "--rm", "busybox", "/bin/sh", "-c", "cat /proc/filesystems")
|
|
||||||
out, err := cmd.CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return bytes.Contains(out, []byte("overlay\n"))
|
|
||||||
},
|
|
||||||
"Test cannot be run without suppport for overlayfs",
|
|
||||||
}
|
|
||||||
overlay2Supported = testRequirement{
|
|
||||||
func() bool {
|
|
||||||
if !overlayFSSupported.Condition() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
daemonV, err := kernel.ParseRelease(daemonKernelVersion)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
requiredV := kernel.VersionInfo{Kernel: 4}
|
|
||||||
return kernel.CompareKernelVersion(*daemonV, requiredV) > -1
|
|
||||||
|
|
||||||
},
|
|
||||||
"Test cannot be run without overlay2 support (kernel 4.0+)",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
SysInfo = sysinfo.New(true)
|
|
||||||
}
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/docker/docker/pkg/parsers/kernel"
|
||||||
|
"github.com/docker/docker/pkg/sysinfo"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// SysInfo stores information about which features a kernel supports.
|
||||||
|
SysInfo *sysinfo.SysInfo
|
||||||
|
)
|
||||||
|
|
||||||
|
func cpuCfsPeriod() bool {
|
||||||
|
return SysInfo.CPUCfsPeriod
|
||||||
|
}
|
||||||
|
|
||||||
|
func cpuCfsQuota() bool {
|
||||||
|
return SysInfo.CPUCfsQuota
|
||||||
|
}
|
||||||
|
|
||||||
|
func cpuShare() bool {
|
||||||
|
return SysInfo.CPUShares
|
||||||
|
}
|
||||||
|
|
||||||
|
func oomControl() bool {
|
||||||
|
return SysInfo.OomKillDisable
|
||||||
|
}
|
||||||
|
|
||||||
|
func pidsLimit() bool {
|
||||||
|
return SysInfo.PidsLimit
|
||||||
|
}
|
||||||
|
|
||||||
|
func kernelMemorySupport() bool {
|
||||||
|
return SysInfo.KernelMemory
|
||||||
|
}
|
||||||
|
|
||||||
|
func memoryLimitSupport() bool {
|
||||||
|
return SysInfo.MemoryLimit
|
||||||
|
}
|
||||||
|
|
||||||
|
func memoryReservationSupport() bool {
|
||||||
|
return SysInfo.MemoryReservation
|
||||||
|
}
|
||||||
|
|
||||||
|
func swapMemorySupport() bool {
|
||||||
|
return SysInfo.SwapLimit
|
||||||
|
}
|
||||||
|
|
||||||
|
func memorySwappinessSupport() bool {
|
||||||
|
return SysInfo.MemorySwappiness
|
||||||
|
}
|
||||||
|
|
||||||
|
func blkioWeight() bool {
|
||||||
|
return SysInfo.BlkioWeight
|
||||||
|
}
|
||||||
|
|
||||||
|
func cgroupCpuset() bool {
|
||||||
|
return SysInfo.Cpuset
|
||||||
|
}
|
||||||
|
|
||||||
|
func seccompEnabled() bool {
|
||||||
|
return supportsSeccomp && SysInfo.Seccomp
|
||||||
|
}
|
||||||
|
|
||||||
|
func bridgeNfIptables() bool {
|
||||||
|
return !SysInfo.BridgeNFCallIPTablesDisabled
|
||||||
|
}
|
||||||
|
|
||||||
|
func bridgeNfIP6tables() bool {
|
||||||
|
return !SysInfo.BridgeNFCallIP6TablesDisabled
|
||||||
|
}
|
||||||
|
|
||||||
|
func unprivilegedUsernsClone() bool {
|
||||||
|
content, err := ioutil.ReadFile("/proc/sys/kernel/unprivileged_userns_clone")
|
||||||
|
return err != nil || !strings.Contains(string(content), "0")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ambientCapabilities() bool {
|
||||||
|
content, err := ioutil.ReadFile("/proc/self/status")
|
||||||
|
return err != nil || strings.Contains(string(content), "CapAmb:")
|
||||||
|
}
|
||||||
|
|
||||||
|
func overlayFSSupported() bool {
|
||||||
|
cmd := exec.Command(dockerBinary, "run", "--rm", "busybox", "/bin/sh", "-c", "cat /proc/filesystems")
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return bytes.Contains(out, []byte("overlay\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func overlay2Supported() bool {
|
||||||
|
if !overlayFSSupported() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
daemonV, err := kernel.ParseRelease(daemonKernelVersion)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
requiredV := kernel.VersionInfo{Kernel: 4}
|
||||||
|
return kernel.CompareKernelVersion(*daemonV, requiredV) > -1
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
SysInfo = sysinfo.New(true)
|
||||||
|
}
|
Loading…
Reference in New Issue