11
11
package main
12
12
13
13
import (
14
- "bytes"
15
14
"context"
15
+ "os"
16
+ "os/signal"
17
+ "syscall"
16
18
17
19
"github.com/docker/docker/client"
18
- "github.com/jessevdk/go-flags"
19
20
"github.com/pkg/errors"
20
21
"github.com/rs/xid"
21
22
@@ -31,57 +32,18 @@ import (
31
32
"gitlab.com/postgres-ai/database-lab/version"
32
33
)
33
34
34
- var opts struct {
35
- VerificationToken string `short:"t" long:"token" description:"API verification token" env:"VERIFICATION_TOKEN"`
36
-
37
- MountDir string `long:"mount-dir" description:"clones data mount directory" env:"MOUNT_DIR"`
38
- UnixSocketDir string `long:"sockets-dir" description:"unix sockets directory for secure connection to clones" env:"UNIX_SOCKET_DIR"`
39
- DockerImage string `long:"docker-image" description:"clones Docker image" env:"DOCKER_IMAGE"`
40
-
41
- ShowHelp func () error `long:"help" description:"Show this help message"`
42
- }
43
-
44
35
func main () {
45
36
log .Msg ("Database Lab version: " , version .GetVersion ())
46
37
47
- // Load CLI options.
48
- if _ , err := parseArgs (); err != nil {
49
- if flags .WroteHelp (err ) {
50
- return
51
- }
38
+ instanceID := xid .New ().String ()
52
39
53
- log .Fatal ("Args parse error:" , err )
54
- }
40
+ log .Msg ("Database Lab Instance ID:" , instanceID )
55
41
56
- cfg , err := config . LoadConfig ( "config.yml" )
42
+ cfg , err := loadConfiguration ( instanceID )
57
43
if err != nil {
58
44
log .Fatalf (errors .WithMessage (err , "failed to parse config" ))
59
45
}
60
46
61
- log .DEBUG = cfg .Global .Debug
62
- log .Dbg ("Config loaded" , cfg )
63
-
64
- // TODO(anatoly): Annotate envs in configs. Use different lib for flags/configs?
65
- if len (opts .MountDir ) > 0 {
66
- cfg .Provision .Options .ClonesMountDir = opts .MountDir
67
- }
68
-
69
- if len (opts .UnixSocketDir ) > 0 {
70
- cfg .Provision .Options .UnixSocketDir = opts .UnixSocketDir
71
- }
72
-
73
- if len (opts .DockerImage ) > 0 {
74
- cfg .Provision .Options .DockerImage = opts .DockerImage
75
- }
76
-
77
- if cfg .Provision .Options .ClonesMountDir != "" {
78
- cfg .Global .ClonesMountDir = cfg .Provision .Options .ClonesMountDir
79
- }
80
-
81
- cfg .Global .InstanceID = xid .New ().String ()
82
-
83
- log .Msg ("Database Lab Instance ID" , cfg .Global .InstanceID )
84
-
85
47
ctx , cancel := context .WithCancel (context .Background ())
86
48
defer cancel ()
87
49
@@ -121,40 +83,73 @@ func main() {
121
83
log .Fatalf (errors .WithMessage (err , "failed to create a new platform service" ))
122
84
}
123
85
124
- if len (opts .VerificationToken ) > 0 {
125
- cfg .Server .VerificationToken = opts .VerificationToken
126
- }
127
-
128
86
observerCfg := & observer.Config {
129
87
CloneDir : cfg .Provision .Options .ClonesMountDir ,
130
88
DataSubDir : cfg .Global .DataSubDir ,
131
89
SocketDir : cfg .Provision .Options .UnixSocketDir ,
132
90
}
133
91
134
- // Start the Database Lab.
135
92
server := srv .NewServer (& cfg .Server , observerCfg , cloningSvc , platformSvc , dockerCLI )
93
+
94
+ c := make (chan os.Signal , 1 )
95
+ signal .Notify (c , syscall .SIGHUP )
96
+
97
+ go func () {
98
+ for range c {
99
+ log .Msg ("Reloading configuration" )
100
+
101
+ if err := reloadConfig (instanceID , provisionSvc , retrievalSvc , cloningSvc , platformSvc , server ); err != nil {
102
+ log .Err ("Failed to reload configuration" , err )
103
+ }
104
+
105
+ log .Msg ("Configuration has been reloaded" )
106
+ }
107
+ }()
108
+
109
+ // Start the Database Lab.
136
110
if err = server .Run (); err != nil {
137
111
log .Fatalf (err )
138
112
}
139
113
}
140
114
141
- func parseArgs () ([]string , error ) {
142
- var parser = flags .NewParser (& opts , flags .Default & ^ flags .HelpFlag )
115
+ func loadConfiguration (instanceID string ) (* config.Config , error ) {
116
+ cfg , err := config .LoadConfig ("config.yml" )
117
+ if err != nil {
118
+ return nil , errors .Wrap (err , "failed to parse config" )
119
+ }
143
120
144
- // jessevdk/go-flags lib doesn't allow to use short flag -h because
145
- // it's binded to usage help. We need to hack it a bit to use -h
146
- // for as a hostname option.
147
- // See https://github.com/jessevdk/go-flags/issues/240
148
- opts .ShowHelp = func () error {
149
- var b bytes.Buffer
121
+ log .DEBUG = cfg .Global .Debug
122
+ log .Dbg ("Config loaded" , cfg )
150
123
151
- parser .WriteHelp (& b )
124
+ if cfg .Provision .Options .ClonesMountDir != "" {
125
+ cfg .Global .ClonesMountDir = cfg .Provision .Options .ClonesMountDir
126
+ }
152
127
153
- return & flags.Error {
154
- Type : flags .ErrHelp ,
155
- Message : b .String (),
156
- }
128
+ cfg .Global .InstanceID = instanceID
129
+
130
+ return cfg , nil
131
+ }
132
+
133
+ func reloadConfig (instanceID string , provisionSvc provision.Provision , retrievalSvc * retrieval.Retrieval , cloningSvc cloning.Cloning ,
134
+ platformSvc * platform.Service , server * srv.Server ) error {
135
+ cfg , err := loadConfiguration (instanceID )
136
+ if err != nil {
137
+ return err
138
+ }
139
+
140
+ if err := provision .IsValidConfig (cfg .Provision ); err != nil {
141
+ return err
157
142
}
158
143
159
- return parser .Parse ()
144
+ if err := retrieval .IsValidConfig (cfg ); err != nil {
145
+ return err
146
+ }
147
+
148
+ provisionSvc .Reload (cfg .Provision )
149
+ retrievalSvc .Reload (cfg )
150
+ cloningSvc .Reload (cfg .Cloning )
151
+ platformSvc .Reload (cfg .Platform )
152
+ server .Reload (cfg .Server )
153
+
154
+ return nil
160
155
}
0 commit comments