2016-12-16 09:13:23 -05:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2017-09-14 13:17:49 -04:00
|
|
|
"context"
|
2016-12-16 09:13:23 -05:00
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
2017-08-25 18:48:36 -04:00
|
|
|
"strconv"
|
2016-12-16 09:13:23 -05:00
|
|
|
"strings"
|
2019-10-09 15:06:15 -04:00
|
|
|
"testing"
|
2016-12-16 09:13:23 -05:00
|
|
|
"time"
|
|
|
|
|
2017-09-14 13:17:49 -04:00
|
|
|
"github.com/docker/docker/api/types"
|
2018-05-04 17:15:00 -04:00
|
|
|
"github.com/docker/docker/api/types/swarm"
|
|
|
|
"github.com/docker/docker/api/types/versions"
|
2017-09-14 13:17:49 -04:00
|
|
|
"github.com/docker/docker/client"
|
2016-12-16 09:13:23 -05:00
|
|
|
"github.com/docker/docker/integration-cli/requirement"
|
2019-08-29 16:52:40 -04:00
|
|
|
"github.com/docker/docker/testutil/registry"
|
2016-12-16 09:13:23 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
func ArchitectureIsNot(arch string) bool {
|
|
|
|
return os.Getenv("DOCKER_ENGINE_GOARCH") != arch
|
|
|
|
}
|
|
|
|
|
|
|
|
func DaemonIsWindows() bool {
|
2017-09-20 08:47:49 -04:00
|
|
|
return testEnv.OSType == "windows"
|
2016-12-16 09:13:23 -05:00
|
|
|
}
|
|
|
|
|
2017-07-31 17:23:52 -04:00
|
|
|
func DaemonIsWindowsAtLeastBuild(buildNumber int) func() bool {
|
|
|
|
return func() bool {
|
2017-09-20 08:47:49 -04:00
|
|
|
if testEnv.OSType != "windows" {
|
2017-08-25 18:48:36 -04:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
version := testEnv.DaemonInfo.KernelVersion
|
|
|
|
numVersion, _ := strconv.Atoi(strings.Split(version, " ")[1])
|
|
|
|
return numVersion >= buildNumber
|
2017-07-31 17:23:52 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-16 09:13:23 -05:00
|
|
|
func DaemonIsLinux() bool {
|
2017-09-20 08:47:49 -04:00
|
|
|
return testEnv.OSType == "linux"
|
2016-12-16 09:13:23 -05:00
|
|
|
}
|
|
|
|
|
2018-05-04 17:15:00 -04:00
|
|
|
func MinimumAPIVersion(version string) func() bool {
|
|
|
|
return func() bool {
|
|
|
|
return versions.GreaterThanOrEqualTo(testEnv.DaemonAPIVersion(), version)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-14 13:17:49 -04:00
|
|
|
func OnlyDefaultNetworks() bool {
|
2019-01-03 16:49:00 -05:00
|
|
|
cli, err := client.NewClientWithOpts(client.FromEnv)
|
2017-09-14 13:17:49 -04:00
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
networks, err := cli.NetworkList(context.TODO(), types.NetworkListOptions{})
|
|
|
|
if err != nil || len(networks) > 0 {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
2017-09-08 10:44:19 -04:00
|
|
|
}
|
|
|
|
|
2016-12-16 09:13:23 -05:00
|
|
|
func IsAmd64() bool {
|
2017-08-25 18:48:36 -04:00
|
|
|
return os.Getenv("DOCKER_ENGINE_GOARCH") == "amd64"
|
2016-12-16 09:13:23 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func NotArm() bool {
|
|
|
|
return ArchitectureIsNot("arm")
|
|
|
|
}
|
|
|
|
|
|
|
|
func NotArm64() bool {
|
|
|
|
return ArchitectureIsNot("arm64")
|
|
|
|
}
|
|
|
|
|
|
|
|
func NotPpc64le() bool {
|
|
|
|
return ArchitectureIsNot("ppc64le")
|
|
|
|
}
|
|
|
|
|
|
|
|
func UnixCli() bool {
|
|
|
|
return isUnixCli
|
|
|
|
}
|
|
|
|
|
|
|
|
func Network() bool {
|
|
|
|
// Set a timeout on the GET at 15s
|
2019-08-05 11:54:15 -04:00
|
|
|
const timeout = 15 * time.Second
|
|
|
|
const url = "https://hub.docker.com"
|
2016-12-16 09:13:23 -05:00
|
|
|
|
|
|
|
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 {
|
2018-05-04 17:15:00 -04:00
|
|
|
if strings.HasPrefix(testEnv.DaemonInfo.OperatingSystem, "SUSE Linux Enterprise Server ") {
|
|
|
|
return false
|
|
|
|
}
|
2021-08-24 06:10:50 -04:00
|
|
|
buf, err := os.ReadFile("/sys/module/apparmor/parameters/enabled")
|
2016-12-16 09:13:23 -05:00
|
|
|
return err == nil && len(buf) > 1 && buf[0] == 'Y'
|
|
|
|
}
|
|
|
|
|
|
|
|
func Devicemapper() bool {
|
2017-08-25 18:48:36 -04:00
|
|
|
return strings.HasPrefix(testEnv.DaemonInfo.Driver, "devicemapper")
|
2016-12-16 09:13:23 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
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 {
|
2017-09-20 08:47:49 -04:00
|
|
|
if testEnv.OSType == "windows" {
|
2017-08-25 18:48:36 -04:00
|
|
|
return testEnv.DaemonInfo.Isolation == "hyperv"
|
2016-12-16 09:13:23 -05:00
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
func IsolationIs(expectedIsolation string) bool {
|
2017-09-20 08:47:49 -04:00
|
|
|
return testEnv.OSType == "windows" && string(testEnv.DaemonInfo.Isolation) == expectedIsolation
|
2016-12-16 09:13:23 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func IsolationIsHyperv() bool {
|
|
|
|
return IsolationIs("hyperv")
|
|
|
|
}
|
|
|
|
|
|
|
|
func IsolationIsProcess() bool {
|
|
|
|
return IsolationIs("process")
|
|
|
|
}
|
|
|
|
|
2018-09-07 00:17:30 -04:00
|
|
|
// RegistryHosting returns whether the host can host a registry (v2) or not
|
2018-04-13 04:45:34 -04:00
|
|
|
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(registry.V2binary)
|
|
|
|
return err == nil
|
|
|
|
}
|
|
|
|
|
2020-09-21 15:21:22 -04:00
|
|
|
func RuntimeIsWindowsContainerd() bool {
|
|
|
|
return os.Getenv("DOCKER_WINDOWS_CONTAINERD_RUNTIME") == "1"
|
|
|
|
}
|
|
|
|
|
2018-05-04 17:15:00 -04:00
|
|
|
func SwarmInactive() bool {
|
|
|
|
return testEnv.DaemonInfo.Swarm.LocalNodeState == swarm.LocalNodeStateInactive
|
|
|
|
}
|
|
|
|
|
2018-05-15 20:11:25 -04:00
|
|
|
func TODOBuildkit() bool {
|
|
|
|
return os.Getenv("DOCKER_BUILDKIT") == ""
|
|
|
|
}
|
|
|
|
|
2021-03-18 14:36:00 -04:00
|
|
|
func DockerCLIVersion(t testing.TB) string {
|
|
|
|
out, _ := dockerCmd(t, "--version")
|
|
|
|
version := strings.Fields(out)
|
|
|
|
if len(version) < 3 {
|
|
|
|
t.Fatal("unknown version output", version)
|
|
|
|
}
|
|
|
|
return version[2]
|
|
|
|
}
|
|
|
|
|
2016-12-16 09:13:23 -05:00
|
|
|
// testRequires checks if the environment satisfies the requirements
|
|
|
|
// for the test to run or skips the tests.
|
2019-10-09 15:06:15 -04:00
|
|
|
func testRequires(t *testing.T, requirements ...requirement.Test) {
|
|
|
|
t.Helper()
|
|
|
|
requirement.Is(t, requirements...)
|
2016-12-16 09:13:23 -05:00
|
|
|
}
|