2016-12-16 14:13:23 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2017-09-14 17:17:49 +00:00
|
|
|
"context"
|
2016-12-16 14:13:23 +00:00
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"strings"
|
2019-10-09 19:06:15 +00:00
|
|
|
"testing"
|
2016-12-16 14:13:23 +00:00
|
|
|
"time"
|
|
|
|
|
2022-08-22 17:53:07 +00:00
|
|
|
"github.com/containerd/containerd/plugin"
|
2017-09-14 17:17:49 +00:00
|
|
|
"github.com/docker/docker/api/types"
|
2018-05-04 21:15:00 +00:00
|
|
|
"github.com/docker/docker/api/types/swarm"
|
|
|
|
"github.com/docker/docker/api/types/versions"
|
2017-09-14 17:17:49 +00:00
|
|
|
"github.com/docker/docker/client"
|
2016-12-16 14:13:23 +00:00
|
|
|
"github.com/docker/docker/integration-cli/requirement"
|
2019-08-29 20:52:40 +00:00
|
|
|
"github.com/docker/docker/testutil/registry"
|
2016-12-16 14:13:23 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func ArchitectureIsNot(arch string) bool {
|
|
|
|
return os.Getenv("DOCKER_ENGINE_GOARCH") != arch
|
|
|
|
}
|
|
|
|
|
|
|
|
func DaemonIsWindows() bool {
|
2017-09-20 12:47:49 +00:00
|
|
|
return testEnv.OSType == "windows"
|
2016-12-16 14:13:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func DaemonIsLinux() bool {
|
2017-09-20 12:47:49 +00:00
|
|
|
return testEnv.OSType == "linux"
|
2016-12-16 14:13:23 +00:00
|
|
|
}
|
|
|
|
|
2018-05-04 21:15:00 +00:00
|
|
|
func MinimumAPIVersion(version string) func() bool {
|
|
|
|
return func() bool {
|
|
|
|
return versions.GreaterThanOrEqualTo(testEnv.DaemonAPIVersion(), version)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-14 17:17:49 +00:00
|
|
|
func OnlyDefaultNetworks() bool {
|
2023-04-03 11:00:29 +00:00
|
|
|
apiClient, err := client.NewClientWithOpts(client.FromEnv)
|
2017-09-14 17:17:49 +00:00
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
2023-04-03 11:00:29 +00:00
|
|
|
networks, err := apiClient.NetworkList(context.TODO(), types.NetworkListOptions{})
|
2017-09-14 17:17:49 +00:00
|
|
|
if err != nil || len(networks) > 0 {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
2017-09-08 14:44:19 +00:00
|
|
|
}
|
|
|
|
|
2016-12-16 14:13:23 +00:00
|
|
|
func IsAmd64() bool {
|
2017-08-25 22:48:36 +00:00
|
|
|
return os.Getenv("DOCKER_ENGINE_GOARCH") == "amd64"
|
2016-12-16 14:13:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NotArm() bool {
|
|
|
|
return ArchitectureIsNot("arm")
|
|
|
|
}
|
|
|
|
|
|
|
|
func NotArm64() bool {
|
|
|
|
return ArchitectureIsNot("arm64")
|
|
|
|
}
|
|
|
|
|
|
|
|
func NotPpc64le() bool {
|
|
|
|
return ArchitectureIsNot("ppc64le")
|
|
|
|
}
|
|
|
|
|
|
|
|
func UnixCli() bool {
|
|
|
|
return isUnixCli
|
|
|
|
}
|
|
|
|
|
2022-08-25 13:36:00 +00:00
|
|
|
func GitHubActions() bool {
|
|
|
|
return os.Getenv("GITHUB_ACTIONS") != ""
|
|
|
|
}
|
|
|
|
|
2016-12-16 14:13:23 +00:00
|
|
|
func Network() bool {
|
|
|
|
// Set a timeout on the GET at 15s
|
2019-08-05 15:54:15 +00:00
|
|
|
const timeout = 15 * time.Second
|
|
|
|
const url = "https://hub.docker.com"
|
2016-12-16 14:13:23 +00:00
|
|
|
|
2023-04-03 11:00:29 +00:00
|
|
|
c := http.Client{
|
2016-12-16 14:13:23 +00:00
|
|
|
Timeout: timeout,
|
|
|
|
}
|
|
|
|
|
2023-04-03 11:00:29 +00:00
|
|
|
resp, err := c.Get(url)
|
2016-12-16 14:13:23 +00:00
|
|
|
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 21:15:00 +00:00
|
|
|
if strings.HasPrefix(testEnv.DaemonInfo.OperatingSystem, "SUSE Linux Enterprise Server ") {
|
|
|
|
return false
|
|
|
|
}
|
2021-08-24 10:10:50 +00:00
|
|
|
buf, err := os.ReadFile("/sys/module/apparmor/parameters/enabled")
|
2016-12-16 14:13:23 +00:00
|
|
|
return err == nil && len(buf) > 1 && buf[0] == 'Y'
|
|
|
|
}
|
|
|
|
|
|
|
|
func Devicemapper() bool {
|
2017-08-25 22:48:36 +00:00
|
|
|
return strings.HasPrefix(testEnv.DaemonInfo.Driver, "devicemapper")
|
2016-12-16 14:13:23 +00:00
|
|
|
}
|
|
|
|
|
2022-08-22 17:53:07 +00:00
|
|
|
// containerdSnapshotterEnabled checks if the daemon in the test-environment is
|
|
|
|
// configured with containerd-snapshotters enabled.
|
|
|
|
func containerdSnapshotterEnabled() bool {
|
|
|
|
for _, v := range testEnv.DaemonInfo.DriverStatus {
|
|
|
|
if v[0] == "driver-type" {
|
|
|
|
return v[1] == string(plugin.SnapshotPlugin)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2016-12-16 14:13:23 +00: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 12:47:49 +00:00
|
|
|
if testEnv.OSType == "windows" {
|
2022-02-17 17:25:38 +00:00
|
|
|
return testEnv.DaemonInfo.Isolation.IsHyperV()
|
2016-12-16 14:13:23 +00:00
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2018-09-07 04:17:30 +00:00
|
|
|
// RegistryHosting returns whether the host can host a registry (v2) or not
|
2018-04-13 08:45:34 +00: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 19:21:22 +00:00
|
|
|
func RuntimeIsWindowsContainerd() bool {
|
|
|
|
return os.Getenv("DOCKER_WINDOWS_CONTAINERD_RUNTIME") == "1"
|
|
|
|
}
|
|
|
|
|
2018-05-04 21:15:00 +00:00
|
|
|
func SwarmInactive() bool {
|
|
|
|
return testEnv.DaemonInfo.Swarm.LocalNodeState == swarm.LocalNodeStateInactive
|
|
|
|
}
|
|
|
|
|
2018-05-16 00:11:25 +00:00
|
|
|
func TODOBuildkit() bool {
|
|
|
|
return os.Getenv("DOCKER_BUILDKIT") == ""
|
|
|
|
}
|
|
|
|
|
2021-03-18 18:36:00 +00: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 14:13:23 +00:00
|
|
|
// testRequires checks if the environment satisfies the requirements
|
|
|
|
// for the test to run or skips the tests.
|
2019-10-09 19:06:15 +00:00
|
|
|
func testRequires(t *testing.T, requirements ...requirement.Test) {
|
|
|
|
t.Helper()
|
|
|
|
requirement.Is(t, requirements...)
|
2016-12-16 14:13:23 +00:00
|
|
|
}
|