mirror of
https://github.com/containers/podman.git
synced 2025-07-15 03:02:52 +08:00
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
This commit is contained in:
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
Reference in New Issue
Block a user