aboutsummaryrefslogtreecommitdiffstats
path: root/extras/hs-test/container.go
diff options
context:
space:
mode:
Diffstat (limited to 'extras/hs-test/container.go')
-rw-r--r--extras/hs-test/container.go153
1 files changed, 138 insertions, 15 deletions
diff --git a/extras/hs-test/container.go b/extras/hs-test/container.go
index e9aa7b261c4..1dc65fff308 100644
--- a/extras/hs-test/container.go
+++ b/extras/hs-test/container.go
@@ -2,18 +2,73 @@ package main
import (
"fmt"
+ "os"
+ "strings"
"github.com/edwarnicke/exechelper"
)
type Volume struct {
- name string
- path string
+ hostDir string
+ containerDir string
}
type Container struct {
- name string
- volumes []*Volume
+ isOptional bool
+ name string
+ image string
+ workDir string
+ volumes map[string]Volume
+ envVars map[string]string
+}
+
+func NewContainer(yamlInput ContainerConfig) (*Container, error) {
+ containerName := yamlInput["name"].(string)
+ if len(containerName) == 0 {
+ err := fmt.Errorf("container name must not be blank")
+ return nil, err
+ }
+
+ var container = new(Container)
+ container.volumes = make(map[string]Volume)
+ container.envVars = make(map[string]string)
+ container.name = containerName
+
+ if image, ok := yamlInput["image"]; ok {
+ container.image = image.(string)
+ } else {
+ container.image = "hs-test/vpp"
+ }
+
+ if isOptional, ok := yamlInput["is-optional"]; ok {
+ container.isOptional = isOptional.(bool)
+ } else {
+ container.isOptional = false
+ }
+
+ if _, ok := yamlInput["volumes"]; ok {
+ r:= strings.NewReplacer("$HST_DIR", workDir)
+ for _, volu := range yamlInput["volumes"].([]interface{}) {
+ volumeMap := volu.(ContainerConfig)
+ hostDir := r.Replace(volumeMap["host-dir"].(string))
+ containerDir := volumeMap["container-dir"].(string)
+ container.addVolume(hostDir, containerDir)
+
+ if isDefaultWorkDir, ok := volumeMap["is-default-work-dir"]; ok &&
+ isDefaultWorkDir.(bool) &&
+ len(container.workDir) == 0 {
+ container.workDir = containerDir
+ }
+
+ }
+ }
+
+ if _, ok := yamlInput["vars"]; ok {
+ for _, envVar := range yamlInput["vars"].([]interface{}) {
+ container.addEnvVar(envVar)
+ }
+ }
+ return container, nil
}
func (c *Container) run() error {
@@ -22,34 +77,102 @@ func (c *Container) run() error {
}
exechelper.Run(fmt.Sprintf("mkdir -p /tmp/%s/sync", c.name))
- syncPath := fmt.Sprintf("-v /tmp/%s/sync:/tmp/sync", c.name)
- cmd := "docker run --cap-add=all -d --privileged --network host --rm "
+ syncPath := fmt.Sprintf(" -v %s:/tmp/sync", c.getSyncPath())
+ cmd := "docker run --cap-add=all -d --privileged --network host --rm"
cmd += syncPath
- cmd += c.getVolumes()
- cmd += " --name " + c.name + " hs-test/vpp"
+ cmd += c.getVolumesAsCliOption()
+ cmd += c.getEnvVarsAsCliOption()
+ cmd += " --name " + c.name + " " + c.image
fmt.Println(cmd)
err := exechelper.Run(cmd)
if err != nil {
- return fmt.Errorf("create volume failed: %s", err)
+ return fmt.Errorf("container run failed: %s", err)
}
return nil
}
-func (c *Container) addVolume(name string, containerPath string) {
- c.volumes = append(c.volumes, &Volume{name, containerPath})
+func (c *Container) addVolume(hostDir string, containerDir string) {
+ var volume Volume
+ volume.hostDir = hostDir
+ volume.containerDir = containerDir
+ c.volumes[hostDir] = volume
}
-func (c *Container) getVolumes() string {
- dockerOption := ""
+func (c *Container) getVolumeByHostDir(hostDir string) Volume {
+ return c.volumes[hostDir]
+}
+
+func (c *Container) getVolumesAsCliOption() string {
+ cliOption := ""
if len(c.volumes) > 0 {
for _, volume := range c.volumes {
- dockerOption += fmt.Sprintf(" -v %s:%s", volume.name, volume.path)
+ cliOption += fmt.Sprintf(" -v %s:%s", volume.hostDir, volume.containerDir)
}
}
- return dockerOption
+ return cliOption
+}
+
+func (c *Container) getWorkDirAsCliOption() string {
+ if len(c.workDir) == 0 {
+ return ""
+ }
+ return fmt.Sprintf(" --workdir=\"%s\"", c.workDir)
+}
+
+func (c *Container) addEnvVar(envVar interface{}) {
+ envVarMap := envVar.(ContainerConfig)
+ name := envVarMap["name"].(string)
+ value := envVarMap["value"].(string)
+ c.envVars[name] = value
+}
+
+func (c *Container) getEnvVarsAsCliOption() string {
+ cliOption := ""
+ if len(c.envVars) == 0 {
+ return cliOption
+ }
+
+ for name, value := range c.envVars {
+ cliOption += fmt.Sprintf(" -e %s=%s", name, value)
+ }
+ return cliOption
+}
+
+func (c *Container) getSyncPath() string {
+ return fmt.Sprintf("/tmp/%s/sync", c.name)
+}
+
+func (c *Container) exec(command string) (string, error) {
+ cliCommand := "docker exec -d " + c.name + " " + command
+ byteOutput, err := exechelper.CombinedOutput(cliCommand)
+ return string(byteOutput), err
+}
+
+func (c *Container) execAction(args string) (string, error) {
+ syncFile := c.getSyncPath() + "/rc"
+ os.Remove(syncFile)
+
+ workDir := c.getWorkDirAsCliOption()
+ cmd := fmt.Sprintf("docker exec -d %s %s hs-test %s",
+ workDir,
+ c.name,
+ args)
+ err := exechelper.Run(cmd)
+ if err != nil {
+ return "", err
+ }
+ res, err := waitForSyncFile(syncFile)
+ if err != nil {
+ return "", fmt.Errorf("failed to read sync file while executing 'hs-test %s': %v", args, err)
+ }
+ o := res.StdOutput + res.ErrOutput
+ if res.Code != 0 {
+ return o, fmt.Errorf("cmd resulted in non-zero value %d: %s", res.Code, res.Desc)
+ }
+ return o, err
}
func (c *Container) stop() error {