From 4f825f2e079c1cf3ec6c9fd2c5378ce2db18d4f0 Mon Sep 17 00:00:00 2001 From: baude Date: Fri, 21 Sep 2018 09:43:54 -0500 Subject: Add container runlabel command Execute the command as described by a container image. The value of the label is processed into a command by: 1. Ensuring the first argument of the command is podman. 2. Substituting any variables with those defined by the environment or otherwise. If no label exists in the container image, nothing is done. podman container runlabel LABEL IMAGE extra_args Signed-off-by: baude --- cmd/podman/shared/funcs.go | 57 ++++++++++++++++++++++++++ cmd/podman/shared/funcs_test.go | 89 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 cmd/podman/shared/funcs.go create mode 100644 cmd/podman/shared/funcs_test.go (limited to 'cmd/podman/shared') diff --git a/cmd/podman/shared/funcs.go b/cmd/podman/shared/funcs.go new file mode 100644 index 000000000..5c401634c --- /dev/null +++ b/cmd/podman/shared/funcs.go @@ -0,0 +1,57 @@ +package shared + +import ( + "fmt" + "os" + "strings" +) + +// GenerateCommand takes a label (string) and converts it to an executable command +func GenerateCommand(command, imageName, name string) []string { + var ( + newCommand []string + ) + if name == "" { + name = imageName + } + cmd := strings.Split(command, " ") + // Replace the first position of cmd with podman whether + // it is docker, /usr/bin/docker, or podman + newCommand = append(newCommand, "podman") + for _, arg := range cmd[1:] { + var newArg string + switch arg { + case "IMAGE": + newArg = imageName + case "IMAGE=IMAGE": + newArg = fmt.Sprintf("IMAGE=%s", imageName) + case "NAME": + newArg = name + case "NAME=NAME": + newArg = fmt.Sprintf("NAME=%s", name) + default: + newArg = arg + } + newCommand = append(newCommand, newArg) + } + return newCommand +} + +// GenerateRunEnvironment merges the current environment variables with optional +// environment variables provided by the user +func GenerateRunEnvironment(name, imageName string, opts map[string]string) []string { + newEnv := os.Environ() + newEnv = append(newEnv, fmt.Sprintf("NAME=%s", name)) + newEnv = append(newEnv, fmt.Sprintf("IMAGE=%s", imageName)) + + if opts["opt1"] != "" { + newEnv = append(newEnv, fmt.Sprintf("OPT1=%s", opts["opt1"])) + } + if opts["opt2"] != "" { + newEnv = append(newEnv, fmt.Sprintf("OPT2=%s", opts["opt2"])) + } + if opts["opt3"] != "" { + newEnv = append(newEnv, fmt.Sprintf("OPT3=%s", opts["opt3"])) + } + return newEnv +} diff --git a/cmd/podman/shared/funcs_test.go b/cmd/podman/shared/funcs_test.go new file mode 100644 index 000000000..3d0ac005f --- /dev/null +++ b/cmd/podman/shared/funcs_test.go @@ -0,0 +1,89 @@ +package shared + +import ( + "strings" + "testing" + + "github.com/containers/libpod/pkg/util" + "github.com/stretchr/testify/assert" +) + +var ( + name = "foo" + imageName = "bar" +) + +func TestGenerateCommand(t *testing.T) { + inputCommand := "docker run -it --name NAME -e NAME=NAME -e IMAGE=IMAGE IMAGE echo install" + correctCommand := "podman run -it --name bar -e NAME=bar -e IMAGE=foo foo echo install" + newCommand := GenerateCommand(inputCommand, "foo", "bar") + assert.Equal(t, correctCommand, strings.Join(newCommand, " ")) +} + +func TestGenerateCommandPath(t *testing.T) { + inputCommand := "/usr/bin/docker run -it --name NAME -e NAME=NAME -e IMAGE=IMAGE IMAGE echo install" + correctCommand := "podman run -it --name bar -e NAME=bar -e IMAGE=foo foo echo install" + newCommand := GenerateCommand(inputCommand, "foo", "bar") + assert.Equal(t, correctCommand, strings.Join(newCommand, " ")) +} + +func TestGenerateCommandNoSetName(t *testing.T) { + inputCommand := "docker run -it --name NAME -e NAME=NAME -e IMAGE=IMAGE IMAGE echo install" + correctCommand := "podman run -it --name foo -e NAME=foo -e IMAGE=foo foo echo install" + newCommand := GenerateCommand(inputCommand, "foo", "") + assert.Equal(t, correctCommand, strings.Join(newCommand, " ")) +} + +func TestGenerateCommandNoName(t *testing.T) { + inputCommand := "docker run -it -e IMAGE=IMAGE IMAGE echo install" + correctCommand := "podman run -it -e IMAGE=foo foo echo install" + newCommand := GenerateCommand(inputCommand, "foo", "") + assert.Equal(t, correctCommand, strings.Join(newCommand, " ")) +} + +func TestGenerateCommandAlreadyPodman(t *testing.T) { + inputCommand := "podman run -it --name NAME -e NAME=NAME -e IMAGE=IMAGE IMAGE echo install" + correctCommand := "podman run -it --name bar -e NAME=bar -e IMAGE=foo foo echo install" + newCommand := GenerateCommand(inputCommand, "foo", "bar") + assert.Equal(t, correctCommand, strings.Join(newCommand, " ")) +} + +func TestGenerateRunEnvironment(t *testing.T) { + opts := make(map[string]string) + opts["opt1"] = "one" + opts["opt2"] = "two" + opts["opt3"] = "three" + envs := GenerateRunEnvironment(name, imageName, opts) + assert.True(t, util.StringInSlice("OPT1=one", envs)) + assert.True(t, util.StringInSlice("OPT2=two", envs)) + assert.True(t, util.StringInSlice("OPT3=three", envs)) +} + +func TestGenerateRunEnvironmentNoOpts(t *testing.T) { + opts := make(map[string]string) + envs := GenerateRunEnvironment(name, imageName, opts) + assert.False(t, util.StringInSlice("OPT1=", envs)) + assert.False(t, util.StringInSlice("OPT2=", envs)) + assert.False(t, util.StringInSlice("OPT3=", envs)) +} + +func TestGenerateRunEnvironmentSingleOpt(t *testing.T) { + opts := make(map[string]string) + opts["opt1"] = "one" + envs := GenerateRunEnvironment(name, imageName, opts) + assert.True(t, util.StringInSlice("OPT1=one", envs)) + assert.False(t, util.StringInSlice("OPT2=", envs)) + assert.False(t, util.StringInSlice("OPT3=", envs)) +} + +func TestGenerateRunEnvironmentName(t *testing.T) { + opts := make(map[string]string) + envs := GenerateRunEnvironment(name, imageName, opts) + assert.True(t, util.StringInSlice("NAME=foo", envs)) +} + +func TestGenerateRunEnvironmentImage(t *testing.T) { + opts := make(map[string]string) + envs := GenerateRunEnvironment(name, imageName, opts) + assert.True(t, util.StringInSlice("IMAGE=bar", envs)) +} -- cgit v1.2.3-54-g00ecf