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 }