github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/volume/service/db.go (about) 1 package service // import "github.com/demonoid81/moby/volume/service" 2 3 import ( 4 "encoding/json" 5 6 "github.com/demonoid81/moby/errdefs" 7 "github.com/pkg/errors" 8 "github.com/sirupsen/logrus" 9 bolt "go.etcd.io/bbolt" 10 ) 11 12 var volumeBucketName = []byte("volumes") 13 14 type volumeMetadata struct { 15 Name string 16 Driver string 17 Labels map[string]string 18 Options map[string]string 19 } 20 21 func (s *VolumeStore) setMeta(name string, meta volumeMetadata) error { 22 return s.db.Update(func(tx *bolt.Tx) error { 23 return setMeta(tx, name, meta) 24 }) 25 } 26 27 func setMeta(tx *bolt.Tx, name string, meta volumeMetadata) error { 28 metaJSON, err := json.Marshal(meta) 29 if err != nil { 30 return err 31 } 32 b, err := tx.CreateBucketIfNotExists(volumeBucketName) 33 if err != nil { 34 return errors.Wrap(err, "error creating volume bucket") 35 } 36 return errors.Wrap(b.Put([]byte(name), metaJSON), "error setting volume metadata") 37 } 38 39 func (s *VolumeStore) getMeta(name string) (volumeMetadata, error) { 40 var meta volumeMetadata 41 err := s.db.View(func(tx *bolt.Tx) error { 42 return getMeta(tx, name, &meta) 43 }) 44 return meta, err 45 } 46 47 func getMeta(tx *bolt.Tx, name string, meta *volumeMetadata) error { 48 b := tx.Bucket(volumeBucketName) 49 if b == nil { 50 return errdefs.NotFound(errors.New("volume bucket does not exist")) 51 } 52 val := b.Get([]byte(name)) 53 if len(val) == 0 { 54 return nil 55 } 56 if err := json.Unmarshal(val, meta); err != nil { 57 return errors.Wrap(err, "error unmarshaling volume metadata") 58 } 59 return nil 60 } 61 62 func (s *VolumeStore) removeMeta(name string) error { 63 return s.db.Update(func(tx *bolt.Tx) error { 64 return removeMeta(tx, name) 65 }) 66 } 67 68 func removeMeta(tx *bolt.Tx, name string) error { 69 b := tx.Bucket(volumeBucketName) 70 return errors.Wrap(b.Delete([]byte(name)), "error removing volume metadata") 71 } 72 73 // listMeta is used during restore to get the list of volume metadata 74 // from the on-disk database. 75 // Any errors that occur are only logged. 76 func listMeta(tx *bolt.Tx) []volumeMetadata { 77 var ls []volumeMetadata 78 b := tx.Bucket(volumeBucketName) 79 b.ForEach(func(k, v []byte) error { 80 if len(v) == 0 { 81 // don't try to unmarshal an empty value 82 return nil 83 } 84 85 var m volumeMetadata 86 if err := json.Unmarshal(v, &m); err != nil { 87 // Just log the error 88 logrus.Errorf("Error while reading volume metadata for volume %q: %v", string(k), err) 89 return nil 90 } 91 ls = append(ls, m) 92 return nil 93 }) 94 return ls 95 }