~axwalk/juju-core/lp1260171-stopinstances-ids

« back to all changes in this revision

Viewing changes to provider/joyent/environ_instance.go

  • Committer: Andrew Wilkins
  • Date: 2014-05-13 11:37:40 UTC
  • Revision ID: andrew.wilkins@canonical.com-20140513113740-xghytp9prigo5add
Change StopInstances to take []instance.Id

StopInstances previously took []instance.Instance,
which is unnecessary for most providers, and imposes
an unnecessary cost for callers that only have IDs
initially. We change StopInstances to 

The openstack provider's StopInstances is now slightly
more expensive than before, requiring an additional call
to Instances. This cost will disappear when we fix the
security groups/open-port implementation.

Drive-by: the maas provider now uses a bulk "release"
in StopInstances.

Live tested on ec2, local, virtual MAAS, canonistack, azure.
I lack a Joyent account, but I think it should be fine.

Fixes lp:1260171
Fixes lp:1316272

Show diffs side-by-side

added added

removed removed

Lines of Context:
232
232
        return instance.Address{}, errors.NotImplementedf("AllocateAddress")
233
233
}
234
234
 
235
 
func (env *joyentEnviron) StopInstances(instances []instance.Instance) error {
 
235
func (env *joyentEnviron) StopInstances(ids []instance.Id) error {
236
236
        // Remove all the instances in parallel so that we incur less round-trips.
237
237
        var wg sync.WaitGroup
238
238
        //var err error
239
 
        wg.Add(len(instances))
240
 
        errc := make(chan error, len(instances))
241
 
        for _, inst := range instances {
242
 
                inst := inst.(*joyentInstance)
 
239
        wg.Add(len(ids))
 
240
        errc := make(chan error, len(ids))
 
241
        for _, id := range ids {
 
242
                id := id // copy to new free var for closure
243
243
                go func() {
244
244
                        defer wg.Done()
245
 
                        if err := inst.Stop(); err != nil {
 
245
                        if err := env.stopInstance(string(id)); err != nil {
246
246
                                errc <- err
247
247
                        }
248
248
                }()
257
257
        return nil
258
258
}
259
259
 
 
260
func (env *joyentEnviron) stopInstance(id string) error {
 
261
        // wait for machine to be running
 
262
        // if machine is still provisioning stop will fail
 
263
        for !env.pollMachineState(id, "running") {
 
264
                time.Sleep(1 * time.Second)
 
265
        }
 
266
 
 
267
        err := env.compute.cloudapi.StopMachine(id)
 
268
        if err != nil {
 
269
                return fmt.Errorf("cannot stop instance %s: %v", id, err)
 
270
        }
 
271
 
 
272
        // wait for machine to be stopped
 
273
        for !env.pollMachineState(id, "stopped") {
 
274
                time.Sleep(1 * time.Second)
 
275
        }
 
276
 
 
277
        err = env.compute.cloudapi.DeleteMachine(id)
 
278
        if err != nil {
 
279
                return fmt.Errorf("cannot delete instance %s: %v", id, err)
 
280
        }
 
281
 
 
282
        return nil
 
283
}
 
284
 
 
285
func (env *joyentEnviron) pollMachineState(machineId, state string) bool {
 
286
        machineConfig, err := env.compute.cloudapi.GetMachine(machineId)
 
287
        if err != nil {
 
288
                return false
 
289
        }
 
290
        return strings.EqualFold(machineConfig.State, state)
 
291
}
 
292
 
260
293
func (env *joyentEnviron) listInstanceTypes() ([]instances.InstanceType, error) {
261
294
        packages, err := env.compute.cloudapi.ListPackages(nil)
262
295
        if err != nil {