builder/googlecompute: delete instance

This commit is contained in:
Mitchell Hashimoto 2013-12-12 22:34:47 -08:00
parent f72f7a37d1
commit 57f707dfcc
5 changed files with 70 additions and 22 deletions

View File

@ -4,6 +4,9 @@ package googlecompute
// with GCE. The Driver interface exists mostly to allow a mock implementation // with GCE. The Driver interface exists mostly to allow a mock implementation
// to be used to test the steps. // to be used to test the steps.
type Driver interface { type Driver interface {
// DeleteInstance deletes the given instance.
DeleteInstance(zone, name string) (<-chan error, error)
// RunInstance takes the given config and launches an instance. // RunInstance takes the given config and launches an instance.
RunInstance(*InstanceConfig) (<-chan error, error) RunInstance(*InstanceConfig) (<-chan error, error)
} }

View File

@ -59,6 +59,17 @@ func NewDriverGCE(ui packer.Ui, projectId string, c *clientSecrets, key []byte)
}, nil }, nil
} }
func (d *driverGCE) DeleteInstance(zone, name string) (<-chan error, error) {
op, err := d.service.Instances.Delete(d.projectId, zone, name).Do()
if err != nil {
return nil, err
}
errCh := make(chan error, 1)
go waitForState(errCh, "DONE", d.refreshZoneOp(zone, op))
return errCh, nil
}
func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) { func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) {
// Get the zone // Get the zone
d.ui.Message(fmt.Sprintf("Loading zone: %s", c.Zone)) d.ui.Message(fmt.Sprintf("Loading zone: %s", c.Zone))

View File

@ -3,11 +3,30 @@ package googlecompute
// DriverMock is a Driver implementation that is a mocked out so that // DriverMock is a Driver implementation that is a mocked out so that
// it can be used for tests. // it can be used for tests.
type DriverMock struct { type DriverMock struct {
DeleteInstanceZone string
DeleteInstanceName string
DeleteInstanceErrCh <-chan error
DeleteInstanceErr error
RunInstanceConfig *InstanceConfig RunInstanceConfig *InstanceConfig
RunInstanceErrCh <-chan error RunInstanceErrCh <-chan error
RunInstanceErr error RunInstanceErr error
} }
func (d *DriverMock) DeleteInstance(zone, name string) (<-chan error, error) {
d.DeleteInstanceZone = zone
d.DeleteInstanceName = name
resultCh := d.DeleteInstanceErrCh
if resultCh == nil {
ch := make(chan error)
close(ch)
resultCh = ch
}
return resultCh, d.DeleteInstanceErr
}
func (d *DriverMock) RunInstance(c *InstanceConfig) (<-chan error, error) { func (d *DriverMock) RunInstance(c *InstanceConfig) (<-chan error, error) {
d.RunInstanceConfig = c d.RunInstanceConfig = c

View File

@ -68,27 +68,28 @@ func (s *StepCreateInstance) Cleanup(state multistep.StateBag) {
if s.instanceName == "" { if s.instanceName == "" {
return return
} }
/*
var ( config := state.Get("config").(*Config)
client = state.Get("client").(*GoogleComputeClient) driver := state.Get("driver").(Driver)
config = state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui)
ui = state.Get("ui").(packer.Ui)
) ui.Say("Deleting instance...")
ui.Say("Destroying instance...") errCh, err := driver.DeleteInstance(config.Zone, s.instanceName)
operation, err := client.DeleteInstance(config.Zone, s.instanceName) if err == nil {
if err != nil { select {
ui.Error(fmt.Sprintf("Error destroying instance. Please destroy it manually: %v", s.instanceName)) case err = <-errCh:
case <-time.After(config.stateTimeout):
err = errors.New("time out while waiting for instance to delete")
} }
ui.Say("Waiting for the instance to be deleted...") }
for {
status, err := client.ZoneOperationStatus(config.Zone, operation.Name) if err != nil {
if err != nil { ui.Error(fmt.Sprintf(
ui.Error(fmt.Sprintf("Error destroying instance. Please destroy it manually: %v", s.instanceName)) "Error deleting instance. Please delete it manually.\n\n"+
} "Name: %s\n"+
if status == "DONE" { "Error: %s", s.instanceName, err))
break }
}
} s.instanceName = ""
*/
return return
} }

View File

@ -18,15 +18,29 @@ func TestStepCreateInstance(t *testing.T) {
state.Put("ssh_public_key", "key") state.Put("ssh_public_key", "key")
config := state.Get("config").(*Config)
driver := state.Get("driver").(*DriverMock)
// run the step // run the step
if action := step.Run(state); action != multistep.ActionContinue { if action := step.Run(state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action) t.Fatalf("bad action: %#v", action)
} }
// Verify state // Verify state
if _, ok := state.GetOk("instance_name"); !ok { nameRaw, ok := state.GetOk("instance_name")
if !ok {
t.Fatal("should have instance name") t.Fatal("should have instance name")
} }
// cleanup
step.Cleanup(state)
if driver.DeleteInstanceName != nameRaw.(string) {
t.Fatal("should've deleted instance")
}
if driver.DeleteInstanceZone != config.Zone {
t.Fatal("bad zone: %#v", driver.DeleteInstanceZone)
}
} }
func TestStepCreateInstance_error(t *testing.T) { func TestStepCreateInstance_error(t *testing.T) {