1
// Copyright 2014 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
9
"gopkg.in/juju/blobstore.v2"
14
// metadataDB is the name of the blobstore metadata database.
17
// blobstoreDB is the name of the blobstore GridFS database.
18
blobstoreDB = "blobstore"
21
// Storage is an interface providing methods for storing and retrieving
23
type Storage interface {
24
// Get returns an io.ReadCloser for data at path, namespaced to the
27
// If the data is still being uploaded and is not fully written yet, a
28
// blobstore.ErrUploadPending error is returned. This means the path is
29
// valid but the caller should try again later to retrieve the data.
30
Get(path string) (r io.ReadCloser, length int64, err error)
32
// Put stores data from reader at path, namespaced to the model.
33
Put(path string, r io.Reader, length int64) error
35
// PutAndCheckHash stores data from reader at path, namespaced to
36
// the model. It also ensures the stored data has the correct
38
PutAndCheckHash(path string, r io.Reader, length int64, hash string) error
40
// Remove removes data at path, namespaced to the model.
41
Remove(path string) error
44
// Storage returns a Storage for the model with the specified UUID.
45
func NewStorage(modelUUID string, session *mgo.Session) Storage {
46
return stateStorage{modelUUID, session}
49
type stateStorage struct {
54
func (s stateStorage) blobstore() (*mgo.Session, blobstore.ManagedStorage) {
55
session := s.session.Copy()
56
rs := blobstore.NewGridFS(blobstoreDB, blobstoreDB, session)
57
db := session.DB(metadataDB)
58
return session, blobstore.NewManagedStorage(db, rs)
61
func (s stateStorage) Get(path string) (r io.ReadCloser, length int64, err error) {
62
session, ms := s.blobstore()
63
r, length, err = ms.GetForBucket(s.modelUUID, path)
68
return &stateStorageReadCloser{r, session}, length, nil
71
func (s stateStorage) Put(path string, r io.Reader, length int64) error {
72
session, ms := s.blobstore()
74
return ms.PutForBucket(s.modelUUID, path, r, length)
77
func (s stateStorage) PutAndCheckHash(path string, r io.Reader, length int64, hash string) error {
78
session, ms := s.blobstore()
80
return ms.PutForBucketAndCheckHash(s.modelUUID, path, r, length, hash)
83
func (s stateStorage) Remove(path string) error {
84
session, ms := s.blobstore()
86
return ms.RemoveForBucket(s.modelUUID, path)
89
type stateStorageReadCloser struct {
94
func (r *stateStorageReadCloser) Close() error {
96
return r.ReadCloser.Close()