Modify /etc/resolv.conf when connecting/disconnecting

The `podman network connect` and `podman network disconnect`
commands give containers access to different networks than the
ones they were created with; these networks can also have DNS
servers associated with them. Until now, however, we did not
modify resolv.conf as network membership changed.

With this PR, `podman network connect` will add any new
nameservers supported by the new network to the container's
/etc/resolv.conf, and `podman network disconnect` command will do
the opposite, removing the network's nameservers from
`/etc/resolv.conf`.

Fixes #9603

Signed-off-by: Matthew Heon <matthew.heon@pm.me>
This commit is contained in:
Matthew Heon
2022-02-09 15:02:55 -05:00
committed by Matthew Heon
parent 6ffd59828d
commit 87cca4e5e3
3 changed files with 190 additions and 23 deletions

View File

@ -1170,6 +1170,7 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
}
// update network status if container is running
oldStatus, statusExist := networkStatus[netName]
delete(networkStatus, netName)
c.state.NetworkStatus = networkStatus
err = c.save()
@ -1180,8 +1181,26 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
// Reload ports when there are still connected networks, maybe we removed the network interface with the child ip.
// Reloading without connected networks does not make sense, so we can skip this step.
if rootless.IsRootless() && len(networkStatus) > 0 {
return c.reloadRootlessRLKPortMapping()
if err := c.reloadRootlessRLKPortMapping(); err != nil {
return err
}
}
// Update resolv.conf if required
if statusExist {
stringIPs := make([]string, 0, len(oldStatus.DNSServerIPs))
for _, ip := range oldStatus.DNSServerIPs {
stringIPs = append(stringIPs, ip.String())
}
if len(stringIPs) == 0 {
return nil
}
logrus.Debugf("Removing DNS Servers %v from resolv.conf", stringIPs)
if err := c.removeNameserver(stringIPs); err != nil {
return err
}
}
return nil
}
@ -1263,11 +1282,36 @@ func (c *Container) NetworkConnect(nameOrID, netName string, netOpts types.PerNe
if err != nil {
return err
}
// The first network needs a port reload to set the correct child ip for the rootlessport process.
// Adding a second network does not require a port reload because the child ip is still valid.
if rootless.IsRootless() && len(networks) == 0 {
return c.reloadRootlessRLKPortMapping()
if err := c.reloadRootlessRLKPortMapping(); err != nil {
return err
}
}
ipv6, err := c.checkForIPv6(networkStatus)
if err != nil {
return err
}
// Update resolv.conf if required
stringIPs := make([]string, 0, len(results[netName].DNSServerIPs))
for _, ip := range results[netName].DNSServerIPs {
if (ip.To4() == nil) && !ipv6 {
continue
}
stringIPs = append(stringIPs, ip.String())
}
if len(stringIPs) == 0 {
return nil
}
logrus.Debugf("Adding DNS Servers %v to resolv.conf", stringIPs)
if err := c.addNameserver(stringIPs); err != nil {
return err
}
return nil
}