environment.go 4.1 KB

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