diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-06-11 10:02:45 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-06-11 12:12:01 +0300 |
| commit | d6ae9b97396cde206f3d294594cd4a8fd55e3c63 (patch) | |
| tree | 6338574f771e54458ca3aa6b76d802e25d7d64c9 | |
| parent | 866118af36a38963903be2bdee4aff0c36ae365f (diff) | |
dashboard/app: simplify config deployment
Currently one needs to switch between config_stub.go and prod
config back and forth on every deployment. This is very
inconvinient. Rework config, so that switching is not necessary.
| -rw-r--r-- | dashboard/app/api.go | 2 | ||||
| -rw-r--r-- | dashboard/app/app_test.go | 10 | ||||
| -rw-r--r-- | dashboard/app/config.go | 44 | ||||
| -rw-r--r-- | dashboard/app/config_stub.go | 47 | ||||
| -rw-r--r-- | dashboard/app/main.go | 2 | ||||
| -rw-r--r-- | dashboard/app/reporting_email.go | 2 | ||||
| -rw-r--r-- | dashboard/app/util_test.go | 2 |
7 files changed, 41 insertions, 68 deletions
diff --git a/dashboard/app/api.go b/dashboard/app/api.go index 1b5f016ca..93ae5a275 100644 --- a/dashboard/app/api.go +++ b/dashboard/app/api.go @@ -25,7 +25,7 @@ import ( "google.golang.org/appengine/log" ) -func init() { +func initAPIHandlers() { http.Handle("/api", handleJSON(handleAPI)) } diff --git a/dashboard/app/app_test.go b/dashboard/app/app_test.go index 21fdc75b3..f40a648ea 100644 --- a/dashboard/app/app_test.go +++ b/dashboard/app/app_test.go @@ -14,8 +14,13 @@ import ( "github.com/google/syzkaller/dashboard/dashapi" ) +func init() { + initMocks() + installConfig(testConfig) +} + // Config used in tests. -var config = GlobalConfig{ +var testConfig = &GlobalConfig{ AccessLevel: AccessPublic, AuthDomain: "@syzkaller.com", Clients: map[string]string{ @@ -124,7 +129,8 @@ var config = GlobalConfig{ }, }, "access-public": &Config{ - Key: "publickeypublickeypublickey", + AccessLevel: AccessPublic, + Key: "publickeypublickeypublickey", Clients: map[string]string{ clientPublic: keyPublic, }, diff --git a/dashboard/app/config.go b/dashboard/app/config.go index cb826a782..c4d702d08 100644 --- a/dashboard/app/config.go +++ b/dashboard/app/config.go @@ -126,10 +126,6 @@ const ( FilterHold // Hold off with reporting this bug. ) -func reportAllFilter(bug *Bug) FilterResult { return FilterReport } -func reportSkipFilter(bug *Bug) FilterResult { return FilterSkip } -func reportHoldFilter(bug *Bug) FilterResult { return FilterHold } - func (cfg *Config) ReportingByName(name string) *Reporting { for i := range cfg.Reporting { reporting := &cfg.Reporting[i] @@ -140,19 +136,26 @@ func (cfg *Config) ReportingByName(name string) *Reporting { return nil } -func init() { - // Validate the global config. - if len(config.Namespaces) == 0 { +// config is populated by installConfig which should be called either from tests +// or from a separate file that provides actual production config. +var config *GlobalConfig + +func installConfig(cfg *GlobalConfig) { + if config != nil { + panic("another config is already installed") + } + // Validate the global cfg. + if len(cfg.Namespaces) == 0 { panic("no namespaces found") } - for i := range config.EmailBlacklist { - config.EmailBlacklist[i] = email.CanonicalEmail(config.EmailBlacklist[i]) + for i := range cfg.EmailBlacklist { + cfg.EmailBlacklist[i] = email.CanonicalEmail(cfg.EmailBlacklist[i]) } namespaces := make(map[string]bool) clientNames := make(map[string]bool) - checkClients(clientNames, config.Clients) - checkConfigAccessLevel(&config.AccessLevel, AccessPublic, "global") - for ns, cfg := range config.Namespaces { + checkClients(clientNames, cfg.Clients) + checkConfigAccessLevel(&cfg.AccessLevel, AccessPublic, "global") + for ns, cfg := range cfg.Namespaces { if ns == "" { panic("empty namespace name") } @@ -188,7 +191,7 @@ func init() { if len(cfg.Reporting) == 0 { panic(fmt.Sprintf("no reporting in namespace %q", ns)) } - checkConfigAccessLevel(&cfg.AccessLevel, config.AccessLevel, fmt.Sprintf("namespace %q", ns)) + checkConfigAccessLevel(&cfg.AccessLevel, cfg.AccessLevel, fmt.Sprintf("namespace %q", ns)) parentAccessLevel := cfg.AccessLevel reportingNames := make(map[string]bool) // Go backwards because access levels get stricter backwards. @@ -207,7 +210,7 @@ func init() { fmt.Sprintf("reporting %q/%q", ns, reporting.Name)) parentAccessLevel = reporting.AccessLevel if reporting.Filter == nil { - reporting.Filter = reportAllFilter + reporting.Filter = func(bug *Bug) FilterResult { return FilterReport } } reportingNames[reporting.Name] = true if reporting.Config.Type() == "" { @@ -222,7 +225,7 @@ func init() { } } } - for repo, info := range config.KernelRepos { + for repo, info := range cfg.KernelRepos { if info.Alias == "" { panic(fmt.Sprintf("empty kernel repo alias for %q", repo)) } @@ -230,6 +233,17 @@ func init() { panic(fmt.Sprintf("bad kernel repo reporting priority %v for %q", prio, repo)) } } + config = cfg + initEmailReporting() + initHTTPHandlers() + initAPIHandlers() +} + +func init() { + // Prevents gometalinter from considering everything as dead code. + if false { + installConfig(nil) + } } func checkConfigAccessLevel(current *AccessLevel, parent AccessLevel, what string) { diff --git a/dashboard/app/config_stub.go b/dashboard/app/config_stub.go deleted file mode 100644 index dc7f3b6c5..000000000 --- a/dashboard/app/config_stub.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2017 syzkaller project authors. All rights reserved. -// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. - -// +build !aetest - -package dash - -import "time" - -// Stub config variable that merely makes link success. -// The app will panic in init with this empty config. -// When deploying the app one needs to replace this config with a real one. -// See an example below. -var config GlobalConfig - -// Example config: -var _ = GlobalConfig{ - Namespaces: map[string]*Config{ - "upstream": &Config{ - Key: "123", - Clients: map[string]string{ - "foo": "bar", - }, - MailWithoutReport: false, - WaitForRepro: 12 * time.Hour, - Reporting: []Reporting{ - Reporting{ - Name: "upstream", - DailyLimit: 10, - Filter: reportAllFilter, - Config: &EmailConfig{ - Email: "syzkaller@googlegroups.com", - MailMaintainers: true, - }, - }, - Reporting{ - Name: "another", - Filter: reportSkipFilter, - }, - Reporting{ - Name: "yetanother", - Filter: reportHoldFilter, - }, - }, - }, - }, -} diff --git a/dashboard/app/main.go b/dashboard/app/main.go index 5e3792a9d..431c490bb 100644 --- a/dashboard/app/main.go +++ b/dashboard/app/main.go @@ -21,7 +21,7 @@ import ( // This file contains web UI http handlers. -func init() { +func initHTTPHandlers() { http.Handle("/", handlerWrapper(handleMain)) http.Handle("/bug", handlerWrapper(handleBug)) http.Handle("/text", handlerWrapper(handleText)) diff --git a/dashboard/app/reporting_email.go b/dashboard/app/reporting_email.go index a7b885001..de5855bc2 100644 --- a/dashboard/app/reporting_email.go +++ b/dashboard/app/reporting_email.go @@ -26,7 +26,7 @@ import ( // Email reporting interface. -func init() { +func initEmailReporting() { http.HandleFunc("/email_poll", handleEmailPoll) http.HandleFunc("/_ah/mail/", handleIncomingMail) http.HandleFunc("/_ah/bounce", handleEmailBounce) diff --git a/dashboard/app/util_test.go b/dashboard/app/util_test.go index 3a005ea5f..2504a52d1 100644 --- a/dashboard/app/util_test.go +++ b/dashboard/app/util_test.go @@ -357,7 +357,7 @@ Content-Type: text/plain c.expectOK(c.POST("/_ah/mail/", email)) } -func init() { +func initMocks() { // Mock time as some functionality relies on real time. timeNow = func(c context.Context) time.Time { return getRequestContext(c).mockedTime |
