Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(46)

Side by Side Diff: worker/apiuniter/modes.go

Issue 13355046: worker/apiuniter: State to API migration (Closed)
Patch Set: worker/apiuniter: State to API migration Created 11 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « worker/apiuniter/jujuc/util_test.go ('k') | worker/apiuniter/relationer.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012, 2013 Canonical Ltd. 1 // Copyright 2012, 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 apiuniter 4 package apiuniter
5 5
6 import ( 6 import (
7 stderrors "errors" 7 stderrors "errors"
8 "fmt" 8 "fmt"
9 9
10 "launchpad.net/tomb" 10 "launchpad.net/tomb"
11 11
12 "launchpad.net/juju-core/charm" 12 "launchpad.net/juju-core/charm"
13 "launchpad.net/juju-core/charm/hooks" 13 "launchpad.net/juju-core/charm/hooks"
14 "launchpad.net/juju-core/environs" 14 "launchpad.net/juju-core/environs"
15 "launchpad.net/juju-core/errors"
16 "launchpad.net/juju-core/state"
17 "launchpad.net/juju-core/state/api/params" 15 "launchpad.net/juju-core/state/api/params"
18 "launchpad.net/juju-core/state/watcher" 16 "launchpad.net/juju-core/state/watcher"
19 "launchpad.net/juju-core/worker" 17 "launchpad.net/juju-core/worker"
20 ucharm "launchpad.net/juju-core/worker/apiuniter/charm" 18 ucharm "launchpad.net/juju-core/worker/apiuniter/charm"
21 "launchpad.net/juju-core/worker/apiuniter/hook" 19 "launchpad.net/juju-core/worker/apiuniter/hook"
22 ) 20 )
23 21
24 // Mode defines the signature of the functions that implement the possible 22 // Mode defines the signature of the functions that implement the possible
25 // states of a running Uniter. 23 // states of a running Uniter.
26 type Mode func(u *Uniter) (Mode, error) 24 type Mode func(u *Uniter) (Mode, error)
27 25
28 // ModeInit is the initial Uniter mode. 26 // ModeInit is the initial Uniter mode.
29 func ModeInit(u *Uniter) (next Mode, err error) { 27 func ModeInit(u *Uniter) (next Mode, err error) {
30 defer modeContext("ModeInit", &err)() 28 defer modeContext("ModeInit", &err)()
31 logger.Infof("updating unit addresses") 29 logger.Infof("updating unit addresses")
32 » // TODO(dimitern): Once the uniter is using the API, change the 30 » // TODO(dimitern): We might be able to drop all this address stuff
33 » // following block to use st.ProviderType() instead of calling 31 » // entirely once we have machine addresses.
34 » // st.EnvironConfig. Also, We might be able to drop all this 32 » providerType, err := u.st.ProviderType()
35 » // address stuff entirely once we have machine addresses.
36 » cfg, err := u.st.EnvironConfig()
37 if err != nil { 33 if err != nil {
38 return nil, err 34 return nil, err
39 } 35 }
40 » provider, err := environs.Provider(cfg.Type()) 36 » provider, err := environs.Provider(providerType)
41 if err != nil { 37 if err != nil {
42 return nil, err 38 return nil, err
43 } 39 }
44 if private, err := provider.PrivateAddress(); err != nil { 40 if private, err := provider.PrivateAddress(); err != nil {
41 logger.Errorf("cannot get unit's private address: %v", err)
45 return nil, err 42 return nil, err
46 } else if err = u.unit.SetPrivateAddress(private); err != nil { 43 } else if err = u.unit.SetPrivateAddress(private); err != nil {
44 logger.Errorf("cannot set unit's private address: %v", err)
47 return nil, err 45 return nil, err
48 } 46 }
49 if public, err := provider.PublicAddress(); err != nil { 47 if public, err := provider.PublicAddress(); err != nil {
48 logger.Errorf("cannot get unit's public address: %v", err)
50 return nil, err 49 return nil, err
51 } else if err = u.unit.SetPublicAddress(public); err != nil { 50 } else if err = u.unit.SetPublicAddress(public); err != nil {
51 logger.Errorf("cannot set unit's public address: %v", err)
52 return nil, err 52 return nil, err
53 } 53 }
54 logger.Infof("reconciling relation state") 54 logger.Infof("reconciling relation state")
55 if err := u.restoreRelations(); err != nil { 55 if err := u.restoreRelations(); err != nil {
56 return nil, err 56 return nil, err
57 } 57 }
58 return ModeContinue, nil 58 return ModeContinue, nil
59 } 59 }
60 60
61 // ModeContinue determines what action to take based on persistent uniter state. 61 // ModeContinue determines what action to take based on persistent uniter state.
62 func ModeContinue(u *Uniter) (next Mode, err error) { 62 func ModeContinue(u *Uniter) (next Mode, err error) {
63 defer modeContext("ModeContinue", &err)() 63 defer modeContext("ModeContinue", &err)()
64 64
65 // If we haven't yet loaded state, do so. 65 // If we haven't yet loaded state, do so.
66 if u.s == nil { 66 if u.s == nil {
67 logger.Infof("loading uniter state") 67 logger.Infof("loading uniter state")
68 if u.s, err = u.sf.Read(); err == ErrNoStateFile { 68 if u.s, err = u.sf.Read(); err == ErrNoStateFile {
69 // When no state exists, start from scratch. 69 // When no state exists, start from scratch.
70 logger.Infof("charm is not deployed") 70 logger.Infof("charm is not deployed")
71 » » » curl, _ := u.service.CharmURL() 71 » » » curl, _, err := u.service.CharmURL()
72 » » » if err != nil {
73 » » » » return nil, err
74 » » » }
72 return ModeInstalling(curl), nil 75 return ModeInstalling(curl), nil
73 } else if err != nil { 76 } else if err != nil {
74 return nil, err 77 return nil, err
75 } 78 }
76 } 79 }
77 80
78 // Filter out states not related to charm deployment. 81 // Filter out states not related to charm deployment.
79 switch u.s.Op { 82 switch u.s.Op {
80 case Continue: 83 case Continue:
81 logger.Infof("continuing after %q hook", u.s.Hook.Kind) 84 logger.Infof("continuing after %q hook", u.s.Hook.Kind)
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 } 191 }
189 return ModeContinue, nil 192 return ModeContinue, nil
190 } 193 }
191 194
192 // ModeTerminating marks the unit dead and returns ErrTerminateAgent. 195 // ModeTerminating marks the unit dead and returns ErrTerminateAgent.
193 func ModeTerminating(u *Uniter) (next Mode, err error) { 196 func ModeTerminating(u *Uniter) (next Mode, err error) {
194 defer modeContext("ModeTerminating", &err)() 197 defer modeContext("ModeTerminating", &err)()
195 if err = u.unit.SetStatus(params.StatusStopped, ""); err != nil { 198 if err = u.unit.SetStatus(params.StatusStopped, ""); err != nil {
196 return nil, err 199 return nil, err
197 } 200 }
198 » w := u.unit.Watch() 201 » w, err := u.unit.Watch()
202 » if err != nil {
203 » » return nil, err
204 » }
199 defer watcher.Stop(w, &u.tomb) 205 defer watcher.Stop(w, &u.tomb)
200 for { 206 for {
201 select { 207 select {
202 case <-u.tomb.Dying(): 208 case <-u.tomb.Dying():
203 return nil, tomb.ErrDying 209 return nil, tomb.ErrDying
204 case _, ok := <-w.Changes(): 210 case _, ok := <-w.Changes():
205 if !ok { 211 if !ok {
206 return nil, watcher.MustErr(w) 212 return nil, watcher.MustErr(w)
207 } 213 }
208 if err := u.unit.Refresh(); err != nil { 214 if err := u.unit.Refresh(); err != nil {
209 return nil, err 215 return nil, err
210 } 216 }
211 » » » // TODO(dimitern): Once the uniter uses the API, call 217 » » » if hasSubs, err := u.unit.HasSubordinates(); err != nil {
212 » » » // u.unit.HasSubordinates() here instead. 218 » » » » return nil, err
213 » » » if len(u.unit.SubordinateNames()) > 0 { 219 » » » } else if hasSubs {
214 continue 220 continue
215 } 221 }
216 // The unit is known to be Dying; so if it didn't have s ubordinates 222 // The unit is known to be Dying; so if it didn't have s ubordinates
217 // just above, it can't acquire new ones before this cal l. 223 // just above, it can't acquire new ones before this cal l.
218 if err := u.unit.EnsureDead(); err != nil { 224 if err := u.unit.EnsureDead(); err != nil {
219 return nil, err 225 return nil, err
220 } 226 }
221 return nil, worker.ErrTerminateAgent 227 return nil, worker.ErrTerminateAgent
222 } 228 }
223 } 229 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 } 293 }
288 } 294 }
289 } 295 }
290 296
291 // modeAbideDyingLoop handles the proper termination of all relations in 297 // modeAbideDyingLoop handles the proper termination of all relations in
292 // response to a Dying unit. 298 // response to a Dying unit.
293 func modeAbideDyingLoop(u *Uniter) (next Mode, err error) { 299 func modeAbideDyingLoop(u *Uniter) (next Mode, err error) {
294 if err := u.unit.Refresh(); err != nil { 300 if err := u.unit.Refresh(); err != nil {
295 return nil, err 301 return nil, err
296 } 302 }
297 » // TODO(dimitern): Once the uniter uses the API, use 303 » if err = u.unit.DestroyAllSubordinates(); err != nil {
298 » // u.unit.DestroyAllSubordinates() here, instead of going 304 » » return nil, err
299 » // through each subordinate calling Destroy() on it.
300 » for _, name := range u.unit.SubordinateNames() {
301 » » if sub, err := u.st.Unit(name); errors.IsNotFoundError(err) {
302 » » » continue
303 » » } else if err != nil {
304 » » » return nil, err
305 » » } else if err = sub.Destroy(); err != nil {
306 » » » return nil, err
307 » » }
308 } 305 }
309 for id, r := range u.relationers { 306 for id, r := range u.relationers {
310 if err := r.SetDying(); err != nil { 307 if err := r.SetDying(); err != nil {
311 return nil, err 308 return nil, err
312 } else if r.IsImplicit() { 309 } else if r.IsImplicit() {
313 delete(u.relationers, id) 310 delete(u.relationers, id)
314 } 311 }
315 } 312 }
316 for { 313 for {
317 if len(u.relationers) == 0 { 314 if len(u.relationers) == 0 {
(...skipping 28 matching lines...) Expand all
346 return nil, err 343 return nil, err
347 } 344 }
348 u.f.WantResolvedEvent() 345 u.f.WantResolvedEvent()
349 u.f.WantUpgradeEvent(true) 346 u.f.WantUpgradeEvent(true)
350 for { 347 for {
351 select { 348 select {
352 case <-u.tomb.Dying(): 349 case <-u.tomb.Dying():
353 return nil, tomb.ErrDying 350 return nil, tomb.ErrDying
354 case rm := <-u.f.ResolvedEvents(): 351 case rm := <-u.f.ResolvedEvents():
355 switch rm { 352 switch rm {
356 » » » case state.ResolvedRetryHooks: 353 » » » case params.ResolvedRetryHooks:
357 err = u.runHook(*u.s.Hook) 354 err = u.runHook(*u.s.Hook)
358 » » » case state.ResolvedNoHooks: 355 » » » case params.ResolvedNoHooks:
359 err = u.commitHook(*u.s.Hook) 356 err = u.commitHook(*u.s.Hook)
360 default: 357 default:
361 return nil, fmt.Errorf("unknown resolved mode %q ", rm) 358 return nil, fmt.Errorf("unknown resolved mode %q ", rm)
362 } 359 }
363 if e := u.f.ClearResolved(); e != nil { 360 if e := u.f.ClearResolved(); e != nil {
364 return nil, e 361 return nil, e
365 } 362 }
366 if err == errHookFailed { 363 if err == errHookFailed {
367 continue 364 continue
368 } else if err != nil { 365 } else if err != nil {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 logger.Infof("%s starting", name) 412 logger.Infof("%s starting", name)
416 return func() { 413 return func() {
417 logger.Debugf("%s exiting", name) 414 logger.Debugf("%s exiting", name)
418 switch *err { 415 switch *err {
419 case nil, tomb.ErrDying, worker.ErrTerminateAgent: 416 case nil, tomb.ErrDying, worker.ErrTerminateAgent:
420 default: 417 default:
421 *err = stderrors.New(name + ": " + (*err).Error()) 418 *err = stderrors.New(name + ": " + (*err).Error())
422 } 419 }
423 } 420 }
424 } 421 }
OLDNEW
« no previous file with comments | « worker/apiuniter/jujuc/util_test.go ('k') | worker/apiuniter/relationer.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b