From 40640ef43f5e896fb7d75e49e346b7168681dbc5 Mon Sep 17 00:00:00 2001 From: Nick Cabatoff Date: Mon, 8 Nov 2021 10:04:17 -0500 Subject: [PATCH] Fix errors logged on standbys when we try to write versions to storage (#13042) --- changelog/13042.txt | 3 +++ vault/activity_log.go | 3 ++- vault/core.go | 17 +++++++---------- vault/core_util_common.go | 29 ++++------------------------- vault/core_util_common_test.go | 8 ++++---- 5 files changed, 20 insertions(+), 40 deletions(-) create mode 100644 changelog/13042.txt diff --git a/changelog/13042.txt b/changelog/13042.txt new file mode 100644 index 000000000..192b4d463 --- /dev/null +++ b/changelog/13042.txt @@ -0,0 +1,3 @@ +```release-note:bug +core: Fix warnings logged on perf standbys re stored versions +``` \ No newline at end of file diff --git a/vault/activity_log.go b/vault/activity_log.go index 59e524bd1..d57242b47 100644 --- a/vault/activity_log.go +++ b/vault/activity_log.go @@ -411,6 +411,8 @@ func (a *ActivityLog) saveCurrentSegmentInternal(ctx context.Context, force bool // be written to storage, since if we remove this code we will incur // data loss for one segment's worth of TWEs. if len(a.currentSegment.tokenCount.CountByNamespaceID) > 0 || force { + // We can get away with simply using the oldest version stored because + // the storing of versions was introduced at the same time as this code. oldestVersion, oldestUpgradeTime, err := a.core.FindOldestVersionTimestamp() switch { case err != nil: @@ -1086,7 +1088,6 @@ func (c *Core) setupActivityLog(ctx context.Context, wg *sync.WaitGroup) error { // stopActivityLog removes the ActivityLog from Core // and frees any resources. func (c *Core) stopActivityLog() { - // preSeal may run before startActivityLog got a chance to complete. if c.activityLog != nil { // Shut down background worker diff --git a/vault/core.go b/vault/core.go index 3b9242498..77408ef08 100644 --- a/vault/core.go +++ b/vault/core.go @@ -1047,17 +1047,17 @@ func NewCore(conf *CoreConfig) (*Core, error) { // HandleVersionTimeStamps stores the current version at the current time to // storage, and then loads all versions and upgrade timestamps out from storage. -func (c *Core) HandleVersionTimeStamps(ctx context.Context) error { +func (c *Core) handleVersionTimeStamps(ctx context.Context) error { currentTime := time.Now() - isUpdated, err := c.StoreVersionTimestamp(ctx, version.Version, currentTime) + isUpdated, err := c.storeVersionTimestamp(ctx, version.Version, currentTime) if err != nil { - return err + return fmt.Errorf("error storing vault version: %w", err) } if isUpdated { c.logger.Info("Recorded vault version", "vault version", version.Version, "upgrade time", currentTime) } // Finally, load the versions into core fields - err = c.HandleLoadVersionTimestamps(ctx) + err = c.loadVersionTimestamps(ctx) if err != nil { return err } @@ -2000,6 +2000,9 @@ func (s standardUnsealStrategy) unseal(ctx context.Context, logger log.Logger, c return err } } + if err := c.handleVersionTimeStamps(ctx); err != nil { + return err + } if err := c.setupPluginCatalog(ctx); err != nil { return err } @@ -2157,11 +2160,6 @@ func (c *Core) postUnseal(ctx context.Context, ctxCancelFunc context.CancelFunc, c.logger.Warn("post-unseal post seal migration failed", "error", err) } } - err := c.HandleVersionTimeStamps(c.activeContext) - if err != nil { - c.logger.Warn("post-unseal version timestamp setup failed", "error", err) - - } c.logger.Info("post-unseal setup complete") return nil @@ -2689,7 +2687,6 @@ func (c *Core) SetConfig(conf *server.Config) { } func (c *Core) GetListenerCustomResponseHeaders(listenerAdd string) *ListenerCustomHeaders { - customHeaders := c.customListenerHeader.Load() if customHeaders == nil { return nil diff --git a/vault/core_util_common.go b/vault/core_util_common.go index a70cac733..d99203712 100644 --- a/vault/core_util_common.go +++ b/vault/core_util_common.go @@ -11,9 +11,9 @@ import ( const vaultVersionPath string = "core/versions/" -// StoreVersionTimestamp will store the version and timestamp pair to storage only if no entry +// storeVersionTimestamp will store the version and timestamp pair to storage only if no entry // for that version already exists in storage. -func (c *Core) StoreVersionTimestamp(ctx context.Context, version string, currentTime time.Time) (bool, error) { +func (c *Core) storeVersionTimestamp(ctx context.Context, version string, currentTime time.Time) (bool, error) { timeStamp, err := c.barrier.Get(ctx, vaultVersionPath+version) if err != nil { return false, err @@ -39,27 +39,6 @@ func (c *Core) StoreVersionTimestamp(ctx context.Context, version string, curren return true, nil } -// FindMostRecentVersionTimestamp loads the current vault version and associated -// upgrade time from storage. -func (c *Core) FindMostRecentVersionTimestamp() (string, time.Time, error) { - if c.VersionTimestamps == nil || len(c.VersionTimestamps) == 0 { - return "", time.Time{}, fmt.Errorf("Version timestamps are not initialized") - } - var latestUpgradeTime time.Time - var mostRecentVersion string - for version, upgradeTime := range c.VersionTimestamps { - if upgradeTime.After(latestUpgradeTime) { - mostRecentVersion = version - latestUpgradeTime = upgradeTime - } - } - // This if-case should never be hit - if mostRecentVersion == "" { - return "", latestUpgradeTime, fmt.Errorf("Empty vault version was written to storage at time: %+v", latestUpgradeTime) - } - return mostRecentVersion, latestUpgradeTime, nil -} - // FindOldestVersionTimestamp searches for the vault version with the oldest // upgrade timestamp from storage. The earliest version this can be (barring // downgrades) is 1.9.0. @@ -80,9 +59,9 @@ func (c *Core) FindOldestVersionTimestamp() (string, time.Time, error) { return oldestVersion, oldestUpgradeTime, nil } -// HandleLoadVersionTimestamps loads all the vault versions and associated +// loadVersionTimestamps loads all the vault versions and associated // upgrade timestamps from storage. -func (c *Core) HandleLoadVersionTimestamps(ctx context.Context) (retErr error) { +func (c *Core) loadVersionTimestamps(ctx context.Context) (retErr error) { vaultVersions, err := c.barrier.List(ctx, vaultVersionPath) if err != nil { return fmt.Errorf("unable to retrieve vault versions from storage: %+w", err) diff --git a/vault/core_util_common_test.go b/vault/core_util_common_test.go index 46fda7ed9..906988a8f 100644 --- a/vault/core_util_common_test.go +++ b/vault/core_util_common_test.go @@ -13,7 +13,7 @@ import ( func TestStoreMultipleVaultVersions(t *testing.T) { c, _, _ := TestCoreUnsealed(t) upgradeTimePlusEpsilon := time.Now() - wasStored, err := c.StoreVersionTimestamp(context.Background(), version.Version, upgradeTimePlusEpsilon.Add(30*time.Hour)) + wasStored, err := c.storeVersionTimestamp(context.Background(), version.Version, upgradeTimePlusEpsilon.Add(30*time.Hour)) if err != nil || wasStored { t.Fatalf("vault version was re-stored: %v, err is: %s", wasStored, err.Error()) } @@ -32,9 +32,9 @@ func TestGetOldestVersion(t *testing.T) { c, _, _ := TestCoreUnsealed(t) upgradeTimePlusEpsilon := time.Now() - c.StoreVersionTimestamp(context.Background(), "1.9.1", upgradeTimePlusEpsilon.Add(-4*time.Hour)) - c.StoreVersionTimestamp(context.Background(), "1.9.2", upgradeTimePlusEpsilon.Add(2*time.Hour)) - c.HandleLoadVersionTimestamps(c.activeContext) + c.storeVersionTimestamp(context.Background(), "1.9.1", upgradeTimePlusEpsilon.Add(-4*time.Hour)) + c.storeVersionTimestamp(context.Background(), "1.9.2", upgradeTimePlusEpsilon.Add(2*time.Hour)) + c.loadVersionTimestamps(c.activeContext) if len(c.VersionTimestamps) != 3 { t.Fatalf("expected 3 entries in timestamps map after refresh, found: %d", len(c.VersionTimestamps)) }