Skip to content

Commit

Permalink
api: retry the getDirectory request on DNS errors
Browse files Browse the repository at this point in the history
In some situations, even thought you have proper start-up ordering, DNS
might briefly be unavailable when the lego units are started. This is
especially critical as systemd doesn't enforce ordering after targets
(e.g. the nss-lookup.target) when configuration is being changed and
both the local DNS resolver & lego are being restarted at the same time.
  • Loading branch information
andir committed Nov 3, 2020
1 parent 38f23c8 commit 77f171f
Showing 1 changed file with 30 additions and 1 deletion.
31 changes: 30 additions & 1 deletion acme/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"encoding/json"
"errors"
"fmt"
"net"
"net/http"
"time"

Expand Down Expand Up @@ -154,7 +155,35 @@ func (a *Core) GetDirectory() acme.Directory {

func getDirectory(do *sender.Doer, caDirURL string) (acme.Directory, error) {
var dir acme.Directory
if _, err := do.Get(caDirURL, &dir); err != nil {

bo := backoff.NewExponentialBackOff()
bo.InitialInterval = 200 * time.Millisecond
bo.MaxInterval = 5 * time.Second
bo.MaxElapsedTime = 20 * time.Second

ctx, cancel := context.WithCancel(context.Background())
operation := func() error {
var err error
_, err = do.Get(caDirURL, &dir)
if err != nil {
var e *net.DNSError
if errors.As(err, &e) {
return err
}

cancel()
return err
}

return nil
}

notify := func(err error, duration time.Duration) {
log.Infof("retry due do: %v", err)
}

err := backoff.RetryNotify(operation, backoff.WithContext(bo, ctx), notify)
if err != nil {
return dir, fmt.Errorf("get directory at '%s': %w", caDirURL, err)
}

Expand Down

0 comments on commit 77f171f

Please sign in to comment.