// setAllocatedOrRelease tries to associate the newly allocated // address addr with the container. On failure it makes the best // effort to cleanup and release addr, logging issues along the way. func (p *ProvisionerAPI) setAllocatedOrRelease( addr *state.IPAddress, environ environs.NetworkingEnviron, instId instance.Id, container *state.Machine, subnetId network.Id, macAddress string, ) (err error) { defer func() { if errors.Cause(err) == nil { // Success! return } logger.Warningf( "failed to mark address %q as %q to container %q: %v (releasing and retrying)", addr.String(), state.AddressStateAllocated, container, err, ) // It's as good as unavailable for us, so mark it as // such. err = setAddrState(addr, state.AddressStateUnavailable) if err != nil { logger.Warningf( "cannot set address %q to %q: %v (ignoring and releasing)", addr.String(), state.AddressStateUnavailable, err, ) } err = environ.ReleaseAddress(instId, subnetId, addr.Address(), addr.MACAddress(), "") if err == nil { logger.Infof("address %q released; trying to allocate new", addr.String()) return } logger.Warningf( "failed to release address %q on instance %q and subnet %q: %v (ignoring and retrying)", addr.String(), instId, subnetId, err, ) }() // Any errors returned below will trigger the release/cleanup // steps above. if err = allocateAddrTo(addr, container, macAddress); err != nil { return errors.Trace(err) } if err = setAddrsTo(addr, container); err != nil { return errors.Trace(err) } logger.Infof("assigned address %q to container %q", addr.String(), container) return nil }
func (a *addresserHandler) releaseIPAddress(addr *state.IPAddress) (err error) { defer errors.DeferredAnnotatef(&err, "failed to release address %v", addr.Value()) logger.Debugf("attempting to release dead address %#v", addr.Value()) subnetId := network.Id(addr.SubnetId()) for attempt := common.ShortAttempt.Start(); attempt.Next(); { err = a.releaser.ReleaseAddress(addr.InstanceId(), subnetId, addr.Address(), addr.MACAddress()) if err == nil { return nil } } // Don't remove the address from state so we // can retry releasing the address later. logger.Warningf("cannot release address %q: %v (will retry)", addr.Value(), err) return errors.Trace(err) }
func (s *IPAddressSuite) assertAddress( c *gc.C, ipAddr *state.IPAddress, addr network.Address, ipState state.AddressState, machineId, ifaceId, subnetId string, ) { c.Assert(ipAddr, gc.NotNil) c.Assert(ipAddr.MachineId(), gc.Equals, machineId) c.Assert(ipAddr.InterfaceId(), gc.Equals, ifaceId) c.Assert(ipAddr.SubnetId(), gc.Equals, subnetId) c.Assert(ipAddr.Value(), gc.Equals, addr.Value) c.Assert(ipAddr.Type(), gc.Equals, addr.Type) c.Assert(ipAddr.Scope(), gc.Equals, addr.Scope) c.Assert(ipAddr.State(), gc.Equals, ipState) c.Assert(ipAddr.Address(), jc.DeepEquals, addr) c.Assert(ipAddr.String(), gc.Equals, addr.String()) c.Assert(ipAddr.Id(), gc.Equals, s.State.EnvironUUID()+":"+addr.Value) c.Assert(ipAddr.InstanceId(), gc.Equals, instance.UnknownId) }