github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/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/blobstore/v3"
     8  	"github.com/juju/errors"
     9  	jujutxn "github.com/juju/txn/v3"
    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  	modelStorage := newBinaryStorageCloser(st.database, toolsmetadataC, st.ModelUUID())
    21  	if st.IsController() {
    22  		return modelStorage, nil
    23  	}
    24  	// This is a hosted model. Hosted models have their own tools
    25  	// catalogue, which we combine with the controller's.
    26  	controllerStorage := newBinaryStorageCloser(
    27  		st.database, toolsmetadataC, st.ControllerModelUUID(),
    28  	)
    29  	storage, err := binarystorage.NewLayeredStorage(modelStorage, controllerStorage)
    30  	if err != nil {
    31  		modelStorage.Close()
    32  		controllerStorage.Close()
    33  		return nil, errors.Trace(err)
    34  	}
    35  	return &storageCloser{storage, func() {
    36  		modelStorage.Close()
    37  		controllerStorage.Close()
    38  	}}, nil
    39  }
    40  
    41  func newBinaryStorageCloser(db Database, collectionName, uuid string) binarystorage.StorageCloser {
    42  	db, closer1 := db.CopyForModel(uuid)
    43  	metadataCollection, closer2 := db.GetCollection(collectionName)
    44  	txnRunner, closer3 := db.TransactionRunner()
    45  	closer := func() {
    46  		closer3()
    47  		closer2()
    48  		closer1()
    49  	}
    50  	storage := newBinaryStorage(uuid, metadataCollection, txnRunner)
    51  	return &storageCloser{storage, closer}
    52  }
    53  
    54  func newBinaryStorage(uuid string, metadataCollection mongo.Collection, txnRunner jujutxn.Runner) binarystorage.Storage {
    55  	db := metadataCollection.Writeable().Underlying().Database
    56  	rs := blobstore.NewGridFS(blobstoreDB, blobstoreDB, db.Session)
    57  	managedStorage := blobstore.NewManagedStorage(db, rs)
    58  	return binarystorageNew(uuid, managedStorage, metadataCollection, txnRunner)
    59  }
    60  
    61  type storageCloser struct {
    62  	binarystorage.Storage
    63  	closer func()
    64  }
    65  
    66  func (sc *storageCloser) Close() error {
    67  	sc.closer()
    68  	return nil
    69  }