Skip to content

Commit

Permalink
state: Add 'version' file
Browse files Browse the repository at this point in the history
There's a possibility that we make breaking changes
to the state store in the future.

To detect and upgrade it automatically, add a 'version' file
to the state store.

Its current value is "1",
and that's what we'll assume when the file is absent.

The binary will refuse to run against a store with a version
newer than the current binary.
  • Loading branch information
abhinav committed Dec 21, 2024
1 parent 618a3f8 commit db3400f
Show file tree
Hide file tree
Showing 7 changed files with 555 additions and 4 deletions.
6 changes: 6 additions & 0 deletions .changes/unreleased/Added-20241220-194631.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Added
body: >-
state: Track version of the state store layout in use.
This should be a no-op for users, but it guards against corruption
in case of future changes to the layout.
time: 2024-12-20T19:46:31.685098-05:00
271 changes: 271 additions & 0 deletions internal/spice/state/mocks_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions internal/spice/state/storage/mem.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"encoding/json"
"fmt"
"iter"
"slices"
"sort"
"strings"
"sync"
Expand All @@ -24,6 +26,17 @@ func NewMemBackend() *MemBackend {
}
}

// AddFiles adds the given files to the memory backend,
// overwriting similarly named files.
func (m *MemBackend) AddFiles(files iter.Seq2[string, []byte]) {
m.mu.Lock()
defer m.mu.Unlock()

for name, body := range files {
m.items[name] = slices.Clone(body)
}
}

// Get retrieves a value from the store
func (m *MemBackend) Get(ctx context.Context, key string, dst any) error {
m.mu.RLock()
Expand Down
26 changes: 22 additions & 4 deletions internal/spice/state/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ type DB interface {

var _ DB = (*storage.DB)(nil)

//go:generate mockgen -destination mocks_test.go -package state -typed . DB

// Store implements storage for state tracked by gs.
type Store struct {
db DB
Expand Down Expand Up @@ -105,11 +107,23 @@ func InitStore(ctx context.Context, req InitStoreRequest) (*Store, error) {
}
}

info := repoInfo{
Trunk: req.Trunk,
Remote: req.Remote,
update := storage.UpdateRequest{
Sets: []storage.SetRequest{
{
Key: _repoJSON,
Value: repoInfo{
Trunk: req.Trunk,
Remote: req.Remote,
},
},
{
Key: _versionFile,
Value: LatestVersion,
},
},
Message: "initialize store",
}
if err := db.Set(ctx, _repoJSON, info, "initialize store"); err != nil {
if err := db.Update(ctx, update); err != nil {
return nil, fmt.Errorf("put repo state: %w", err)
}

Expand Down Expand Up @@ -165,6 +179,10 @@ func OpenStore(ctx context.Context, db DB, logger *log.Logger) (*Store, error) {
logger = log.New(io.Discard)
}

if err := checkVersion(ctx, db); err != nil {
return nil, fmt.Errorf("check store layout: %w", err)
}

var info repoInfo
if err := db.Get(ctx, _repoJSON, &info); err != nil {
if errors.Is(err, ErrNotExist) {
Expand Down
Loading

0 comments on commit db3400f

Please sign in to comment.