diff --git a/dhcp/dhcp_windows.go b/dhcp/dhcp_windows.go index da092ce3bc..78db5ded98 100644 --- a/dhcp/dhcp_windows.go +++ b/dhcp/dhcp_windows.go @@ -87,44 +87,44 @@ func (s *Socket) Close() error { func (c *DHCP) getIPv4InterfaceAddresses(ifName string) ([]net.IP, error) { nic, err := c.netioClient.GetNetworkInterfaceByName(ifName) if err != nil { - return []net.IP{}, err + return []net.IP{}, errors.Wrap(err, "failed to get interface by name to find ipv4 addresses") } addresses, err := c.netioClient.GetNetworkInterfaceAddrs(nic) if err != nil { - return []net.IP{}, err + return []net.IP{}, errors.Wrap(err, "failed to get interface addresses") } ret := []net.IP{} for _, address := range addresses { // check if the ip is ipv4 and parse it - ip, _, err := net.ParseCIDR(address.String()) - if err != nil || ip.To4() == nil { + ip, _, cidrErr := net.ParseCIDR(address.String()) + if cidrErr != nil || ip.To4() == nil { continue } ret = append(ret, ip) } c.logger.Info("Interface addresses found", zap.Any("foundIPs", addresses), zap.Any("selectedIPs", ret)) - return ret, err + return ret, nil } -func (c *DHCP) verifyIPv4InterfaceAddressCount(ifName string, count, maxRuns int, sleep time.Duration) error { +func (c *DHCP) verifyIPv4InterfaceAddressCount(ctx context.Context, ifName string, count, maxRuns int, sleep time.Duration) error { retrier := retry.Retrier{ Cooldown: retry.Max(maxRuns, retry.Fixed(sleep)), } - addressCountErr := retrier.Do(context.Background(), func() error { + addressCountErr := retrier.Do(ctx, func() error { addresses, err := c.getIPv4InterfaceAddresses(ifName) if err != nil || len(addresses) != count { return errIncorrectAddressCount } return nil }) - return addressCountErr + return errors.Wrap(addressCountErr, "failed to verify interface ipv4 address count") } // issues a dhcp discover request on an interface by finding the secondary's ip and sending on its ip func (c *DHCP) DiscoverRequest(ctx context.Context, macAddress net.HardwareAddr, ifName string) error { // Find the ipv4 address of the secondary interface (we're betting that this gets autoconfigured) - err := c.verifyIPv4InterfaceAddressCount(ifName, 1, retryCount, ipAssignRetryDelay) + err := c.verifyIPv4InterfaceAddressCount(ctx, ifName, 1, retryCount, ipAssignRetryDelay) if err != nil { return errors.Wrap(err, "failed to get auto ip config assigned in apipa range in time") } @@ -181,7 +181,7 @@ func (c *DHCP) DiscoverRequest(ctx context.Context, macAddress net.HardwareAddr, Cooldown: retry.Max(retryCount, retry.Fixed(retryDelay)), } // retry sending the packet until it succeeds - err = retrier.Do(context.Background(), func() error { + err = retrier.Do(ctx, func() error { _, sockErr := sock.Write(bytesToSend) return sockErr }) diff --git a/network/network_windows.go b/network/network_windows.go index b87a00bc2b..f3614fc1c3 100644 --- a/network/network_windows.go +++ b/network/network_windows.go @@ -46,6 +46,7 @@ const ( defaultIPv6Route = "::/0" // Default IPv6 nextHop defaultIPv6NextHop = "fe80::1234:5678:9abc" + dhcpTimeout = 15 * time.Second ) // Windows implementation of route. @@ -438,8 +439,7 @@ func (nm *networkManager) newNetworkImplHnsV2(nwInfo *EndpointInfo, extIf *exter func (nm *networkManager) sendDHCPDiscoverOnSecondary(client dhcpClient, mac net.HardwareAddr, ifName string) error { // issue dhcp discover packet to ensure mapping created for dns via wireserver to work // we do not use the response for anything - timeout := 15 * time.Second - ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(timeout)) + ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(dhcpTimeout)) defer cancel() logger.Info("Sending DHCP packet", zap.Any("macAddress", mac), zap.String("ifName", ifName)) err := client.DiscoverRequest(ctx, mac, ifName) diff --git a/network/transparent_vlan_endpointclient_linux.go b/network/transparent_vlan_endpointclient_linux.go index e9151ec5c0..05e7c6d458 100644 --- a/network/transparent_vlan_endpointclient_linux.go +++ b/network/transparent_vlan_endpointclient_linux.go @@ -680,10 +680,10 @@ func (client *TransparentVlanEndpointClient) Retry(f func() error) error { retrier := retry.Retrier{ Cooldown: retry.Max(numRetries, retry.Fixed(sleepDelay)), } - return retrier.Do(context.Background(), func() error { + return errors.Wrap(retrier.Do(context.Background(), func() error { // we always want to retry, so all errors are temporary errors - return retry.WrapTemporaryError(f()) - }) + return retry.WrapTemporaryError(f()) // nolint + }), "error during retry") } // Helper function that allows executing a function in a VM namespace diff --git a/retry/retry.go b/retry/retry.go index e37f86073e..741d4ac521 100644 --- a/retry/retry.go +++ b/retry/retry.go @@ -36,9 +36,11 @@ func (r RetriableError) Error() string { } return r.err.Error() } + func (r RetriableError) Unwrap() error { return r.err } + func (r RetriableError) Temporary() bool { return true } diff --git a/retry/retry_test.go b/retry/retry_test.go index 68f7dc97cc..d8607128fd 100644 --- a/retry/retry_test.go +++ b/retry/retry_test.go @@ -10,6 +10,8 @@ import ( "github.com/stretchr/testify/require" ) +var errTest = errors.New("mock error") + type TestError struct{} func (t TestError) Error() string { @@ -168,13 +170,12 @@ func TestMax(t *testing.T) { func TestRetriableError(t *testing.T) { // wrapping nil returns a nil - require.Nil(t, WrapTemporaryError(nil)) + require.NoError(t, WrapTemporaryError(nil)) - mockError := errors.New("mock error") - wrappedMockError := WrapTemporaryError(pkgerrors.Wrap(mockError, "nested")) + wrappedMockError := WrapTemporaryError(pkgerrors.Wrap(testError, "nested")) // temporary errors should still be able to be unwrapped - require.ErrorIs(t, wrappedMockError, mockError) + require.ErrorIs(t, wrappedMockError, testError) var temporaryError TemporaryError require.ErrorAs(t, wrappedMockError, &temporaryError) @@ -194,7 +195,7 @@ func createFunctionWithFailurePattern(errorPattern []error) func() error { } func TestRunWithRetries(t *testing.T) { - errMock := WrapTemporaryError(errors.New("mock error")) + errMock := WrapTemporaryError(testError) retries := 3 // runs 4 times, then errors before the 5th retrier := Retrier{ Cooldown: Max(retries, Fixed(100*time.Millisecond)),