summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/create.go81
-rw-r--r--libpod/options.go132
-rw-r--r--pkg/spec/createconfig.go8
-rw-r--r--pkg/spec/parse.go6
-rw-r--r--test/e2e/pod_infra_container_test.go24
-rw-r--r--test/e2e/pod_pod_namespaces.go89
-rw-r--r--test/e2e/run_test.go8
7 files changed, 170 insertions, 178 deletions
diff --git a/cmd/podman/create.go b/cmd/podman/create.go
index 7a3b26c85..bc010d047 100644
--- a/cmd/podman/create.go
+++ b/cmd/podman/create.go
@@ -16,7 +16,7 @@ import (
ann "github.com/containers/libpod/pkg/annotations"
"github.com/containers/libpod/pkg/apparmor"
"github.com/containers/libpod/pkg/inspect"
- "github.com/containers/libpod/pkg/namespaces"
+ ns "github.com/containers/libpod/pkg/namespaces"
"github.com/containers/libpod/pkg/rootless"
cc "github.com/containers/libpod/pkg/spec"
"github.com/containers/libpod/pkg/util"
@@ -357,6 +357,33 @@ func configureEntrypoint(c *cli.Context, data *inspect.ImageData) []string {
return entrypoint
}
+func configurePod(c *cli.Context, runtime *libpod.Runtime, namespaces map[string]string) (map[string]string, error) {
+ pod, err := runtime.LookupPod(c.String("pod"))
+ if err != nil {
+ return namespaces, err
+ }
+ podInfraID, err := pod.InfraContainerID()
+ if err != nil {
+ return namespaces, err
+ }
+ if (namespaces["pid"] == cc.Pod) || (!c.IsSet("pid") && pod.SharesPID()) {
+ namespaces["pid"] = fmt.Sprintf("container:%s", podInfraID)
+ }
+ if (namespaces["net"] == cc.Pod) || (!c.IsSet("net") && pod.SharesNet()) {
+ namespaces["net"] = fmt.Sprintf("container:%s", podInfraID)
+ }
+ if (namespaces["user"] == cc.Pod) || (!c.IsSet("user") && pod.SharesUser()) {
+ namespaces["user"] = fmt.Sprintf("container:%s", podInfraID)
+ }
+ if (namespaces["ipc"] == cc.Pod) || (!c.IsSet("ipc") && pod.SharesIPC()) {
+ namespaces["ipc"] = fmt.Sprintf("container:%s", podInfraID)
+ }
+ if (namespaces["uts"] == cc.Pod) || (!c.IsSet("uts") && pod.SharesUTS()) {
+ namespaces["uts"] = fmt.Sprintf("container:%s", podInfraID)
+ }
+ return namespaces, nil
+}
+
// Parses CLI options related to container creation into a config which can be
// parsed into an OCI runtime spec
func parseCreateOpts(ctx context.Context, c *cli.Context, runtime *libpod.Runtime, imageName string, data *inspect.ImageData) (*cc.CreateConfig, error) {
@@ -444,56 +471,48 @@ func parseCreateOpts(ctx context.Context, c *cli.Context, runtime *libpod.Runtim
}
// Kernel Namespaces
- var pod *libpod.Pod
+ // TODO Fix handling of namespace from pod
+ // Instead of integrating here, should be done in libpod
+ // However, that also involves setting up security opts
+ // when the pod's namespace is integrated
+ namespaces := map[string]string{
+ "pid": c.String("pid"),
+ "net": c.String("net"),
+ "ipc": c.String("ipc"),
+ "user": c.String("userns"),
+ "uts": c.String("uts"),
+ }
+
if c.IsSet("pod") {
- pod, err = runtime.LookupPod(c.String("pod"))
+ namespaces, err = configurePod(c, runtime, namespaces)
if err != nil {
return nil, err
}
}
- pidModeStr := c.String("pid")
- if !c.IsSet("pid") && pod != nil && pod.SharesPID() {
- pidModeStr = cc.POD
- }
- pidMode := namespaces.PidMode(pidModeStr)
+ pidMode := ns.PidMode(namespaces["pid"])
if !cc.Valid(string(pidMode), pidMode) {
return nil, errors.Errorf("--pid %q is not valid", c.String("pid"))
}
- usernsModeStr := c.String("userns")
- if !c.IsSet("userns") && pod != nil && pod.SharesUser() {
- usernsModeStr = cc.POD
- }
- usernsMode := namespaces.UsernsMode(usernsModeStr)
+ usernsMode := ns.UsernsMode(namespaces["user"])
if !cc.Valid(string(usernsMode), usernsMode) {
- return nil, errors.Errorf("--userns %q is not valid", c.String("userns"))
+ return nil, errors.Errorf("--userns %q is not valid", namespaces["user"])
}
- utsModeStr := c.String("uts")
- if !c.IsSet("uts") && pod != nil && pod.SharesUTS() {
- utsModeStr = cc.POD
- }
- utsMode := namespaces.UTSMode(utsModeStr)
+ utsMode := ns.UTSMode(namespaces["uts"])
if !cc.Valid(string(utsMode), utsMode) {
- return nil, errors.Errorf("--uts %q is not valid", c.String("uts"))
+ return nil, errors.Errorf("--uts %q is not valid", namespaces["uts"])
}
- ipcModeStr := c.String("ipc")
- if !c.IsSet("ipc") && pod != nil && pod.SharesIPC() {
- ipcModeStr = cc.POD
- }
- ipcMode := namespaces.IpcMode(ipcModeStr)
+ ipcMode := ns.IpcMode(namespaces["ipc"])
if !cc.Valid(string(ipcMode), ipcMode) {
return nil, errors.Errorf("--ipc %q is not valid", ipcMode)
}
- netModeStr := c.String("network")
- if !c.IsSet("network") && pod != nil && pod.SharesNet() {
- netModeStr = cc.POD
- }
+
// Make sure if network is set to container namespace, port binding is not also being asked for
- netMode := namespaces.NetworkMode(netModeStr)
- if netMode.IsContainer() || cc.IsPod(netModeStr) {
+ netMode := ns.NetworkMode(namespaces["net"])
+ if netMode.IsContainer() {
if len(c.StringSlice("publish")) > 0 || c.Bool("publish-all") {
return nil, errors.Errorf("cannot set port bindings on an existing container network namespace")
}
diff --git a/libpod/options.go b/libpod/options.go
index ae6b19055..e6751d68d 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -549,94 +549,6 @@ func WithExitCommand(exitCommand []string) CtrCreateOption {
}
}
-// WithIPCNSFromPod indicates the the container should join the IPC namespace of
-// its pod
-func WithIPCNSFromPod(p *Pod) CtrCreateOption {
- return func(ctr *Container) error {
- if ctr.valid {
- return ErrCtrFinalized
- }
-
- if err := validPodNSOption(p, ctr.config.Pod); err != nil {
- return err
- }
-
- infraContainer, err := p.InfraContainerID()
- if err != nil {
- return err
- }
- ctr.config.IPCNsCtr = infraContainer
-
- return nil
- }
-}
-
-// WithMountNSFromPod indicates the the container should join the Mount namespace of
-// its pod
-func WithMountNSFromPod(p *Pod) CtrCreateOption {
- return func(ctr *Container) error {
- if ctr.valid {
- return ErrCtrFinalized
- }
-
- if err := validPodNSOption(p, ctr.config.Pod); err != nil {
- return err
- }
-
- infraContainer, err := p.InfraContainerID()
- if err != nil {
- return err
- }
- ctr.config.MountNsCtr = infraContainer
-
- return nil
- }
-}
-
-// WithNetNSFromPod indicates the the container should join the network namespace of
-// its pod
-func WithNetNSFromPod(p *Pod) CtrCreateOption {
- return func(ctr *Container) error {
- if ctr.valid {
- return ErrCtrFinalized
- }
-
- if err := validPodNSOption(p, ctr.config.Pod); err != nil {
- return err
- }
-
- infraContainer, err := p.InfraContainerID()
- if err != nil {
- return err
- }
- ctr.config.NetNsCtr = infraContainer
-
- return nil
- }
-}
-
-// WithPIDNSFromPod indicates the the container should join the PID namespace of
-// its pod
-func WithPIDNSFromPod(p *Pod) CtrCreateOption {
- return func(ctr *Container) error {
- if ctr.valid {
- return ErrCtrFinalized
- }
-
- if err := validPodNSOption(p, ctr.config.Pod); err != nil {
- return err
- }
-
- infraContainer, err := p.InfraContainerID()
- if err != nil {
- return err
- }
- ctr.config.PIDNsCtr = infraContainer
-
- return nil
- }
-}
-
// WithUTSNSFromPod indicates the the container should join the UTS namespace of
// its pod
func WithUTSNSFromPod(p *Pod) CtrCreateOption {
@@ -659,50 +571,6 @@ func WithUTSNSFromPod(p *Pod) CtrCreateOption {
}
}
-// WithUserNSFromPod indicates the the container should join the User namespace of
-// its pod
-func WithUserNSFromPod(p *Pod) CtrCreateOption {
- return func(ctr *Container) error {
- if ctr.valid {
- return ErrCtrFinalized
- }
-
- if err := validPodNSOption(p, ctr.config.Pod); err != nil {
- return err
- }
-
- infraContainer, err := p.InfraContainerID()
- if err != nil {
- return err
- }
- ctr.config.UserNsCtr = infraContainer
-
- return nil
- }
-}
-
-// WithCgroupNSFromPod indicates the the container should join the Cgroup namespace of
-// its pod
-func WithCgroupNSFromPod(p *Pod) CtrCreateOption {
- return func(ctr *Container) error {
- if ctr.valid {
- return ErrCtrFinalized
- }
-
- if err := validPodNSOption(p, ctr.config.Pod); err != nil {
- return err
- }
-
- infraContainer, err := p.InfraContainerID()
- if err != nil {
- return err
- }
- ctr.config.CgroupNsCtr = infraContainer
-
- return nil
- }
-}
-
// WithIPCNSFrom indicates the the container should join the IPC namespace of
// the given container.
// If the container has joined a pod, it can only join the namespaces of
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index 0b7ee993d..3cca345b4 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -385,8 +385,6 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime) ([]lib
return nil, errors.Wrapf(err, "container %q not found", c.NetMode.ConnectedContainer())
}
options = append(options, libpod.WithNetNSFrom(connectedCtr))
- } else if IsPod(string(c.NetMode)) {
- options = append(options, libpod.WithNetNSFromPod(pod))
} else if !c.NetMode.IsHost() && !c.NetMode.IsNone() {
isRootless := rootless.IsRootless()
postConfigureNetNS := isRootless || (len(c.IDMappings.UIDMap) > 0 || len(c.IDMappings.GIDMap) > 0) && !c.UsernsMode.IsHost()
@@ -404,9 +402,6 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime) ([]lib
options = append(options, libpod.WithPIDNSFrom(connectedCtr))
}
- if IsPod(string(c.PidMode)) {
- options = append(options, libpod.WithPIDNSFromPod(pod))
- }
if c.IpcMode.IsContainer() {
connectedCtr, err := c.Runtime.LookupContainer(c.IpcMode.Container())
@@ -416,9 +411,6 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime) ([]lib
options = append(options, libpod.WithIPCNSFrom(connectedCtr))
}
- if IsPod(string(c.IpcMode)) {
- options = append(options, libpod.WithIPCNSFromPod(pod))
- }
if IsPod(string(c.UtsMode)) {
options = append(options, libpod.WithUTSNSFromPod(pod))
diff --git a/pkg/spec/parse.go b/pkg/spec/parse.go
index dc4f50a3e..9b2dd1347 100644
--- a/pkg/spec/parse.go
+++ b/pkg/spec/parse.go
@@ -8,9 +8,9 @@ import (
"github.com/docker/go-units"
)
-// POD signifies a kernel namespace is being shared
+// Pod signifies a kernel namespace is being shared
// by a container with the pod it is associated with
-const POD = "pod"
+const Pod = "pod"
// weightDevice is a structure that holds device:weight pair
type weightDevice struct {
@@ -36,7 +36,7 @@ func IsNS(s string) bool {
// IsPod returns if the specified string is pod
func IsPod(s string) bool {
- return s == POD
+ return s == Pod
}
// Valid checks the validity of a linux namespace
diff --git a/test/e2e/pod_infra_container_test.go b/test/e2e/pod_infra_container_test.go
index 2dcce6525..8fb0c388c 100644
--- a/test/e2e/pod_infra_container_test.go
+++ b/test/e2e/pod_infra_container_test.go
@@ -113,6 +113,30 @@ var _ = Describe("Podman pod create", func() {
Expect(session.ExitCode()).To(Not(Equal(0)))
})
+ It("podman pod correctly sets up IPCNS", func() {
+ session := podmanTest.Podman([]string{"pod", "create", "--share", "ipc"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ podID := session.OutputToString()
+
+ session = podmanTest.Podman([]string{"pod", "start", podID})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ podmanTest.RestoreArtifact(fedoraMinimal)
+ session = podmanTest.Podman([]string{"run", "--pod", podID, fedoraMinimal, "/bin/sh", "-c", "'touch /dev/shm/hi'"})
+ session.WaitWithDefaultTimeout()
+ if session.ExitCode() != 0 {
+ Skip("ShmDir not initialized, skipping...")
+ }
+ Expect(session.ExitCode()).To(Equal(0))
+
+ session = podmanTest.Podman([]string{"run", "--pod", podID, fedoraMinimal, "/bin/sh", "-c", "'ls /dev/shm'"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(Equal("hi"))
+ })
+
It("podman pod correctly sets up PIDNS", func() {
session := podmanTest.Podman([]string{"pod", "create", "--share", "pid", "--name", "test-pod"})
session.WaitWithDefaultTimeout()
diff --git a/test/e2e/pod_pod_namespaces.go b/test/e2e/pod_pod_namespaces.go
new file mode 100644
index 000000000..3e84005c3
--- /dev/null
+++ b/test/e2e/pod_pod_namespaces.go
@@ -0,0 +1,89 @@
+package integration
+
+import (
+ "fmt"
+ "os"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+var _ = Describe("Podman pod create", func() {
+ var (
+ tempdir string
+ err error
+ podmanTest PodmanTest
+ )
+
+ BeforeEach(func() {
+ tempdir, err = CreateTempDirInTempDir()
+ if err != nil {
+ os.Exit(1)
+ }
+ podmanTest = PodmanCreate(tempdir)
+ podmanTest.RestoreAllArtifacts()
+ podmanTest.RestoreArtifact(infra)
+ })
+
+ AfterEach(func() {
+ podmanTest.CleanupPod()
+ f := CurrentGinkgoTestDescription()
+ timedResult := fmt.Sprintf("Test: %s completed in %f seconds", f.TestText, f.Duration.Seconds())
+ GinkgoWriter.Write([]byte(timedResult))
+ })
+
+ It("podman pod container share Namespaces", func() {
+ session := podmanTest.Podman([]string{"pod", "create"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ podID := session.OutputToString()
+
+ session = podmanTest.Podman([]string{"pod", "start", podID})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ session = podmanTest.Podman([]string{"run", "--pod", podID, "-d", ALPINE, "top"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ check := podmanTest.Podman([]string{"ps", "-a", "--ns", "--format", "{{.IPC}} {{.UTS}} {{.NET}}"})
+ check.WaitWithDefaultTimeout()
+ Expect(check.ExitCode()).To(Equal(0))
+ outputArray := check.OutputToStringArray()
+ Expect(len(outputArray)).To(Equal(2))
+
+ NAMESPACE1 := outputArray[0]
+ fmt.Println("NAMESPACE1:", NAMESPACE1)
+ NAMESPACE2 := outputArray[1]
+ fmt.Println("NAMESPACE2:", NAMESPACE2)
+ Expect(NAMESPACE1).To(Equal(NAMESPACE2))
+ })
+
+ It("podman pod container dontshare PIDNS", func() {
+ session := podmanTest.Podman([]string{"pod", "create"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ podID := session.OutputToString()
+
+ session = podmanTest.Podman([]string{"pod", "start", podID})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ session = podmanTest.Podman([]string{"run", "--pod", podID, "-d", ALPINE, "top"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ check := podmanTest.Podman([]string{"ps", "-a", "--ns", "--format", "{{.PIDNS}}"})
+ check.WaitWithDefaultTimeout()
+ Expect(check.ExitCode()).To(Equal(0))
+ outputArray := check.OutputToStringArray()
+ Expect(len(outputArray)).To(Equal(2))
+
+ NAMESPACE1 := outputArray[0]
+ fmt.Println("NAMESPACE1:", NAMESPACE1)
+ NAMESPACE2 := outputArray[1]
+ fmt.Println("NAMESPACE2:", NAMESPACE2)
+ Expect(NAMESPACE1).To(Not(Equal(NAMESPACE2)))
+ })
+
+})
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 3ea639a11..3d487db66 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -235,10 +235,10 @@ var _ = Describe("Podman run", func() {
})
It("podman run with cidfile", func() {
- session := podmanTest.Podman([]string{"run", "--cidfile", "/tmp/cidfile", ALPINE, "ls"})
+ session := podmanTest.Podman([]string{"run", "--cidfile", tempdir + "cidfile", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- err := os.Remove("/tmp/cidfile")
+ err := os.Remove(tempdir + "cidfile")
Expect(err).To(BeNil())
})
@@ -317,7 +317,7 @@ var _ = Describe("Podman run", func() {
It("podman test hooks", func() {
hcheck := "/run/hookscheck"
- hooksDir := "/tmp/hooks"
+ hooksDir := tempdir + "/hooks"
os.Mkdir(hooksDir, 0755)
fileutils.CopyFile("hooks/hooks.json", hooksDir)
os.Setenv("HOOK_OPTION", fmt.Sprintf("--hooks-dir-path=%s", hooksDir))
@@ -347,7 +347,7 @@ var _ = Describe("Podman run", func() {
err = ioutil.WriteFile(secretsFile, []byte(secretsString), 0755)
Expect(err).To(BeNil())
- targetDir := "/tmp/symlink/target"
+ targetDir := tempdir + "/symlink/target"
err = os.MkdirAll(targetDir, 0755)
Expect(err).To(BeNil())
keyFile := filepath.Join(targetDir, "key.pem")