// deleteSecurityGroup attempts to delete the security group. Should it fail, // the deletion is retried due to timing issues in openstack. A security group // cannot be deleted while it is in use. Theoretically we terminate all the // instances before we attempt to delete the associated security groups, but // in practice nova hasn't always finished with the instance before it // returns, so there is a race condition where we think the instance is // terminated and hence attempt to delete the security groups but nova still // has it around internally. To attempt to catch this timing issue, deletion // of the groups is tried multiple times. func deleteSecurityGroup(novaclient *nova.Client, name, id string) { logger.Debugf("deleting security group %q", name) err := retry.Call(retry.CallArgs{ Func: func() error { return novaclient.DeleteSecurityGroup(id) }, NotifyFunc: func(err error, attempt int) { if attempt%4 == 0 { message := fmt.Sprintf("waiting to delete security group %q", name) if attempt != 4 { message = "still " + message } logger.Debugf(message) } }, Attempts: 30, Delay: time.Second, // TODO(dimitern): This should be fixed to take a clock.Clock arg, not // hard-coded WallClock, like in provider/ec2/securitygroups_test.go! // See PR juju:#5197, especially the code around autoAdvancingClock. // LP Bug: http://pad.lv/1580626. Clock: clock.WallClock, }) if err != nil { logger.Warningf("cannot delete security group %q. Used by another model?", name) } }
// deleteSecurityGroup attempts to delete the security group. Should it fail, // the deletion is retried due to timing issues in openstack. A security group // cannot be deleted while it is in use. Theoretically we terminate all the // instances before we attempt to delete the associated security groups, but // in practice nova hasn't always finished with the instance before it // returns, so there is a race condition where we think the instance is // terminated and hence attempt to delete the security groups but nova still // has it around internally. To attempt to catch this timing issue, deletion // of the groups is tried multiple times. func deleteSecurityGroup(novaclient *nova.Client, name, id string) { logger.Debugf("deleting security group %q", name) err := retry.Call(retry.CallArgs{ Func: func() error { return novaclient.DeleteSecurityGroup(id) }, NotifyFunc: func(err error, attempt int) { if attempt%4 == 0 { message := fmt.Sprintf("waiting to delete security group %q", name) if attempt != 4 { message = "still " + message } logger.Debugf(message) } }, Attempts: 30, Delay: time.Second, Clock: clock.WallClock, }) if err != nil { logger.Warningf("cannot delete security group %q. Used by another environment?", name) } }