Left: | ||
Right: |
OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2013 Canonical Ltd. | |
2 // Licensed under the AGPLv3, see LICENCE file for details. | |
3 | |
4 package charmrevisionupdater | |
5 | |
6 import ( | |
7 "launchpad.net/loggo" | |
8 | |
9 "launchpad.net/juju-core/charm" | |
10 "launchpad.net/juju-core/log" | |
11 "launchpad.net/juju-core/state" | |
12 "launchpad.net/juju-core/state/api/params" | |
13 "launchpad.net/juju-core/state/apiserver/common" | |
14 ) | |
15 | |
16 var logger = loggo.GetLogger("juju.state.apiserver.charmrevisionupdater") | |
17 | |
18 // CharmRevisionUpdater defines the methods on the charmrevisionupdater API end point. | |
19 type CharmRevisionUpdater interface { | |
20 UpdateLatestRevisions() (params.ErrorResult, error) | |
21 } | |
22 | |
23 // CharmRevisionUpdaterAPI implements the CharmRevisionUpdater interface and is the concrete | |
24 // implementation of the api end point. | |
25 type CharmRevisionUpdaterAPI struct { | |
26 state *state.State | |
27 resources *common.Resources | |
28 authorizer common.Authorizer | |
29 } | |
30 | |
31 var _ CharmRevisionUpdater = (*CharmRevisionUpdaterAPI)(nil) | |
32 | |
33 // NewCharmRevisionUpdaterAPI creates a new server-side charmrevisionupdater API end point. | |
34 func NewCharmRevisionUpdaterAPI( | |
35 st *state.State, | |
36 resources *common.Resources, | |
37 authorizer common.Authorizer, | |
38 ) (*CharmRevisionUpdaterAPI, error) { | |
39 if !authorizer.AuthMachineAgent() && !authorizer.AuthStateManager() { | |
40 return nil, common.ErrPerm | |
41 } | |
42 return &CharmRevisionUpdaterAPI{ | |
43 state: st, resources: resources, authorizer: authorizer}, nil | |
44 } | |
45 | |
46 // UpdateLatestRevisions retrieves the latest revision information from the char m store for all deployed charms | |
47 // and records this information in state. | |
48 func (api *CharmRevisionUpdaterAPI) UpdateLatestRevisions() (params.ErrorResult, error) { | |
49 deployedCharms, err := fetchAllDeployedCharms(api.state) | |
50 if err != nil { | |
51 return params.ErrorResult{common.ServerError(err)}, nil | |
52 } | |
53 // Look up the revision information for all the deployed charms. | |
54 curls, err := retrieveLatestCharmInfo(deployedCharms) | |
55 if err != nil { | |
56 return params.ErrorResult{common.ServerError(err)}, nil | |
57 } | |
58 // Add the charms and latest revision info to state as charm placeholder s. | |
59 for _, curl := range curls { | |
60 if err = api.state.AddStoreCharmPlaceholder(curl); err != nil { | |
61 return params.ErrorResult{common.ServerError(err)}, nil | |
62 } | |
63 } | |
64 return params.ErrorResult{}, nil | |
65 } | |
66 | |
67 // fetchAllServicesAndUnits returns a map from service name to service | |
68 // and a map from service name to unit name to unit. | |
69 func fetchAllDeployedCharms(st *state.State) (map[string]*charm.URL, error) { | |
70 deployedCharms := make(map[string]*charm.URL) | |
71 services, err := st.AllServices() | |
72 if err != nil { | |
73 return nil, err | |
74 } | |
75 for _, s := range services { | |
76 url, _ := s.CharmURL() | |
77 // Record the basic charm information so it can be bulk processe d later to | |
78 // get the available revision numbers from the repo. | |
79 baseCharm := url.WithRevision(-1) | |
80 deployedCharms[baseCharm.String()] = baseCharm | |
jameinel
2014/01/16 09:56:16
This breaks if you have the same charm deployed to
wallyworld
2014/01/16 10:11:47
Yes, that's the intent. See below.
| |
81 } | |
82 return deployedCharms, nil | |
83 } | |
84 | |
85 // retrieveLatestCharmInfo looks up the charm store to return the charm URLs for the | |
86 // latest revision of the deployed charms. | |
87 func retrieveLatestCharmInfo(deployedCharms map[string]*charm.URL) ([]*charm.URL , error) { | |
88 var curls []*charm.URL | |
89 for _, curl := range deployedCharms { | |
90 if curl.Schema == "local" { | |
91 // Version checking for charms from local repositories i s not | |
92 // currently supported, since we don't yet support passi ng in | |
93 // a path to the local repo. This may change if the need arises. | |
94 continue | |
95 } | |
96 curls = append(curls, curl) | |
97 } | |
98 | |
99 // Do a bulk call to get the revision info for all charms. | |
100 revInfo, err := charm.Store.Latest(curls...) | |
101 if err != nil { | |
102 return nil, log.LoggedErrorf(logger, "finding charm revision inf o: %v", err) | |
103 } | |
104 var latestCurls []*charm.URL | |
105 for i, info := range revInfo { | |
106 curl := curls[i] | |
107 if info.Err == nil { | |
108 latestCurls = append(latestCurls, curl.WithRevision(info .Revision)) | |
109 } else { | |
110 logger.Errorf("retrieving charm info for %s: %v", curl, info.Err) | |
111 } | |
112 } | |
113 return latestCurls, nil | |
114 } | |
OLD | NEW |