From dd3f6064f6e252d4654c44941df6ff7f47c6197b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 12 Feb 2021 14:38:20 -0600 Subject: [PATCH] dhcp: add -resendmax option to limit lease acquisition time for testcases The default lease acquisition timeout of 62 seconds is way too long when running multiple testcases, overrunning the `go test` timeout of 10m. Let testcases specify a shorter timeout. Signed-off-by: Dan Williams --- plugins/ipam/dhcp/daemon.go | 14 ++++++++------ plugins/ipam/dhcp/lease.go | 12 +++++++----- plugins/ipam/dhcp/main.go | 4 +++- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/plugins/ipam/dhcp/daemon.go b/plugins/ipam/dhcp/daemon.go index 8635e7ce..73606d0d 100644 --- a/plugins/ipam/dhcp/daemon.go +++ b/plugins/ipam/dhcp/daemon.go @@ -43,13 +43,15 @@ type DHCP struct { leases map[string]*DHCPLease hostNetnsPrefix string clientTimeout time.Duration + clientResendMax time.Duration broadcast bool } -func newDHCP(clientTimeout time.Duration) *DHCP { +func newDHCP(clientTimeout, clientResendMax time.Duration) *DHCP { return &DHCP{ - leases: make(map[string]*DHCPLease), - clientTimeout: clientTimeout, + leases: make(map[string]*DHCPLease), + clientTimeout: clientTimeout, + clientResendMax: clientResendMax, } } @@ -67,7 +69,7 @@ func (d *DHCP) Allocate(args *skel.CmdArgs, result *current.Result) error { clientID := generateClientID(args.ContainerID, conf.Name, args.IfName) hostNetns := d.hostNetnsPrefix + args.Netns - l, err := AcquireLease(clientID, hostNetns, args.IfName, d.clientTimeout, d.broadcast) + l, err := AcquireLease(clientID, hostNetns, args.IfName, d.clientTimeout, d.clientResendMax, d.broadcast) if err != nil { return err } @@ -161,7 +163,7 @@ func getListener(socketPath string) (net.Listener, error) { func runDaemon( pidfilePath, hostPrefix, socketPath string, - dhcpClientTimeout time.Duration, broadcast bool, + dhcpClientTimeout time.Duration, resendMax time.Duration, broadcast bool, ) error { // since other goroutines (on separate threads) will change namespaces, // ensure the RPC server does not get scheduled onto those @@ -182,7 +184,7 @@ func runDaemon( return fmt.Errorf("Error getting listener: %v", err) } - dhcp := newDHCP(dhcpClientTimeout) + dhcp := newDHCP(dhcpClientTimeout, resendMax) dhcp.hostNetnsPrefix = hostPrefix dhcp.broadcast = broadcast rpc.Register(dhcp) diff --git a/plugins/ipam/dhcp/lease.go b/plugins/ipam/dhcp/lease.go index 855dd28c..ef68931d 100644 --- a/plugins/ipam/dhcp/lease.go +++ b/plugins/ipam/dhcp/lease.go @@ -57,6 +57,7 @@ type DHCPLease struct { rebindingTime time.Time expireTime time.Time timeout time.Duration + resendMax time.Duration broadcast bool stopping uint32 stop chan struct{} @@ -68,13 +69,14 @@ type DHCPLease struct { // calling DHCPLease.Stop() func AcquireLease( clientID, netns, ifName string, - timeout time.Duration, broadcast bool, + timeout, resendMax time.Duration, broadcast bool, ) (*DHCPLease, error) { errCh := make(chan error, 1) l := &DHCPLease{ clientID: clientID, stop: make(chan struct{}), timeout: timeout, + resendMax: resendMax, broadcast: broadcast, } @@ -139,7 +141,7 @@ func (l *DHCPLease) acquire() error { opts[dhcp4.OptionClientIdentifier] = []byte(l.clientID) opts[dhcp4.OptionParameterRequestList] = []byte{byte(dhcp4.OptionRouter), byte(dhcp4.OptionSubnetMask)} - pkt, err := backoffRetry(func() (*dhcp4.Packet, error) { + pkt, err := backoffRetry(l.resendMax, func() (*dhcp4.Packet, error) { ok, ack, err := DhcpRequest(c, opts) switch { case err != nil: @@ -258,7 +260,7 @@ func (l *DHCPLease) renew() error { opts := make(dhcp4.Options) opts[dhcp4.OptionClientIdentifier] = []byte(l.clientID) - pkt, err := backoffRetry(func() (*dhcp4.Packet, error) { + pkt, err := backoffRetry(l.resendMax, func() (*dhcp4.Packet, error) { ok, ack, err := DhcpRenew(c, *l.ack, opts) switch { case err != nil: @@ -340,7 +342,7 @@ func jitter(span time.Duration) time.Duration { return time.Duration(float64(span) * (2.0*rand.Float64() - 1.0)) } -func backoffRetry(f func() (*dhcp4.Packet, error)) (*dhcp4.Packet, error) { +func backoffRetry(resendMax time.Duration, f func() (*dhcp4.Packet, error)) (*dhcp4.Packet, error) { var baseDelay time.Duration = resendDelay0 var sleepTime time.Duration @@ -358,7 +360,7 @@ func backoffRetry(f func() (*dhcp4.Packet, error)) (*dhcp4.Packet, error) { time.Sleep(sleepTime) - if baseDelay < resendDelayMax { + if baseDelay < resendMax { baseDelay *= 2 } else { break diff --git a/plugins/ipam/dhcp/main.go b/plugins/ipam/dhcp/main.go index 858dfb10..72680607 100644 --- a/plugins/ipam/dhcp/main.go +++ b/plugins/ipam/dhcp/main.go @@ -40,19 +40,21 @@ func main() { var socketPath string var broadcast bool var timeout time.Duration + var resendMax time.Duration daemonFlags := flag.NewFlagSet("daemon", flag.ExitOnError) daemonFlags.StringVar(&pidfilePath, "pidfile", "", "optional path to write daemon PID to") daemonFlags.StringVar(&hostPrefix, "hostprefix", "", "optional prefix to host root") daemonFlags.StringVar(&socketPath, "socketpath", "", "optional dhcp server socketpath") daemonFlags.BoolVar(&broadcast, "broadcast", false, "broadcast DHCP leases") daemonFlags.DurationVar(&timeout, "timeout", 10*time.Second, "optional dhcp client timeout duration") + daemonFlags.DurationVar(&resendMax, "resendmax", resendDelayMax, "optional dhcp client resend max duration") daemonFlags.Parse(os.Args[2:]) if socketPath == "" { socketPath = defaultSocketPath } - if err := runDaemon(pidfilePath, hostPrefix, socketPath, timeout, broadcast); err != nil { + if err := runDaemon(pidfilePath, hostPrefix, socketPath, timeout, resendMax, broadcast); err != nil { log.Printf(err.Error()) os.Exit(1) }