diff --git a/pkg/bdb/migrate/mig004/migrate.go b/pkg/bdb/migrate/mig004/migrate.go new file mode 100644 index 0000000..9eda5d8 --- /dev/null +++ b/pkg/bdb/migrate/mig004/migrate.go @@ -0,0 +1,85 @@ +package mig004 + +import ( + "bytes" + "context" + + "github.com/aserto-dev/azm/model" + v3 "github.com/aserto-dev/azm/v3" + dsm3 "github.com/aserto-dev/go-directory/aserto/directory/model/v3" + "github.com/aserto-dev/go-edge-ds/pkg/bdb" + "github.com/aserto-dev/go-edge-ds/pkg/bdb/migrate/mig" + "github.com/rs/zerolog" + + bolt "go.etcd.io/bbolt" +) + +// mig004 +// +// reload model from manifest and write new model back to db. +const ( + Version string = "0.0.4" +) + +var fnMap = []func(*zerolog.Logger, *bolt.DB, *bolt.DB) error{ + mig.CreateBucket(bdb.SystemPath), + + mig.CreateBucket(bdb.ManifestPath), + migrateModel(), + + mig.CreateBucket(bdb.ObjectsPath), + mig.CreateBucket(bdb.RelationsObjPath), +} + +func Migrate(log *zerolog.Logger, roDB, rwDB *bolt.DB) error { + log.Info().Str("version", Version).Msg("StartMigration") + for _, fn := range fnMap { + if err := fn(log, roDB, rwDB); err != nil { + return err + } + } + log.Info().Str("version", Version).Msg("FinishedMigration") + return nil +} + +func migrateModel() func(*zerolog.Logger, *bolt.DB, *bolt.DB) error { + return func(log *zerolog.Logger, roDB *bolt.DB, rwDB *bolt.DB) error { + // skip when roDB is nil. + if roDB == nil { + log.Debug().Msg("SKIP MigrateModel") + return nil + } + + ctx := context.Background() + m, err := loadModel(ctx, roDB) + if err != nil { + return err + } + + if err := rwDB.Update(func(tx *bolt.Tx) error { + _, err := bdb.SetAny[model.Model](ctx, tx, bdb.ManifestPath, bdb.ModelKey, m) + return err + }); err != nil { + return err + } + + return nil + } +} + +func loadModel(ctx context.Context, roDB *bolt.DB) (*model.Model, error) { + var m *model.Model + if err := roDB.View(func(rtx *bolt.Tx) error { + manifestBody, err := bdb.Get[dsm3.Body](ctx, rtx, bdb.ManifestPath, bdb.BodyKey) + if err != nil { + return err + } + + m, err = v3.Load(bytes.NewReader(manifestBody.Data)) + return err + }); err != nil { + return m, err + } + + return m, nil +} diff --git a/pkg/bdb/migrate/migrate.go b/pkg/bdb/migrate/migrate.go index 06f106a..e82cc49 100644 --- a/pkg/bdb/migrate/migrate.go +++ b/pkg/bdb/migrate/migrate.go @@ -10,6 +10,7 @@ import ( "github.com/aserto-dev/go-edge-ds/pkg/bdb/migrate/mig001" "github.com/aserto-dev/go-edge-ds/pkg/bdb/migrate/mig002" "github.com/aserto-dev/go-edge-ds/pkg/bdb/migrate/mig003" + "github.com/aserto-dev/go-edge-ds/pkg/bdb/migrate/mig004" "github.com/aserto-dev/go-edge-ds/pkg/fs" "github.com/Masterminds/semver" @@ -25,6 +26,7 @@ var migMap = map[string]Migration{ mig001.Version: mig001.Migrate, mig002.Version: mig002.Migrate, mig003.Version: mig003.Migrate, + mig004.Version: mig004.Migrate, } var ( diff --git a/pkg/bdb/model.go b/pkg/bdb/model.go index 8be7c73..59d7860 100644 --- a/pkg/bdb/model.go +++ b/pkg/bdb/model.go @@ -1,11 +1,9 @@ package bdb import ( - "bytes" - "encoding/json" + "context" "github.com/aserto-dev/azm/model" - v3 "github.com/aserto-dev/azm/v3" bolt "go.etcd.io/bbolt" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -15,12 +13,14 @@ import ( // and swaps the model instance in the cache.Cache using // cache.UpdateModel. func (s *BoltDB) LoadModel() error { + ctx := context.Background() + err := s.db.View(func(tx *bolt.Tx) error { if ok, _ := BucketExists(tx, ManifestPath); !ok { return nil } - buf, version, err := readModel(tx) + mod, err := GetAny[model.Model](ctx, tx, ManifestPath, ModelKey) switch { case status.Code(err) == codes.NotFound: return nil @@ -28,24 +28,6 @@ func (s *BoltDB) LoadModel() error { return err } - var mod *model.Model - - switch version { - case model.ModelVersion: - // The serialized model is on the latest version - var m model.Model - if err := json.Unmarshal(buf, &m); err != nil { - return err - } - mod = &m - default: - // need to reload the model from the manifest - mod, err = fromManifest(tx) - if err != nil { - return err - } - } - if err := s.mc.UpdateModel(mod); err != nil { return err } @@ -55,26 +37,3 @@ func (s *BoltDB) LoadModel() error { return err } - -func readModel(tx *bolt.Tx) ([]byte, int, error) { - buf, err := GetKey(tx, ManifestPath, ModelKey) - if err != nil { - return nil, 0, err - } - - var m map[string]any - if err := json.Unmarshal(buf, &m); err != nil { - return nil, 0, err - } - - return buf, int(m["version"].(float64)), nil -} - -func fromManifest(tx *bolt.Tx) (*model.Model, error) { - manifest, err := GetKey(tx, ManifestPath, BodyKey) - if err != nil { - return nil, err - } - - return v3.Load(bytes.NewReader(manifest)) -} diff --git a/pkg/directory/directory.go b/pkg/directory/directory.go index 83e9414..ef058fb 100644 --- a/pkg/directory/directory.go +++ b/pkg/directory/directory.go @@ -28,7 +28,7 @@ import ( // required minimum schema version, when the current version is lower, migration will be invoked to update to the minimum schema version required. const ( - schemaVersion string = "0.0.3" + schemaVersion string = "0.0.4" manifestVersion int = 2 manifestName string = "edge" )