|
@@ -1,19 +1,11 @@
|
|
package environment
|
|
package environment
|
|
|
|
|
|
import (
|
|
import (
|
|
- "fmt"
|
|
|
|
- "io/ioutil"
|
|
|
|
"os"
|
|
"os"
|
|
|
|
+
|
|
"os/exec"
|
|
"os/exec"
|
|
- "path/filepath"
|
|
|
|
- "strconv"
|
|
|
|
- "strings"
|
|
|
|
|
|
|
|
- "github.com/docker/docker/api/types"
|
|
|
|
- "github.com/docker/docker/api/types/container"
|
|
|
|
- "github.com/docker/docker/client"
|
|
|
|
- "github.com/docker/docker/opts"
|
|
|
|
- "golang.org/x/net/context"
|
|
|
|
|
|
+ "github.com/docker/docker/internal/test/environment"
|
|
)
|
|
)
|
|
|
|
|
|
var (
|
|
var (
|
|
@@ -23,89 +15,28 @@ var (
|
|
|
|
|
|
func init() {
|
|
func init() {
|
|
if DefaultClientBinary == "" {
|
|
if DefaultClientBinary == "" {
|
|
- // TODO: to be removed once we no longer depend on the docker cli for integration tests
|
|
|
|
- //panic("TEST_CLIENT_BINARY must be set")
|
|
|
|
DefaultClientBinary = "docker"
|
|
DefaultClientBinary = "docker"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-// Execution holds informations about the test execution environment.
|
|
|
|
|
|
+// Execution contains information about the current test execution and daemon
|
|
|
|
+// under test
|
|
type Execution struct {
|
|
type Execution struct {
|
|
- daemonPlatform string
|
|
|
|
- localDaemon bool
|
|
|
|
- experimentalDaemon bool
|
|
|
|
- daemonStorageDriver string
|
|
|
|
- isolation container.Isolation
|
|
|
|
- daemonPid int
|
|
|
|
- daemonKernelVersion string
|
|
|
|
- // For a local daemon on Linux, these values will be used for testing
|
|
|
|
- // user namespace support as the standard graph path(s) will be
|
|
|
|
- // appended with the root remapped uid.gid prefix
|
|
|
|
- dockerBasePath string
|
|
|
|
- volumesConfigPath string
|
|
|
|
- containerStoragePath string
|
|
|
|
- // baseImage is the name of the base image for testing
|
|
|
|
- // Environment variable WINDOWS_BASE_IMAGE can override this
|
|
|
|
- baseImage string
|
|
|
|
|
|
+ environment.Execution
|
|
dockerBinary string
|
|
dockerBinary string
|
|
|
|
+}
|
|
|
|
|
|
- protectedElements protectedElements
|
|
|
|
|
|
+// DockerBinary returns the docker binary for this testing environment
|
|
|
|
+func (e *Execution) DockerBinary() string {
|
|
|
|
+ return e.dockerBinary
|
|
}
|
|
}
|
|
|
|
|
|
-// New creates a new Execution struct
|
|
|
|
|
|
+// New returns details about the testing environment
|
|
func New() (*Execution, error) {
|
|
func New() (*Execution, error) {
|
|
- localDaemon := true
|
|
|
|
- // Deterministically working out the environment in which CI is running
|
|
|
|
- // to evaluate whether the daemon is local or remote is not possible through
|
|
|
|
- // a build tag.
|
|
|
|
- //
|
|
|
|
- // For example Windows to Linux CI under Jenkins tests the 64-bit
|
|
|
|
- // Windows binary build with the daemon build tag, but calls a remote
|
|
|
|
- // Linux daemon.
|
|
|
|
- //
|
|
|
|
- // We can't just say if Windows then assume the daemon is local as at
|
|
|
|
- // some point, we will be testing the Windows CLI against a Windows daemon.
|
|
|
|
- //
|
|
|
|
- // Similarly, it will be perfectly valid to also run CLI tests from
|
|
|
|
- // a Linux CLI (built with the daemon tag) against a Windows daemon.
|
|
|
|
- if len(os.Getenv("DOCKER_REMOTE_DAEMON")) > 0 {
|
|
|
|
- localDaemon = false
|
|
|
|
- }
|
|
|
|
- info, err := getDaemonDockerInfo()
|
|
|
|
|
|
+ env, err := environment.New()
|
|
if err != nil {
|
|
if err != nil {
|
|
return nil, err
|
|
return nil, err
|
|
}
|
|
}
|
|
- daemonPlatform := info.OSType
|
|
|
|
- if daemonPlatform != "linux" && daemonPlatform != "windows" {
|
|
|
|
- return nil, fmt.Errorf("Cannot run tests against platform: %s", daemonPlatform)
|
|
|
|
- }
|
|
|
|
- baseImage := "scratch"
|
|
|
|
- volumesConfigPath := filepath.Join(info.DockerRootDir, "volumes")
|
|
|
|
- containerStoragePath := filepath.Join(info.DockerRootDir, "containers")
|
|
|
|
- // Make sure in context of daemon, not the local platform. Note we can't
|
|
|
|
- // use filepath.FromSlash or ToSlash here as they are a no-op on Unix.
|
|
|
|
- if daemonPlatform == "windows" {
|
|
|
|
- volumesConfigPath = strings.Replace(volumesConfigPath, `/`, `\`, -1)
|
|
|
|
- containerStoragePath = strings.Replace(containerStoragePath, `/`, `\`, -1)
|
|
|
|
-
|
|
|
|
- baseImage = "microsoft/windowsservercore"
|
|
|
|
- if len(os.Getenv("WINDOWS_BASE_IMAGE")) > 0 {
|
|
|
|
- baseImage = os.Getenv("WINDOWS_BASE_IMAGE")
|
|
|
|
- fmt.Println("INFO: Windows Base image is ", baseImage)
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- volumesConfigPath = strings.Replace(volumesConfigPath, `\`, `/`, -1)
|
|
|
|
- containerStoragePath = strings.Replace(containerStoragePath, `\`, `/`, -1)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- var daemonPid int
|
|
|
|
- dest := os.Getenv("DEST")
|
|
|
|
- b, err := ioutil.ReadFile(filepath.Join(dest, "docker.pid"))
|
|
|
|
- if err == nil {
|
|
|
|
- if p, err := strconv.ParseInt(string(b), 10, 32); err == nil {
|
|
|
|
- daemonPid = int(p)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
|
|
dockerBinary, err := exec.LookPath(DefaultClientBinary)
|
|
dockerBinary, err := exec.LookPath(DefaultClientBinary)
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -113,117 +44,36 @@ func New() (*Execution, error) {
|
|
}
|
|
}
|
|
|
|
|
|
return &Execution{
|
|
return &Execution{
|
|
- localDaemon: localDaemon,
|
|
|
|
- daemonPlatform: daemonPlatform,
|
|
|
|
- daemonStorageDriver: info.Driver,
|
|
|
|
- daemonKernelVersion: info.KernelVersion,
|
|
|
|
- dockerBasePath: info.DockerRootDir,
|
|
|
|
- volumesConfigPath: volumesConfigPath,
|
|
|
|
- containerStoragePath: containerStoragePath,
|
|
|
|
- isolation: info.Isolation,
|
|
|
|
- daemonPid: daemonPid,
|
|
|
|
- experimentalDaemon: info.ExperimentalBuild,
|
|
|
|
- baseImage: baseImage,
|
|
|
|
- dockerBinary: dockerBinary,
|
|
|
|
- protectedElements: protectedElements{
|
|
|
|
- images: map[string]struct{}{},
|
|
|
|
- },
|
|
|
|
|
|
+ Execution: *env,
|
|
|
|
+ dockerBinary: dockerBinary,
|
|
}, nil
|
|
}, nil
|
|
}
|
|
}
|
|
-func getDaemonDockerInfo() (types.Info, error) {
|
|
|
|
- // FIXME(vdemeester) should be safe to use as is
|
|
|
|
- client, err := client.NewEnvClient()
|
|
|
|
- if err != nil {
|
|
|
|
- return types.Info{}, err
|
|
|
|
- }
|
|
|
|
- return client.Info(context.Background())
|
|
|
|
|
|
+
|
|
|
|
+// DockerBasePath is the base path of the docker folder (by default it is -/var/run/docker)
|
|
|
|
+// TODO: remove
|
|
|
|
+// Deprecated: use Execution.DaemonInfo.DockerRootDir
|
|
|
|
+func (e *Execution) DockerBasePath() string {
|
|
|
|
+ return e.DaemonInfo.DockerRootDir
|
|
}
|
|
}
|
|
|
|
|
|
-// LocalDaemon is true if the daemon under test is on the same
|
|
|
|
-// host as the CLI.
|
|
|
|
-func (e *Execution) LocalDaemon() bool {
|
|
|
|
- return e.localDaemon
|
|
|
|
|
|
+// ExperimentalDaemon tell whether the main daemon has
|
|
|
|
+// experimental features enabled or not
|
|
|
|
+// Deprecated: use DaemonInfo.ExperimentalBuild
|
|
|
|
+func (e *Execution) ExperimentalDaemon() bool {
|
|
|
|
+ return e.DaemonInfo.ExperimentalBuild
|
|
}
|
|
}
|
|
|
|
|
|
// DaemonPlatform is held globally so that tests can make intelligent
|
|
// DaemonPlatform is held globally so that tests can make intelligent
|
|
// decisions on how to configure themselves according to the platform
|
|
// decisions on how to configure themselves according to the platform
|
|
// of the daemon. This is initialized in docker_utils by sending
|
|
// of the daemon. This is initialized in docker_utils by sending
|
|
// a version call to the daemon and examining the response header.
|
|
// a version call to the daemon and examining the response header.
|
|
|
|
+// Deprecated: use Execution.DaemonInfo.OSType
|
|
func (e *Execution) DaemonPlatform() string {
|
|
func (e *Execution) DaemonPlatform() string {
|
|
- return e.daemonPlatform
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// DockerBasePath is the base path of the docker folder (by default it is -/var/run/docker)
|
|
|
|
-func (e *Execution) DockerBasePath() string {
|
|
|
|
- return e.dockerBasePath
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// VolumesConfigPath is the path of the volume configuration for the testing daemon
|
|
|
|
-func (e *Execution) VolumesConfigPath() string {
|
|
|
|
- return e.volumesConfigPath
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// ContainerStoragePath is the path where the container are stored for the testing daemon
|
|
|
|
-func (e *Execution) ContainerStoragePath() string {
|
|
|
|
- return e.containerStoragePath
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// DaemonStorageDriver is held globally so that tests can know the storage
|
|
|
|
-// driver of the daemon. This is initialized in docker_utils by sending
|
|
|
|
-// a version call to the daemon and examining the response header.
|
|
|
|
-func (e *Execution) DaemonStorageDriver() string {
|
|
|
|
- return e.daemonStorageDriver
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// Isolation is the isolation mode of the daemon under test
|
|
|
|
-func (e *Execution) Isolation() container.Isolation {
|
|
|
|
- return e.isolation
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// DaemonPID is the pid of the main test daemon
|
|
|
|
-func (e *Execution) DaemonPID() int {
|
|
|
|
- return e.daemonPid
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// ExperimentalDaemon tell whether the main daemon has
|
|
|
|
-// experimental features enabled or not
|
|
|
|
-func (e *Execution) ExperimentalDaemon() bool {
|
|
|
|
- return e.experimentalDaemon
|
|
|
|
|
|
+ return e.DaemonInfo.OSType
|
|
}
|
|
}
|
|
|
|
|
|
// MinimalBaseImage is the image used for minimal builds (it depends on the platform)
|
|
// MinimalBaseImage is the image used for minimal builds (it depends on the platform)
|
|
|
|
+// Deprecated: use Execution.PlatformDefaults.BaseImage
|
|
func (e *Execution) MinimalBaseImage() string {
|
|
func (e *Execution) MinimalBaseImage() string {
|
|
- return e.baseImage
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// DaemonKernelVersion is the kernel version of the daemon as a string, as returned
|
|
|
|
-// by an INFO call to the daemon.
|
|
|
|
-func (e *Execution) DaemonKernelVersion() string {
|
|
|
|
- return e.daemonKernelVersion
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// DaemonKernelVersionNumeric is the kernel version of the daemon as an integer.
|
|
|
|
-// Mostly useful on Windows where DaemonKernelVersion holds the full string such
|
|
|
|
-// as `10.0 14393 (14393.447.amd64fre.rs1_release_inmarket.161102-0100)`, but
|
|
|
|
-// integration tests really only need the `14393` piece to make decisions.
|
|
|
|
-func (e *Execution) DaemonKernelVersionNumeric() int {
|
|
|
|
- if e.daemonPlatform != "windows" {
|
|
|
|
- return -1
|
|
|
|
- }
|
|
|
|
- v, _ := strconv.Atoi(strings.Split(e.daemonKernelVersion, " ")[1])
|
|
|
|
- return v
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// DockerBinary returns the docker binary for this testing environment
|
|
|
|
-func (e *Execution) DockerBinary() string {
|
|
|
|
- return e.dockerBinary
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// DaemonHost return the daemon host string for this test execution
|
|
|
|
-func DaemonHost() string {
|
|
|
|
- daemonURLStr := "unix://" + opts.DefaultUnixSocket
|
|
|
|
- if daemonHostVar := os.Getenv("DOCKER_HOST"); daemonHostVar != "" {
|
|
|
|
- daemonURLStr = daemonHostVar
|
|
|
|
- }
|
|
|
|
- return daemonURLStr
|
|
|
|
|
|
+ return e.PlatformDefaults.BaseImage
|
|
}
|
|
}
|