mirror of https://github.com/portainer/portainer
fix(datastore): export/import the bolt sequence number EE-2451 (#6571)
* Implement setter/getter for the sequence * import/export counts * fix go tests. rename vars * Improved and simplified the logic. Made it more generic * Remove unused methods * remove unused methods * not part of branch fixpull/6584/head
parent
5d75ca34ea
commit
a89c3773dd
|
@ -33,4 +33,7 @@ type Connection interface {
|
||||||
GetAll(bucketName string, obj interface{}, append func(o interface{}) (interface{}, error)) error
|
GetAll(bucketName string, obj interface{}, append func(o interface{}) (interface{}, error)) error
|
||||||
GetAllWithJsoniter(bucketName string, obj interface{}, append func(o interface{}) (interface{}, error)) error
|
GetAllWithJsoniter(bucketName string, obj interface{}, append func(o interface{}) (interface{}, error)) error
|
||||||
ConvertToKey(v int) []byte
|
ConvertToKey(v int) []byte
|
||||||
|
|
||||||
|
BackupMetadata() (map[string]interface{}, error)
|
||||||
|
RestoreMetadata(s map[string]interface{}) error
|
||||||
}
|
}
|
||||||
|
|
|
@ -376,3 +376,40 @@ func (connection *DbConnection) GetAllWithJsoniter(bucketName string, obj interf
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (connection *DbConnection) BackupMetadata() (map[string]interface{}, error) {
|
||||||
|
buckets := map[string]interface{}{}
|
||||||
|
|
||||||
|
err := connection.View(func(tx *bolt.Tx) error {
|
||||||
|
err := tx.ForEach(func(name []byte, bucket *bolt.Bucket) error {
|
||||||
|
bucketName := string(name)
|
||||||
|
bucket = tx.Bucket([]byte(bucketName))
|
||||||
|
seqId := bucket.Sequence()
|
||||||
|
buckets[bucketName] = int(seqId)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
|
||||||
|
return buckets, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (connection *DbConnection) RestoreMetadata(s map[string]interface{}) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
for bucketName, v := range s {
|
||||||
|
id, ok := v.(float64) // JSON ints are unmarshalled to interface as float64. See: https://pkg.go.dev/encoding/json#Decoder.Decode
|
||||||
|
if !ok {
|
||||||
|
logrus.Errorf("Failed to restore metadata to bucket %s, skipped", bucketName)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
err = connection.Batch(func(tx *bolt.Tx) error {
|
||||||
|
bucket := tx.Bucket([]byte(bucketName))
|
||||||
|
return bucket.SetSequence(uint64(id))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package fdoprofile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
portainer "github.com/portainer/portainer/api"
|
portainer "github.com/portainer/portainer/api"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
|
@ -369,6 +369,7 @@ type storeExport struct {
|
||||||
User []portainer.User `json:"users,omitempty"`
|
User []portainer.User `json:"users,omitempty"`
|
||||||
Version map[string]string `json:"version,omitempty"`
|
Version map[string]string `json:"version,omitempty"`
|
||||||
Webhook []portainer.Webhook `json:"webhooks,omitempty"`
|
Webhook []portainer.Webhook `json:"webhooks,omitempty"`
|
||||||
|
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *Store) Export(filename string) (err error) {
|
func (store *Store) Export(filename string) (err error) {
|
||||||
|
@ -561,6 +562,11 @@ func (store *Store) Export(filename string) (err error) {
|
||||||
"INSTANCE_ID": instance,
|
"INSTANCE_ID": instance,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backup.Metadata, err = store.connection.BackupMetadata()
|
||||||
|
if err != nil {
|
||||||
|
logrus.WithError(err).Errorf("Exporting Metadata")
|
||||||
|
}
|
||||||
|
|
||||||
b, err := json.MarshalIndent(backup, "", " ")
|
b, err := json.MarshalIndent(backup, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -569,6 +575,7 @@ func (store *Store) Export(filename string) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *Store) Import(filename string) (err error) {
|
func (store *Store) Import(filename string) (err error) {
|
||||||
|
|
||||||
backup := storeExport{}
|
backup := storeExport{}
|
||||||
|
|
||||||
s, err := ioutil.ReadFile(filename)
|
s, err := ioutil.ReadFile(filename)
|
||||||
|
@ -669,5 +676,5 @@ func (store *Store) Import(filename string) (err error) {
|
||||||
store.Webhook().UpdateWebhook(v.ID, &v)
|
store.Webhook().UpdateWebhook(v.ID, &v)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return store.connection.RestoreMetadata(backup.Metadata)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue