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 (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -53,21 +52,10 @@ func blockAccessToKernelFilesystems(config *createConfig, g *generate.Generator)
|
|||||||
func addPidNS(config *createConfig, g *generate.Generator) error {
|
func addPidNS(config *createConfig, g *generate.Generator) error {
|
||||||
pidMode := config.PidMode
|
pidMode := config.PidMode
|
||||||
if pidMode.IsHost() {
|
if pidMode.IsHost() {
|
||||||
return g.RemoveLinuxNamespace(libpod.PIDNamespace)
|
return g.RemoveLinuxNamespace(string(spec.PIDNamespace))
|
||||||
}
|
}
|
||||||
if pidMode.IsContainer() {
|
if pidMode.IsContainer() {
|
||||||
ctr, err := config.Runtime.LookupContainer(pidMode.Container())
|
logrus.Debug("using container pidmode")
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -76,7 +64,7 @@ func addNetNS(config *createConfig, g *generate.Generator) error {
|
|||||||
netMode := config.NetMode
|
netMode := config.NetMode
|
||||||
if netMode.IsHost() {
|
if netMode.IsHost() {
|
||||||
logrus.Debug("Using host netmode")
|
logrus.Debug("Using host netmode")
|
||||||
return g.RemoveLinuxNamespace(libpod.NetNamespace)
|
return g.RemoveLinuxNamespace(spec.NetworkNamespace)
|
||||||
} else if netMode.IsNone() {
|
} else if netMode.IsNone() {
|
||||||
logrus.Debug("Using none netmode")
|
logrus.Debug("Using none netmode")
|
||||||
return nil
|
return nil
|
||||||
@ -85,18 +73,6 @@ func addNetNS(config *createConfig, g *generate.Generator) error {
|
|||||||
return nil
|
return nil
|
||||||
} else if netMode.IsContainer() {
|
} else if netMode.IsContainer() {
|
||||||
logrus.Debug("Using container netmode")
|
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 {
|
} else {
|
||||||
return errors.Errorf("unknown network mode")
|
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 {
|
func addUTSNS(config *createConfig, g *generate.Generator) error {
|
||||||
utsMode := config.UtsMode
|
utsMode := config.UtsMode
|
||||||
if utsMode.IsHost() {
|
if utsMode.IsHost() {
|
||||||
return g.RemoveLinuxNamespace(libpod.UTSNamespace)
|
return g.RemoveLinuxNamespace(spec.UTSNamespace)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -114,21 +90,10 @@ func addUTSNS(config *createConfig, g *generate.Generator) error {
|
|||||||
func addIpcNS(config *createConfig, g *generate.Generator) error {
|
func addIpcNS(config *createConfig, g *generate.Generator) error {
|
||||||
ipcMode := config.IpcMode
|
ipcMode := config.IpcMode
|
||||||
if ipcMode.IsHost() {
|
if ipcMode.IsHost() {
|
||||||
return g.RemoveLinuxNamespace(libpod.IPCNamespace)
|
return g.RemoveLinuxNamespace(spec.IPCNamespace)
|
||||||
}
|
}
|
||||||
if ipcMode.IsContainer() {
|
if ipcMode.IsContainer() {
|
||||||
ctr, err := config.Runtime.LookupContainer(ipcMode.Container())
|
logrus.Debug("Using container ipcmode")
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -580,9 +545,33 @@ func (c *createConfig) GetContainerCreateOptions() ([]libpod.CtrCreateOption, er
|
|||||||
options = append(options, libpod.WithName(c.Name))
|
options = append(options, libpod.WithName(c.Name))
|
||||||
}
|
}
|
||||||
// TODO parse ports into libpod format and include
|
// 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{}))
|
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.WithStopSignal(c.StopSignal))
|
||||||
options = append(options, libpod.WithStopTimeout(c.StopTimeout))
|
options = append(options, libpod.WithStopTimeout(c.StopTimeout))
|
||||||
return options, nil
|
return options, nil
|
||||||
|
@ -133,7 +133,6 @@ type Container struct {
|
|||||||
// TODO enable pod support
|
// TODO enable pod support
|
||||||
// TODO Add readonly support
|
// TODO Add readonly support
|
||||||
// TODO add SHM size support
|
// TODO add SHM size support
|
||||||
// TODO add shared namespace support
|
|
||||||
|
|
||||||
// containerRuntimeInfo contains the current state of the container
|
// containerRuntimeInfo contains the current state of the container
|
||||||
// It is stored on disk in a tmpfs and recreated on reboot
|
// It is stored on disk in a tmpfs and recreated on reboot
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package libpod
|
package libpod
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -13,27 +12,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ctrNotImplemented = func(c *Container) error {
|
|
||||||
return fmt.Errorf("NOT IMPLEMENTED")
|
|
||||||
}
|
|
||||||
nameRegex = regexp.MustCompile("[a-zA-Z0-9_-]+")
|
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
|
// Runtime Creation Options
|
||||||
|
|
||||||
// WithStorageConfig uses the given configuration to set up container storage
|
// 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
|
// WithPod adds the container to a pod
|
||||||
func (r *Runtime) WithPod(pod *Pod) CtrCreateOption {
|
func (r *Runtime) WithPod(pod *Pod) CtrCreateOption {
|
||||||
return func(ctr *Container) error {
|
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
|
// WithNetNS indicates that the container should be given a new network
|
||||||
// namespace with a minimal configuration
|
// namespace with a minimal configuration
|
||||||
// An optional array of port mappings can be provided
|
// An optional array of port mappings can be provided
|
||||||
@ -443,6 +573,10 @@ func WithNetNS(portMappings []ocicni.PortMapping) CtrCreateOption {
|
|||||||
return ErrCtrFinalized
|
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
|
ctr.config.CreateNetNS = true
|
||||||
copy(ctr.config.PortMappings, portMappings)
|
copy(ctr.config.PortMappings, portMappings)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user