summaryrefslogtreecommitdiff
path: root/libpod/container_internal.go
diff options
context:
space:
mode:
Diffstat (limited to 'libpod/container_internal.go')
-rw-r--r--libpod/container_internal.go249
1 files changed, 4 insertions, 245 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 22b398709..452be176c 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -8,7 +8,6 @@ import (
"io"
"io/ioutil"
"os"
- "path"
"path/filepath"
"strings"
"syscall"
@@ -17,14 +16,12 @@ import (
"github.com/containers/storage"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/chrootarchive"
- "github.com/containers/storage/pkg/idtools"
"github.com/docker/docker/pkg/mount"
"github.com/docker/docker/pkg/stringid"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
- crioAnnotations "github.com/projectatomic/libpod/pkg/annotations"
"github.com/projectatomic/libpod/pkg/chrootuser"
"github.com/projectatomic/libpod/pkg/hooks"
"github.com/projectatomic/libpod/pkg/hooks/exec"
@@ -33,7 +30,6 @@ import (
"github.com/projectatomic/libpod/pkg/util"
"github.com/sirupsen/logrus"
"github.com/ulule/deepcopier"
- "golang.org/x/sys/unix"
"golang.org/x/text/language"
)
@@ -748,9 +744,8 @@ func (c *Container) mountStorage() (err error) {
if !mounted {
shmOptions := fmt.Sprintf("mode=1777,size=%d", c.config.ShmSize)
- if err := unix.Mount("shm", c.config.ShmDir, "tmpfs", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV,
- label.FormatMountLabel(shmOptions, c.config.MountLabel)); err != nil {
- return errors.Wrapf(err, "failed to mount shm tmpfs %q", c.config.ShmDir)
+ if err := c.mountSHM(shmOptions); err != nil {
+ return err
}
if err := os.Chown(c.config.ShmDir, c.RootUID(), c.RootGID()); err != nil {
return errors.Wrapf(err, "failed to chown %s", c.config.ShmDir)
@@ -786,53 +781,6 @@ func (c *Container) mountStorage() (err error) {
return c.save()
}
-// prepare mounts the container and sets up other required resources like net
-// namespaces
-func (c *Container) prepare() (err error) {
- // Mount storage if not mounted
- if err := c.mountStorage(); err != nil {
- return err
- }
-
- // Set up network namespace if not already set up
- if c.config.CreateNetNS && c.state.NetNS == nil && !c.config.PostConfigureNetNS {
- if err := c.runtime.createNetNS(c); err != nil {
- // Tear down storage before exiting to make sure we
- // don't leak mounts
- if err2 := c.cleanupStorage(); err2 != nil {
- logrus.Errorf("Error cleaning up storage for container %s: %v", c.ID(), err2)
- }
- return err
- }
- }
-
- return nil
-}
-
-// cleanupNetwork unmounts and cleans up the container's network
-func (c *Container) cleanupNetwork() error {
- if c.state.NetNS == nil {
- logrus.Debugf("Network is already cleaned up, skipping...")
- return nil
- }
-
- // Stop the container's network namespace (if it has one)
- if err := c.runtime.teardownNetNS(c); err != nil {
- logrus.Errorf("unable to cleanup network for container %s: %q", c.ID(), err)
- }
-
- c.state.NetNS = nil
- c.state.IPs = nil
- c.state.Interfaces = nil
- c.state.Routes = nil
-
- if c.valid {
- return c.save()
- }
-
- return nil
-}
-
// cleanupStorage unmounts and cleans up the container's root filesystem
func (c *Container) cleanupStorage() error {
if !c.state.Mounted {
@@ -842,10 +790,8 @@ func (c *Container) cleanupStorage() error {
}
for _, mount := range c.config.Mounts {
- if err := unix.Unmount(mount, unix.MNT_DETACH); err != nil {
- if err != syscall.EINVAL {
- logrus.Warnf("container %s failed to unmount %s : %v", c.ID(), mount, err)
- }
+ if err := c.unmountSHM(mount); err != nil {
+ return err
}
}
if c.config.Rootfs != "" {
@@ -1178,193 +1124,6 @@ func (c *Container) generateHosts() (string, error) {
return c.writeStringToRundir("hosts", hosts)
}
-// Generate spec for a container
-// Accepts a map of the container's dependencies
-func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
- g := generate.NewFromSpec(c.config.Spec)
-
- // If network namespace was requested, add it now
- if c.config.CreateNetNS {
- if c.config.PostConfigureNetNS {
- g.AddOrReplaceLinuxNamespace(spec.NetworkNamespace, "")
- } else {
- g.AddOrReplaceLinuxNamespace(spec.NetworkNamespace, c.state.NetNS.Path())
- }
- }
-
- // Remove the default /dev/shm mount to ensure we overwrite it
- g.RemoveMount("/dev/shm")
-
- // Add bind mounts to container
- for dstPath, srcPath := range c.state.BindMounts {
- newMount := spec.Mount{
- Type: "bind",
- Source: srcPath,
- Destination: dstPath,
- Options: []string{"rw", "bind"},
- }
- if !MountExists(g.Mounts(), dstPath) {
- g.AddMount(newMount)
- } else {
- logrus.Warnf("User mount overriding libpod mount at %q", dstPath)
- }
- }
-
- var err error
- if !rootless.IsRootless() {
- if c.state.ExtensionStageHooks, err = c.setupOCIHooks(ctx, g.Config); err != nil {
- return nil, errors.Wrapf(err, "error setting up OCI Hooks")
- }
- }
-
- // Bind builtin image volumes
- if c.config.Rootfs == "" && c.config.ImageVolumes {
- if err := c.addImageVolumes(ctx, &g); err != nil {
- return nil, errors.Wrapf(err, "error mounting image volumes")
- }
- }
-
- if c.config.User != "" {
- if !c.state.Mounted {
- return nil, errors.Wrapf(ErrCtrStateInvalid, "container %s must be mounted in order to translate User field", c.ID())
- }
- uid, gid, err := chrootuser.GetUser(c.state.Mountpoint, c.config.User)
- if err != nil {
- return nil, err
- }
- // User and Group must go together
- g.SetProcessUID(uid)
- g.SetProcessGID(gid)
- }
-
- // Add addition groups if c.config.GroupAdd is not empty
- if len(c.config.Groups) > 0 {
- if !c.state.Mounted {
- return nil, errors.Wrapf(ErrCtrStateInvalid, "container %s must be mounted in order to add additional groups", c.ID())
- }
- for _, group := range c.config.Groups {
- gid, err := chrootuser.GetGroup(c.state.Mountpoint, group)
- if err != nil {
- return nil, err
- }
- g.AddProcessAdditionalGid(gid)
- }
- }
-
- // Look up and add groups the user belongs to, if a group wasn't directly specified
- if !rootless.IsRootless() && !strings.Contains(c.config.User, ":") {
- groups, err := chrootuser.GetAdditionalGroupsForUser(c.state.Mountpoint, uint64(g.Config.Process.User.UID))
- if err != nil && errors.Cause(err) != chrootuser.ErrNoSuchUser {
- return nil, err
- }
- for _, gid := range groups {
- g.AddProcessAdditionalGid(gid)
- }
- }
-
- // Add shared namespaces from other containers
- if c.config.IPCNsCtr != "" {
- if err := c.addNamespaceContainer(&g, IPCNS, c.config.IPCNsCtr, spec.IPCNamespace); err != nil {
- return nil, err
- }
- }
- if c.config.MountNsCtr != "" {
- if err := c.addNamespaceContainer(&g, MountNS, c.config.MountNsCtr, spec.MountNamespace); err != nil {
- return nil, err
- }
- }
- if c.config.NetNsCtr != "" {
- if err := c.addNamespaceContainer(&g, NetNS, c.config.NetNsCtr, spec.NetworkNamespace); err != nil {
- return nil, err
- }
- }
- if c.config.PIDNsCtr != "" {
- if err := c.addNamespaceContainer(&g, PIDNS, c.config.PIDNsCtr, string(spec.PIDNamespace)); err != nil {
- return nil, err
- }
- }
- if c.config.UserNsCtr != "" {
- if err := c.addNamespaceContainer(&g, UserNS, c.config.UserNsCtr, spec.UserNamespace); err != nil {
- return nil, err
- }
- }
- if c.config.UTSNsCtr != "" {
- if err := c.addNamespaceContainer(&g, UTSNS, c.config.UTSNsCtr, spec.UTSNamespace); err != nil {
- return nil, err
- }
- }
- if c.config.CgroupNsCtr != "" {
- if err := c.addNamespaceContainer(&g, CgroupNS, c.config.CgroupNsCtr, spec.CgroupNamespace); err != nil {
- return nil, err
- }
- }
-
- if c.config.Rootfs == "" {
- if err := idtools.MkdirAllAs(c.state.RealMountpoint, 0700, c.RootUID(), c.RootGID()); err != nil {
- return nil, err
- }
- }
-
- g.SetRootPath(c.state.RealMountpoint)
- g.AddAnnotation(crioAnnotations.Created, c.config.CreatedTime.Format(time.RFC3339Nano))
- g.AddAnnotation("org.opencontainers.image.stopSignal", fmt.Sprintf("%d", c.config.StopSignal))
-
- g.SetHostname(c.Hostname())
- g.AddProcessEnv("HOSTNAME", g.Config.Hostname)
-
- // Only add container environment variable if not already present
- foundContainerEnv := false
- for _, env := range g.Config.Process.Env {
- if strings.HasPrefix(env, "container=") {
- foundContainerEnv = true
- break
- }
- }
- if !foundContainerEnv {
- g.AddProcessEnv("container", "libpod")
- }
-
- if rootless.IsRootless() {
- g.SetLinuxCgroupsPath("")
- } else if c.runtime.config.CgroupManager == SystemdCgroupsManager {
- // When runc is set to use Systemd as a cgroup manager, it
- // expects cgroups to be passed as follows:
- // slice:prefix:name
- systemdCgroups := fmt.Sprintf("%s:libpod:%s", path.Base(c.config.CgroupParent), c.ID())
- logrus.Debugf("Setting CGroups for container %s to %s", c.ID(), systemdCgroups)
- g.SetLinuxCgroupsPath(systemdCgroups)
- } else {
- cgroupPath, err := c.CGroupPath()
- if err != nil {
- return nil, err
- }
- logrus.Debugf("Setting CGroup path for container %s to %s", c.ID(), cgroupPath)
- g.SetLinuxCgroupsPath(cgroupPath)
- }
-
- return g.Config, nil
-}
-
-// Add an existing container's namespace to the spec
-func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr string, specNS string) error {
- nsCtr, err := c.runtime.state.Container(ctr)
- if err != nil {
- return errors.Wrapf(err, "error retrieving dependency %s of container %s from state", ctr, c.ID())
- }
-
- // TODO need unlocked version of this for use in pods
- nsPath, err := nsCtr.NamespacePath(ns)
- if err != nil {
- return err
- }
-
- if err := g.AddOrReplaceLinuxNamespace(specNS, nsPath); err != nil {
- return err
- }
-
- return nil
-}
-
func (c *Container) addImageVolumes(ctx context.Context, g *generate.Generator) error {
mountPoint := c.state.Mountpoint
if !c.state.Mounted {