mirror of https://github.com/containers/podman.git
Add support for joining shared namespaces in libpod
Signed-off-by: Matthew Heon <matthew.heon@gmail.com> Closes: #220 Approved by: rhatdan
This commit is contained in:
parent
333f664da7
commit
fe0e1cd11b
|
@ -63,6 +63,49 @@ const (
|
||||||
// CgroupParent is the default prefix to a cgroup path in libpod
|
// CgroupParent is the default prefix to a cgroup path in libpod
|
||||||
var CgroupParent = "/libpod_parent"
|
var CgroupParent = "/libpod_parent"
|
||||||
|
|
||||||
|
// LinuxNS represents a Linux namespace
|
||||||
|
type LinuxNS int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// InvalidNS is an invalid namespace
|
||||||
|
InvalidNS LinuxNS = iota
|
||||||
|
// IPCNS is the IPC namespace
|
||||||
|
IPCNS LinuxNS = iota
|
||||||
|
// MntNS is the mount namespace
|
||||||
|
MountNS LinuxNS = iota
|
||||||
|
// NetNS is the network namespace
|
||||||
|
NetNS LinuxNS = iota
|
||||||
|
// PIDNS is the PID namespace
|
||||||
|
PIDNS LinuxNS = iota
|
||||||
|
// UserNS is the user namespace
|
||||||
|
UserNS LinuxNS = iota
|
||||||
|
// UTSNS is the UTS namespace
|
||||||
|
UTSNS LinuxNS = iota
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns a string representation of a Linux namespace
|
||||||
|
// It is guaranteed to be the name of the namespace in /proc for valid ns types
|
||||||
|
func (ns LinuxNS) String() string {
|
||||||
|
switch ns {
|
||||||
|
case InvalidNS:
|
||||||
|
return "invalid"
|
||||||
|
case IPCNS:
|
||||||
|
return "ipc"
|
||||||
|
case MountNS:
|
||||||
|
return "mnt"
|
||||||
|
case NetNS:
|
||||||
|
return "net"
|
||||||
|
case PIDNS:
|
||||||
|
return "pid"
|
||||||
|
case UserNS:
|
||||||
|
return "user"
|
||||||
|
case UTSNS:
|
||||||
|
return "uts"
|
||||||
|
default:
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Container is a single OCI container
|
// Container is a single OCI container
|
||||||
type Container struct {
|
type Container struct {
|
||||||
config *ContainerConfig
|
config *ContainerConfig
|
||||||
|
@ -484,6 +527,26 @@ func (c *Container) MountPoint() (string, error) {
|
||||||
return c.state.Mountpoint, nil
|
return c.state.Mountpoint, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NamespacePath returns the path of one of the container's namespaces
|
||||||
|
// If the container is not running, an error will be returned
|
||||||
|
func (c *Container) NamespacePath(ns LinuxNS) (string, error) {
|
||||||
|
c.lock.Lock()
|
||||||
|
defer c.lock.Unlock()
|
||||||
|
if err := c.syncContainer(); err != nil {
|
||||||
|
return "", errors.Wrapf(err, "error updating container %s state", c.ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.state.State != ContainerStateRunning {
|
||||||
|
return "", errors.Wrapf(ErrCtrStopped, "cannot get namespace path unless container %s is running", c.ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
if ns == InvalidNS {
|
||||||
|
return "", errors.Wrapf(ErrInvalidArg, "invalid namespace requested from container %s", c.ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("/proc/%d/ns/%s", c.state.PID, ns.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
// The path to the container's root filesystem - where the OCI spec will be
|
// The path to the container's root filesystem - where the OCI spec will be
|
||||||
// placed, amongst other things
|
// placed, amongst other things
|
||||||
func (c *Container) bundlePath() string {
|
func (c *Container) bundlePath() string {
|
||||||
|
@ -766,6 +829,98 @@ func (c *Container) Init() (err error) {
|
||||||
g.SetProcessGID(gid)
|
g.SetProcessGID(gid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add shared namespaces from other containers
|
||||||
|
if c.config.IPCNsCtr != "" {
|
||||||
|
ipcCtr, err := c.runtime.state.Container(c.config.IPCNsCtr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
nsPath, err := ipcCtr.NamespacePath(IPCNS)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := g.AddOrReplaceLinuxNamespace(spec.IPCNamespace, nsPath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if c.config.MountNsCtr != "" {
|
||||||
|
mountCtr, err := c.runtime.state.Container(c.config.MountNsCtr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
nsPath, err := mountCtr.NamespacePath(MountNS)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := g.AddOrReplaceLinuxNamespace(spec.MountNamespace, nsPath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if c.config.NetNsCtr != "" {
|
||||||
|
netCtr, err := c.runtime.state.Container(c.config.NetNsCtr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
nsPath, err := netCtr.NamespacePath(NetNS)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := g.AddOrReplaceLinuxNamespace(spec.NetworkNamespace, nsPath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if c.config.PIDNsCtr != "" {
|
||||||
|
pidCtr, err := c.runtime.state.Container(c.config.PIDNsCtr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
nsPath, err := pidCtr.NamespacePath(PIDNS)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := g.AddOrReplaceLinuxNamespace(string(spec.PIDNamespace), nsPath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if c.config.UserNsCtr != "" {
|
||||||
|
userCtr, err := c.runtime.state.Container(c.config.UserNsCtr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
nsPath, err := userCtr.NamespacePath(UserNS)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := g.AddOrReplaceLinuxNamespace(spec.UserNamespace, nsPath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if c.config.UTSNsCtr != "" {
|
||||||
|
utsCtr, err := c.runtime.state.Container(c.config.UTSNsCtr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
nsPath, err := utsCtr.NamespacePath(UTSNS)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := g.AddOrReplaceLinuxNamespace(spec.UTSNamespace, nsPath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
c.runningSpec = g.Spec()
|
c.runningSpec = g.Spec()
|
||||||
c.runningSpec.Root.Path = c.state.Mountpoint
|
c.runningSpec.Root.Path = c.state.Mountpoint
|
||||||
c.runningSpec.Annotations[crioAnnotations.Created] = c.config.CreatedTime.Format(time.RFC3339Nano)
|
c.runningSpec.Annotations[crioAnnotations.Created] = c.config.CreatedTime.Format(time.RFC3339Nano)
|
||||||
|
|
Loading…
Reference in New Issue