func startInstance(ec2HostConfig *config.Ec2HostConfig, instance *ec2.Instance, svc *ec2.EC2) error { startCalled := false instanceId := *instance.InstanceId // wait until the state is anything but "pending" statePoll: for { state, err := getInstanceState(instanceId, svc) if err != nil { return err } log.Printf("Instance %s is in state %s", instanceId, state) switch state { case "pending", "shutting-down", "stopping": // for any of the transient states, just wait time.Sleep(time.Second / 2) case "running": // running is the state we want to get to break statePoll case "stopped": log.Printf("starting instance %s", instanceId) if startCalled { return fmt.Errorf("instance %s did not enter the running state", instanceId) } // start a stopped instance params := &ec2.StartInstancesInput{ InstanceIds: []*string{aws.String(instanceId)}, } _, err := svc.StartInstances(params) if err != nil { return err } startCalled = true case "terminated": return fmt.Errorf("Instance is terminated") } } // wait for SSH port to be open, too for { // re-search for the instance, since it probably didn't have a public ip address // when it was disconnected -- TODO refactor if instance.PublicIpAddress == nil { var err error instance, err = findInstance(ec2HostConfig, svc) if err != nil { return fmt.Errorf("while searcihng for running instance: %s", err) } } conn, err := net.Dial("tcp", fmt.Sprintf("%s:22", *instance.PublicIpAddress)) if err != nil { log.Printf("connecting to port 22: %s; retrying", err) time.Sleep(time.Second / 2) } else { conn.Close() break } } return nil }