diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2019-03-15 15:21:21 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2019-03-17 18:06:44 +0100 |
| commit | 03efedc6d1ffa8d8f76696875571b908cfe2fea1 (patch) | |
| tree | feb302a493671c533b7adff32e88938c27d8e22e /dashboard | |
| parent | c1fd2f3b4aa8dc263c14ecc1c5bee9e721600407 (diff) | |
dashboard/app: add handler for config migration
updateBugReporting adds missing reporting stages to bugs in a single namespace.
Use with care. There is no undo.
This can be used to migrate datastore to a new config with more reporting stages.
This functionality is intentionally not connected to any handler.
Before invoking it is recommented to stop all connected instances just in case.
Diffstat (limited to 'dashboard')
| -rw-r--r-- | dashboard/app/admin.go | 69 | ||||
| -rw-r--r-- | dashboard/app/api.go | 17 |
2 files changed, 78 insertions, 8 deletions
diff --git a/dashboard/app/admin.go b/dashboard/app/admin.go index db122297a..ce14a067c 100644 --- a/dashboard/app/admin.go +++ b/dashboard/app/admin.go @@ -80,8 +80,6 @@ func dropNamespace(c context.Context, w http.ResponseWriter, r *http.Request) er return nil } -var _ = dropNamespace // prevent warnings about dead code - func dropNamespaceReportingState(c context.Context, w http.ResponseWriter, ns string, dryRun bool) error { tx := func(c context.Context) error { state, err := loadReportingState(c) @@ -121,3 +119,70 @@ func dropEntities(c context.Context, keys []*datastore.Key, dryRun bool) error { } return nil } + +// updateBugReporting adds missing reporting stages to bugs in a single namespace. +// Use with care. There is no undo. +// This can be used to migrate datastore to a new config with more reporting stages. +// This functionality is intentionally not connected to any handler. +// Before invoking it is recommended to stop all connected instances just in case. +func updateBugReporting(c context.Context, w http.ResponseWriter, r *http.Request) error { + if accessLevel(c, r) != AccessAdmin { + return fmt.Errorf("admin only") + } + ns := r.FormValue("ns") + if ns == "" { + return fmt.Errorf("no ns parameter") + } + var bugs []*Bug + keys, err := datastore.NewQuery("Bug"). + Filter("Namespace=", ns). + GetAll(c, &bugs) + if err != nil { + return err + } + log.Warningf(c, "fetched %v bugs for namespce %v", len(bugs), ns) + cfg := config.Namespaces[ns] + var batchKeys []*datastore.Key + const batchSize = 20 + for i, bug := range bugs { + if len(bug.Reporting) >= len(cfg.Reporting) { + continue + } + batchKeys = append(batchKeys, keys[i]) + if len(batchKeys) == batchSize { + if err := updateBugReportingBatch(c, cfg, batchKeys); err != nil { + return err + } + batchKeys = nil + } + } + if len(batchKeys) != 0 { + if err := updateBugReportingBatch(c, cfg, batchKeys); err != nil { + return err + } + } + return nil +} + +func updateBugReportingBatch(c context.Context, cfg *Config, keys []*datastore.Key) error { + tx := func(c context.Context) error { + bugs := make([]*Bug, len(keys)) + if err := datastore.GetMulti(c, keys, bugs); err != nil { + return err + } + for _, bug := range bugs { + createBugReporting(bug, cfg) + } + _, err := datastore.PutMulti(c, keys, bugs) + return err + } + err := datastore.RunInTransaction(c, tx, &datastore.TransactionOptions{XG: true}) + log.Warningf(c, "updated %v bugs: %v", len(keys), err) + return err +} + +// Prevent warnings about dead code. +var ( + _ = dropNamespace + _ = updateBugReporting +) diff --git a/dashboard/app/api.go b/dashboard/app/api.go index 32cab3871..1f4fea5dd 100644 --- a/dashboard/app/api.go +++ b/dashboard/app/api.go @@ -988,12 +988,7 @@ func createBugForCrash(c context.Context, ns string, req *dashapi.Crash) (*Bug, FirstTime: now, LastTime: now, } - for _, rep := range config.Namespaces[ns].Reporting { - bug.Reporting = append(bug.Reporting, BugReporting{ - Name: rep.Name, - ID: bugReportingHash(bugHash, rep.Name), - }) - } + createBugReporting(bug, config.Namespaces[ns]) if bugKey, err = datastore.Put(c, bugKey, bug); err != nil { return fmt.Errorf("failed to put new bug: %v", err) } @@ -1018,6 +1013,16 @@ func createBugForCrash(c context.Context, ns string, req *dashapi.Crash) (*Bug, return bug, bugKey, nil } +func createBugReporting(bug *Bug, cfg *Config) { + for len(bug.Reporting) < len(cfg.Reporting) { + rep := &cfg.Reporting[len(bug.Reporting)] + bug.Reporting = append(bug.Reporting, BugReporting{ + Name: rep.Name, + ID: bugReportingHash(bug.keyHash(), rep.Name), + }) + } +} + func isActiveBug(c context.Context, bug *Bug) (bool, error) { if bug == nil { return false, nil |
