github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/resource/resourceadapters/opener.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package resourceadapters
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"gopkg.in/juju/names.v2"
     9  
    10  	csclient "github.com/juju/juju/charmstore"
    11  	"github.com/juju/juju/resource"
    12  	"github.com/juju/juju/resource/charmstore"
    13  	corestate "github.com/juju/juju/state"
    14  )
    15  
    16  // NewResourceOpener returns a new resource.Opener for the given unit.
    17  //
    18  // The caller owns the State provided. It is the caller's
    19  // responsibility to close it.
    20  //
    21  // TODO(mjs): This is the entry point for a whole lot of untested shim
    22  // code in this package. At some point this should be sorted out.
    23  func NewResourceOpener(st *corestate.State, unitName string) (opener resource.Opener, err error) {
    24  	unit, err := st.Unit(unitName)
    25  	if err != nil {
    26  		return nil, errors.Annotate(err, "loading unit")
    27  	}
    28  
    29  	resources, err := st.Resources()
    30  	if err != nil {
    31  		return nil, errors.Trace(err)
    32  	}
    33  
    34  	opener = &resourceOpener{
    35  		st:     st,
    36  		res:    resources,
    37  		userID: unit.Tag(),
    38  		unit:   unit,
    39  	}
    40  	return opener, nil
    41  }
    42  
    43  // resourceOpener is an implementation of server.ResourceOpener.
    44  type resourceOpener struct {
    45  	st     *corestate.State
    46  	res    corestate.Resources
    47  	userID names.Tag
    48  	unit   *corestate.Unit
    49  }
    50  
    51  // OpenResource implements server.ResourceOpener.
    52  func (ro *resourceOpener) OpenResource(name string) (o resource.Opened, err error) {
    53  	if ro.unit == nil {
    54  		return resource.Opened{}, errors.Errorf("missing unit")
    55  	}
    56  	app, err := ro.unit.Application()
    57  	if err != nil {
    58  		return resource.Opened{}, errors.Trace(err)
    59  	}
    60  	cURL, _ := ro.unit.CharmURL()
    61  	id := csclient.CharmID{
    62  		URL:     cURL,
    63  		Channel: app.Channel(),
    64  	}
    65  
    66  	csOpener := newCharmstoreOpener(ro.st)
    67  	client, err := csOpener.NewClient()
    68  	if err != nil {
    69  		return resource.Opened{}, errors.Trace(err)
    70  	}
    71  
    72  	cache := &charmstoreEntityCache{
    73  		st:            ro.res,
    74  		userID:        ro.userID,
    75  		unit:          ro.unit,
    76  		applicationID: ro.unit.ApplicationName(),
    77  	}
    78  
    79  	res, reader, err := charmstore.GetResource(charmstore.GetResourceArgs{
    80  		Client:  client,
    81  		Cache:   cache,
    82  		CharmID: id,
    83  		Name:    name,
    84  	})
    85  	if err != nil {
    86  		return resource.Opened{}, errors.Trace(err)
    87  	}
    88  
    89  	opened := resource.Opened{
    90  		Resource:   res,
    91  		ReadCloser: reader,
    92  	}
    93  	return opened, nil
    94  }