diff options
author | Valentin Rothberg <rothberg@redhat.com> | 2020-05-29 10:35:22 +0200 |
---|---|---|
committer | Valentin Rothberg <rothberg@redhat.com> | 2020-06-11 11:01:13 +0200 |
commit | cf89bb671184e453c4ba5f27e26d02216d8fc491 (patch) | |
tree | ed707e35dcae297a60e97150bc407d9a5ea5ff80 | |
parent | 7d71d24440afbf30689c53c2c69205072e4b029f (diff) | |
download | podman-cf89bb671184e453c4ba5f27e26d02216d8fc491.tar.gz podman-cf89bb671184e453c4ba5f27e26d02216d8fc491.tar.bz2 podman-cf89bb671184e453c4ba5f27e26d02216d8fc491.zip |
container-{create,run}: add `--pod-id-file`
Allow containers to join an existing pod via the `--pod-id-file` which
is already supported by a number of `podman-pod` subcommands. Also add
tests to make sure it's working and to prevent future regressions.
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
-rw-r--r-- | cmd/podman/common/create.go | 5 | ||||
-rw-r--r-- | cmd/podman/common/create_opts.go | 1 | ||||
-rw-r--r-- | cmd/podman/common/specgen.go | 11 | ||||
-rw-r--r-- | cmd/podman/common/util.go | 25 | ||||
-rw-r--r-- | cmd/podman/pods/common.go | 23 | ||||
-rw-r--r-- | cmd/podman/pods/rm.go | 3 | ||||
-rw-r--r-- | cmd/podman/pods/start.go | 3 | ||||
-rw-r--r-- | cmd/podman/pods/stop.go | 3 | ||||
-rw-r--r-- | completions/bash/podman | 3 | ||||
-rw-r--r-- | docs/source/markdown/podman-create.1.md | 4 | ||||
-rw-r--r-- | docs/source/markdown/podman-run.1.md | 4 | ||||
-rw-r--r-- | test/e2e/create_test.go | 37 |
12 files changed, 95 insertions, 27 deletions
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go index 86cd51643..e79c5c20b 100644 --- a/cmd/podman/common/create.go +++ b/cmd/podman/common/create.go @@ -338,6 +338,11 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet { "pod", "", "Run container in an existing pod", ) + createFlags.StringVar( + &cf.PodIDFile, + "pod-id-file", "", + "Read the pod ID from the file", + ) createFlags.BoolVar( &cf.Privileged, "privileged", false, diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go index 4cba5daf7..98dc6744c 100644 --- a/cmd/podman/common/create_opts.go +++ b/cmd/podman/common/create_opts.go @@ -68,6 +68,7 @@ type ContainerCLIOpts struct { PID string PIDsLimit int64 Pod string + PodIDFile string Privileged bool PublishAll bool Pull string diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go index 2286e67de..fee9d8c7b 100644 --- a/cmd/podman/common/specgen.go +++ b/cmd/podman/common/specgen.go @@ -254,6 +254,17 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string s.PublishExposedPorts = c.PublishAll s.Pod = c.Pod + if len(c.PodIDFile) > 0 { + if len(s.Pod) > 0 { + return errors.New("Cannot specify both --pod and --pod-id-file") + } + podID, err := ReadPodIDFile(c.PodIDFile) + if err != nil { + return err + } + s.Pod = podID + } + expose, err := createExpose(c.Expose) if err != nil { return err diff --git a/cmd/podman/common/util.go b/cmd/podman/common/util.go index a3626b4e4..422e241af 100644 --- a/cmd/podman/common/util.go +++ b/cmd/podman/common/util.go @@ -1,6 +1,7 @@ package common import ( + "io/ioutil" "net" "strconv" "strings" @@ -10,6 +11,30 @@ import ( "github.com/sirupsen/logrus" ) +// ReadPodIDFile reads the specified file and returns its content (i.e., first +// line). +func ReadPodIDFile(path string) (string, error) { + content, err := ioutil.ReadFile(path) + if err != nil { + return "", errors.Wrap(err, "error reading pod ID file") + } + return strings.Split(string(content), "\n")[0], nil +} + +// ReadPodIDFiles reads the specified files and returns their content (i.e., +// first line). +func ReadPodIDFiles(files []string) ([]string, error) { + ids := []string{} + for _, file := range files { + id, err := ReadPodIDFile(file) + if err != nil { + return nil, err + } + ids = append(ids, id) + } + return ids, nil +} + // createExpose parses user-provided exposed port definitions and converts them // into SpecGen format. // TODO: The SpecGen format should really handle ranges more sanely - we could diff --git a/cmd/podman/pods/common.go b/cmd/podman/pods/common.go deleted file mode 100644 index 1c4195095..000000000 --- a/cmd/podman/pods/common.go +++ /dev/null @@ -1,23 +0,0 @@ -package pods - -import ( - "io/ioutil" - "strings" - - "github.com/pkg/errors" -) - -// readPodIDFiles reads the specified files and returns their content (i.e., -// first line). -func readPodIDFiles(files []string) ([]string, error) { - ids := []string{} - for _, podFile := range files { - content, err := ioutil.ReadFile(podFile) - if err != nil { - return nil, errors.Wrap(err, "error reading pod ID file") - } - id := strings.Split(string(content), "\n")[0] - ids = append(ids, id) - } - return ids, nil -} diff --git a/cmd/podman/pods/rm.go b/cmd/podman/pods/rm.go index ecceda32a..8de0bce9e 100644 --- a/cmd/podman/pods/rm.go +++ b/cmd/podman/pods/rm.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/containers/libpod/cmd/podman/common" "github.com/containers/libpod/cmd/podman/parse" "github.com/containers/libpod/cmd/podman/registry" "github.com/containers/libpod/cmd/podman/utils" @@ -61,7 +62,7 @@ func rm(cmd *cobra.Command, args []string) error { errs utils.OutputErrors ) - ids, err := readPodIDFiles(rmOptions.PodIDFiles) + ids, err := common.ReadPodIDFiles(rmOptions.PodIDFiles) if err != nil { return err } diff --git a/cmd/podman/pods/start.go b/cmd/podman/pods/start.go index 86517190d..97020b360 100644 --- a/cmd/podman/pods/start.go +++ b/cmd/podman/pods/start.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/containers/libpod/cmd/podman/common" "github.com/containers/libpod/cmd/podman/parse" "github.com/containers/libpod/cmd/podman/registry" "github.com/containers/libpod/cmd/podman/utils" @@ -61,7 +62,7 @@ func start(cmd *cobra.Command, args []string) error { errs utils.OutputErrors ) - ids, err := readPodIDFiles(startOptions.PodIDFiles) + ids, err := common.ReadPodIDFiles(startOptions.PodIDFiles) if err != nil { return err } diff --git a/cmd/podman/pods/stop.go b/cmd/podman/pods/stop.go index fd66488f9..628e8a536 100644 --- a/cmd/podman/pods/stop.go +++ b/cmd/podman/pods/stop.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/containers/libpod/cmd/podman/common" "github.com/containers/libpod/cmd/podman/parse" "github.com/containers/libpod/cmd/podman/registry" "github.com/containers/libpod/cmd/podman/utils" @@ -68,7 +69,7 @@ func stop(cmd *cobra.Command, args []string) error { stopOptions.Timeout = int(stopOptions.TimeoutCLI) } - ids, err := readPodIDFiles(stopOptions.PodIDFiles) + ids, err := common.ReadPodIDFiles(stopOptions.PodIDFiles) if err != nil { return err } diff --git a/completions/bash/podman b/completions/bash/podman index 6528281ba..0e4b60b14 100644 --- a/completions/bash/podman +++ b/completions/bash/podman @@ -2102,6 +2102,7 @@ _podman_container_run() { --pid --pids-limit --pod + --pod-id-file --publish -p --pull --runtime @@ -2206,7 +2207,7 @@ _podman_container_run() { __podman_complete_capabilities return ;; - --cidfile|--env-file|--init-path|--label-file) + --cidfile|--env-file|--init-path|--label-file|--pod-id-file) _filedir return ;; diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md index a69ef04d1..81c83369a 100644 --- a/docs/source/markdown/podman-create.1.md +++ b/docs/source/markdown/podman-create.1.md @@ -593,6 +593,10 @@ Tune the container's pids limit. Set `0` to have unlimited pids for the containe Run container in an existing pod. If you want Podman to make the pod for you, preference the pod name with `new:`. To make a pod with more granular options, use the `podman pod create` command before creating a container. +**--pod-id-file**=*path* + +Run container in an existing pod and read the pod's ID from the specified file. If a container is run with a pod, and the pod has an infra-container, the infra-container will be started before the container is. + **--privileged**=*true|false* Give extended privileges to this container. The default is *false*. diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md index 02db8b205..4f43e4c19 100644 --- a/docs/source/markdown/podman-run.1.md +++ b/docs/source/markdown/podman-run.1.md @@ -605,6 +605,10 @@ Run container in an existing pod. If you want Podman to make the pod for you, pr To make a pod with more granular options, use the **podman pod create** command before creating a container. If a container is run with a pod, and the pod has an infra-container, the infra-container will be started before the container is. +**--pod-id-file**=*path* + +Run container in an existing pod and read the pod's ID from the specified file. If a container is run with a pod, and the pod has an infra-container, the infra-container will be started before the container is. + **--privileged**=**true**|**false** Give extended privileges to this container. The default is **false**. diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go index f40472a7c..b9a1ff83d 100644 --- a/test/e2e/create_test.go +++ b/test/e2e/create_test.go @@ -2,6 +2,7 @@ package integration import ( "fmt" + "io/ioutil" "os" "path/filepath" @@ -221,6 +222,42 @@ var _ = Describe("Podman create", func() { Expect(match).To(BeTrue()) }) + It("podman create --pod-id-file", func() { + // First, make sure that --pod and --pod-id-file yield an error + // if used together. + session := podmanTest.Podman([]string{"create", "--pod", "foo", "--pod-id-file", "bar", ALPINE, "ls"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(125)) + + tmpDir, err := ioutil.TempDir("", "") + Expect(err).To(BeNil()) + defer os.RemoveAll(tmpDir) + + podName := "rudoplh" + ctrName := "prancer" + podIDFile := tmpDir + "pod-id-file" + + // Now, let's create a pod with --pod-id-file. + session = podmanTest.Podman([]string{"pod", "create", "--pod-id-file", podIDFile, "--name", podName}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"pod", "inspect", podName}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.IsJSONOutputValid()).To(BeTrue()) + podData := session.InspectPodToJSON() + + // Finally we can create a container with --pod-id-file and do + // some checks to make sure it's working as expected. + session = podmanTest.Podman([]string{"create", "--pod-id-file", podIDFile, "--name", ctrName, ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + ctrJSON := podmanTest.InspectContainer(ctrName) + Expect(podData.ID).To(Equal(ctrJSON[0].Pod)) // Make sure the container's pod matches the pod's ID + }) + It("podman run entrypoint and cmd test", func() { name := "test101" create := podmanTest.Podman([]string{"create", "--name", name, redis}) |