forked from aerokube/ggr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
146 lines (130 loc) · 4.08 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package main
import (
"flag"
"fmt"
"log"
"net/http"
"path/filepath"
"strings"
"context"
. "github.com/aerokube/ggr/config"
"os"
"os/signal"
"syscall"
"time"
)
var (
listen string
quotaDir string
users string
timeout time.Duration
gracefulPeriod time.Duration
guestAccessAllowed bool
guestUserName string
rootToken string
verbose bool
startTime = time.Now()
lastReloadTime = time.Now()
version bool
gitRevision = "HEAD"
buildStamp = "unknown"
)
func loadQuotaFiles(quotaDir string) error {
log.Printf("[-] [-] [INIT] [-] [-] [-] [-] [-] [-] [Loading configuration files from \"%s\"]\n", quotaDir)
glob := fmt.Sprintf("%s%c%s", quotaDir, filepath.Separator, "*.xml")
files, _ := filepath.Glob(glob)
if len(files) == 0 {
return fmt.Errorf("no quota XML files found in [%s] - exiting", quotaDir)
}
for _, file := range files {
loadQuotaFile(file)
}
return nil
}
func loadQuotaFile(file string) {
fileName := filepath.Base(file)
quotaName := strings.TrimSuffix(fileName, filepath.Ext(fileName))
var browsers Browsers
err := readConfig(file, &browsers)
if err != nil {
log.Printf("[-] [-] [INIT] [-] [-] [-] [-] [-] [-] [Failed to load configuration from \"%s\": %v]\n", fileName, err)
return
}
updateQuota(quotaName, browsers)
if verbose {
log.Printf("[-] [-] [INIT] [-] [-] [-] [-] [-] [-] [Loaded configuration from \"%s\"]\n%v\n", file, browsers)
}
}
func updateQuota(quotaName string, browsers Browsers) {
confLock.Lock()
defer confLock.Unlock()
quota[quotaName] = ggrBrowsers{browsers}
routes = appendRoutes(routes, &browsers)
lastReloadTime = time.Now()
}
func showVersion() {
fmt.Printf("Git Revision: %s\n", gitRevision)
fmt.Printf("UTC Build Time: %s\n", buildStamp)
}
func fileExists(p string) bool {
fileInfo, err := os.Stat(p)
return !os.IsNotExist(err) && !fileInfo.IsDir()
}
func init() {
flag.BoolVar(&guestAccessAllowed, "guests-allowed", false, "Allow guest (unauthenticated) users to access the grid")
flag.StringVar(&guestUserName, "guests-quota", "guest", "Which quota file to use for guests")
flag.StringVar(&listen, "listen", ":4444", "host and port to listen to")
flag.StringVar("aDir, "quotaDir", "quota", "quota directory")
flag.StringVar(&users, "users", ".htpasswd", "htpasswd auth file path")
flag.DurationVar(&timeout, "timeout", 300*time.Second, "session creation timeout in time.Duration format, e.g. 300s or 500ms")
flag.DurationVar(&gracefulPeriod, "graceful-period", 300*time.Second, "graceful shutdown period in time.Duration format, e.g. 300s or 500ms")
flag.StringVar(&rootToken, "root-token", "", "Root token value")
flag.BoolVar(&version, "version", false, "show version and exit")
flag.BoolVar(&verbose, "verbose", false, "enable verbose mode")
flag.Parse()
if version {
showVersion()
os.Exit(0)
}
log.Printf("[-] [-] [INIT] [-] [-] [-] [-] [-] [-] [Users file is \"%s\"]\n", users)
if !fileExists(users) && !guestAccessAllowed {
log.Fatalf("[-] [-] [INIT] [-] [-] [-] [-] [-] [-] [Users file \"%s\" does not exist or is a directory]\n", users)
}
if err := loadQuotaFiles(quotaDir); err != nil {
log.Fatalf("[-] [-] [INIT] [-] [-] [-] [-] [-] [-] [%v]\n", err)
}
sig := make(chan os.Signal)
signal.Notify(sig, syscall.SIGHUP)
go func() {
for {
<-sig
err := loadQuotaFiles(quotaDir)
if err != nil {
log.Printf("[-] [-] [INIT] [-] [-] [-] [-] [-] [-] [%v]\n", err)
}
}
}()
}
func main() {
stop := make(chan os.Signal)
signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)
server := &http.Server{
Addr: listen,
Handler: mux(),
}
e := make(chan error)
go func() {
e <- server.ListenAndServe()
}()
select {
case err := <-e:
log.Fatalf("[-] [-] [INIT] [-] [-] [-] [-] [-] [-] [%v]\n", err)
case <-stop:
}
log.Printf("[-] [%s] [SHUTTING_DOWN] [-] [-] [-] [-] [-] [-] [-]\n", gracefulPeriod)
ctx, cancel := context.WithTimeout(context.Background(), gracefulPeriod)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
log.Fatalf("[-] [-] [SHUTDOWN_FAILURE] [-] [-] [-] [-] [-] [-] [%v]\n", err)
}
}