diff --git a/Makefile b/Makefile index f6be52a5..695cfcfa 100644 --- a/Makefile +++ b/Makefile @@ -216,17 +216,18 @@ var commit = "$(COMMIT)" // version is the runtime version. var version = "$(VERSION)" -const defaultHypervisorPath = "$(QEMUPATH)" -const defaultImagePath = "$(IMAGEPATH)" -const defaultKernelPath = "$(KERNELPATH)" +var defaultHypervisorPath = "$(QEMUPATH)" +var defaultImagePath = "$(IMAGEPATH)" +var defaultKernelPath = "$(KERNELPATH)" +var defaultPauseRootPath = "$(PAUSEROOTPATH)" +var defaultShimPath = "$(SHIMPATH)" + const defaultKernelParams = "$(KERNELPARAMS)" const defaultMachineType = "$(MACHINETYPE)" -const defaultPauseRootPath = "$(PAUSEROOTPATH)" const defaultProxyURL = "$(PROXYURL)" const defaultRootDirectory = "$(PKGRUNDIR)" const defaultRuntimeLib = "$(PKGLIBDIR)" const defaultRuntimeRun = "$(PKGRUNDIR)" -const defaultShimPath = "$(SHIMPATH)" const pauseBinRelativePath = "$(PAUSEBINRELPATH)" const defaultVCPUCount uint32 = $(DEFVCPUS) diff --git a/README.md b/README.md index ef18dc52..ac969555 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ but can be enabled with a simple change to the [configuration](#Configuration) f First, to determine the configuration file path for your host run: ```bash -$ cc-runtime cc-env | grep -A 2 'Runtime.Config.Location' +$ cc-runtime cc-env | grep -A 1 Runtime.Config ``` To enable the global log: diff --git a/cc-env.go b/cc-env.go index 12b6573a..f19a823c 100644 --- a/cc-env.go +++ b/cc-env.go @@ -17,7 +17,6 @@ package main import ( "errors" "os" - "path/filepath" "strings" "github.com/BurntSushi/toml" @@ -31,7 +30,7 @@ import ( // // XXX: Increment for every change to the output format // (meaning any change to the EnvInfo type). -const formatVersion = "1.0.3" +const formatVersion = "1.0.4" // MetaInfo stores information on the format of the output itself type MetaInfo struct { @@ -39,18 +38,17 @@ type MetaInfo struct { Version string } -// PathInfo stores a path in its original, and fully resolved forms -type PathInfo struct { - Path string - Resolved string -} - // KernelInfo stores kernel details type KernelInfo struct { - Location PathInfo + Path string Parameters string } +// ImageInfo stores root filesystem image details +type ImageInfo struct { + Path string +} + // CPUInfo stores host CPU details type CPUInfo struct { Vendor string @@ -59,8 +57,7 @@ type CPUInfo struct { // RuntimeConfigInfo stores runtime config details. type RuntimeConfigInfo struct { - Location PathInfo - // Note a PathInfo as it may not exist (validly) + Path string GlobalLogPath string } @@ -81,7 +78,7 @@ type RuntimeVersionInfo struct { type HypervisorInfo struct { MachineType string Version string - Location PathInfo + Path string } // ProxyInfo stores proxy details @@ -93,16 +90,16 @@ type ProxyInfo struct { // ShimInfo stores shim details type ShimInfo struct { - Type string - Version string - Location PathInfo + Type string + Version string + Path string } // AgentInfo stores agent details type AgentInfo struct { - Type string - Version string - PauseBin PathInfo + Type string + Version string + PauseBinPath string } // DistroInfo stores host operating system distribution details. @@ -127,7 +124,7 @@ type EnvInfo struct { Meta MetaInfo Runtime RuntimeInfo Hypervisor HypervisorInfo - Image PathInfo + Image ImageInfo Kernel KernelInfo Proxy ProxyInfo Shim ShimInfo @@ -150,12 +147,7 @@ func getRuntimeInfo(configFile, logFile string, config oci.RuntimeConfig) Runtim runtimeConfig := RuntimeConfigInfo{ GlobalLogPath: logFile, - Location: PathInfo{ - // This path is already resolved by - // loadConfiguration(). - Path: configFile, - Resolved: configFile, - }, + Path: configFile, } return RuntimeInfo{ @@ -240,12 +232,8 @@ func getShimInfo(config oci.RuntimeConfig) (ShimInfo, error) { } shimPath := shimConfig.Path - shimPathResolved, err := filepath.EvalSymlinks(shimPath) - if err != nil { - return ShimInfo{}, err - } - version, err := getCommandVersion(shimPathResolved) + version, err := getCommandVersion(shimPath) if err != nil { version = unknown } @@ -253,10 +241,7 @@ func getShimInfo(config oci.RuntimeConfig) (ShimInfo, error) { ccShim := ShimInfo{ Type: string(config.ShimType), Version: version, - Location: PathInfo{ - Path: shimPath, - Resolved: shimPathResolved, - }, + Path: shimPath, } return ccShim, nil @@ -269,25 +254,20 @@ func getAgentInfo(config oci.RuntimeConfig) (AgentInfo, error) { } agentBinPath := agentConfig.PauseBinPath - agentBinPathResolved, err := filepath.EvalSymlinks(agentBinPath) - if err != nil { - return AgentInfo{}, err - } ccAgent := AgentInfo{ - Type: string(config.AgentType), - Version: unknown, - PauseBin: PathInfo{ - Path: agentBinPath, - Resolved: agentBinPathResolved, - }, + Type: string(config.AgentType), + Version: unknown, + PauseBinPath: agentBinPath, } return ccAgent, nil } -func getHypervisorInfo(config oci.RuntimeConfig, hypervisorDetails hypervisorDetails) HypervisorInfo { - version, err := getCommandVersion(hypervisorDetails.HypervisorPath) +func getHypervisorInfo(config oci.RuntimeConfig) HypervisorInfo { + hypervisorPath := config.HypervisorConfig.HypervisorPath + + version, err := getCommandVersion(hypervisorPath) if err != nil { version = unknown } @@ -295,10 +275,7 @@ func getHypervisorInfo(config oci.RuntimeConfig, hypervisorDetails hypervisorDet return HypervisorInfo{ MachineType: config.HypervisorConfig.HypervisorMachineType, Version: version, - Location: PathInfo{ - Path: config.HypervisorConfig.HypervisorPath, - Resolved: hypervisorDetails.HypervisorPath, - }, + Path: hypervisorPath, } } @@ -307,11 +284,6 @@ func getEnvInfo(configFile, logfilePath string, config oci.RuntimeConfig) (env E ccRuntime := getRuntimeInfo(configFile, logfilePath, config) - resolvedHypervisor, err := getHypervisorDetails(config) - if err != nil { - return EnvInfo{}, err - } - ccHost, err := getHostInfo() if err != nil { return EnvInfo{}, err @@ -332,18 +304,14 @@ func getEnvInfo(configFile, logfilePath string, config oci.RuntimeConfig) (env E return EnvInfo{}, err } - hypervisor := getHypervisorInfo(config, resolvedHypervisor) + hypervisor := getHypervisorInfo(config) - image := PathInfo{ - Path: config.HypervisorConfig.ImagePath, - Resolved: resolvedHypervisor.ImagePath, + image := ImageInfo{ + Path: config.HypervisorConfig.ImagePath, } kernel := KernelInfo{ - Location: PathInfo{ - Path: config.HypervisorConfig.KernelPath, - Resolved: resolvedHypervisor.KernelPath, - }, + Path: config.HypervisorConfig.KernelPath, Parameters: strings.Join(vc.SerializeParams(config.HypervisorConfig.KernelParams, "="), " "), } diff --git a/cc-env_test.go b/cc-env_test.go index f7f9e2fb..bac9333f 100644 --- a/cc-env_test.go +++ b/cc-env_test.go @@ -161,10 +161,7 @@ func getExpectedShimDetails(config oci.RuntimeConfig) (ShimInfo, error) { return ShimInfo{ Type: string(config.ShimType), Version: testShimVersion, - Location: PathInfo{ - Path: shimPath, - Resolved: shimPath, - }, + Path: shimPath, }, nil } @@ -177,12 +174,9 @@ func getExpectedAgentDetails(config oci.RuntimeConfig) (AgentInfo, error) { agentBinPath := agentConfig.PauseBinPath return AgentInfo{ - Type: string(config.AgentType), - Version: unknown, - PauseBin: PathInfo{ - Path: agentBinPath, - Resolved: agentBinPath, - }, + Type: string(config.AgentType), + Version: unknown, + PauseBinPath: agentBinPath, }, nil } @@ -259,28 +253,21 @@ model name : %s func getExpectedHypervisor(config oci.RuntimeConfig) HypervisorInfo { return HypervisorInfo{ - Version: testHypervisorVersion, - Location: PathInfo{ - Path: config.HypervisorConfig.HypervisorPath, - Resolved: config.HypervisorConfig.HypervisorPath, - }, + Version: testHypervisorVersion, + Path: config.HypervisorConfig.HypervisorPath, MachineType: config.HypervisorConfig.HypervisorMachineType, } } -func getExpectedImage(config oci.RuntimeConfig) PathInfo { - return PathInfo{ - Path: config.HypervisorConfig.ImagePath, - Resolved: config.HypervisorConfig.ImagePath, +func getExpectedImage(config oci.RuntimeConfig) ImageInfo { + return ImageInfo{ + Path: config.HypervisorConfig.ImagePath, } } func getExpectedKernel(config oci.RuntimeConfig) KernelInfo { return KernelInfo{ - Location: PathInfo{ - Path: config.HypervisorConfig.KernelPath, - Resolved: config.HypervisorConfig.KernelPath, - }, + Path: config.HypervisorConfig.KernelPath, Parameters: strings.Join(vc.SerializeParams(config.HypervisorConfig.KernelParams, "="), " "), } } @@ -294,10 +281,7 @@ func getExpectedRuntimeDetails(configFile, logFile string) RuntimeInfo { }, Config: RuntimeConfigInfo{ GlobalLogPath: logFile, - Location: PathInfo{ - Path: configFile, - Resolved: configFile, - }, + Path: configFile, }, } } @@ -514,129 +498,6 @@ func TestCCEnvGetEnvInfoNoProcVersion(t *testing.T) { assert.Error(t, err) } -func TestCCEnvGetEnvInfoNoHypervisor(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "") - if err != nil { - panic(err) - } - defer os.RemoveAll(tmpdir) - - const logFile = "/tmp/file.log" - - configFile, config, err := makeRuntimeConfig(tmpdir) - assert.NoError(t, err) - - expected, err := getExpectedSettings(config, tmpdir, configFile, logFile) - assert.NoError(t, err) - - err = os.Remove(expected.Hypervisor.Location.Resolved) - assert.NoError(t, err) - - _, err = getEnvInfo(configFile, logFile, config) - assert.Error(t, err) -} - -func TestCCEnvGetEnvInfoNoImage(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "") - if err != nil { - panic(err) - } - defer os.RemoveAll(tmpdir) - - const logFile = "/tmp/file.log" - - configFile, config, err := makeRuntimeConfig(tmpdir) - assert.NoError(t, err) - - expected, err := getExpectedSettings(config, tmpdir, configFile, logFile) - assert.NoError(t, err) - - err = os.Remove(expected.Image.Resolved) - assert.NoError(t, err) - - _, err = getEnvInfo(configFile, logFile, config) - assert.Error(t, err) -} - -func TestCCEnvGetEnvInfoNoKernel(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "") - if err != nil { - panic(err) - } - defer os.RemoveAll(tmpdir) - - const logFile = "/tmp/file.log" - - configFile, config, err := makeRuntimeConfig(tmpdir) - assert.NoError(t, err) - - expected, err := getExpectedSettings(config, tmpdir, configFile, logFile) - assert.NoError(t, err) - - err = os.Remove(expected.Kernel.Location.Resolved) - assert.NoError(t, err) - - _, err = getEnvInfo(configFile, logFile, config) - assert.Error(t, err) -} - -func TestCCEnvGetEnvInfoNoShim(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "") - if err != nil { - panic(err) - } - defer os.RemoveAll(tmpdir) - - const logFile = "/tmp/file.log" - - configFile, config, err := makeRuntimeConfig(tmpdir) - assert.NoError(t, err) - - expected, err := getExpectedSettings(config, tmpdir, configFile, logFile) - assert.NoError(t, err) - - err = os.Remove(expected.Shim.Location.Resolved) - assert.NoError(t, err) - - _, err = getEnvInfo(configFile, logFile, config) - assert.Error(t, err) -} - -func TestCCEnvGetEnvInfoInvalidAgent(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "") - if err != nil { - panic(err) - } - defer os.RemoveAll(tmpdir) - - const logFile = "/tmp/file.log" - - configFile, config, err := makeRuntimeConfig(tmpdir) - assert.NoError(t, err) - - _, err = getExpectedSettings(config, tmpdir, configFile, logFile) - assert.NoError(t, err) - - //err = os.Remove(expected.Shim.Location.Resolved) - //assert.NoError(t, err) - - cwd, err := os.Getwd() - assert.NoError(t, err) - defer os.Chdir(cwd) - - agentConfig, ok := config.AgentConfig.(vc.HyperConfig) - assert.True(t, ok) - - dir := filepath.Dir(agentConfig.PauseBinPath) - - // remove the pause bins parent directory - err = os.RemoveAll(dir) - assert.NoError(t, err) - - _, err = getEnvInfo(configFile, logFile, config) - assert.Error(t, err) -} - func TestCCEnvGetEnvInfoInvalidProxy(t *testing.T) { tmpdir, err := ioutil.TempDir("", "") @@ -775,28 +636,6 @@ func TestCCEnvGetShimInfo(t *testing.T) { assert.Equal(t, expectedShim, ccShim) } -func TestCCEnvGetShimInfoENOENT(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "") - if err != nil { - panic(err) - } - defer os.RemoveAll(tmpdir) - - _, config, err := makeRuntimeConfig(tmpdir) - assert.NoError(t, err) - - expectedShim, err := getExpectedShimDetails(config) - assert.NoError(t, err) - - // remove the shim ensuring its version cannot be queried - shim := expectedShim.Location.Resolved - err = os.Remove(shim) - assert.NoError(t, err) - - _, err = getShimInfo(config) - assert.Error(t, err) -} - func TestCCEnvGetShimInfoNoVersion(t *testing.T) { tmpdir, err := ioutil.TempDir("", "") if err != nil { @@ -810,7 +649,7 @@ func TestCCEnvGetShimInfoNoVersion(t *testing.T) { expectedShim, err := getExpectedShimDetails(config) assert.NoError(t, err) - shim := expectedShim.Location.Resolved + shim := expectedShim.Path // ensure querying the shim version fails err = createFile(shim, `#!/bin/sh @@ -880,58 +719,21 @@ func TestCCEnvGetAgentInfoInvalidType(t *testing.T) { assert.Error(t, err) } -func TestCCEnvGetAgentInfoUnableToResolvePath(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "") - if err != nil { - panic(err) - } - defer os.RemoveAll(tmpdir) - - _, config, err := makeRuntimeConfig(tmpdir) - assert.NoError(t, err) - - _, err = getExpectedAgentDetails(config) - assert.NoError(t, err) - - cwd, err := os.Getwd() - assert.NoError(t, err) - defer os.Chdir(cwd) - - agentConfig, ok := config.AgentConfig.(vc.HyperConfig) - assert.True(t, ok) - - dir := filepath.Dir(agentConfig.PauseBinPath) - - // remove the pause bins parent directory - err = os.RemoveAll(dir) - assert.NoError(t, err) - - _, err = getAgentInfo(config) - assert.Error(t, err) -} - func testCCEnvShowSettings(t *testing.T, tmpdir string, tmpfile *os.File) error { ccRuntime := RuntimeInfo{} ccHypervisor := HypervisorInfo{ - Location: PathInfo{ - Path: "/hypervisor/path", - Resolved: "/resolved/hypervisor/path", - }, + Path: "/resolved/hypervisor/path", MachineType: "hypervisor-machine-type", } - ccImage := PathInfo{ - Path: "/image/path", - Resolved: "/resolved/image/path", + ccImage := ImageInfo{ + Path: "/resolved/image/path", } ccKernel := KernelInfo{ - Location: PathInfo{ - Path: "/kernel/path", - Resolved: "/resolved/kernel/path", - }, + Path: "/kernel/path", Parameters: "foo=bar xyz", } @@ -944,19 +746,13 @@ func testCCEnvShowSettings(t *testing.T, tmpdir string, tmpfile *os.File) error ccShim := ShimInfo{ Type: "shim-type", Version: "shim-version", - Location: PathInfo{ - Path: "/shim/path", - Resolved: "/resolved/shim/path", - }, + Path: "/resolved/shim/path", } ccAgent := AgentInfo{ - Type: "agent-type", - Version: "agent-version", - PauseBin: PathInfo{ - Path: "/agent/path", - Resolved: "/resolved/agent/path", - }, + Type: "agent-type", + Version: "agent-version", + PauseBinPath: "/resolved/agent/path", } expectedHostDetails, err := getExpectedHostDetails(tmpdir) @@ -1059,38 +855,6 @@ func TestCCEnvHandleSettings(t *testing.T) { assert.NoError(t, err) } -func TestCCEnvHandleSettingsGetEnvInfoFailure(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "") - if err != nil { - panic(err) - } - defer os.RemoveAll(tmpdir) - - const logFile = "/tmp/file.log" - - configFile, config, err := makeRuntimeConfig(tmpdir) - assert.NoError(t, err) - - _, err = getExpectedSettings(config, tmpdir, configFile, logFile) - assert.NoError(t, err) - - m := map[string]interface{}{ - "configFile": configFile, - "logfilePath": logFile, - "runtimeConfig": config, - } - - tmpfile, err := ioutil.TempFile("", "") - assert.NoError(t, err) - defer os.Remove(tmpfile.Name()) - - err = os.Remove(config.HypervisorConfig.HypervisorPath) - assert.NoError(t, err) - - err = handleSettings(tmpfile, m) - assert.Error(t, err) -} - func TestCCEnvHandleSettingsInvalidParams(t *testing.T) { err := handleSettings(nil, map[string]interface{}{}) assert.Error(t, err) @@ -1216,21 +980,14 @@ func TestCCEnvCLIFunctionFail(t *testing.T) { fn, ok := ccEnvCLICommand.Action.(func(context *cli.Context) error) assert.True(t, ok) - devNull, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0666) - assert.NoError(t, err) - - // throw away output savedOutputFile := defaultOutputFile - defaultOutputFile = devNull + // invalidate + defaultOutputFile = nil defer func() { defaultOutputFile = savedOutputFile }() - // cause a failure - err = os.Remove(config.HypervisorConfig.HypervisorPath) - assert.NoError(t, err) - err = fn(ctx) assert.Error(t, err) } @@ -1247,7 +1004,7 @@ func TestGetHypervisorInfo(t *testing.T) { _, config, err := makeRuntimeConfig(tmpdir) assert.NoError(err) - info := getHypervisorInfo(config, hypervisorDetails{}) + info := getHypervisorInfo(config) - assert.Equal(info.Version, unknown) + assert.Equal(info.Version, testHypervisorVersion) } diff --git a/config.go b/config.go index 06ef8540..e60d549a 100644 --- a/config.go +++ b/config.go @@ -102,28 +102,34 @@ type agent struct { PauseRootPath string `toml:"pause_root_path"` } -func (h hypervisor) path() string { +func (h hypervisor) path() (string, error) { + p := h.Path + if h.Path == "" { - return defaultHypervisorPath + p = defaultHypervisorPath } - return h.Path + return resolvePath(p) } -func (h hypervisor) kernel() string { - if h.Kernel == "" { - return defaultKernelPath +func (h hypervisor) kernel() (string, error) { + p := h.Kernel + + if p == "" { + p = defaultKernelPath } - return h.Kernel + return resolvePath(p) } -func (h hypervisor) image() string { - if h.Image == "" { - return defaultImagePath +func (h hypervisor) image() (string, error) { + p := h.Image + + if p == "" { + p = defaultImagePath } - return h.Image + return resolvePath(p) } func (h hypervisor) kernelParams() string { @@ -172,26 +178,42 @@ func (p proxy) url() string { return p.URL } -func (s shim) path() string { - if s.Path == "" { - return defaultShimPath +func (s shim) path() (string, error) { + p := s.Path + + if p == "" { + p = defaultShimPath } - return s.Path + return resolvePath(p) } -func (a agent) pauseRootPath() string { - if a.PauseRootPath == "" { - return defaultPauseRootPath +func (a agent) pauseRootPath() (string, error) { + p := a.PauseRootPath + + if p == "" { + p = defaultPauseRootPath } - return a.PauseRootPath + return resolvePath(p) } func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) { - hypervisor := h.path() - kernel := h.kernel() - image := h.image() + hypervisor, err := h.path() + if err != nil { + return vc.HypervisorConfig{}, err + } + + kernel, err := h.kernel() + if err != nil { + return vc.HypervisorConfig{}, err + } + + image, err := h.image() + if err != nil { + return vc.HypervisorConfig{}, err + } + kernelParams := h.kernelParams() machineType := h.machineType() @@ -217,10 +239,9 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) { } func newHyperstartAgentConfig(a agent) (vc.HyperConfig, error) { - dir := a.pauseRootPath() - - if !fileExists(dir) { - return vc.HyperConfig{}, fmt.Errorf("Directory does not exist: %v", dir) + dir, err := a.pauseRootPath() + if err != nil { + return vc.HyperConfig{}, err } path := filepath.Join(dir, pauseBinRelativePath) @@ -235,10 +256,9 @@ func newHyperstartAgentConfig(a agent) (vc.HyperConfig, error) { } func newCCShimConfig(s shim) (vc.CCShimConfig, error) { - path := s.path() - - if !fileExists(path) { - return vc.CCShimConfig{}, fmt.Errorf("File does not exist: %v", path) + path, err := s.path() + if err != nil { + return vc.CCShimConfig{}, err } return vc.CCShimConfig{ @@ -312,6 +332,9 @@ func updateRuntimeConfig(configPath string, tomlConf tomlConfig, config *oci.Run // // If ignoreLogging is true, the global log will not be initialised nor // will this function make any log calls. +// +// All paths are resolved fully meaning if this function does not return an +// error, all paths are valid at the time of the call. func loadConfiguration(configPath string, ignoreLogging bool) (resolvedConfigPath, logfilePath string, config oci.RuntimeConfig, err error) { defaultHypervisorConfig := vc.HypervisorConfig{ HypervisorPath: defaultHypervisorPath, diff --git a/config_test.go b/config_test.go index dfcded0a..74ae631b 100644 --- a/config_test.go +++ b/config_test.go @@ -799,49 +799,145 @@ func TestNewCCShimConfig(t *testing.T) { } func TestHypervisorDefaults(t *testing.T) { - h := hypervisor{} - - assert.Equal(t, h.path(), defaultHypervisorPath, "default hypervisor path wrong") - assert.Equal(t, h.kernel(), defaultKernelPath, "default hypervisor kernel wrong") - assert.Equal(t, h.image(), defaultImagePath, "default hypervisor image wrong") - assert.Equal(t, h.kernelParams(), defaultKernelParams, "default hypervisor image wrong") - assert.Equal(t, h.machineType(), defaultMachineType, "default hypervisor machine type wrong") - assert.Equal(t, h.defaultVCPUs(), defaultVCPUCount, "default vCPU number is wrong") - assert.Equal(t, h.defaultMemSz(), defaultMemSize, "default memory size is wrong") - - path := "/foo" - h.Path = path - assert.Equal(t, h.path(), path, "custom hypervisor path wrong") - - kernel := "wibble" - h.Kernel = kernel - assert.Equal(t, h.kernel(), kernel, "custom hypervisor kernel wrong") + assert := assert.New(t) - kernelParams := "foo=bar xyz" - h.KernelParams = kernelParams - assert.Equal(t, h.kernelParams(), kernelParams, "custom hypervisor kernel parameterms wrong") + h := hypervisor{} - image := "foo" - h.Image = image - assert.Equal(t, h.image(), image, "custom hypervisor image wrong") + assert.Equal(h.machineType(), defaultMachineType, "default hypervisor machine type wrong") + assert.Equal(h.defaultVCPUs(), defaultVCPUCount, "default vCPU number is wrong") + assert.Equal(h.defaultMemSz(), defaultMemSize, "default memory size is wrong") machineType := "foo" h.MachineType = machineType - assert.Equal(t, h.machineType(), machineType, "custom hypervisor machine type wrong") + assert.Equal(h.machineType(), machineType, "custom hypervisor machine type wrong") // auto inferring h.DefaultVCPUs = -1 - assert.Equal(t, h.defaultVCPUs(), uint32(goruntime.NumCPU()), "default vCPU number is wrong") + assert.Equal(h.defaultVCPUs(), uint32(goruntime.NumCPU()), "default vCPU number is wrong") h.DefaultVCPUs = 2 - assert.Equal(t, h.defaultVCPUs(), uint32(2), "default vCPU number is wrong") + assert.Equal(h.defaultVCPUs(), uint32(2), "default vCPU number is wrong") // qemu supports max 255 h.DefaultVCPUs = 8086 - assert.Equal(t, h.defaultVCPUs(), uint32(255), "default vCPU number is wrong") + assert.Equal(h.defaultVCPUs(), uint32(255), "default vCPU number is wrong") h.DefaultMemSz = 1024 - assert.Equal(t, h.defaultMemSz(), uint32(1024), "default memory size is wrong") + assert.Equal(h.defaultMemSz(), uint32(1024), "default memory size is wrong") +} + +func TestHypervisorDefaultsHypervisor(t *testing.T) { + assert := assert.New(t) + + tmpdir, err := ioutil.TempDir(testDir, "") + assert.NoError(err) + defer os.RemoveAll(tmpdir) + + testHypervisorPath := filepath.Join(tmpdir, "hypervisor") + testHypervisorLinkPath := filepath.Join(tmpdir, "hypervisor-link") + + err = createEmptyFile(testHypervisorPath) + assert.NoError(err) + + err = syscall.Symlink(testHypervisorPath, testHypervisorLinkPath) + assert.NoError(err) + + savedHypervisorPath := defaultHypervisorPath + + defer func() { + defaultHypervisorPath = savedHypervisorPath + }() + + defaultHypervisorPath = testHypervisorPath + h := hypervisor{} + p, err := h.path() + assert.NoError(err) + assert.Equal(p, defaultHypervisorPath, "default hypervisor path wrong") + + // test path resolution + defaultHypervisorPath = testHypervisorLinkPath + h = hypervisor{} + p, err = h.path() + assert.NoError(err) + assert.Equal(p, testHypervisorPath) +} + +func TestHypervisorDefaultsKernel(t *testing.T) { + assert := assert.New(t) + + tmpdir, err := ioutil.TempDir(testDir, "") + assert.NoError(err) + defer os.RemoveAll(tmpdir) + + testKernelPath := filepath.Join(tmpdir, "kernel") + testKernelLinkPath := filepath.Join(tmpdir, "kernel-link") + + err = createEmptyFile(testKernelPath) + assert.NoError(err) + + err = syscall.Symlink(testKernelPath, testKernelLinkPath) + assert.NoError(err) + + savedKernelPath := defaultKernelPath + + defer func() { + defaultKernelPath = savedKernelPath + }() + + defaultKernelPath = testKernelPath + + h := hypervisor{} + p, err := h.kernel() + assert.NoError(err) + assert.Equal(p, defaultKernelPath, "default Kernel path wrong") + + // test path resolution + defaultKernelPath = testKernelLinkPath + h = hypervisor{} + p, err = h.kernel() + assert.NoError(err) + assert.Equal(p, testKernelPath) + + assert.Equal(h.kernelParams(), defaultKernelParams, "default hypervisor image wrong") + kernelParams := "foo=bar xyz" + h.KernelParams = kernelParams + assert.Equal(h.kernelParams(), kernelParams, "custom hypervisor kernel parameterms wrong") +} + +func TestHypervisorDefaultsImage(t *testing.T) { + assert := assert.New(t) + + tmpdir, err := ioutil.TempDir(testDir, "") + assert.NoError(err) + defer os.RemoveAll(tmpdir) + + testImagePath := filepath.Join(tmpdir, "image") + testImageLinkPath := filepath.Join(tmpdir, "image-link") + + err = createEmptyFile(testImagePath) + assert.NoError(err) + + err = syscall.Symlink(testImagePath, testImageLinkPath) + assert.NoError(err) + + savedImagePath := defaultImagePath + + defer func() { + defaultImagePath = savedImagePath + }() + + defaultImagePath = testImagePath + h := hypervisor{} + p, err := h.image() + assert.NoError(err) + assert.Equal(p, defaultImagePath, "default Image path wrong") + + // test path resolution + defaultImagePath = testImageLinkPath + h = hypervisor{} + p, err = h.image() + assert.NoError(err) + assert.Equal(p, testImagePath) } func TestProxyDefaults(t *testing.T) { @@ -856,23 +952,75 @@ func TestProxyDefaults(t *testing.T) { } func TestShimDefaults(t *testing.T) { - s := shim{} + assert := assert.New(t) + + tmpdir, err := ioutil.TempDir(testDir, "") + assert.NoError(err) + defer os.RemoveAll(tmpdir) + + testShimPath := filepath.Join(tmpdir, "shim") + testShimLinkPath := filepath.Join(tmpdir, "shim-link") + + err = createEmptyFile(testShimPath) + assert.NoError(err) - assert.Equal(t, s.path(), defaultShimPath, "default shim path wrong") + err = syscall.Symlink(testShimPath, testShimLinkPath) + assert.NoError(err) + + savedShimPath := defaultShimPath + + defer func() { + defaultShimPath = savedShimPath + }() + + defaultShimPath = testShimPath + s := shim{} + p, err := s.path() + assert.NoError(err) + assert.Equal(p, defaultShimPath, "default shim path wrong") - path := "/foo/bar" - s.Path = path - assert.Equal(t, s.path(), path, "custom shim path wrong") + // test path resolution + defaultShimPath = testShimLinkPath + s = shim{} + p, err = s.path() + assert.NoError(err) + assert.Equal(p, testShimPath) } func TestAgentDefaults(t *testing.T) { - a := agent{} + assert := assert.New(t) + + tmpdir, err := ioutil.TempDir(testDir, "") + assert.NoError(err) + defer os.RemoveAll(tmpdir) + + testPauseRootPath := filepath.Join(tmpdir, "pause") + testPauseRootLinkPath := filepath.Join(tmpdir, "pause-link") + + err = os.MkdirAll(testPauseRootPath, testDirMode) + assert.NoError(err) + + err = syscall.Symlink(testPauseRootPath, testPauseRootLinkPath) + assert.NoError(err) + + savedPauseRootPath := defaultPauseRootPath - assert.Equal(t, a.pauseRootPath(), defaultPauseRootPath, "default agent pause root path wrong") + defer func() { + defaultPauseRootPath = savedPauseRootPath + }() - path := "/foo/bar/baz" - a.PauseRootPath = path - assert.Equal(t, a.pauseRootPath(), path, "custom agent pause root path wrong") + defaultPauseRootPath = testPauseRootPath + + a := agent{} + p, err := a.pauseRootPath() + assert.NoError(err) + assert.Equal(p, defaultPauseRootPath, "default agent pause root path wrong") + + // test path resolution + defaultPauseRootPath = testPauseRootLinkPath + p, err = a.pauseRootPath() + assert.NoError(err) + assert.Equal(p, testPauseRootPath, "default agent pause root path wrong") } func TestGetDefaultConfigFilePaths(t *testing.T) { diff --git a/list.go b/list.go index c5a24995..5a149778 100644 --- a/list.go +++ b/list.go @@ -20,7 +20,6 @@ import ( "errors" "fmt" "os" - "path/filepath" "text/tabwriter" "time" @@ -236,36 +235,22 @@ func getContainers(context *cli.Context) ([]fullContainerState, error) { // getHypervisorDetails returns details of the hypervisor used to host // the container. -// -// It ensures all paths are fully expanded. func getHypervisorDetails(runtimeConfig oci.RuntimeConfig) (hypervisorDetails, error) { initialHypervisorPath := runtimeConfig.HypervisorConfig.HypervisorPath initialKernelPath := runtimeConfig.HypervisorConfig.KernelPath initialImagePath := runtimeConfig.HypervisorConfig.ImagePath - if initialHypervisorPath == "" { - return hypervisorDetails{}, fmt.Errorf("Need hypervisor path") - } - - if initialKernelPath == "" { - return hypervisorDetails{}, fmt.Errorf("Need kernel path") - } - - if initialImagePath == "" { - return hypervisorDetails{}, fmt.Errorf("Need image path") - } - - hypervisorPath, err := filepath.EvalSymlinks(initialHypervisorPath) + hypervisorPath, err := resolvePath(initialHypervisorPath) if err != nil { return hypervisorDetails{}, err } - kernelPath, err := filepath.EvalSymlinks(initialKernelPath) + kernelPath, err := resolvePath(initialKernelPath) if err != nil { return hypervisorDetails{}, err } - imagePath, err := filepath.EvalSymlinks(initialImagePath) + imagePath, err := resolvePath(initialImagePath) if err != nil { return hypervisorDetails{}, err }