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>
This commit is contained in:
parent
7d71d24440
commit
cf89bb6711
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ type ContainerCLIOpts struct {
|
|||
PID string
|
||||
PIDsLimit int64
|
||||
Pod string
|
||||
PodIDFile string
|
||||
Privileged bool
|
||||
PublishAll bool
|
||||
Pull string
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
;;
|
||||
|
|
|
|||
|
|
@ -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*.
|
||||
|
|
|
|||
|
|
@ -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**.
|
||||
|
|
|
|||
|
|
@ -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})
|
||||
|
|
|
|||
Loading…
Reference in New Issue