From 38d3c839ef501cec84b21832e7c4a8bf1dac344b Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 21 Jun 2022 16:56:57 +0200 Subject: [PATCH 1/6] Add config.GetActiveConfigValues to export active config values --- config/main.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/config/main.go b/config/main.go index 1882707..ac2881d 100644 --- a/config/main.go +++ b/config/main.go @@ -112,3 +112,22 @@ func AddToDebugInfo(di *debug.Info) { lines..., ) } + +// GetActiveConfigValues returns a map with the active config values. +func GetActiveConfigValues() map[string]interface{} { + values := make(map[string]interface{}) + + // Collect active values from options. + _ = ForEachOption(func(opt *Option) error { + opt.Lock() + defer opt.Unlock() + + if opt.ReleaseLevel <= getReleaseLevel() && opt.activeValue != nil { + values[opt.Key] = opt.activeValue.getData(opt) + } + + return nil + }) + + return values +} From 8421b8fba852bd2e6b06f7b29a156e31ff6d8789 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 21 Jun 2022 16:57:37 +0200 Subject: [PATCH 2/6] Add clean export function for updater.Resource --- updater/export.go | 5 ++--- updater/resource.go | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/updater/export.go b/updater/export.go index 7ce394a..55b64a3 100644 --- a/updater/export.go +++ b/updater/export.go @@ -1,7 +1,6 @@ package updater -// Export exports the list of resources. All resources must be -// locked when accessed. +// Export exports the list of resources. func (reg *ResourceRegistry) Export() map[string]*Resource { reg.RLock() defer reg.RUnlock() @@ -9,7 +8,7 @@ func (reg *ResourceRegistry) Export() map[string]*Resource { // copy the map copiedResources := make(map[string]*Resource) for key, val := range reg.resources { - copiedResources[key] = val + copiedResources[key] = val.Export() } return copiedResources diff --git a/updater/resource.go b/updater/resource.go index ab9b38a..81e2896 100644 --- a/updater/resource.go +++ b/updater/resource.go @@ -117,6 +117,26 @@ func (rv *ResourceVersion) isBetaVersionNumber() bool { //nolint:unused } } +// Export makes a copy of the resource with only the exposed information. +func (res *Resource) Export() *Resource { + res.Lock() + defer res.Unlock() + + // Copy attibutes. + export := &Resource{ + Identifier: res.Identifier, + Versions: make([]*ResourceVersion, len(res.Versions)), + ActiveVersion: res.ActiveVersion, + SelectedVersion: res.SelectedVersion, + } + // Copy Versions slice. + for i := 0; i < len(res.Versions); i++ { + export.Versions[i] = res.Versions[i] + } + + return export +} + // Len is the number of elements in the collection. // It implements sort.Interface for ResourceVersion. func (res *Resource) Len() int { From f3591e81c3a3147a4adf7517bff66d85c2830fe0 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 21 Jun 2022 16:58:06 +0200 Subject: [PATCH 3/6] Fix update cycle to notification attach to module --- modules/status.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/status.go b/modules/status.go index 2810fec..325f144 100644 --- a/modules/status.go +++ b/modules/status.go @@ -180,7 +180,7 @@ func (m *Module) Resolve(failureID string) { // Propagate failure status. if failureUpdateNotifyFuncReady.IsSet() { - _ = m.RunWorker("failure status updater", func(context.Context) error { + m.StartWorker("failure status updater", func(context.Context) error { // Only use data in worker that won't change anymore. failureUpdateNotifyFunc(FailureNone, resolveFailureID, "", "") return nil From efcea66226cec6ca97b28a0748bfe456f3b8b997 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 21 Jun 2022 16:59:41 +0200 Subject: [PATCH 4/6] Add better handling for panics within api endpoint handlers --- api/router.go | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/api/router.go b/api/router.go index bdc24c3..71502c3 100644 --- a/api/router.go +++ b/api/router.go @@ -3,9 +3,11 @@ package api import ( "context" "errors" + "fmt" "net/http" "net/url" "path" + "runtime/debug" "strings" "sync" "time" @@ -226,13 +228,34 @@ func (mh *mainHandler) handle(w http.ResponseWriter, r *http.Request) error { w.Header().Add("Vary", "Origin") } - // Handle request. - if handler != nil { - handler.ServeHTTP(lrw, r) - } else { + // Check if we have a handler. + if handler == nil { http.Error(lrw, "Not found.", http.StatusNotFound) + return nil } + // Format panics in handler. + defer func() { + if panicValue := recover(); panicValue != nil { + if devMode() { + http.Error( + lrw, + fmt.Sprintf( + "Internal Server Error: %s\n\n%s", + panicValue, + debug.Stack(), + ), + http.StatusInternalServerError, + ) + } else { + http.Error(lrw, "Internal Server Error.", http.StatusInternalServerError) + } + } + }() + + // Handle with registered handler. + handler.ServeHTTP(lrw, r) + return nil } From e7d9ee9db071dc24ebf621fc64f6a393d50cac70 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 21 Jun 2022 16:59:50 +0200 Subject: [PATCH 5/6] Improve log message formatting --- database/migration/migration.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/database/migration/migration.go b/database/migration/migration.go index 5cd6126..63a0845 100644 --- a/database/migration/migration.go +++ b/database/migration/migration.go @@ -76,12 +76,12 @@ func (reg *Registry) Migrate(ctx context.Context) (err error) { defer reg.lock.Unlock() start := time.Now() - log.Infof("[migration] migration of %s started", reg.key) + log.Infof("migration: migration of %s started", reg.key) defer func() { if err != nil { - log.Errorf("[migration] migration of %s failed after %s: %s", reg.key, time.Since(start), err) + log.Errorf("migration: migration of %s failed after %s: %s", reg.key, time.Since(start), err) } else { - log.Infof("[migration] migration of %s finished after %s", reg.key, time.Since(start)) + log.Infof("migration: migration of %s finished after %s", reg.key, time.Since(start)) } }() @@ -114,7 +114,7 @@ func (reg *Registry) Migrate(ctx context.Context) (err error) { if err := m.MigrateFunc(migrationCtx, lastAppliedMigration, target, db); err != nil { diag.Wrapped = err diag.FailedMigration = m.Description - tracer.Infof("[migration] applied migration for %s: %s - %s", reg.key, target.String(), m.Description) + tracer.Infof("migration: applied migration for %s: %s - %s", reg.key, target.String(), m.Description) tracer.Submit() return diag } @@ -127,7 +127,7 @@ func (reg *Registry) Migrate(ctx context.Context) (err error) { diag.Wrapped = err diag.FailedMigration = m.Description } - tracer.Infof("[migration] applied migration for %s: %s - %s", reg.key, target.String(), m.Description) + tracer.Infof("migration: applied migration for %s: %s - %s", reg.key, target.String(), m.Description) tracer.Submit() } From aef3f523ce48fd8ad6338cf3ed15e3cce8ac4a68 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 22 Jun 2022 09:44:38 +0200 Subject: [PATCH 6/6] Improve updater.Resource.Export() documentation --- updater/resource.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/updater/resource.go b/updater/resource.go index 81e2896..eeda5db 100644 --- a/updater/resource.go +++ b/updater/resource.go @@ -118,6 +118,8 @@ func (rv *ResourceVersion) isBetaVersionNumber() bool { //nolint:unused } // Export makes a copy of the resource with only the exposed information. +// Attributes are copied and safe to access. +// Any ResourceVersion must not be modified. func (res *Resource) Export() *Resource { res.Lock() defer res.Unlock()