Left: | ||
Right: |
OLD | NEW |
---|---|
1 // Copyright 2013 Canonical Ltd. | 1 // Copyright 2013 Canonical Ltd. |
2 // Licensed under the AGPLv3, see LICENCE file for details. | 2 // Licensed under the AGPLv3, see LICENCE file for details. |
3 | 3 |
4 package apiserver | 4 package apiserver |
5 | 5 |
6 import ( | 6 import ( |
7 "fmt" | 7 "fmt" |
8 "launchpad.net/juju-core/charm" | 8 "launchpad.net/juju-core/charm" |
9 "launchpad.net/juju-core/juju" | 9 "launchpad.net/juju-core/juju" |
10 "launchpad.net/juju-core/log" | 10 "launchpad.net/juju-core/log" |
11 "launchpad.net/juju-core/state" | 11 "launchpad.net/juju-core/state" |
12 "launchpad.net/juju-core/state/api" | 12 "launchpad.net/juju-core/state/api" |
13 "launchpad.net/juju-core/state/api/params" | 13 "launchpad.net/juju-core/state/api/params" |
14 "launchpad.net/juju-core/state/multiwatcher" | 14 "launchpad.net/juju-core/state/multiwatcher" |
15 "launchpad.net/juju-core/state/presence" | 15 "launchpad.net/juju-core/state/presence" |
16 "launchpad.net/juju-core/state/statecmd" | 16 "launchpad.net/juju-core/state/statecmd" |
17 statewatcher "launchpad.net/juju-core/state/watcher" | 17 statewatcher "launchpad.net/juju-core/state/watcher" |
18 "strconv" | 18 "strconv" |
19 "sync" | 19 "sync" |
20 ) | 20 ) |
21 | 21 |
22 // srvRoot represents a single client's connection to the state. | 22 // srvRoot represents a single client's connection to the state. |
23 type srvRoot struct { | 23 type srvRoot struct { |
24 admin *srvAdmin | 24 admin *srvAdmin |
25 client *srvClient | 25 client *srvClient |
26 state *srvState | |
26 srv *Server | 27 srv *Server |
27 resources *resources | 28 resources *resources |
28 | 29 |
29 user authUser | 30 user authUser |
30 } | 31 } |
31 | 32 |
32 // srvAdmin is the only object that unlogged-in | 33 // srvAdmin is the only object that unlogged-in |
33 // clients can access. It holds any methods | 34 // clients can access. It holds any methods |
34 // that are needed to log in. | 35 // that are needed to log in. |
35 type srvAdmin struct { | 36 type srvAdmin struct { |
(...skipping 16 matching lines...) Expand all Loading... | |
52 type srvUser struct { | 53 type srvUser struct { |
53 root *srvRoot | 54 root *srvRoot |
54 u *state.User | 55 u *state.User |
55 } | 56 } |
56 | 57 |
57 // srvClient serves client-specific API methods. | 58 // srvClient serves client-specific API methods. |
58 type srvClient struct { | 59 type srvClient struct { |
59 root *srvRoot | 60 root *srvRoot |
60 } | 61 } |
61 | 62 |
63 // srvState serves agent-specific top-level state API methods. | |
64 type srvState struct { | |
65 root *srvRoot | |
66 } | |
67 | |
68 // WatchMachines registers a srvLifecycleWatcher that notifies of | |
69 // changes to the lifecycles of the machines in the environment. The | |
70 // result contains the id of the registered watcher and the initial | |
71 // list of machine ids. | |
72 func (s *srvState) WatchMachines() (params.LifecycleWatchResults, error) { | |
rog
2013/05/24 13:35:13
these two methods should be further down the file,
dimitern
2013/05/24 14:07:44
Done.
| |
73 watcher := s.root.srv.state.WatchMachines() | |
74 // To save an extra round-trip to call Next after Watch, we check | |
75 // for initial changes. | |
76 initial, ok := <-watcher.Changes() | |
77 if !ok { | |
78 return params.LifecycleWatchResults{}, statewatcher.MustErr(watc her) | |
79 } | |
80 return params.LifecycleWatchResults{ | |
81 LifecycleWatcherId: s.root.resources.register(watcher).id, | |
82 Ids: initial, | |
83 }, nil | |
84 } | |
85 | |
86 // WatchEnvironConfig registers a srvEnvironConfigWatcher for | |
87 // observing changes to the environment configuration. The result | |
88 // contains the id of the registered watcher and the current | |
89 // environment configuration. | |
90 func (s *srvState) WatchEnvironConfig() (params.EnvironConfigWatchResults, error ) { | |
91 watcher := s.root.srv.state.WatchEnvironConfig() | |
rog
2013/05/24 13:35:13
// TODO restrict access to environment manager mac
dimitern
2013/05/24 14:07:44
No need, I added the authEnvironManager check anyw
| |
92 // To save an extra round-trip to call Next after Watch, we check | |
rog
2013/05/24 13:35:13
// The watcher always sends an initial value on th
dimitern
2013/05/24 14:07:44
Done. Also updated the other places.
| |
93 // for initial changes. | |
94 initial, ok := <-watcher.Changes() | |
95 if !ok { | |
96 return params.EnvironConfigWatchResults{}, statewatcher.MustErr( watcher) | |
97 } | |
98 return params.EnvironConfigWatchResults{ | |
99 EnvironConfigWatcherId: s.root.resources.register(watcher).id, | |
100 Config: initial.AllAttrs(), | |
101 }, nil | |
102 } | |
103 | |
62 func newStateServer(srv *Server) *srvRoot { | 104 func newStateServer(srv *Server) *srvRoot { |
63 r := &srvRoot{ | 105 r := &srvRoot{ |
64 srv: srv, | 106 srv: srv, |
65 resources: newResources(), | 107 resources: newResources(), |
66 } | 108 } |
67 r.admin = &srvAdmin{ | 109 r.admin = &srvAdmin{ |
68 root: r, | 110 root: r, |
69 } | 111 } |
70 r.client = &srvClient{ | 112 r.client = &srvClient{ |
71 root: r, | 113 root: r, |
72 } | 114 } |
115 r.state = &srvState{ | |
116 root: r, | |
117 } | |
73 return r | 118 return r |
74 } | 119 } |
75 | 120 |
76 // Kill implements rpc.Killer. It cleans up any resources that need | 121 // Kill implements rpc.Killer. It cleans up any resources that need |
77 // cleaning up to ensure that all outstanding requests return. | 122 // cleaning up to ensure that all outstanding requests return. |
78 func (r *srvRoot) Kill() { | 123 func (r *srvRoot) Kill() { |
79 r.resources.stopAll() | 124 r.resources.stopAll() |
80 } | 125 } |
81 | 126 |
82 // Admin returns an object that provides API access | 127 // Admin returns an object that provides API access |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
204 watcher := r.resources.get(id) | 249 watcher := r.resources.get(id) |
205 if watcher == nil { | 250 if watcher == nil { |
206 return srvEntityWatcher{}, errUnknownWatcher | 251 return srvEntityWatcher{}, errUnknownWatcher |
207 } | 252 } |
208 if _, ok := watcher.resource.(*state.EntityWatcher); !ok { | 253 if _, ok := watcher.resource.(*state.EntityWatcher); !ok { |
209 return srvEntityWatcher{}, errUnknownWatcher | 254 return srvEntityWatcher{}, errUnknownWatcher |
210 } | 255 } |
211 return srvEntityWatcher{watcher}, nil | 256 return srvEntityWatcher{watcher}, nil |
212 } | 257 } |
213 | 258 |
259 // LifecycleWatcher returns an object that provides | |
260 // API access to methods on a state.LifecycleWatcher. | |
261 // Each client has its own current set of watchers, stored | |
262 // in r.resources. | |
263 func (r *srvRoot) LifecycleWatcher(id string) (srvLifecycleWatcher, error) { | |
264 if err := r.requireAgent(); err != nil { | |
265 return srvLifecycleWatcher{}, err | |
266 } | |
267 watcher := r.resources.get(id) | |
268 if watcher == nil { | |
269 return srvLifecycleWatcher{}, errUnknownWatcher | |
270 } | |
271 if _, ok := watcher.resource.(*state.LifecycleWatcher); !ok { | |
272 return srvLifecycleWatcher{}, errUnknownWatcher | |
273 } | |
274 return srvLifecycleWatcher{watcher}, nil | |
275 } | |
276 | |
277 // EnvironConfigWatcher returns an object that provides | |
278 // API access to methods on a state.EnvironConfigWatcher. | |
279 // Each client has its own current set of watchers, stored | |
280 // in r.resources. | |
281 func (r *srvRoot) EnvironConfigWatcher(id string) (srvEnvironConfigWatcher, erro r) { | |
282 if err := r.requireAgent(); err != nil { | |
283 return srvEnvironConfigWatcher{}, err | |
284 } | |
285 watcher := r.resources.get(id) | |
286 if watcher == nil { | |
287 return srvEnvironConfigWatcher{}, errUnknownWatcher | |
288 } | |
289 if _, ok := watcher.resource.(*state.EnvironConfigWatcher); !ok { | |
290 return srvEnvironConfigWatcher{}, errUnknownWatcher | |
291 } | |
292 return srvEnvironConfigWatcher{watcher}, nil | |
293 } | |
294 | |
214 // AllWatcher returns an object that provides API access to methods on | 295 // AllWatcher returns an object that provides API access to methods on |
215 // a state/multiwatcher.Watcher, which watches any changes to the | 296 // a state/multiwatcher.Watcher, which watches any changes to the |
216 // state. Each client has its own current set of watchers, stored in | 297 // state. Each client has its own current set of watchers, stored in |
217 // r.resources. | 298 // r.resources. |
218 func (r *srvRoot) AllWatcher(id string) (srvClientAllWatcher, error) { | 299 func (r *srvRoot) AllWatcher(id string) (srvClientAllWatcher, error) { |
219 if err := r.requireClient(); err != nil { | 300 if err := r.requireClient(); err != nil { |
220 return srvClientAllWatcher{}, err | 301 return srvClientAllWatcher{}, err |
221 } | 302 } |
222 watcher := r.resources.get(id) | 303 watcher := r.resources.get(id) |
223 if watcher == nil { | 304 if watcher == nil { |
224 return srvClientAllWatcher{}, errUnknownWatcher | 305 return srvClientAllWatcher{}, errUnknownWatcher |
225 } | 306 } |
226 if _, ok := watcher.resource.(*multiwatcher.Watcher); !ok { | 307 if _, ok := watcher.resource.(*multiwatcher.Watcher); !ok { |
227 return srvClientAllWatcher{}, errUnknownWatcher | 308 return srvClientAllWatcher{}, errUnknownWatcher |
228 } | 309 } |
229 return srvClientAllWatcher{watcher}, nil | 310 return srvClientAllWatcher{watcher}, nil |
230 | 311 |
231 } | 312 } |
232 | 313 |
314 // State returns an object that provides API access to top-level state methods. | |
315 func (r *srvRoot) State(id string) (*srvState, error) { | |
316 if err := r.requireAgent(); err != nil { | |
317 return nil, err | |
318 } | |
319 if id != "" { | |
320 // Safeguard id for possible future use. | |
321 return nil, errBadId | |
322 } | |
323 return r.state, nil | |
324 } | |
325 | |
233 // Client returns an object that provides access | 326 // Client returns an object that provides access |
234 // to methods accessible to non-agent clients. | 327 // to methods accessible to non-agent clients. |
235 func (r *srvRoot) Client(id string) (*srvClient, error) { | 328 func (r *srvRoot) Client(id string) (*srvClient, error) { |
236 if err := r.requireClient(); err != nil { | 329 if err := r.requireClient(); err != nil { |
237 return nil, err | 330 return nil, err |
238 } | 331 } |
239 if id != "" { | 332 if id != "" { |
240 // Safeguard id for possible future use. | 333 // Safeguard id for possible future use. |
241 return nil, errBadId | 334 return nil, errBadId |
242 } | 335 } |
(...skipping 30 matching lines...) Expand all Loading... | |
273 if _, ok := <-watcher.Changes(); ok { | 366 if _, ok := <-watcher.Changes(); ok { |
274 return nil | 367 return nil |
275 } | 368 } |
276 err := watcher.Err() | 369 err := watcher.Err() |
277 if err == nil { | 370 if err == nil { |
278 err = errStoppedWatcher | 371 err = errStoppedWatcher |
279 } | 372 } |
280 return err | 373 return err |
281 } | 374 } |
282 | 375 |
376 // srvLifecycleWatcher notifies about lifecycle changes for all | |
377 // entities of a given kind. See state.LifecycleWatcher. | |
378 type srvLifecycleWatcher struct { | |
379 *srvResource | |
380 } | |
381 | |
382 // Next returns when a change has occured to the lifecycle of an | |
383 // entity of the collection being watched since the most recent call | |
384 // to Next or the Watch call that created the srvLifecycleWatcher. | |
385 func (w srvLifecycleWatcher) Next() (params.LifecycleWatchResults, error) { | |
386 watcher := w.resource.(*state.LifecycleWatcher) | |
387 if changes, ok := <-watcher.Changes(); ok { | |
388 return params.LifecycleWatchResults{ | |
389 Ids: changes, | |
390 }, nil | |
391 } | |
392 err := watcher.Err() | |
393 if err == nil { | |
394 err = errStoppedWatcher | |
395 } | |
396 return params.LifecycleWatchResults{}, err | |
397 } | |
398 | |
399 // srvEnvironConfigWatcher notifies about changes to the environment | |
400 // configuration. See state.EnvironConfigWatcher. | |
401 type srvEnvironConfigWatcher struct { | |
402 *srvResource | |
403 } | |
404 | |
405 // Next returns when a change has occured to the environment | |
406 // configuration since the most recent call to Next or the Watch call | |
407 // that created the srvEnvironConfigWatcher. | |
408 func (w srvEnvironConfigWatcher) Next() (params.EnvironConfigWatchResults, error ) { | |
409 watcher := w.resource.(*state.EnvironConfigWatcher) | |
410 if changes, ok := <-watcher.Changes(); ok { | |
411 return params.EnvironConfigWatchResults{ | |
412 Config: changes.AllAttrs(), | |
413 }, nil | |
414 } | |
415 err := watcher.Err() | |
416 if err == nil { | |
417 err = errStoppedWatcher | |
418 } | |
419 return params.EnvironConfigWatchResults{}, err | |
420 } | |
421 | |
283 func (c *srvClient) Status() (api.Status, error) { | 422 func (c *srvClient) Status() (api.Status, error) { |
284 ms, err := c.root.srv.state.AllMachines() | 423 ms, err := c.root.srv.state.AllMachines() |
285 if err != nil { | 424 if err != nil { |
286 return api.Status{}, err | 425 return api.Status{}, err |
287 } | 426 } |
288 status := api.Status{ | 427 status := api.Status{ |
289 Machines: make(map[string]api.MachineInfo), | 428 Machines: make(map[string]api.MachineInfo), |
290 } | 429 } |
291 for _, m := range ms { | 430 for _, m := range ms { |
292 instId, _ := m.InstanceId() | 431 instId, _ := m.InstanceId() |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
513 | 652 |
514 // Get retrieves all the details of a machine. | 653 // Get retrieves all the details of a machine. |
515 func (m *srvMachine) Get() (info params.Machine) { | 654 func (m *srvMachine) Get() (info params.Machine) { |
516 instId, _ := m.m.InstanceId() | 655 instId, _ := m.m.InstanceId() |
517 info.InstanceId = string(instId) | 656 info.InstanceId = string(instId) |
518 info.Life = params.Life(m.m.Life().String()) | 657 info.Life = params.Life(m.m.Life().String()) |
519 return | 658 return |
520 } | 659 } |
521 | 660 |
522 func (m *srvMachine) Watch() (params.EntityWatcherId, error) { | 661 func (m *srvMachine) Watch() (params.EntityWatcherId, error) { |
523 » w := m.m.Watch() | 662 » watcher := m.m.Watch() |
524 » if _, ok := <-w.Changes(); !ok { | 663 » // To save an extra round-trip to call Next after Watch, we check |
525 » » return params.EntityWatcherId{}, statewatcher.MustErr(w) | 664 » // for initial changes. |
665 » if _, ok := <-watcher.Changes(); !ok { | |
666 » » return params.EntityWatcherId{}, statewatcher.MustErr(watcher) | |
526 } | 667 } |
527 return params.EntityWatcherId{ | 668 return params.EntityWatcherId{ |
528 » » EntityWatcherId: m.root.resources.register(w).id, | 669 » » EntityWatcherId: m.root.resources.register(watcher).id, |
529 }, nil | 670 }, nil |
530 } | 671 } |
531 | 672 |
532 // SetAgentAlive signals that the agent for machine m is alive. | 673 // SetAgentAlive signals that the agent for machine m is alive. |
533 func (m *srvMachine) SetAgentAlive() (params.PingerId, error) { | 674 func (m *srvMachine) SetAgentAlive() (params.PingerId, error) { |
534 if !m.root.authOwner(m.m) { | 675 if !m.root.authOwner(m.m) { |
535 return params.PingerId{}, errPerm | 676 return params.PingerId{}, errPerm |
536 } | 677 } |
537 pinger, err := m.m.SetAgentAlive() | 678 pinger, err := m.m.SetAgentAlive() |
538 if err != nil { | 679 if err != nil { |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
741 func (rs *resources) stopAll() { | 882 func (rs *resources) stopAll() { |
742 rs.mu.Lock() | 883 rs.mu.Lock() |
743 defer rs.mu.Unlock() | 884 defer rs.mu.Unlock() |
744 for _, r := range rs.rs { | 885 for _, r := range rs.rs { |
745 if err := r.resource.Stop(); err != nil { | 886 if err := r.resource.Stop(); err != nil { |
746 log.Errorf("state/api: error stopping %T resource: %v", r, err) | 887 log.Errorf("state/api: error stopping %T resource: %v", r, err) |
747 } | 888 } |
748 } | 889 } |
749 rs.rs = make(map[string]*srvResource) | 890 rs.rs = make(map[string]*srvResource) |
750 } | 891 } |
OLD | NEW |