github.com/zhouyu0/docker-note@v0.0.0-20190722021225-b8d3825084db/internal/test/environment/environment.go (about)

     1  package environment // import "github.com/docker/docker/internal/test/environment"
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  
    10  	"github.com/docker/docker/api/types"
    11  	"github.com/docker/docker/client"
    12  	"github.com/docker/docker/internal/test/fixtures/load"
    13  	"github.com/pkg/errors"
    14  )
    15  
    16  // Execution contains information about the current test execution and daemon
    17  // under test
    18  type Execution struct {
    19  	client            client.APIClient
    20  	DaemonInfo        types.Info
    21  	OSType            string
    22  	PlatformDefaults  PlatformDefaults
    23  	protectedElements protectedElements
    24  }
    25  
    26  // PlatformDefaults are defaults values for the platform of the daemon under test
    27  type PlatformDefaults struct {
    28  	BaseImage            string
    29  	VolumesConfigPath    string
    30  	ContainerStoragePath string
    31  }
    32  
    33  // New creates a new Execution struct
    34  func New() (*Execution, error) {
    35  	client, err := client.NewClientWithOpts(client.FromEnv)
    36  	if err != nil {
    37  		return nil, errors.Wrapf(err, "failed to create client")
    38  	}
    39  
    40  	info, err := client.Info(context.Background())
    41  	if err != nil {
    42  		return nil, errors.Wrapf(err, "failed to get info from daemon")
    43  	}
    44  
    45  	osType := getOSType(info)
    46  
    47  	return &Execution{
    48  		client:            client,
    49  		DaemonInfo:        info,
    50  		OSType:            osType,
    51  		PlatformDefaults:  getPlatformDefaults(info, osType),
    52  		protectedElements: newProtectedElements(),
    53  	}, nil
    54  }
    55  
    56  func getOSType(info types.Info) string {
    57  	// Docker EE does not set the OSType so allow the user to override this value.
    58  	userOsType := os.Getenv("TEST_OSTYPE")
    59  	if userOsType != "" {
    60  		return userOsType
    61  	}
    62  	return info.OSType
    63  }
    64  
    65  func getPlatformDefaults(info types.Info, osType string) PlatformDefaults {
    66  	volumesPath := filepath.Join(info.DockerRootDir, "volumes")
    67  	containersPath := filepath.Join(info.DockerRootDir, "containers")
    68  
    69  	switch osType {
    70  	case "linux":
    71  		return PlatformDefaults{
    72  			BaseImage:            "scratch",
    73  			VolumesConfigPath:    toSlash(volumesPath),
    74  			ContainerStoragePath: toSlash(containersPath),
    75  		}
    76  	case "windows":
    77  		baseImage := "microsoft/windowsservercore"
    78  		if overrideBaseImage := os.Getenv("WINDOWS_BASE_IMAGE"); overrideBaseImage != "" {
    79  			baseImage = overrideBaseImage
    80  			if overrideBaseImageTag := os.Getenv("WINDOWS_BASE_IMAGE_TAG"); overrideBaseImageTag != "" {
    81  				baseImage = baseImage + ":" + overrideBaseImageTag
    82  			}
    83  		}
    84  		fmt.Println("INFO: Windows Base image is ", baseImage)
    85  		return PlatformDefaults{
    86  			BaseImage:            baseImage,
    87  			VolumesConfigPath:    filepath.FromSlash(volumesPath),
    88  			ContainerStoragePath: filepath.FromSlash(containersPath),
    89  		}
    90  	default:
    91  		panic(fmt.Sprintf("unknown OSType for daemon: %s", osType))
    92  	}
    93  }
    94  
    95  // Make sure in context of daemon, not the local platform. Note we can't
    96  // use filepath.FromSlash or ToSlash here as they are a no-op on Unix.
    97  func toSlash(path string) string {
    98  	return strings.Replace(path, `\`, `/`, -1)
    99  }
   100  
   101  // IsLocalDaemon is true if the daemon under test is on the same
   102  // host as the test process.
   103  //
   104  // Deterministically working out the environment in which CI is running
   105  // to evaluate whether the daemon is local or remote is not possible through
   106  // a build tag.
   107  //
   108  // For example Windows to Linux CI under Jenkins tests the 64-bit
   109  // Windows binary build with the daemon build tag, but calls a remote
   110  // Linux daemon.
   111  //
   112  // We can't just say if Windows then assume the daemon is local as at
   113  // some point, we will be testing the Windows CLI against a Windows daemon.
   114  //
   115  // Similarly, it will be perfectly valid to also run CLI tests from
   116  // a Linux CLI (built with the daemon tag) against a Windows daemon.
   117  func (e *Execution) IsLocalDaemon() bool {
   118  	return os.Getenv("DOCKER_REMOTE_DAEMON") == ""
   119  }
   120  
   121  // IsRemoteDaemon is true if the daemon under test is on different host
   122  // as the test process.
   123  func (e *Execution) IsRemoteDaemon() bool {
   124  	return !e.IsLocalDaemon()
   125  }
   126  
   127  // DaemonAPIVersion returns the negotiated daemon api version
   128  func (e *Execution) DaemonAPIVersion() string {
   129  	version, err := e.APIClient().ServerVersion(context.TODO())
   130  	if err != nil {
   131  		return ""
   132  	}
   133  	return version.APIVersion
   134  }
   135  
   136  // Print the execution details to stdout
   137  // TODO: print everything
   138  func (e *Execution) Print() {
   139  	if e.IsLocalDaemon() {
   140  		fmt.Println("INFO: Testing against a local daemon")
   141  	} else {
   142  		fmt.Println("INFO: Testing against a remote daemon")
   143  	}
   144  }
   145  
   146  // APIClient returns an APIClient connected to the daemon under test
   147  func (e *Execution) APIClient() client.APIClient {
   148  	return e.client
   149  }
   150  
   151  // IsUserNamespace returns whether the user namespace remapping is enabled
   152  func (e *Execution) IsUserNamespace() bool {
   153  	root := os.Getenv("DOCKER_REMAP_ROOT")
   154  	return root != ""
   155  }
   156  
   157  // EnsureFrozenImagesLinux loads frozen test images into the daemon
   158  // if they aren't already loaded
   159  func EnsureFrozenImagesLinux(testEnv *Execution) error {
   160  	if testEnv.OSType == "linux" {
   161  		err := load.FrozenImagesLinux(testEnv.APIClient(), frozenImages...)
   162  		if err != nil {
   163  			return errors.Wrap(err, "error loading frozen images")
   164  		}
   165  	}
   166  	return nil
   167  }