diff --git a/libpod/container_internal.go b/libpod/container_internal.go index d28eb8c622..487246e7c0 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -18,7 +18,6 @@ import ( "github.com/containers/buildah/pkg/overlay" butil "github.com/containers/buildah/util" "github.com/containers/common/libnetwork/etchosts" - "github.com/containers/common/libnetwork/resolvconf" "github.com/containers/common/pkg/cgroups" "github.com/containers/common/pkg/chown" "github.com/containers/common/pkg/config" @@ -961,51 +960,34 @@ func (c *Container) checkDependenciesRunning() ([]string, error) { } func (c *Container) completeNetworkSetup() error { - var nameservers []string netDisabled, err := c.NetworkDisabled() if err != nil { return err } - if !c.config.PostConfigureNetNS || netDisabled { + if netDisabled { + // with net=none we still want to set up /etc/hosts + return c.addHosts() + } + if c.config.NetNsCtr != "" { return nil } - if err := c.syncContainer(); err != nil { - return err - } - if err := c.runtime.setupNetNS(c); err != nil { - return err - } - if err := c.save(); err != nil { - return err - } - state := c.state - // collect any dns servers that the network backend tells us to use - for _, status := range c.getNetworkStatus() { - for _, server := range status.DNSServerIPs { - nameservers = append(nameservers, server.String()) - } - } - nameservers = c.addSlirp4netnsDNS(nameservers) - - // check if we have a bindmount for /etc/hosts - if hostsBindMount, ok := state.BindMounts[config.DefaultHostsFile]; ok { - entries, err := c.getHostsEntries() - if err != nil { + if c.config.PostConfigureNetNS { + if err := c.syncContainer(); err != nil { return err } - // add new container ips to the hosts file - if err := etchosts.Add(hostsBindMount, entries); err != nil { + if err := c.runtime.setupNetNS(c); err != nil { + return err + } + if err := c.save(); err != nil { return err } } - - // check if we have a bindmount for resolv.conf - resolvBindMount := state.BindMounts[resolvconf.DefaultResolvConf] - if len(nameservers) < 1 || resolvBindMount == "" || len(c.config.NetNsCtr) > 0 { - return nil + // add /etc/hosts entries + if err := c.addHosts(); err != nil { + return err } - // write and return - return resolvconf.Add(resolvBindMount, nameservers) + + return c.addResolvConf() } // Initialize a container, creating it in the runtime diff --git a/libpod/container_internal_common.go b/libpod/container_internal_common.go index 401a3986fc..198cad1f8c 100644 --- a/libpod/container_internal_common.go +++ b/libpod/container_internal_common.go @@ -1819,17 +1819,17 @@ func (c *Container) makeBindMounts() error { // will recreate. Only do this if we aren't sharing them with // another container. if c.config.NetNsCtr == "" { - if resolvePath, ok := c.state.BindMounts["/etc/resolv.conf"]; ok { + if resolvePath, ok := c.state.BindMounts[resolvconf.DefaultResolvConf]; ok { if err := os.Remove(resolvePath); err != nil && !os.IsNotExist(err) { return fmt.Errorf("container %s: %w", c.ID(), err) } - delete(c.state.BindMounts, "/etc/resolv.conf") + delete(c.state.BindMounts, resolvconf.DefaultResolvConf) } - if hostsPath, ok := c.state.BindMounts["/etc/hosts"]; ok { + if hostsPath, ok := c.state.BindMounts[config.DefaultHostsFile]; ok { if err := os.Remove(hostsPath); err != nil && !os.IsNotExist(err) { return fmt.Errorf("container %s: %w", c.ID(), err) } - delete(c.state.BindMounts, "/etc/hosts") + delete(c.state.BindMounts, config.DefaultHostsFile) } } @@ -1851,9 +1851,9 @@ func (c *Container) makeBindMounts() error { // The other container may not have a resolv.conf or /etc/hosts // If it doesn't, don't copy them - resolvPath, exists := bindMounts["/etc/resolv.conf"] + resolvPath, exists := bindMounts[resolvconf.DefaultResolvConf] if !c.config.UseImageResolvConf && exists { - err := c.mountIntoRootDirs("/etc/resolv.conf", resolvPath) + err := c.mountIntoRootDirs(resolvconf.DefaultResolvConf, resolvPath) if err != nil { return fmt.Errorf("assigning mounts to container %s: %w", c.ID(), err) @@ -1896,31 +1896,31 @@ func (c *Container) makeBindMounts() error { } } else { if !c.config.UseImageResolvConf { - if err := c.generateResolvConf(); err != nil { + if err := c.createResolvConf(); err != nil { return fmt.Errorf("creating resolv.conf for container %s: %w", c.ID(), err) } } if !c.config.UseImageHosts { - if err := c.createHosts(); err != nil { + if err := c.createHostsFile(); err != nil { return fmt.Errorf("creating hosts file for container %s: %w", c.ID(), err) } } } - if c.state.BindMounts["/etc/hosts"] != "" { - if err := c.relabel(c.state.BindMounts["/etc/hosts"], c.config.MountLabel, true); err != nil { + if c.state.BindMounts[config.DefaultHostsFile] != "" { + if err := c.relabel(c.state.BindMounts[config.DefaultHostsFile], c.config.MountLabel, true); err != nil { return err } } - if c.state.BindMounts["/etc/resolv.conf"] != "" { - if err := c.relabel(c.state.BindMounts["/etc/resolv.conf"], c.config.MountLabel, true); err != nil { + if c.state.BindMounts[resolvconf.DefaultResolvConf] != "" { + if err := c.relabel(c.state.BindMounts[resolvconf.DefaultResolvConf], c.config.MountLabel, true); err != nil { return err } } - } else if !c.config.UseImageHosts && c.state.BindMounts["/etc/hosts"] == "" { - if err := c.createHosts(); err != nil { + } else if !c.config.UseImageHosts && c.state.BindMounts[config.DefaultHostsFile] == "" { + if err := c.createHostsFile(); err != nil { return fmt.Errorf("creating hosts file for container %s: %w", c.ID(), err) } } @@ -2028,8 +2028,25 @@ rootless=%d return c.makePlatformBindMounts() } -// generateResolvConf generates a containers resolv.conf -func (c *Container) generateResolvConf() error { +// createResolvConf create the resolv.conf file and bind mount it +func (c *Container) createResolvConf() error { + destPath := filepath.Join(c.state.RunDir, "resolv.conf") + f, err := os.Create(destPath) + if err != nil { + return err + } + f.Close() + return c.bindMountRootFile(destPath, resolvconf.DefaultResolvConf) +} + +// addResolvConf add resolv.conf entries +func (c *Container) addResolvConf() error { + destPath, ok := c.state.BindMounts[resolvconf.DefaultResolvConf] + if !ok { + // no resolv.conf mount, do nothing + return nil + } + var ( networkNameServers []string networkSearchDomains []string @@ -2082,11 +2099,7 @@ func (c *Container) generateResolvConf() error { nameservers = networkNameServers // slirp4netns has a built in DNS forwarder. - // If in userns the network is not setup here, instead we need to do that in - // c.completeNetworkSetup() which knows the actual slirp dns ip only at that point - if !c.config.PostConfigureNetNS { - nameservers = c.addSlirp4netnsDNS(nameservers) - } + nameservers = c.addSlirp4netnsDNS(nameservers) } // Set DNS search domains @@ -2103,8 +2116,6 @@ func (c *Container) generateResolvConf() error { options = append(options, c.runtime.config.Containers.DNSOptions...) options = append(options, c.config.DNSOption...) - destPath := filepath.Join(c.state.RunDir, "resolv.conf") - var namespaces []spec.LinuxNamespace if c.config.Spec.Linux != nil { namespaces = c.config.Spec.Linux.Namespaces @@ -2122,7 +2133,7 @@ func (c *Container) generateResolvConf() error { return fmt.Errorf("building resolv.conf for container %s: %w", c.ID(), err) } - return c.bindMountRootFile(destPath, resolvconf.DefaultResolvConf) + return nil } // Check if a container uses IPv6. @@ -2209,36 +2220,38 @@ func (c *Container) getHostsEntries() (etchosts.HostEntries, error) { return entries, nil } -func (c *Container) createHosts() error { - var containerIPsEntries etchosts.HostEntries - var err error - // if we configure the netns after the container create we should not add - // the hosts here since we have no information about the actual ips - // instead we will add them in c.completeNetworkSetup() - if !c.config.PostConfigureNetNS { - containerIPsEntries, err = c.getHostsEntries() - if err != nil { - return fmt.Errorf("failed to get container ip host entries: %w", err) - } +func (c *Container) createHostsFile() error { + targetFile := filepath.Join(c.state.RunDir, "hosts") + f, err := os.Create(targetFile) + if err != nil { + return err + } + f.Close() + return c.bindMountRootFile(targetFile, config.DefaultHostsFile) +} + +func (c *Container) addHosts() error { + targetFile, ok := c.state.BindMounts[config.DefaultHostsFile] + if !ok { + // no host file nothing to do + return nil + } + containerIPsEntries, err := c.getHostsEntries() + if err != nil { + return fmt.Errorf("failed to get container ip host entries: %w", err) } baseHostFile, err := etchosts.GetBaseHostFile(c.runtime.config.Containers.BaseHostsFile, c.state.Mountpoint) if err != nil { return err } - targetFile := filepath.Join(c.state.RunDir, "hosts") - err = etchosts.New(&etchosts.Params{ + return etchosts.New(&etchosts.Params{ BaseFile: baseHostFile, ExtraHosts: c.config.HostAdd, ContainerIPs: containerIPsEntries, HostContainersInternalIP: etchosts.GetHostContainersInternalIP(c.runtime.config, c.state.NetworkStatus, c.runtime.network), TargetFile: targetFile, }) - if err != nil { - return err - } - - return c.bindMountRootFile(targetFile, config.DefaultHostsFile) } // bindMountRootFile will chown and relabel the source file to make it usable in the container.