Ensure that errors setting up the DNS servers get propagated back to the shell (#4598)

Fixes: #4578 

Prior to this fix if there was an error binding to ports for the DNS servers the error would be swallowed by the gated log writer and never output. This fix propagates the DNS server errors back to the shell with a multierror.
This commit is contained in:
Matt Keeler 2018-09-07 10:48:29 -04:00 committed by GitHub
parent 6adaf57a3d
commit cc8327ed9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 4 deletions

View File

@ -38,6 +38,7 @@ import (
"github.com/hashicorp/consul/logger" "github.com/hashicorp/consul/logger"
"github.com/hashicorp/consul/types" "github.com/hashicorp/consul/types"
"github.com/hashicorp/consul/watch" "github.com/hashicorp/consul/watch"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/go-uuid" "github.com/hashicorp/go-uuid"
"github.com/hashicorp/memberlist" "github.com/hashicorp/memberlist"
"github.com/hashicorp/raft" "github.com/hashicorp/raft"
@ -448,6 +449,7 @@ func (a *Agent) Start() error {
func (a *Agent) listenAndServeDNS() error { func (a *Agent) listenAndServeDNS() error {
notif := make(chan net.Addr, len(a.config.DNSAddrs)) notif := make(chan net.Addr, len(a.config.DNSAddrs))
errCh := make(chan error, len(a.config.DNSAddrs))
for _, addr := range a.config.DNSAddrs { for _, addr := range a.config.DNSAddrs {
// create server // create server
s, err := NewDNSServer(a) s, err := NewDNSServer(a)
@ -462,23 +464,26 @@ func (a *Agent) listenAndServeDNS() error {
defer a.wgServers.Done() defer a.wgServers.Done()
err := s.ListenAndServe(addr.Network(), addr.String(), func() { notif <- addr }) err := s.ListenAndServe(addr.Network(), addr.String(), func() { notif <- addr })
if err != nil && !strings.Contains(err.Error(), "accept") { if err != nil && !strings.Contains(err.Error(), "accept") {
a.logger.Printf("[ERR] agent: Error starting DNS server %s (%s): %v", addr.String(), addr.Network(), err) errCh <- err
} }
}(addr) }(addr)
} }
// wait for servers to be up // wait for servers to be up
timeout := time.After(time.Second) timeout := time.After(time.Second)
var merr *multierror.Error
for range a.config.DNSAddrs { for range a.config.DNSAddrs {
select { select {
case addr := <-notif: case addr := <-notif:
a.logger.Printf("[INFO] agent: Started DNS server %s (%s)", addr.String(), addr.Network()) a.logger.Printf("[INFO] agent: Started DNS server %s (%s)", addr.String(), addr.Network())
continue case err := <-errCh:
merr = multierror.Append(merr, err)
case <-timeout: case <-timeout:
return fmt.Errorf("agent: timeout starting DNS servers") merr = multierror.Append(merr, fmt.Errorf("agent: timeout starting DNS servers"))
break
} }
} }
return nil return merr.ErrorOrNil()
} }
// listenHTTP binds listeners to the provided addresses and also returns // listenHTTP binds listeners to the provided addresses and also returns

View File

@ -179,6 +179,10 @@ mapping.
[root@localhost ~]# iptables -t nat -A OUTPUT -d localhost -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 8600 [root@localhost ~]# iptables -t nat -A OUTPUT -d localhost -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 8600
``` ```
Binding to port 53 will usually require running either as a privileged user (or on Linux running with the
CAP_NET_BIND_SERVICE capability). If using the Consul docker image you will need to add the following to the
environment to allow Consul to use the port: `CONSUL_ALLOW_PRIVILEGED_PORTS=yes`
Note: With this setup, PTR record queries will still be sent out Note: With this setup, PTR record queries will still be sent out
to the other configured resolvers in addition to Consul. to the other configured resolvers in addition to Consul.