1package main 2 3import ( 4 "context" 5 "fmt" 6 "io/ioutil" 7 "net/http" 8 "os" 9 "os/exec" 10 "strconv" 11 "strings" 12 "time" 13 14 "github.com/docker/docker/api/types" 15 "github.com/docker/docker/api/types/swarm" 16 "github.com/docker/docker/api/types/versions" 17 "github.com/docker/docker/client" 18 "github.com/docker/docker/integration-cli/requirement" 19 "github.com/docker/docker/internal/test/registry" 20) 21 22func ArchitectureIsNot(arch string) bool { 23 return os.Getenv("DOCKER_ENGINE_GOARCH") != arch 24} 25 26func DaemonIsWindows() bool { 27 return testEnv.OSType == "windows" 28} 29 30func DaemonIsWindowsAtLeastBuild(buildNumber int) func() bool { 31 return func() bool { 32 if testEnv.OSType != "windows" { 33 return false 34 } 35 version := testEnv.DaemonInfo.KernelVersion 36 numVersion, _ := strconv.Atoi(strings.Split(version, " ")[1]) 37 return numVersion >= buildNumber 38 } 39} 40 41func DaemonIsLinux() bool { 42 return testEnv.OSType == "linux" 43} 44 45func MinimumAPIVersion(version string) func() bool { 46 return func() bool { 47 return versions.GreaterThanOrEqualTo(testEnv.DaemonAPIVersion(), version) 48 } 49} 50 51func OnlyDefaultNetworks() bool { 52 cli, err := client.NewEnvClient() 53 if err != nil { 54 return false 55 } 56 networks, err := cli.NetworkList(context.TODO(), types.NetworkListOptions{}) 57 if err != nil || len(networks) > 0 { 58 return false 59 } 60 return true 61} 62 63// Deprecated: use skip.If(t, !testEnv.DaemonInfo.ExperimentalBuild) 64func ExperimentalDaemon() bool { 65 return testEnv.DaemonInfo.ExperimentalBuild 66} 67 68func IsAmd64() bool { 69 return os.Getenv("DOCKER_ENGINE_GOARCH") == "amd64" 70} 71 72func NotArm() bool { 73 return ArchitectureIsNot("arm") 74} 75 76func NotArm64() bool { 77 return ArchitectureIsNot("arm64") 78} 79 80func NotPpc64le() bool { 81 return ArchitectureIsNot("ppc64le") 82} 83 84func NotS390X() bool { 85 return ArchitectureIsNot("s390x") 86} 87 88func SameHostDaemon() bool { 89 return testEnv.IsLocalDaemon() 90} 91 92func UnixCli() bool { 93 return isUnixCli 94} 95 96func ExecSupport() bool { 97 return supportsExec 98} 99 100func Network() bool { 101 // Set a timeout on the GET at 15s 102 var timeout = time.Duration(15 * time.Second) 103 var url = "https://hub.docker.com" 104 105 client := http.Client{ 106 Timeout: timeout, 107 } 108 109 resp, err := client.Get(url) 110 if err != nil && strings.Contains(err.Error(), "use of closed network connection") { 111 panic(fmt.Sprintf("Timeout for GET request on %s", url)) 112 } 113 if resp != nil { 114 resp.Body.Close() 115 } 116 return err == nil 117} 118 119func Apparmor() bool { 120 if strings.HasPrefix(testEnv.DaemonInfo.OperatingSystem, "SUSE Linux Enterprise Server ") { 121 return false 122 } 123 buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled") 124 return err == nil && len(buf) > 1 && buf[0] == 'Y' 125} 126 127func Devicemapper() bool { 128 return strings.HasPrefix(testEnv.DaemonInfo.Driver, "devicemapper") 129} 130 131func IPv6() bool { 132 cmd := exec.Command("test", "-f", "/proc/net/if_inet6") 133 return cmd.Run() != nil 134} 135 136func UserNamespaceROMount() bool { 137 // quick case--userns not enabled in this test run 138 if os.Getenv("DOCKER_REMAP_ROOT") == "" { 139 return true 140 } 141 if _, _, err := dockerCmdWithError("run", "--rm", "--read-only", "busybox", "date"); err != nil { 142 return false 143 } 144 return true 145} 146 147func NotUserNamespace() bool { 148 root := os.Getenv("DOCKER_REMAP_ROOT") 149 return root == "" 150} 151 152func UserNamespaceInKernel() bool { 153 if _, err := os.Stat("/proc/self/uid_map"); os.IsNotExist(err) { 154 /* 155 * This kernel-provided file only exists if user namespaces are 156 * supported 157 */ 158 return false 159 } 160 161 // We need extra check on redhat based distributions 162 if f, err := os.Open("/sys/module/user_namespace/parameters/enable"); err == nil { 163 defer f.Close() 164 b := make([]byte, 1) 165 _, _ = f.Read(b) 166 return string(b) != "N" 167 } 168 169 return true 170} 171 172func IsPausable() bool { 173 if testEnv.OSType == "windows" { 174 return testEnv.DaemonInfo.Isolation == "hyperv" 175 } 176 return true 177} 178 179func NotPausable() bool { 180 if testEnv.OSType == "windows" { 181 return testEnv.DaemonInfo.Isolation == "process" 182 } 183 return false 184} 185 186func IsolationIs(expectedIsolation string) bool { 187 return testEnv.OSType == "windows" && string(testEnv.DaemonInfo.Isolation) == expectedIsolation 188} 189 190func IsolationIsHyperv() bool { 191 return IsolationIs("hyperv") 192} 193 194func IsolationIsProcess() bool { 195 return IsolationIs("process") 196} 197 198// RegistryHosting returns wether the host can host a registry (v2) or not 199func RegistryHosting() bool { 200 // for now registry binary is built only if we're running inside 201 // container through `make test`. Figure that out by testing if 202 // registry binary is in PATH. 203 _, err := exec.LookPath(registry.V2binary) 204 return err == nil 205} 206 207func SwarmInactive() bool { 208 return testEnv.DaemonInfo.Swarm.LocalNodeState == swarm.LocalNodeStateInactive 209} 210 211func TODOBuildkit() bool { 212 return os.Getenv("DOCKER_BUILDKIT") == "" 213} 214 215// testRequires checks if the environment satisfies the requirements 216// for the test to run or skips the tests. 217func testRequires(c requirement.SkipT, requirements ...requirement.Test) { 218 requirement.Is(c, requirements...) 219} 220