| OLD | NEW |
| 1 package uniter | 1 package uniter |
| 2 | 2 |
| 3 import ( | 3 import ( |
| 4 "errors" | 4 "errors" |
| 5 "fmt" | 5 "fmt" |
| 6 "launchpad.net/juju-core/environs" | 6 "launchpad.net/juju-core/environs" |
| 7 "launchpad.net/juju-core/log" | 7 "launchpad.net/juju-core/log" |
| 8 "launchpad.net/juju-core/state" | 8 "launchpad.net/juju-core/state" |
| 9 "launchpad.net/juju-core/state/watcher" | 9 "launchpad.net/juju-core/state/watcher" |
| 10 "launchpad.net/juju-core/worker/uniter/charm" | 10 "launchpad.net/juju-core/worker/uniter/charm" |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 if err = u.unit.SetStatus(state.UnitStarted, ""); err != nil { | 144 if err = u.unit.SetStatus(state.UnitStarted, ""); err != nil { |
| 145 return nil, err | 145 return nil, err |
| 146 } | 146 } |
| 147 | 147 |
| 148 // To begin with, only watch for config changes, and exploit the | 148 // To begin with, only watch for config changes, and exploit the |
| 149 // guaranteed initial send to ensure we run a config-changed hook | 149 // guaranteed initial send to ensure we run a config-changed hook |
| 150 // before starting any other watches. | 150 // before starting any other watches. |
| 151 starting := true | 151 starting := true |
| 152 configw := u.service.WatchConfig() | 152 configw := u.service.WatchConfig() |
| 153 defer stop(configw, &next, &err) | 153 defer stop(configw, &next, &err) |
| 154 » var charmw *state.ServiceCharmWatcher | 154 » var servicew *state.ServiceWatcher |
| 155 » var charms <-chan state.ServiceCharmChange | 155 » var serviceChanges <-chan *state.Service |
| 156 for { | 156 for { |
| 157 select { | 157 select { |
| 158 case <-u.tomb.Dying(): | 158 case <-u.tomb.Dying(): |
| 159 return nil, tomb.ErrDying | 159 return nil, tomb.ErrDying |
| 160 case _, ok := <-configw.Changes(): | 160 case _, ok := <-configw.Changes(): |
| 161 if !ok { | 161 if !ok { |
| 162 return nil, watcher.MustErr(configw) | 162 return nil, watcher.MustErr(configw) |
| 163 } | 163 } |
| 164 hi := hook.Info{Kind: hook.ConfigChanged} | 164 hi := hook.Info{Kind: hook.ConfigChanged} |
| 165 if err = u.runHook(hi); err != nil { | 165 if err = u.runHook(hi); err != nil { |
| 166 if err == errHookFailed { | 166 if err == errHookFailed { |
| 167 return ModeHookError, nil | 167 return ModeHookError, nil |
| 168 } | 168 } |
| 169 return nil, err | 169 return nil, err |
| 170 } | 170 } |
| 171 if starting { | 171 if starting { |
| 172 // If we haven't already set up additional watch
es, do so now. | 172 // If we haven't already set up additional watch
es, do so now. |
| 173 starting = false | 173 starting = false |
| 174 » » » » charmw = u.service.WatchCharm() | 174 » » » » servicew = u.service.Watch() |
| 175 » » » » defer stop(charmw, &next, &err) | 175 » » » » defer stop(servicew, &next, &err) |
| 176 » » » » charms = charmw.Changes() | 176 » » » » serviceChanges = servicew.Changes() |
| 177 } | 177 } |
| 178 » » case ch, ok := <-charms: | 178 » » case service, ok := <-serviceChanges: |
| 179 if !ok { | 179 if !ok { |
| 180 » » » » return nil, watcher.MustErr(charmw) | 180 » » » » return nil, watcher.MustErr(servicew) |
| 181 » » » } |
| 182 » » » ch, _, err := service.Charm() |
| 183 » » » if err != nil { |
| 184 » » » » return nil, err |
| 181 } | 185 } |
| 182 url, err := charm.ReadCharmURL(u.charm) | 186 url, err := charm.ReadCharmURL(u.charm) |
| 183 if err != nil { | 187 if err != nil { |
| 184 return nil, err | 188 return nil, err |
| 185 } | 189 } |
| 186 » » » if *ch.Charm.URL() != *url { | 190 » » » if *ch.URL() != *url { |
| 187 » » » » return ModeUpgrading(ch.Charm), nil | 191 » » » » return ModeUpgrading(ch), nil |
| 188 } | 192 } |
| 189 } | 193 } |
| 190 // TODO: unit death; relations. | 194 // TODO: unit death; relations. |
| 191 } | 195 } |
| 192 panic("unreachable") | 196 panic("unreachable") |
| 193 } | 197 } |
| 194 | 198 |
| 195 // ModeHookError is responsible for watching and responding to: | 199 // ModeHookError is responsible for watching and responding to: |
| 196 // * user resolution of hook errors | 200 // * user resolution of hook errors |
| 197 // * forced charm upgrade requests (not implemented) | 201 // * forced charm upgrade requests (not implemented) |
| 198 // * unit death (not implemented) | 202 // * unit death (not implemented) |
| 199 func ModeHookError(u *Uniter) (next Mode, err error) { | 203 func ModeHookError(u *Uniter) (next Mode, err error) { |
| 200 defer errorContextf(&err, "ModeHookError") | 204 defer errorContextf(&err, "ModeHookError") |
| 201 s, err := u.sf.Read() | 205 s, err := u.sf.Read() |
| 202 if err != nil { | 206 if err != nil { |
| 203 return nil, err | 207 return nil, err |
| 204 } | 208 } |
| 205 if s.Op != RunHook || s.OpStep != Pending { | 209 if s.Op != RunHook || s.OpStep != Pending { |
| 206 return nil, fmt.Errorf("insane uniter state: %#v", s) | 210 return nil, fmt.Errorf("insane uniter state: %#v", s) |
| 207 } | 211 } |
| 208 msg := fmt.Sprintf("hook failed: %q", s.Hook.Kind) | 212 msg := fmt.Sprintf("hook failed: %q", s.Hook.Kind) |
| 209 if err = u.unit.SetStatus(state.UnitError, msg); err != nil { | 213 if err = u.unit.SetStatus(state.UnitError, msg); err != nil { |
| 210 return nil, err | 214 return nil, err |
| 211 } | 215 } |
| 212 | 216 |
| 213 // Wait for shutdown, error resolution, or forced charm upgrade. | 217 // Wait for shutdown, error resolution, or forced charm upgrade. |
| 214 » resolvedw := u.unit.WatchResolved() | 218 » unitw := u.unit.Watch() |
| 215 » defer stop(resolvedw, &next, &err) | 219 » defer stop(unitw, &next, &err) |
| 216 » charmw := u.service.WatchCharm() | 220 » servicew := u.service.Watch() |
| 217 » defer stop(charmw, &next, &err) | 221 » defer stop(servicew, &next, &err) |
| 218 for { | 222 for { |
| 219 select { | 223 select { |
| 220 case <-u.tomb.Dying(): | 224 case <-u.tomb.Dying(): |
| 221 return nil, tomb.ErrDying | 225 return nil, tomb.ErrDying |
| 222 » » case rm, ok := <-resolvedw.Changes(): | 226 » » case unit, ok := <-unitw.Changes(): |
| 227 » » » // TODO: unit death. |
| 223 if !ok { | 228 if !ok { |
| 224 » » » » return nil, watcher.MustErr(resolvedw) | 229 » » » » return nil, watcher.MustErr(unitw) |
| 225 } | 230 } |
| 226 » » » switch rm { | 231 » » » switch unit.Resolved() { |
| 227 case state.ResolvedNone: | 232 case state.ResolvedNone: |
| 228 continue | 233 continue |
| 229 case state.ResolvedRetryHooks: | 234 case state.ResolvedRetryHooks: |
| 230 err = u.runHook(*s.Hook) | 235 err = u.runHook(*s.Hook) |
| 231 case state.ResolvedNoHooks: | 236 case state.ResolvedNoHooks: |
| 232 err = u.commitHook(*s.Hook) | 237 err = u.commitHook(*s.Hook) |
| 233 default: | 238 default: |
| 234 » » » » panic(fmt.Errorf("unhandled resolved mode %q", r
m)) | 239 » » » » panic(fmt.Errorf("unhandled resolved mode %q", u
nit.Resolved())) |
| 235 } | 240 } |
| 236 » » » if e := u.unit.ClearResolved(); e != nil { | 241 » » » if e := unit.ClearResolved(); e != nil { |
| 237 err = e | 242 err = e |
| 238 } | 243 } |
| 239 if err == errHookFailed { | 244 if err == errHookFailed { |
| 240 continue | 245 continue |
| 241 } else if err != nil { | 246 } else if err != nil { |
| 242 return nil, err | 247 return nil, err |
| 243 } | 248 } |
| 244 return ModeContinue, nil | 249 return ModeContinue, nil |
| 245 » » case ch, ok := <-charmw.Changes(): | 250 » » case service, ok := <-servicew.Changes(): |
| 246 if !ok { | 251 if !ok { |
| 247 » » » » return nil, watcher.MustErr(charmw) | 252 » » » » return nil, watcher.MustErr(servicew) |
| 253 » » » } |
| 254 » » » ch, force, err := service.Charm() |
| 255 » » » if err != nil { |
| 256 » » » » return nil, err |
| 248 } | 257 } |
| 249 url, err := charm.ReadCharmURL(u.charm) | 258 url, err := charm.ReadCharmURL(u.charm) |
| 250 if err != nil { | 259 if err != nil { |
| 251 return nil, err | 260 return nil, err |
| 252 } | 261 } |
| 253 » » » if ch.Force && *ch.Charm.URL() != *url { | 262 » » » if force && *ch.URL() != *url { |
| 254 » » » » return ModeUpgrading(ch.Charm), nil | 263 » » » » return ModeUpgrading(ch), nil |
| 255 } | 264 } |
| 256 } | 265 } |
| 257 // TODO: unit death. | |
| 258 } | 266 } |
| 259 panic("unreachable") | 267 panic("unreachable") |
| 260 } | 268 } |
| 261 | 269 |
| 262 // ModeUpgrading is responsible for upgrading the charm. | 270 // ModeUpgrading is responsible for upgrading the charm. |
| 263 func ModeUpgrading(sch *state.Charm) Mode { | 271 func ModeUpgrading(sch *state.Charm) Mode { |
| 264 return func(u *Uniter) (Mode, error) { | 272 return func(u *Uniter) (Mode, error) { |
| 265 log.Printf("upgrading charm to %q", sch.URL()) | 273 log.Printf("upgrading charm to %q", sch.URL()) |
| 266 if err := u.deploy(sch, Upgrade); err != nil { | 274 if err := u.deploy(sch, Upgrade); err != nil { |
| 267 if err == charm.ErrConflict { | 275 if err == charm.ErrConflict { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 } | 343 } |
| 336 | 344 |
| 337 // errorContextf prefixes the error stored in err with text formatted | 345 // errorContextf prefixes the error stored in err with text formatted |
| 338 // according to the format specifier. If err does not contain an error, | 346 // according to the format specifier. If err does not contain an error, |
| 339 // or if err is tomb.ErrDying, errorContextf does nothing. | 347 // or if err is tomb.ErrDying, errorContextf does nothing. |
| 340 func errorContextf(err *error, format string, args ...interface{}) { | 348 func errorContextf(err *error, format string, args ...interface{}) { |
| 341 if *err != nil && *err != tomb.ErrDying { | 349 if *err != nil && *err != tomb.ErrDying { |
| 342 *err = errors.New(fmt.Sprintf(format, args...) + ": " + (*err).E
rror()) | 350 *err = errors.New(fmt.Sprintf(format, args...) + ": " + (*err).E
rror()) |
| 343 } | 351 } |
| 344 } | 352 } |
| OLD | NEW |