mirror of https://github.com/containers/podman.git
Merge pull request #5434 from mheon/force_delete_cni_netreg
Attempt manual removal of CNI IP allocations on refresh
This commit is contained in:
commit
e34ec617a3
|
@ -470,9 +470,9 @@ func (c *Container) teardownStorage() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset resets state fields to default values
|
// Reset resets state fields to default values.
|
||||||
// It is performed before a refresh and clears the state after a reboot
|
// It is performed before a refresh and clears the state after a reboot.
|
||||||
// It does not save the results - assumes the database will do that for us
|
// It does not save the results - assumes the database will do that for us.
|
||||||
func resetState(state *ContainerState) error {
|
func resetState(state *ContainerState) error {
|
||||||
state.PID = 0
|
state.PID = 0
|
||||||
state.ConmonPID = 0
|
state.ConmonPID = 0
|
||||||
|
@ -483,7 +483,6 @@ func resetState(state *ContainerState) error {
|
||||||
}
|
}
|
||||||
state.ExecSessions = make(map[string]*ExecSession)
|
state.ExecSessions = make(map[string]*ExecSession)
|
||||||
state.LegacyExecSessions = nil
|
state.LegacyExecSessions = nil
|
||||||
state.NetworkStatus = nil
|
|
||||||
state.BindMounts = make(map[string]string)
|
state.BindMounts = make(map[string]string)
|
||||||
state.StoppedByUser = false
|
state.StoppedByUser = false
|
||||||
state.RestartPolicyMatch = false
|
state.RestartPolicyMatch = false
|
||||||
|
@ -539,6 +538,18 @@ func (c *Container) refresh() error {
|
||||||
}
|
}
|
||||||
c.lock = lock
|
c.lock = lock
|
||||||
|
|
||||||
|
// Try to delete any lingering IP allocations.
|
||||||
|
// If this fails, just log and ignore.
|
||||||
|
// I'm a little concerned that this is so far down in refresh() and we
|
||||||
|
// could fail before getting to it - but the worst that would happen is
|
||||||
|
// that Inspect() would return info on IPs we no longer own.
|
||||||
|
if len(c.state.NetworkStatus) > 0 {
|
||||||
|
if err := c.removeIPv4Allocations(); err != nil {
|
||||||
|
logrus.Errorf("Error removing IP allocations for container %s: %v", c.ID(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.state.NetworkStatus = nil
|
||||||
|
|
||||||
if err := c.save(); err != nil {
|
if err := c.save(); err != nil {
|
||||||
return errors.Wrapf(err, "error refreshing state for container %s", c.ID())
|
return errors.Wrapf(err, "error refreshing state for container %s", c.ID())
|
||||||
}
|
}
|
||||||
|
@ -548,11 +559,58 @@ func (c *Container) refresh() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if rootless.IsRootless() {
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try and remove IP address allocations. Presently IPv4 only.
|
||||||
|
// Should be safe as rootless because NetworkStatus should only be populated if
|
||||||
|
// CNI is running.
|
||||||
|
func (c *Container) removeIPv4Allocations() error {
|
||||||
|
cniNetworksDir, err := getCNINetworksDir()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(c.state.NetworkStatus) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.refreshCNI()
|
cniDefaultNetwork := ""
|
||||||
|
if c.runtime.netPlugin != nil {
|
||||||
|
cniDefaultNetwork = c.runtime.netPlugin.GetDefaultNetworkName()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(c.config.Networks) > 0 && len(c.config.Networks) != len(c.state.NetworkStatus):
|
||||||
|
return errors.Wrapf(define.ErrInternal, "network mismatch: asked to join %d CNI networks but got %d CNI results", len(c.config.Networks), len(c.state.NetworkStatus))
|
||||||
|
case len(c.config.Networks) == 0 && len(c.state.NetworkStatus) != 1:
|
||||||
|
return errors.Wrapf(define.ErrInternal, "network mismatch: did not specify CNI networks but joined more than one (%d)", len(c.state.NetworkStatus))
|
||||||
|
case len(c.config.Networks) == 0 && cniDefaultNetwork == "":
|
||||||
|
return errors.Wrapf(define.ErrInternal, "could not retrieve name of CNI default network")
|
||||||
|
}
|
||||||
|
|
||||||
|
for index, result := range c.state.NetworkStatus {
|
||||||
|
for _, ctrIP := range result.IPs {
|
||||||
|
if ctrIP.Version != "4" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
candidate := ""
|
||||||
|
if len(c.config.Networks) > 0 {
|
||||||
|
// CNI returns networks in order we passed them.
|
||||||
|
// So our index into results should be our index
|
||||||
|
// into networks.
|
||||||
|
candidate = filepath.Join(cniNetworksDir, c.config.Networks[index], ctrIP.Address.IP.String())
|
||||||
|
} else {
|
||||||
|
candidate = filepath.Join(cniNetworksDir, cniDefaultNetwork, ctrIP.Address.IP.String())
|
||||||
|
}
|
||||||
|
logrus.Debugf("Going to try removing IP address reservation file %q for container %s", candidate, c.ID())
|
||||||
|
if err := os.Remove(candidate); err != nil && !os.IsNotExist(err) {
|
||||||
|
return errors.Wrapf(err, "error removing CNI IP reservation file %q for container %s", candidate, c.ID())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove conmon attach socket and terminal resize FIFO
|
// Remove conmon attach socket and terminal resize FIFO
|
||||||
|
|
|
@ -1436,13 +1436,6 @@ func (c *Container) copyOwnerAndPerms(source, dest string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Teardown CNI config on refresh
|
|
||||||
func (c *Container) refreshCNI() error {
|
|
||||||
// Let's try and delete any lingering network config...
|
|
||||||
podNetwork := c.runtime.getPodNetwork(c.ID(), c.config.Name, "", c.config.Networks, c.config.PortMappings, c.config.StaticIP, c.config.StaticMAC)
|
|
||||||
return c.runtime.netPlugin.TearDownPod(podNetwork)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get cgroup path in a format suitable for the OCI spec
|
// Get cgroup path in a format suitable for the OCI spec
|
||||||
func (c *Container) getOCICgroupPath() (string, error) {
|
func (c *Container) getOCICgroupPath() (string, error) {
|
||||||
unified, err := cgroups.IsCgroup2UnifiedMode()
|
unified, err := cgroups.IsCgroup2UnifiedMode()
|
||||||
|
|
|
@ -41,10 +41,6 @@ func (c *Container) copyOwnerAndPerms(source, dest string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) refreshCNI() error {
|
|
||||||
return define.ErrNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Container) getOCICgroupPath() (string, error) {
|
func (c *Container) getOCICgroupPath() (string, error) {
|
||||||
return "", define.ErrNotImplemented
|
return "", define.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
|
@ -657,6 +657,13 @@ func resultToBasicNetworkConfig(result *cnitypes.Result) (InspectBasicNetworkCon
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a horrible hack, necessary because CNI does not properly clean up
|
||||||
|
// after itself on an unclean reboot. Return what we're pretty sure is the path
|
||||||
|
// to CNI's internal files (it's not really exposed to us).
|
||||||
|
func getCNINetworksDir() (string, error) {
|
||||||
|
return "/var/lib/cni/networks", nil
|
||||||
|
}
|
||||||
|
|
||||||
type logrusDebugWriter struct {
|
type logrusDebugWriter struct {
|
||||||
prefix string
|
prefix string
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,3 +23,7 @@ func (r *Runtime) createNetNS(ctr *Container) (err error) {
|
||||||
func (c *Container) getContainerNetworkInfo() (*InspectNetworkSettings, error) {
|
func (c *Container) getContainerNetworkInfo() (*InspectNetworkSettings, error) {
|
||||||
return nil, define.ErrNotImplemented
|
return nil, define.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getCNINetworksDir() (string, error) {
|
||||||
|
return "", define.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue