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  }