-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.go
132 lines (109 loc) · 2.71 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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package main
import (
"context"
"flag"
"io/ioutil"
"net/http"
"os"
"os/signal"
"time"
"github.com/BurntSushi/toml"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
var (
// Version contains current Depot application version
// information
Version string
verbose bool
configFile string
)
func main() {
// CLI options
flag.BoolVar(&verbose, "verbose", false, "Enables verbose logging")
flag.StringVar(&configFile, "config", "./config.toml", "Configuration file location")
flag.Parse()
// Setup signal handling
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
// Setup logging
defer func() { _ = zap.L().Sync() }()
if err := configureLogging(verbose); err != nil {
panic(err)
}
zap.L().Info("Depot", zap.String("version", Version))
zap.L().Info("Work in progress, it's far from being done :(")
// Read configuration
var rawConfig []byte
rawConfig, err := ioutil.ReadFile(configFile)
if err != nil {
panic(err)
}
var config tomlConfig
if err := toml.Unmarshal(rawConfig, &config); err != nil {
panic(err)
}
if err := config.Validate(); err != nil {
panic(err)
}
// Boot up the HTTP server
server := setupServer(&config)
go func() {
zap.L().Info("Starting HTTP server", zap.String("address", config.Depot.ListenAddress))
if err := server.ListenAndServe(); err != http.ErrServerClosed {
zap.L().Error("Failed to serve", zap.Error(err))
}
}()
// Wait until exit signal
<-c
zap.L().Info("Got interrupt signal")
// Shut down
shutdownDone := make(chan bool, 1)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer cancel()
go func() {
_ = server.Shutdown(ctx)
shutdownDone <- true
}()
zap.L().Info("Shutting down")
select {
case <-shutdownDone:
zap.L().Debug("Shutdown done")
case <-ctx.Done():
zap.L().Warn("Shutdown timed out")
}
if config.Depot.SaveConfigChanges {
zap.L().Info("Saving configuration")
var f *os.File
if f, err = os.OpenFile(configFile, os.O_CREATE|os.O_WRONLY, 0600); err != nil {
zap.L().Error("Failed to open config file for saving", zap.String("file", configFile), zap.Error(err))
goto End
}
defer f.Close()
if err := config.Dump(f); err != nil {
zap.L().Error("Failed to write configuration file", zap.String("file", configFile), zap.Error(err))
}
}
End:
zap.L().Info("Bye!")
}
func configureLogging(verbose bool) error {
var cfg zap.Config
if verbose {
cfg = zap.NewDevelopmentConfig()
cfg.Level.SetLevel(zapcore.DebugLevel)
} else {
cfg = zap.NewProductionConfig()
cfg.Level.SetLevel(zapcore.InfoLevel)
}
cfg.Encoding = "console"
cfg.OutputPaths = []string{
"stdout",
}
logger, err := cfg.Build()
if err != nil {
return err
}
zap.ReplaceGlobals(logger)
return nil
}