OLD | NEW |
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 provisioner | 4 package provisioner |
5 | 5 |
6 import ( | 6 import ( |
7 "launchpad.net/juju-core/constraints" | 7 "launchpad.net/juju-core/constraints" |
8 "launchpad.net/juju-core/instance" | 8 "launchpad.net/juju-core/instance" |
9 "launchpad.net/juju-core/names" | 9 "launchpad.net/juju-core/names" |
10 "launchpad.net/juju-core/state" | 10 "launchpad.net/juju-core/state" |
11 "launchpad.net/juju-core/state/api/params" | 11 "launchpad.net/juju-core/state/api/params" |
12 "launchpad.net/juju-core/state/apiserver/common" | 12 "launchpad.net/juju-core/state/apiserver/common" |
13 "launchpad.net/juju-core/state/watcher" | 13 "launchpad.net/juju-core/state/watcher" |
| 14 "launchpad.net/juju-core/utils/set" |
14 ) | 15 ) |
15 | 16 |
16 // ProvisionerAPI provides access to the Provisioner API facade. | 17 // ProvisionerAPI provides access to the Provisioner API facade. |
17 type ProvisionerAPI struct { | 18 type ProvisionerAPI struct { |
18 *common.Remover | 19 *common.Remover |
19 *common.StatusSetter | 20 *common.StatusSetter |
20 *common.DeadEnsurer | 21 *common.DeadEnsurer |
21 *common.PasswordChanger | 22 *common.PasswordChanger |
22 *common.LifeGetter | 23 *common.LifeGetter |
23 *common.StateAddresser | 24 *common.StateAddresser |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 for i, entity := range args.Entities { | 276 for i, entity := range args.Entities { |
276 machine, err := p.getMachine(canAccess, entity.Tag) | 277 machine, err := p.getMachine(canAccess, entity.Tag) |
277 if err == nil { | 278 if err == nil { |
278 result.Results[i].Result = machine.Series() | 279 result.Results[i].Result = machine.Series() |
279 } | 280 } |
280 result.Results[i].Error = common.ServerError(err) | 281 result.Results[i].Error = common.ServerError(err) |
281 } | 282 } |
282 return result, nil | 283 return result, nil |
283 } | 284 } |
284 | 285 |
| 286 // DistributionGroup returns, for each given machine entity, |
| 287 // a slice of instance.Ids that belong to the same distribution |
| 288 // group as that machine. This information may be used to |
| 289 // distribute instances for high availability. |
| 290 func (p *ProvisionerAPI) DistributionGroup(args params.Entities) (params.Distrib
utionGroupResults, error) { |
| 291 result := params.DistributionGroupResults{ |
| 292 Results: make([]params.DistributionGroupResult, len(args.Entitie
s)), |
| 293 } |
| 294 canAccess, err := p.getAuthFunc() |
| 295 if err != nil { |
| 296 return result, err |
| 297 } |
| 298 for i, entity := range args.Entities { |
| 299 machine, err := p.getMachine(canAccess, entity.Tag) |
| 300 if err == nil { |
| 301 // If the machine is an environment manager, return |
| 302 // environment manager instances. Otherwise, return |
| 303 // instances with services in common with the machine |
| 304 // being provisioned. |
| 305 if machine.IsManager() { |
| 306 result.Results[i].Result, err = environManagerIn
stances(p.st) |
| 307 } else { |
| 308 result.Results[i].Result, err = commonServiceIns
tances(p.st, machine) |
| 309 } |
| 310 } |
| 311 result.Results[i].Error = common.ServerError(err) |
| 312 } |
| 313 return result, nil |
| 314 } |
| 315 |
| 316 // environManagerInstances returns all environ manager instances. |
| 317 func environManagerInstances(st *state.State) ([]instance.Id, error) { |
| 318 info, err := st.StateServerInfo() |
| 319 if err != nil { |
| 320 return nil, err |
| 321 } |
| 322 instances := make([]instance.Id, 0, len(info.MachineIds)) |
| 323 for _, id := range info.MachineIds { |
| 324 machine, err := st.Machine(id) |
| 325 if err != nil { |
| 326 return nil, err |
| 327 } |
| 328 instanceId, err := machine.InstanceId() |
| 329 if err == nil { |
| 330 instances = append(instances, instanceId) |
| 331 } else if !state.IsNotProvisionedError(err) { |
| 332 return nil, err |
| 333 } |
| 334 } |
| 335 return instances, nil |
| 336 } |
| 337 |
| 338 // commonServiceInstances returns instances with |
| 339 // services in common with the specified machine. |
| 340 func commonServiceInstances(st *state.State, m *state.Machine) ([]instance.Id, e
rror) { |
| 341 units, err := m.Units() |
| 342 if err != nil { |
| 343 return nil, err |
| 344 } |
| 345 var instanceIdSet set.Strings |
| 346 for _, unit := range units { |
| 347 if !unit.IsPrincipal() { |
| 348 continue |
| 349 } |
| 350 service, err := unit.Service() |
| 351 if err != nil { |
| 352 return nil, err |
| 353 } |
| 354 allUnits, err := service.AllUnits() |
| 355 if err != nil { |
| 356 return nil, err |
| 357 } |
| 358 for _, unit := range allUnits { |
| 359 machineId, err := unit.AssignedMachineId() |
| 360 if state.IsNotAssigned(err) { |
| 361 continue |
| 362 } else if err != nil { |
| 363 return nil, err |
| 364 } |
| 365 machine, err := st.Machine(machineId) |
| 366 if err != nil { |
| 367 return nil, err |
| 368 } |
| 369 instanceId, err := machine.InstanceId() |
| 370 if err == nil { |
| 371 instanceIdSet.Add(string(instanceId)) |
| 372 } else if state.IsNotProvisionedError(err) { |
| 373 continue |
| 374 } else { |
| 375 return nil, err |
| 376 } |
| 377 } |
| 378 } |
| 379 instanceIds := make([]instance.Id, instanceIdSet.Size()) |
| 380 // Sort values to simplify testing. |
| 381 for i, instanceId := range instanceIdSet.SortedValues() { |
| 382 instanceIds[i] = instance.Id(instanceId) |
| 383 } |
| 384 return instanceIds, nil |
| 385 } |
| 386 |
285 // Constraints returns the constraints for each given machine entity. | 387 // Constraints returns the constraints for each given machine entity. |
286 func (p *ProvisionerAPI) Constraints(args params.Entities) (params.ConstraintsRe
sults, error) { | 388 func (p *ProvisionerAPI) Constraints(args params.Entities) (params.ConstraintsRe
sults, error) { |
287 result := params.ConstraintsResults{ | 389 result := params.ConstraintsResults{ |
288 Results: make([]params.ConstraintsResult, len(args.Entities)), | 390 Results: make([]params.ConstraintsResult, len(args.Entities)), |
289 } | 391 } |
290 canAccess, err := p.getAuthFunc() | 392 canAccess, err := p.getAuthFunc() |
291 if err != nil { | 393 if err != nil { |
292 return result, err | 394 return result, err |
293 } | 395 } |
294 for i, entity := range args.Entities { | 396 for i, entity := range args.Entities { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 } | 466 } |
365 watch := newWatchMachineErrorRetry() | 467 watch := newWatchMachineErrorRetry() |
366 // Consume any initial event and forward it to the result. | 468 // Consume any initial event and forward it to the result. |
367 if _, ok := <-watch.Changes(); ok { | 469 if _, ok := <-watch.Changes(); ok { |
368 result.NotifyWatcherId = p.resources.Register(watch) | 470 result.NotifyWatcherId = p.resources.Register(watch) |
369 } else { | 471 } else { |
370 return result, watcher.MustErr(watch) | 472 return result, watcher.MustErr(watch) |
371 } | 473 } |
372 return result, nil | 474 return result, nil |
373 } | 475 } |
OLD | NEW |