Skip to content

Commit

Permalink
Merge pull request clearcontainers#371 from devimc/docker/checkQemuAn…
Browse files Browse the repository at this point in the history
…dProxy

integration/docker: ensure qemu and proxy are not running if start fails
  • Loading branch information
jodh-intel authored Jun 5, 2018
2 parents 584f06e + 0c91f82 commit 02e4a54
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 89 deletions.
42 changes: 35 additions & 7 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ package tests

import (
"io/ioutil"
"log"
"os"
"strings"

"github.com/BurntSushi/toml"
)

// RuntimeConfig is the runtime configuration
type RuntimeConfig struct {
// KataConfiguration is the runtime configuration
type KataConfiguration struct {
Hypervisor map[string]hypervisor
Proxy map[string]proxy
Shim map[string]shim
Expand Down Expand Up @@ -75,13 +78,38 @@ const (
// DefaultShim default shim
DefaultShim = "kata"

// DefaultRuntimeConfigPath is the default path to the runtime configuration file
DefaultRuntimeConfigPath = "/usr/share/defaults/kata-containers/configuration.toml"
// DefaultKataConfigPath is the default path to the kata configuration file
DefaultKataConfigPath = "/usr/share/defaults/kata-containers/configuration.toml"
)

// LoadRuntimeConfiguration loads runtime configuration
func LoadRuntimeConfiguration(configPath string) (RuntimeConfig, error) {
var config RuntimeConfig
// KataConfig is the runtime configuration
var KataConfig KataConfiguration

func init() {
var err error
kataConfigPath := DefaultKataConfigPath

args := []string{"--kata-show-default-config-paths"}
cmd := NewCommand(Runtime, args...)
stdout, _, exitCode := cmd.Run()
if exitCode == 0 && stdout != "" {
for _, c := range strings.Split(stdout, "\n") {
if _, err = os.Stat(c); err == nil {
kataConfigPath = c
break
}
}
}

KataConfig, err = loadKataConfiguration(kataConfigPath)
if err != nil {
log.Fatalf("failed to load kata configuration: %v\n", err)
}
}

// loadKataConfiguration loads kata configuration
func loadKataConfiguration(configPath string) (KataConfiguration, error) {
var config KataConfiguration
configData, err := ioutil.ReadFile(configPath)
if err != nil {
return config, err
Expand Down
6 changes: 5 additions & 1 deletion container.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,13 @@ func (c *Container) Teardown() error {
// - list command shows the container
// - the process id specified in the pid file is running (cc-shim)
// - the VM is running (qemu)
// - the proxy is running
// - the shim is running
// else false is returned
func (c *Container) Exist() bool {
return c.isListed() || c.isWorkloadRunning() || IsVMRunning(*c.ID)
return c.isListed() || c.isWorkloadRunning() ||
HypervisorRunning(*c.ID) || ProxyRunning(*c.ID) ||
ShimRunning(*c.ID)
}

func (c *Container) isListed() bool {
Expand Down
4 changes: 2 additions & 2 deletions integration/docker/cpu_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ var _ = Describe("Hot plug CPUs", func() {
waitTime = 5
maxTries = 5
args = []string{"--rm", "--name", id}
defaultVCPUs = int(runtimeConfig.Hypervisor[DefaultHypervisor].DefaultVCPUs)
defaultVCPUs = int(KataConfig.Hypervisor[DefaultHypervisor].DefaultVCPUs)
Expect(defaultVCPUs).To(BeNumerically(">", 0))
})

Expand Down Expand Up @@ -245,7 +245,7 @@ var _ = Describe("Update number of CPUs", func() {
waitTime = 5
maxTries = 5

defaultVCPUs = int(runtimeConfig.Hypervisor[DefaultHypervisor].DefaultVCPUs)
defaultVCPUs = int(KataConfig.Hypervisor[DefaultHypervisor].DefaultVCPUs)
Expect(defaultVCPUs).To(BeNumerically(">", 0))

runArgs = []string{"--rm", "--name", id, "-dt", DebianImage, "bash"}
Expand Down
6 changes: 5 additions & 1 deletion integration/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,14 +201,18 @@ func IsRunningDockerContainer(name string) bool {
// ExistDockerContainer returns true if any of next cases is true:
// - 'docker ps -a' command shows the container
// - the VM is running (qemu)
// - the proxy is running
// - the shim is running
// else false is returned
func ExistDockerContainer(name string) bool {
state := StatusDockerContainer(name)
if state != "" {
return true
}

return tests.IsVMRunning(name)
return tests.HypervisorRunning(name) ||
tests.ProxyRunning(name) ||
tests.ShimRunning(name)
}

// RemoveDockerContainer removes a container using docker rm -f
Expand Down
24 changes: 0 additions & 24 deletions integration/docker/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
package docker

import (
"os"
"strings"
"testing"

. "github.com/kata-containers/tests"
Expand All @@ -19,33 +17,11 @@ const (
shouldNotFail = false
)

var runtimeConfig RuntimeConfig

func randomDockerName() string {
return RandID(30)
}

func TestIntegration(t *testing.T) {
var err error
runtimeConfigPath := DefaultRuntimeConfigPath

args := []string{"--kata-show-default-config-paths"}
cmd := NewCommand(Runtime, args...)
stdout, _, exitCode := cmd.Run()
if exitCode == 0 && stdout != "" {
for _, c := range strings.Split(stdout, "\n") {
if _, err = os.Stat(c); err == nil {
runtimeConfigPath = c
break
}
}
}

runtimeConfig, err = LoadRuntimeConfiguration(runtimeConfigPath)
if err != nil {
t.Fatalf("failed to load runtime configuration: %v\n", err)
}

// before start we have to download the docker images
images := []string{
Image,
Expand Down
25 changes: 25 additions & 0 deletions integration/docker/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,28 @@ var _ = Describe("run", func() {
})
})
})

var _ = Describe("run nonexistent command", func() {
var (
args []string
id string
exitCode int
)

BeforeEach(func() {
id = randomDockerName()
})

AfterEach(func() {
Expect(ExistDockerContainer(id)).NotTo(BeTrue())
})

Context("Running nonexistent command", func() {
It("container and its components should not exist", func() {
Skip("Issue: https://github.com/kata-containers/runtime/issues/366")
args = []string{"--rm", "--name", id, Image, "does-not-exist"}
_, _, exitCode = dockerRun(args...)
Expect(exitCode).NotTo(Equal(0))
})
})
})
85 changes: 85 additions & 0 deletions process.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright (c) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0

package tests

import (
"errors"
"io/ioutil"
"log"
"os"
"path/filepath"
"regexp"
)

const procPath = "/proc"

var errFound = errors.New("found")

// processRunning looks for a process in /proc that matches with the regexps
func processRunning(regexps []string) bool {
err := filepath.Walk(procPath, func(path string, _ os.FileInfo, _ error) error {
if path == "" {
return filepath.SkipDir
}

info, err := os.Stat(path)
if err != nil {
return filepath.SkipDir
}

if !info.IsDir() {
return filepath.SkipDir
}

content, err := ioutil.ReadFile(filepath.Join(path, "cmdline"))
if err != nil {
return filepath.SkipDir
}

for _, r := range regexps {
matcher := regexp.MustCompile(r)
if matcher.MatchString(string(content)) {
return errFound
}
}

return nil
})

return err == errFound
}

// HypervisorRunning returns true if the hypervisor is still running, otherwise false
func HypervisorRunning(containerID string) bool {
hypervisorPath := KataConfig.Hypervisor[DefaultHypervisor].Path
if hypervisorPath == "" {
log.Fatal("Could not determine if hypervisor is running: hypervisor path is empty")
return false
}
hypervisorRegexps := []string{hypervisorPath + ".*-name.*" + containerID + ".*-qmp.*unix:.*/" + containerID + "/.*"}
return processRunning(hypervisorRegexps)
}

// ProxyRunning returns true if the proxy is still running, otherwise false
func ProxyRunning(containerID string) bool {
proxyPath := KataConfig.Proxy[DefaultProxy].Path
if proxyPath == "" {
log.Fatal("Could not determine if proxy is running: proxy path is empty")
return false
}
proxyRegexps := []string{proxyPath + ".*-listen-socket.*unix:.*/" + containerID + "/.*"}
return processRunning(proxyRegexps)
}

// ShimRunning returns true if the shim is still running, otherwise false
func ShimRunning(containerID string) bool {
shimPath := KataConfig.Shim[DefaultShim].Path
if shimPath == "" {
log.Fatal("Could not determine if shim is running: shim path is empty")
return false
}
shimRegexps := []string{shimPath + ".*-agent.*unix:.*/" + containerID + "/.*-container.*" + containerID + ".*"}
return processRunning(shimRegexps)
}
54 changes: 0 additions & 54 deletions vm.go

This file was deleted.

0 comments on commit 02e4a54

Please sign in to comment.