aboutsummaryrefslogtreecommitdiff
path: root/libpod/container_internal.go
diff options
context:
space:
mode:
authorDaniel J Walsh <dwalsh@redhat.com>2018-11-08 06:12:14 -0500
committerDaniel J Walsh <dwalsh@redhat.com>2018-11-13 06:33:10 -0500
commitbb6c1cf8d1667c7c8e4d539ea2250a18fa89a58a (patch)
treeccc10929a4dd891fbe1a02f0ed290b3aae5eb5c7 /libpod/container_internal.go
parent900436e70f1a79dff6449fbd9997c4da715ddcc6 (diff)
downloadpodman-bb6c1cf8d1667c7c8e4d539ea2250a18fa89a58a.tar.gz
podman-bb6c1cf8d1667c7c8e4d539ea2250a18fa89a58a.tar.bz2
podman-bb6c1cf8d1667c7c8e4d539ea2250a18fa89a58a.zip
libpod should know if the network is disabled
/etc/resolv.conf and /etc/hosts should not be created and mounted when the network is disabled. We should not be calling the network setup and cleanup functions when it is disabled either. In doing this patch, I found that all of the bind mounts were particular to Linux along with the generate functions, so I moved them to container_internal_linux.go Since we are checking if we are using a network namespace, we need to check after the network namespaces has been created in the spec. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
Diffstat (limited to 'libpod/container_internal.go')
-rw-r--r--libpod/container_internal.go228
1 files changed, 1 insertions, 227 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index d2f48d661..051e0aeb7 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -19,14 +19,11 @@ import (
"github.com/containers/libpod/pkg/hooks"
"github.com/containers/libpod/pkg/hooks/exec"
"github.com/containers/libpod/pkg/lookup"
- "github.com/containers/libpod/pkg/resolvconf"
"github.com/containers/libpod/pkg/rootless"
- "github.com/containers/libpod/pkg/secrets"
"github.com/containers/storage"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/chrootarchive"
"github.com/containers/storage/pkg/mount"
- "github.com/opencontainers/runc/libcontainer/user"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
"github.com/opencontainers/selinux/go-selinux/label"
@@ -583,7 +580,7 @@ func (c *Container) checkDependenciesRunningLocked(depCtrs map[string]*Container
}
func (c *Container) completeNetworkSetup() error {
- if !c.config.PostConfigureNetNS {
+ if !c.config.PostConfigureNetNS || c.NetworkDisabled() {
return nil
}
if err := c.syncContainer(); err != nil {
@@ -597,10 +594,6 @@ func (c *Container) completeNetworkSetup() error {
// Initialize a container, creating it in the runtime
func (c *Container) init(ctx context.Context) error {
- if err := c.makeBindMounts(); err != nil {
- return err
- }
-
// Generate the OCI spec
spec, err := c.generateSpec(ctx)
if err != nil {
@@ -987,86 +980,6 @@ func (c *Container) postDeleteHooks(ctx context.Context) (err error) {
return nil
}
-// Make standard bind mounts to include in the container
-func (c *Container) makeBindMounts() error {
- if err := os.Chown(c.state.RunDir, c.RootUID(), c.RootGID()); err != nil {
- return errors.Wrapf(err, "cannot chown run directory %s", c.state.RunDir)
- }
-
- if c.state.BindMounts == nil {
- c.state.BindMounts = make(map[string]string)
- }
-
- // SHM is always added when we mount the container
- c.state.BindMounts["/dev/shm"] = c.config.ShmDir
-
- // Make /etc/resolv.conf
- if _, ok := c.state.BindMounts["/etc/resolv.conf"]; ok {
- // If it already exists, delete so we can recreate
- delete(c.state.BindMounts, "/etc/resolv.conf")
- }
- newResolv, err := c.generateResolvConf()
- if err != nil {
- return errors.Wrapf(err, "error creating resolv.conf for container %s", c.ID())
- }
- c.state.BindMounts["/etc/resolv.conf"] = newResolv
-
- newPasswd, err := c.generatePasswd()
- if err != nil {
- return errors.Wrapf(err, "error creating temporary passwd file for container %s", c.ID())
- }
- if newPasswd != "" {
- // Make /etc/passwd
- if _, ok := c.state.BindMounts["/etc/passwd"]; ok {
- // If it already exists, delete so we can recreate
- delete(c.state.BindMounts, "/etc/passwd")
- }
- logrus.Debugf("adding entry to /etc/passwd for non existent default user")
- c.state.BindMounts["/etc/passwd"] = newPasswd
- }
- // Make /etc/hosts
- if _, ok := c.state.BindMounts["/etc/hosts"]; ok {
- // If it already exists, delete so we can recreate
- delete(c.state.BindMounts, "/etc/hosts")
- }
- newHosts, err := c.generateHosts()
- if err != nil {
- return errors.Wrapf(err, "error creating hosts file for container %s", c.ID())
- }
- c.state.BindMounts["/etc/hosts"] = newHosts
-
- // Make /etc/hostname
- // This should never change, so no need to recreate if it exists
- if _, ok := c.state.BindMounts["/etc/hostname"]; !ok {
- hostnamePath, err := c.writeStringToRundir("hostname", c.Hostname())
- if err != nil {
- return errors.Wrapf(err, "error creating hostname file for container %s", c.ID())
- }
- c.state.BindMounts["/etc/hostname"] = hostnamePath
- }
-
- // Make .containerenv
- // Empty file, so no need to recreate if it exists
- if _, ok := c.state.BindMounts["/run/.containerenv"]; !ok {
- // Empty string for now, but we may consider populating this later
- containerenvPath, err := c.writeStringToRundir(".containerenv", "")
- if err != nil {
- return errors.Wrapf(err, "error creating containerenv file for container %s", c.ID())
- }
- c.state.BindMounts["/run/.containerenv"] = containerenvPath
- }
-
- // Add Secret Mounts
- secretMounts := secrets.SecretMountsWithUIDGID(c.config.MountLabel, c.state.RunDir, c.runtime.config.DefaultMountsFile, c.state.DestinationRunDir, c.RootUID(), c.RootGID())
- for _, mount := range secretMounts {
- if _, ok := c.state.BindMounts[mount.Destination]; !ok {
- c.state.BindMounts[mount.Destination] = mount.Source
- }
- }
-
- return nil
-}
-
// writeStringToRundir copies the provided file to the runtimedir
func (c *Container) writeStringToRundir(destFile, output string) (string, error) {
destFileName := filepath.Join(c.state.RunDir, destFile)
@@ -1095,145 +1008,6 @@ func (c *Container) writeStringToRundir(destFile, output string) (string, error)
return filepath.Join(c.state.DestinationRunDir, destFile), nil
}
-// generatePasswd generates a container specific passwd file,
-// iff g.config.User is a number
-func (c *Container) generatePasswd() (string, error) {
- var (
- groupspec string
- group *user.Group
- gid int
- )
- if c.config.User == "" {
- return "", nil
- }
- spec := strings.SplitN(c.config.User, ":", 2)
- userspec := spec[0]
- if len(spec) > 1 {
- groupspec = spec[1]
- }
- // If a non numeric User, then don't generate passwd
- uid, err := strconv.ParseUint(userspec, 10, 32)
- if err != nil {
- return "", nil
- }
- // Lookup the user to see if it exists in the container image
- _, err = lookup.GetUser(c.state.Mountpoint, userspec)
- if err != nil && err != user.ErrNoPasswdEntries {
- return "", err
- }
- if err == nil {
- return "", nil
- }
- if groupspec != "" {
- if !c.state.Mounted {
- return "", errors.Wrapf(ErrCtrStateInvalid, "container %s must be mounted in order to translate group field for passwd record", c.ID())
- }
- group, err = lookup.GetGroup(c.state.Mountpoint, groupspec)
- if err != nil {
- if err == user.ErrNoGroupEntries {
- return "", errors.Wrapf(err, "unable to get gid %s from group file", groupspec)
- }
- return "", err
- }
- gid = group.Gid
- }
- originPasswdFile := filepath.Join(c.state.Mountpoint, "/etc/passwd")
- orig, err := ioutil.ReadFile(originPasswdFile)
- if err != nil && !os.IsNotExist(err) {
- return "", errors.Wrapf(err, "unable to read passwd file %s", originPasswdFile)
- }
-
- pwd := fmt.Sprintf("%s%d:x:%d:%d:container user:%s:/bin/sh\n", orig, uid, uid, gid, c.WorkingDir())
- passwdFile, err := c.writeStringToRundir("passwd", pwd)
- if err != nil {
- return "", errors.Wrapf(err, "failed to create temporary passwd file")
- }
- if os.Chmod(passwdFile, 0644); err != nil {
- return "", err
- }
- return passwdFile, nil
-}
-
-// generateResolvConf generates a containers resolv.conf
-func (c *Container) generateResolvConf() (string, error) {
- // Determine the endpoint for resolv.conf in case it is a symlink
- resolvPath, err := filepath.EvalSymlinks("/etc/resolv.conf")
- if err != nil {
- return "", err
- }
-
- contents, err := ioutil.ReadFile(resolvPath)
- if err != nil {
- return "", errors.Wrapf(err, "unable to read %s", resolvPath)
- }
-
- // Process the file to remove localhost nameservers
- // TODO: set ipv6 enable bool more sanely
- resolv, err := resolvconf.FilterResolvDNS(contents, true)
- if err != nil {
- return "", errors.Wrapf(err, "error parsing host resolv.conf")
- }
-
- // Make a new resolv.conf
- nameservers := resolvconf.GetNameservers(resolv.Content)
- if len(c.config.DNSServer) > 0 {
- // We store DNS servers as net.IP, so need to convert to string
- nameservers = []string{}
- for _, server := range c.config.DNSServer {
- nameservers = append(nameservers, server.String())
- }
- }
-
- search := resolvconf.GetSearchDomains(resolv.Content)
- if len(c.config.DNSSearch) > 0 {
- search = c.config.DNSSearch
- }
-
- options := resolvconf.GetOptions(resolv.Content)
- if len(c.config.DNSOption) > 0 {
- options = c.config.DNSOption
- }
-
- destPath := filepath.Join(c.state.RunDir, "resolv.conf")
-
- if err := os.Remove(destPath); err != nil && !os.IsNotExist(err) {
- return "", errors.Wrapf(err, "error removing resolv.conf for container %s", c.ID())
- }
-
- // Build resolv.conf
- if _, err = resolvconf.Build(destPath, nameservers, search, options); err != nil {
- return "", errors.Wrapf(err, "error building resolv.conf for container %s")
- }
-
- // Relabel resolv.conf for the container
- if err := label.Relabel(destPath, c.config.MountLabel, false); err != nil {
- return "", err
- }
-
- return filepath.Join(c.state.DestinationRunDir, "resolv.conf"), nil
-}
-
-// generateHosts creates a containers hosts file
-func (c *Container) generateHosts() (string, error) {
- orig, err := ioutil.ReadFile("/etc/hosts")
- if err != nil {
- return "", errors.Wrapf(err, "unable to read /etc/hosts")
- }
- hosts := string(orig)
- if len(c.config.HostAdd) > 0 {
- for _, host := range c.config.HostAdd {
- // the host format has already been verified at this point
- fields := strings.SplitN(host, ":", 2)
- hosts += fmt.Sprintf("%s %s\n", fields[1], fields[0])
- }
- }
- if len(c.state.NetworkStatus) > 0 && len(c.state.NetworkStatus[0].IPs) > 0 {
- ipAddress := strings.Split(c.state.NetworkStatus[0].IPs[0].Address.String(), "/")[0]
- hosts += fmt.Sprintf("%s\t%s\n", ipAddress, c.Hostname())
- }
- return c.writeStringToRundir("hosts", hosts)
-}
-
func (c *Container) addLocalVolumes(ctx context.Context, g *generate.Generator) error {
var uid, gid int
mountPoint := c.state.Mountpoint