in integration_test/gce-testing-internal/gce/gce_testing.go [1342:1412]
func attemptCreateInstance(ctx context.Context, logger *log.Logger, options VMOptions) (vmToReturn *VM, errToReturn error) {
vm := createVMFromVMOptions(options)
imageFamilyScope := options.ImageFamilyScope
if imageFamilyScope == "" {
imageFamilyScope = "global"
}
args := []string{
// "beta" is needed for --max-run-duration.
"beta", "compute", "instances", "create", vm.Name,
"--project=" + vm.Project,
"--zone=" + vm.Zone,
"--machine-type=" + vm.MachineType,
"--image-family-scope=" + imageFamilyScope,
"--network=" + vm.Network,
"--format=json",
}
additionalArgs, err := additionalCreateInstanceArgs(options, vm)
if err != nil {
return nil, err
}
args = append(args, additionalArgs...)
output, err := RunGcloud(ctx, logger, "", args)
if err != nil {
// Note: we don't try and delete the VM in this case because there is
// nothing to delete.
return nil, err
}
defer func() {
if errToReturn != nil {
// This function is responsible for deleting the VM in all error cases.
errToReturn = multierr.Append(errToReturn, DeleteInstance(logger, vm))
// Make sure to never return both a valid VM object and an error.
vmToReturn = nil
}
if errToReturn == nil && vm == nil {
errToReturn = errors.New("programming error: attemptCreateInstance() returned nil VM and nil error")
}
}()
// Pull the instance ID and external IP address out of the output.
id, err := extractID(output.Stdout)
if err != nil {
return nil, err
}
vm.ID = id
logger.Printf("Instance Log: %v", instanceLogURL(vm))
ipAddress, err := extractIPAddress(output.Stdout)
if err != nil {
return nil, err
}
vm.IPAddress = ipAddress
// This is just informational, so it's ok if it fails. Just warn and proceed.
if _, err := DescribeVMDisk(ctx, logger, vm); err != nil {
logger.Printf("Unable to retrieve information about the VM's boot disk: %v", err)
}
if err := verifyVMCreation(ctx, logger, vm); err != nil {
return nil, err
}
return vm, nil
}