forked from mesosphere/mesos-dns
/
main.go
112 lines (95 loc) · 2.4 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package main
import (
"flag"
"fmt"
"os"
"time"
"github.com/mesosphere/mesos-dns/logging"
"github.com/mesosphere/mesos-dns/records"
"github.com/mesosphere/mesos-dns/resolver"
"github.com/mesosphere/mesos-dns/util"
)
const (
zkInitialDetectionTimeout = 30 * time.Second
)
func main() {
util.PanicHandlers = append(util.PanicHandlers, func(_ interface{}) {
// by default the handler already logs the panic
os.Exit(1)
})
var versionFlag bool
// parse flags
cjson := flag.String("config", "config.json", "path to config file (json)")
flag.BoolVar(&versionFlag, "version", false, "output the version")
flag.Parse()
// -version
if versionFlag {
fmt.Println(version)
os.Exit(0)
}
// initialize logging
logging.SetupLogs()
// initialize resolver
config := records.SetConfig(*cjson)
resolver := resolver.New(version, config)
var dnsErr, httpErr, zkErr <-chan error
var newLeader <-chan struct{}
// launch DNS server
if config.DNSOn {
dnsErr = resolver.LaunchDNS()
}
// launch HTTP server
if config.HTTPOn {
httpErr = resolver.LaunchHTTP()
}
// launch Zookeeper listener
if config.Zk != "" {
newLeader, zkErr = resolver.LaunchZK(zkInitialDetectionTimeout)
} else {
// uniform behavior when new leader from masters field
leader := make(chan struct{}, 1)
leader <- struct{}{}
newLeader = leader
}
// print error and terminate
handleServerErr := func(name string, err error) {
if err != nil {
logging.Error.Fatalf("%s failed: %v", name, err)
} else {
logging.Error.Fatalf("%s stopped unexpectedly", name)
}
}
// generate reload signal; up to 1 reload pending at any time
reloadSignal := make(chan struct{}, 1)
tryReload := func() {
// non-blocking, attempt to queue a reload
select {
case reloadSignal <- struct{}{}:
default:
}
}
// periodic loading of DNS state (pull from Master)
go func() {
defer util.HandleCrash()
reloadTimeout := time.Second * time.Duration(config.RefreshSeconds)
reloadTimer := time.AfterFunc(reloadTimeout, tryReload)
for _ = range reloadSignal {
resolver.Reload()
logging.PrintCurLog()
reloadTimer.Reset(reloadTimeout)
}
}()
// infinite loop until there is fatal error
for {
select {
case <-newLeader:
tryReload()
case err := <-dnsErr:
handleServerErr("DNS server", err)
case err := <-httpErr:
handleServerErr("HTTP server", err)
case err := <-zkErr:
handleServerErr("ZK watcher", err)
}
}
}