mirror of
https://github.com/containers/podman.git
synced 2025-06-24 03:08:13 +08:00
Merge pull request #18961 from Luap99/hosts-resolv
libpod: write /etc/{hosts,resolv.conf} once
This commit is contained in:
@ -18,7 +18,6 @@ import (
|
|||||||
"github.com/containers/buildah/pkg/overlay"
|
"github.com/containers/buildah/pkg/overlay"
|
||||||
butil "github.com/containers/buildah/util"
|
butil "github.com/containers/buildah/util"
|
||||||
"github.com/containers/common/libnetwork/etchosts"
|
"github.com/containers/common/libnetwork/etchosts"
|
||||||
"github.com/containers/common/libnetwork/resolvconf"
|
|
||||||
"github.com/containers/common/pkg/cgroups"
|
"github.com/containers/common/pkg/cgroups"
|
||||||
"github.com/containers/common/pkg/chown"
|
"github.com/containers/common/pkg/chown"
|
||||||
"github.com/containers/common/pkg/config"
|
"github.com/containers/common/pkg/config"
|
||||||
@ -961,14 +960,18 @@ func (c *Container) checkDependenciesRunning() ([]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) completeNetworkSetup() error {
|
func (c *Container) completeNetworkSetup() error {
|
||||||
var nameservers []string
|
|
||||||
netDisabled, err := c.NetworkDisabled()
|
netDisabled, err := c.NetworkDisabled()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
if c.config.PostConfigureNetNS {
|
||||||
if err := c.syncContainer(); err != nil {
|
if err := c.syncContainer(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -978,34 +981,13 @@ func (c *Container) completeNetworkSetup() error {
|
|||||||
if err := c.save(); err != nil {
|
if err := c.save(); err != nil {
|
||||||
return err
|
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())
|
|
||||||
}
|
}
|
||||||
}
|
// add /etc/hosts entries
|
||||||
nameservers = c.addSlirp4netnsDNS(nameservers)
|
if err := c.addHosts(); err != nil {
|
||||||
|
|
||||||
// check if we have a bindmount for /etc/hosts
|
|
||||||
if hostsBindMount, ok := state.BindMounts[config.DefaultHostsFile]; ok {
|
|
||||||
entries, err := c.getHostsEntries()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// add new container ips to the hosts file
|
|
||||||
if err := etchosts.Add(hostsBindMount, entries); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if we have a bindmount for resolv.conf
|
return c.addResolvConf()
|
||||||
resolvBindMount := state.BindMounts[resolvconf.DefaultResolvConf]
|
|
||||||
if len(nameservers) < 1 || resolvBindMount == "" || len(c.config.NetNsCtr) > 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// write and return
|
|
||||||
return resolvconf.Add(resolvBindMount, nameservers)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize a container, creating it in the runtime
|
// Initialize a container, creating it in the runtime
|
||||||
|
@ -1819,17 +1819,17 @@ func (c *Container) makeBindMounts() error {
|
|||||||
// will recreate. Only do this if we aren't sharing them with
|
// will recreate. Only do this if we aren't sharing them with
|
||||||
// another container.
|
// another container.
|
||||||
if c.config.NetNsCtr == "" {
|
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) {
|
if err := os.Remove(resolvePath); err != nil && !os.IsNotExist(err) {
|
||||||
return fmt.Errorf("container %s: %w", c.ID(), 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) {
|
if err := os.Remove(hostsPath); err != nil && !os.IsNotExist(err) {
|
||||||
return fmt.Errorf("container %s: %w", c.ID(), 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
|
// The other container may not have a resolv.conf or /etc/hosts
|
||||||
// If it doesn't, don't copy them
|
// If it doesn't, don't copy them
|
||||||
resolvPath, exists := bindMounts["/etc/resolv.conf"]
|
resolvPath, exists := bindMounts[resolvconf.DefaultResolvConf]
|
||||||
if !c.config.UseImageResolvConf && exists {
|
if !c.config.UseImageResolvConf && exists {
|
||||||
err := c.mountIntoRootDirs("/etc/resolv.conf", resolvPath)
|
err := c.mountIntoRootDirs(resolvconf.DefaultResolvConf, resolvPath)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("assigning mounts to container %s: %w", c.ID(), err)
|
return fmt.Errorf("assigning mounts to container %s: %w", c.ID(), err)
|
||||||
@ -1896,31 +1896,31 @@ func (c *Container) makeBindMounts() error {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !c.config.UseImageResolvConf {
|
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)
|
return fmt.Errorf("creating resolv.conf for container %s: %w", c.ID(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !c.config.UseImageHosts {
|
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)
|
return fmt.Errorf("creating hosts file for container %s: %w", c.ID(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.state.BindMounts["/etc/hosts"] != "" {
|
if c.state.BindMounts[config.DefaultHostsFile] != "" {
|
||||||
if err := c.relabel(c.state.BindMounts["/etc/hosts"], c.config.MountLabel, true); err != nil {
|
if err := c.relabel(c.state.BindMounts[config.DefaultHostsFile], c.config.MountLabel, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.state.BindMounts["/etc/resolv.conf"] != "" {
|
if c.state.BindMounts[resolvconf.DefaultResolvConf] != "" {
|
||||||
if err := c.relabel(c.state.BindMounts["/etc/resolv.conf"], c.config.MountLabel, true); err != nil {
|
if err := c.relabel(c.state.BindMounts[resolvconf.DefaultResolvConf], c.config.MountLabel, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if !c.config.UseImageHosts && c.state.BindMounts["/etc/hosts"] == "" {
|
} else if !c.config.UseImageHosts && c.state.BindMounts[config.DefaultHostsFile] == "" {
|
||||||
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)
|
return fmt.Errorf("creating hosts file for container %s: %w", c.ID(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2028,8 +2028,25 @@ rootless=%d
|
|||||||
return c.makePlatformBindMounts()
|
return c.makePlatformBindMounts()
|
||||||
}
|
}
|
||||||
|
|
||||||
// generateResolvConf generates a containers resolv.conf
|
// createResolvConf create the resolv.conf file and bind mount it
|
||||||
func (c *Container) generateResolvConf() error {
|
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 (
|
var (
|
||||||
networkNameServers []string
|
networkNameServers []string
|
||||||
networkSearchDomains []string
|
networkSearchDomains []string
|
||||||
@ -2082,12 +2099,8 @@ func (c *Container) generateResolvConf() error {
|
|||||||
nameservers = networkNameServers
|
nameservers = networkNameServers
|
||||||
|
|
||||||
// slirp4netns has a built in DNS forwarder.
|
// 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
|
// Set DNS search domains
|
||||||
search := networkSearchDomains
|
search := networkSearchDomains
|
||||||
@ -2103,8 +2116,6 @@ func (c *Container) generateResolvConf() error {
|
|||||||
options = append(options, c.runtime.config.Containers.DNSOptions...)
|
options = append(options, c.runtime.config.Containers.DNSOptions...)
|
||||||
options = append(options, c.config.DNSOption...)
|
options = append(options, c.config.DNSOption...)
|
||||||
|
|
||||||
destPath := filepath.Join(c.state.RunDir, "resolv.conf")
|
|
||||||
|
|
||||||
var namespaces []spec.LinuxNamespace
|
var namespaces []spec.LinuxNamespace
|
||||||
if c.config.Spec.Linux != nil {
|
if c.config.Spec.Linux != nil {
|
||||||
namespaces = c.config.Spec.Linux.Namespaces
|
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 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.
|
// Check if a container uses IPv6.
|
||||||
@ -2209,36 +2220,38 @@ func (c *Container) getHostsEntries() (etchosts.HostEntries, error) {
|
|||||||
return entries, nil
|
return entries, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) createHosts() error {
|
func (c *Container) createHostsFile() error {
|
||||||
var containerIPsEntries etchosts.HostEntries
|
targetFile := filepath.Join(c.state.RunDir, "hosts")
|
||||||
var err error
|
f, err := os.Create(targetFile)
|
||||||
// if we configure the netns after the container create we should not add
|
if err != nil {
|
||||||
// the hosts here since we have no information about the actual ips
|
return err
|
||||||
// instead we will add them in c.completeNetworkSetup()
|
}
|
||||||
if !c.config.PostConfigureNetNS {
|
f.Close()
|
||||||
containerIPsEntries, err = c.getHostsEntries()
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get container ip host entries: %w", err)
|
return fmt.Errorf("failed to get container ip host entries: %w", err)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
baseHostFile, err := etchosts.GetBaseHostFile(c.runtime.config.Containers.BaseHostsFile, c.state.Mountpoint)
|
baseHostFile, err := etchosts.GetBaseHostFile(c.runtime.config.Containers.BaseHostsFile, c.state.Mountpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
targetFile := filepath.Join(c.state.RunDir, "hosts")
|
return etchosts.New(&etchosts.Params{
|
||||||
err = etchosts.New(&etchosts.Params{
|
|
||||||
BaseFile: baseHostFile,
|
BaseFile: baseHostFile,
|
||||||
ExtraHosts: c.config.HostAdd,
|
ExtraHosts: c.config.HostAdd,
|
||||||
ContainerIPs: containerIPsEntries,
|
ContainerIPs: containerIPsEntries,
|
||||||
HostContainersInternalIP: etchosts.GetHostContainersInternalIP(c.runtime.config, c.state.NetworkStatus, c.runtime.network),
|
HostContainersInternalIP: etchosts.GetHostContainersInternalIP(c.runtime.config, c.state.NetworkStatus, c.runtime.network),
|
||||||
TargetFile: targetFile,
|
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.
|
// bindMountRootFile will chown and relabel the source file to make it usable in the container.
|
||||||
|
Reference in New Issue
Block a user