summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@gmail.com>2018-01-11 17:41:59 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2018-01-16 14:58:06 +0000
commitd2ec1f76287a55d05ef1378fa31d5474c2bcc0bf (patch)
tree76b28c21de1167a85f04f6a9c596f8c17702b671
parent2ac4192bd3674577c6ab51d6d53a16cb291d0196 (diff)
downloadpodman-d2ec1f76287a55d05ef1378fa31d5474c2bcc0bf.tar.gz
podman-d2ec1f76287a55d05ef1378fa31d5474c2bcc0bf.tar.bz2
podman-d2ec1f76287a55d05ef1378fa31d5474c2bcc0bf.zip
Add API for sharing namespaces
Remove existing code for sharing namespaces and replace with use of this API Signed-off-by: Matthew Heon <matthew.heon@gmail.com> Closes: #220 Approved by: rhatdan
-rw-r--r--cmd/podman/spec.go73
-rw-r--r--libpod/container.go1
-rw-r--r--libpod/options.go190
3 files changed, 193 insertions, 71 deletions
diff --git a/cmd/podman/spec.go b/cmd/podman/spec.go
index 4c17bb62c..35c6ef130 100644
--- a/cmd/podman/spec.go
+++ b/cmd/podman/spec.go
@@ -2,7 +2,6 @@ package main
import (
"encoding/json"
- "fmt"
"io/ioutil"
"strings"
@@ -53,21 +52,10 @@ func blockAccessToKernelFilesystems(config *createConfig, g *generate.Generator)
func addPidNS(config *createConfig, g *generate.Generator) error {
pidMode := config.PidMode
if pidMode.IsHost() {
- return g.RemoveLinuxNamespace(libpod.PIDNamespace)
+ return g.RemoveLinuxNamespace(string(spec.PIDNamespace))
}
if pidMode.IsContainer() {
- ctr, err := config.Runtime.LookupContainer(pidMode.Container())
- if err != nil {
- return errors.Wrapf(err, "container %q not found", pidMode.Container())
- }
- pid, err := ctr.PID()
- if err != nil {
- return errors.Wrapf(err, "Failed to get pid of container %q", pidMode.Container())
- }
- pidNsPath := fmt.Sprintf("/proc/%d/ns/pid", pid)
- if err := g.AddOrReplaceLinuxNamespace(libpod.PIDNamespace, pidNsPath); err != nil {
- return err
- }
+ logrus.Debug("using container pidmode")
}
return nil
}
@@ -76,7 +64,7 @@ func addNetNS(config *createConfig, g *generate.Generator) error {
netMode := config.NetMode
if netMode.IsHost() {
logrus.Debug("Using host netmode")
- return g.RemoveLinuxNamespace(libpod.NetNamespace)
+ return g.RemoveLinuxNamespace(spec.NetworkNamespace)
} else if netMode.IsNone() {
logrus.Debug("Using none netmode")
return nil
@@ -85,18 +73,6 @@ func addNetNS(config *createConfig, g *generate.Generator) error {
return nil
} else if netMode.IsContainer() {
logrus.Debug("Using container netmode")
- ctr, err := config.Runtime.LookupContainer(netMode.ConnectedContainer())
- if err != nil {
- return errors.Wrapf(err, "container %q not found", netMode.ConnectedContainer())
- }
- pid, err := ctr.PID()
- if err != nil {
- return errors.Wrapf(err, "Failed to get pid of container %q", netMode.ConnectedContainer())
- }
- nsPath := fmt.Sprintf("/proc/%d/ns/net", pid)
- if err := g.AddOrReplaceLinuxNamespace(libpod.NetNamespace, nsPath); err != nil {
- return err
- }
} else {
return errors.Errorf("unknown network mode")
}
@@ -106,7 +82,7 @@ func addNetNS(config *createConfig, g *generate.Generator) error {
func addUTSNS(config *createConfig, g *generate.Generator) error {
utsMode := config.UtsMode
if utsMode.IsHost() {
- return g.RemoveLinuxNamespace(libpod.UTSNamespace)
+ return g.RemoveLinuxNamespace(spec.UTSNamespace)
}
return nil
}
@@ -114,21 +90,10 @@ func addUTSNS(config *createConfig, g *generate.Generator) error {
func addIpcNS(config *createConfig, g *generate.Generator) error {
ipcMode := config.IpcMode
if ipcMode.IsHost() {
- return g.RemoveLinuxNamespace(libpod.IPCNamespace)
+ return g.RemoveLinuxNamespace(spec.IPCNamespace)
}
if ipcMode.IsContainer() {
- ctr, err := config.Runtime.LookupContainer(ipcMode.Container())
- if err != nil {
- return errors.Wrapf(err, "container %q not found", ipcMode.Container())
- }
- pid, err := ctr.PID()
- if err != nil {
- return errors.Wrapf(err, "Failed to get pid of container %q", ipcMode.Container())
- }
- nsPath := fmt.Sprintf("/proc/%d/ns/ipc", pid)
- if err := g.AddOrReplaceLinuxNamespace(libpod.IPCNamespace, nsPath); err != nil {
- return err
- }
+ logrus.Debug("Using container ipcmode")
}
return nil
@@ -580,9 +545,33 @@ func (c *createConfig) GetContainerCreateOptions() ([]libpod.CtrCreateOption, er
options = append(options, libpod.WithName(c.Name))
}
// TODO parse ports into libpod format and include
- if !c.NetMode.IsHost() {
+ if !c.NetMode.IsHost() && !c.NetMode.IsContainer() {
options = append(options, libpod.WithNetNS([]ocicni.PortMapping{}))
+ } else if c.NetMode.IsContainer() {
+ connectedCtr, err := c.Runtime.LookupContainer(c.NetMode.ConnectedContainer())
+ if err != nil {
+ return nil, errors.Wrapf(err, "container %q not found", c.NetMode.ConnectedContainer())
+ }
+
+ options = append(options, libpod.WithNetNSFrom(connectedCtr))
}
+ if c.PidMode.IsContainer() {
+ connectedCtr, err := c.Runtime.LookupContainer(c.PidMode.Container())
+ if err != nil {
+ return nil, errors.Wrapf(err, "container %q not found", c.PidMode.Container())
+ }
+
+ options = append(options, libpod.WithPIDNSFrom(connectedCtr))
+ }
+ if c.IpcMode.IsContainer() {
+ connectedCtr, err := c.Runtime.LookupContainer(c.IpcMode.Container())
+ if err != nil {
+ return nil, errors.Wrapf(err, "container %q not found", c.IpcMode.Container())
+ }
+
+ options = append(options, libpod.WithIPCNSFrom(connectedCtr))
+ }
+
options = append(options, libpod.WithStopSignal(c.StopSignal))
options = append(options, libpod.WithStopTimeout(c.StopTimeout))
return options, nil
diff --git a/libpod/container.go b/libpod/container.go
index 7003396ac..cd8cb4a6e 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -133,7 +133,6 @@ type Container struct {
// TODO enable pod support
// TODO Add readonly support
// TODO add SHM size support
-// TODO add shared namespace support
// containerRuntimeInfo contains the current state of the container
// It is stored on disk in a tmpfs and recreated on reboot
diff --git a/libpod/options.go b/libpod/options.go
index 8a9cf94b6..a62a13053 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1,7 +1,6 @@
package libpod
import (
- "fmt"
"path/filepath"
"regexp"
"syscall"
@@ -13,27 +12,9 @@ import (
)
var (
- ctrNotImplemented = func(c *Container) error {
- return fmt.Errorf("NOT IMPLEMENTED")
- }
nameRegex = regexp.MustCompile("[a-zA-Z0-9_-]+")
)
-const (
- // IPCNamespace represents the IPC namespace
- IPCNamespace = "ipc"
- // MountNamespace represents the mount namespace
- MountNamespace = "mount"
- // NetNamespace represents the network namespace
- NetNamespace = "network"
- // PIDNamespace represents the PID namespace
- PIDNamespace = "pid"
- // UserNamespace represents the user namespace
- UserNamespace = "user"
- // UTSNamespace represents the UTS namespace
- UTSNamespace = "uts"
-)
-
// Runtime Creation Options
// WithStorageConfig uses the given configuration to set up container storage
@@ -341,15 +322,6 @@ func WithStdin() CtrCreateOption {
}
}
-// WithSharedNamespaces sets a container to share namespaces with another
-// container. If the from container belongs to a pod, the new container will
-// be added to the pod.
-// By default no namespaces are shared. To share a namespace, add the Namespace
-// string constant to the map as a key
-func WithSharedNamespaces(from *Container, namespaces map[string]string) CtrCreateOption {
- return ctrNotImplemented
-}
-
// WithPod adds the container to a pod
func (r *Runtime) WithPod(pod *Pod) CtrCreateOption {
return func(ctr *Container) error {
@@ -434,6 +406,164 @@ func WithStopTimeout(timeout uint) CtrCreateOption {
}
}
+// WithIPCNSFrom indicates the the container should join the IPC namespace of
+// the given container
+func WithIPCNSFrom(nsCtr *Container) CtrCreateOption {
+ return func(ctr *Container) error {
+ if ctr.valid {
+ return ErrCtrFinalized
+ }
+
+ if !nsCtr.valid {
+ return ErrCtrRemoved
+ }
+
+ if nsCtr.ID() == ctr.ID() {
+ return errors.Wrapf(ErrInvalidArg, "must specify another container")
+ }
+
+ ctr.config.IPCNsCtr = nsCtr.ID()
+
+ return nil
+ }
+}
+
+// WithMountNSFrom indicates the the container should join the mount namespace
+// of the given container
+func WithMountNSFrom(nsCtr *Container) CtrCreateOption {
+ return func(ctr *Container) error {
+ if ctr.valid {
+ return ErrCtrFinalized
+ }
+
+ if !nsCtr.valid {
+ return ErrCtrRemoved
+ }
+
+ if nsCtr.ID() == ctr.ID() {
+ return errors.Wrapf(ErrInvalidArg, "must specify another container")
+ }
+
+ ctr.config.MountNsCtr = nsCtr.ID()
+
+ return nil
+ }
+}
+
+// WithNetNSFrom indicates the the container should join the network namespace
+// of the given container
+func WithNetNSFrom(nsCtr *Container) CtrCreateOption {
+ return func(ctr *Container) error {
+ if ctr.valid {
+ return ErrCtrFinalized
+ }
+
+ if !nsCtr.valid {
+ return ErrCtrRemoved
+ }
+
+ if nsCtr.ID() == ctr.ID() {
+ return errors.Wrapf(ErrInvalidArg, "must specify another container")
+ }
+
+ if ctr.config.CreateNetNS {
+ return errors.Wrapf(ErrInvalidArg, "cannot join another container's net ns as we are making a new net ns")
+ }
+
+ ctr.config.NetNsCtr = nsCtr.ID()
+
+ return nil
+ }
+}
+
+// WithPIDNSFrom indicates the the container should join the PID namespace of
+// the given container
+func WithPIDNSFrom(nsCtr *Container) CtrCreateOption {
+ return func(ctr *Container) error {
+ if ctr.valid {
+ return ErrCtrFinalized
+ }
+
+ if !nsCtr.valid {
+ return ErrCtrRemoved
+ }
+
+ if nsCtr.ID() == ctr.ID() {
+ return errors.Wrapf(ErrInvalidArg, "must specify another container")
+ }
+
+ ctr.config.PIDNsCtr = nsCtr.ID()
+
+ return nil
+ }
+}
+
+// WithUserNSFrom indicates the the container should join the user namespace of
+// the given container
+func WithUserNSFrom(nsCtr *Container) CtrCreateOption {
+ return func(ctr *Container) error {
+ if ctr.valid {
+ return ErrCtrFinalized
+ }
+
+ if !nsCtr.valid {
+ return ErrCtrRemoved
+ }
+
+ if nsCtr.ID() == ctr.ID() {
+ return errors.Wrapf(ErrInvalidArg, "must specify another container")
+ }
+
+ ctr.config.UserNsCtr = nsCtr.ID()
+
+ return nil
+ }
+}
+
+// WithUTSNSFrom indicates the the container should join the UTS namespace of
+// the given container
+func WithUTSNSFrom(nsCtr *Container) CtrCreateOption {
+ return func(ctr *Container) error {
+ if ctr.valid {
+ return ErrCtrFinalized
+ }
+
+ if !nsCtr.valid {
+ return ErrCtrRemoved
+ }
+
+ if nsCtr.ID() == ctr.ID() {
+ return errors.Wrapf(ErrInvalidArg, "must specify another container")
+ }
+
+ ctr.config.UTSNsCtr = nsCtr.ID()
+
+ return nil
+ }
+}
+
+// WithCgroupNSFrom indicates the the container should join the CGroup namespace
+// of the given container
+func WithCgroupNSFrom(nsCtr *Container) CtrCreateOption {
+ return func(ctr *Container) error {
+ if ctr.valid {
+ return ErrCtrFinalized
+ }
+
+ if !nsCtr.valid {
+ return ErrCtrRemoved
+ }
+
+ if nsCtr.ID() == ctr.ID() {
+ return errors.Wrapf(ErrInvalidArg, "must specify another container")
+ }
+
+ ctr.config.CgroupNsCtr = nsCtr.ID()
+
+ return nil
+ }
+}
+
// WithNetNS indicates that the container should be given a new network
// namespace with a minimal configuration
// An optional array of port mappings can be provided
@@ -443,6 +573,10 @@ func WithNetNS(portMappings []ocicni.PortMapping) CtrCreateOption {
return ErrCtrFinalized
}
+ if ctr.config.NetNsCtr != "" {
+ return errors.Wrapf(ErrInvalidArg, "container is already set to join another container's net ns, cannot create a new net ns")
+ }
+
ctr.config.CreateNetNS = true
copy(ctr.config.PortMappings, portMappings)