github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/state/binarystorage.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state 5 6 import ( 7 "github.com/juju/errors" 8 jujutxn "github.com/juju/txn" 9 "gopkg.in/juju/blobstore.v2" 10 11 "github.com/juju/juju/mongo" 12 "github.com/juju/juju/state/binarystorage" 13 ) 14 15 var binarystorageNew = binarystorage.New 16 17 // ToolsStorage returns a new binarystorage.StorageCloser that stores tools 18 // metadata in the "juju" database "toolsmetadata" collection. 19 func (st *State) ToolsStorage() (binarystorage.StorageCloser, error) { 20 if st.IsController() { 21 return st.newBinaryStorageCloser(toolsmetadataC, st.ModelUUID()), nil 22 } 23 24 // This is a hosted model. Hosted models have their own tools 25 // catalogue, which we combine with the controller's. 26 27 controllerSt, err := st.ForModel(st.controllerTag) 28 if err != nil { 29 return nil, errors.Trace(err) 30 } 31 defer controllerSt.Close() 32 controllerStorage, err := controllerSt.ToolsStorage() 33 if err != nil { 34 return nil, errors.Trace(err) 35 } 36 37 modelStorage := st.newBinaryStorageCloser(toolsmetadataC, st.ModelUUID()) 38 storage, err := binarystorage.NewLayeredStorage(modelStorage, controllerStorage) 39 if err != nil { 40 modelStorage.Close() 41 controllerStorage.Close() 42 return nil, errors.Trace(err) 43 } 44 return &storageCloser{storage, func() { 45 modelStorage.Close() 46 controllerStorage.Close() 47 }}, nil 48 } 49 50 // GUIStorage returns a new binarystorage.StorageCloser that stores GUI archive 51 // metadata in the "juju" database "guimetadata" collection. 52 func (st *State) GUIStorage() (binarystorage.StorageCloser, error) { 53 return st.newBinaryStorageCloser(guimetadataC, st.controllerTag.Id()), nil 54 } 55 56 func (st *State) newBinaryStorageCloser(collectionName, uuid string) binarystorage.StorageCloser { 57 db, closer1 := st.database.CopySession() 58 metadataCollection, closer2 := db.GetCollection(collectionName) 59 txnRunner, closer3 := db.TransactionRunner() 60 closer := func() { 61 closer3() 62 closer2() 63 closer1() 64 } 65 storage := newBinaryStorage(uuid, metadataCollection, txnRunner) 66 return &storageCloser{storage, closer} 67 } 68 69 func newBinaryStorage(uuid string, metadataCollection mongo.Collection, txnRunner jujutxn.Runner) binarystorage.Storage { 70 db := metadataCollection.Writeable().Underlying().Database 71 rs := blobstore.NewGridFS(blobstoreDB, blobstoreDB, db.Session) 72 managedStorage := blobstore.NewManagedStorage(db, rs) 73 return binarystorageNew(uuid, managedStorage, metadataCollection, txnRunner) 74 } 75 76 type storageCloser struct { 77 binarystorage.Storage 78 closer func() 79 } 80 81 func (sc *storageCloser) Close() error { 82 sc.closer() 83 return nil 84 }