-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
160 lines (128 loc) · 5.06 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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package main
import (
"flag"
"fmt"
"net/http"
"os"
"os/signal"
"syscall"
_ "gitlab.com/yakshaving.art/git-pull-mirror/metrics"
_ "net/http/pprof"
"github.com/onrik/logrus/filename"
"github.com/sirupsen/logrus"
"gitlab.com/yakshaving.art/git-pull-mirror/config"
"gitlab.com/yakshaving.art/git-pull-mirror/github"
"gitlab.com/yakshaving.art/git-pull-mirror/server"
"gitlab.com/yakshaving.art/git-pull-mirror/version"
"gitlab.com/yakshaving.art/git-pull-mirror/webhooks"
)
func main() {
setupLogger()
args := parseArgs()
if args.ShowVersion {
fmt.Printf("Version: %s Commit: %s Date: %s\n", version.Version, version.Commit, version.Date)
os.Exit(0)
}
if args.Debug {
toggleDebugLogLevel()
}
if err := args.Check(); err != nil {
logrus.Fatalf("Cannot start, arguments are invalid: %s", err)
os.Exit(1)
}
// Start pprof before anything else
go func() {
logrus.Infof("starting pprof listener on %s", args.PprofAddress)
logrus.Fatal(http.ListenAndServe(args.PprofAddress, nil))
}()
c, err := config.LoadConfiguration(args.ConfigFile)
if err != nil {
logrus.Fatalf("Failed to load configuration: %s", err)
}
client, err := createClient(args)
if err != nil {
logrus.Fatalf("Failed to create GitHub Webhooks client: %s", err)
}
if args.DryRun {
os.Exit(0)
}
s := server.New(client, server.WebHooksServerOptions{
GitTimeoutSeconds: args.TimeoutSeconds,
RepositoriesPath: args.RepositoriesPath,
SSHPrivateKey: args.SSHKey,
Concurrency: args.Concurrency,
})
signalCh := make(chan os.Signal, 1)
signal.Notify(signalCh, syscall.SIGHUP, syscall.SIGINT, syscall.SIGUSR1, syscall.SIGUSR2)
ready := make(chan interface{})
go s.Run(args.Address, c, ready)
<-ready
for sig := range signalCh {
switch sig {
case syscall.SIGHUP:
logrus.Info("Reloading the configuration")
c, err := config.LoadConfiguration(args.ConfigFile)
if err != nil {
logrus.Errorf("Failed to load configuration: %s", err)
continue
}
s.Configure(c)
case syscall.SIGUSR1:
logrus.Info("toggling debug log level")
toggleDebugLogLevel()
case syscall.SIGUSR2:
logrus.Info("Received USR2, forcing an update in all the repositories")
s.UpdateAll()
case syscall.SIGINT:
logrus.Info("Shutting down gracefully")
s.Shutdown()
os.Exit(0)
}
}
}
func toggleDebugLogLevel() {
switch logrus.GetLevel() {
case logrus.InfoLevel:
logrus.SetLevel(logrus.DebugLevel)
default:
logrus.SetLevel(logrus.InfoLevel)
}
}
func parseArgs() config.Arguments {
args := config.Arguments{}
flag.StringVar(&args.Address, "listen.address", ":9092", "address in which to listen for webhooks")
flag.StringVar(&args.ConfigFile, "config.file", "mirrors.yml", "configuration file")
flag.StringVar(&args.CallbackURL, "callback.url", os.Getenv("CALLBACK_URL"), "callback url to report to github for webhooks, must include schema and domain")
flag.BoolVar(&args.Debug, "debug", false, "enable debugging log level")
flag.BoolVar(&args.DryRun, "dryrun", false, "execute configuration loading, don't actually do anything")
flag.StringVar(&args.GithubUser, "github.user", os.Getenv("GITHUB_USER"), "github username, used to configure the webhooks through the API")
flag.StringVar(&args.GithubToken, "github.token", os.Getenv("GITHUB_TOKEN"), "github token, used as the password to configure the webhooks through the API")
flag.StringVar(&args.GithubURL, "github.url", "https://api.github.com/hub", "github api url to register webhooks")
// flag.StringVar(&args.GitlabUser, "gitlab.user", os.Getenv("GITLAB_USER"), "gitlab username, used to configure the webhooks through the API")
// flag.StringVar(&args.GitlabToken, "gitlab.token", os.Getenv("GITLAB_TOKEN"), "gitlab token, used as the password to configure the webhooks through the API")
// flag.StringVar(&args.GitlabURL, "gitlab.url", "", "gitlab api url to register webhooks")
flag.StringVar(&args.WebhooksTarget, "webhooks.target", "github", "used to define different kinds of webhooks clients, GitHub by default")
flag.StringVar(&args.RepositoriesPath, "repositories.path", ".", "local path in which to store cloned repositories")
flag.StringVar(&args.SSHKey, "sshkey", os.Getenv("SSH_KEY"), "ssh key to use to identify to remotes")
flag.Uint64Var(&args.TimeoutSeconds, "git.timeout.seconds", 60, "git operations timeout in seconds")
flag.BoolVar(&args.ShowVersion, "version", false, "print the version and exit")
flag.IntVar(&args.Concurrency, "concurrency", 4, "how many background tasks to execute concurrently")
flag.StringVar(&args.PprofAddress, "pprof.address", "localhost:9093", "address in which to listen for pprof debugging requests")
flag.Parse()
return args
}
func createClient(args config.Arguments) (webhooks.Client, error) {
// TODO: based on webhooksTarget we should create a github client or something else
return github.New(github.ClientOpts{
User: args.GithubUser,
Token: args.GithubToken,
GitHubURL: args.GithubURL,
CallbackURL: args.CallbackURL,
})
}
func setupLogger() {
logrus.AddHook(filename.NewHook())
logrus.SetFormatter(&logrus.TextFormatter{
FullTimestamp: true,
})
}