in integration_test/gce-testing-internal/gce/gce_testing.go [1418:1544]
func attemptCreateManagedInstanceGroupVM(ctx context.Context, logger *log.Logger, options VMOptions) (migVmToReturn *ManagedInstanceGroupVM, errToReturn error) {
// We need a shorter uuid here to add suffixes and not go over the 63 character limit
// for resource names.
options.Name = fmt.Sprintf("%s-%s", sandboxPrefix, uuid.NewString()[:30])
migVM := &ManagedInstanceGroupVM{
VM: createVMFromVMOptions(options),
}
// Step #1 : Create vm instance template
createTemplateArgs := []string{
// "beta" is needed for --max-run-duration.
"beta", "compute", "instance-templates", "create", migVM.InstanceTemplateName(),
"--project=" + migVM.Project,
"--machine-type=" + migVM.MachineType,
"--network=" + migVM.Network,
"--format=json",
}
additionalArgs, err := additionalCreateInstanceArgs(options, migVM.VM)
if err != nil {
return nil, err
}
createTemplateArgs = append(createTemplateArgs, additionalArgs...)
output, err := RunGcloud(ctx, logger, "", createTemplateArgs)
if err != nil {
// Note: we don't try and delete the instance template or managed instance group
// in this case because there is nothing to delete.
return nil, err
}
defer func() {
if errToReturn != nil {
// This function is responsible for deleting the ManagedInstanceGroupVM in all error cases.
errToReturn = multierr.Append(errToReturn, DeleteManagedInstanceGroupVM(logger, migVM))
// Make sure to never return both a valid ManagedInstanceGroupVM object and an error.
migVmToReturn = nil
}
if errToReturn == nil && migVM.VM == nil {
errToReturn = errors.New("programming error: attemptCreateManagedInstanceGroupVM() returned nil VM and nil error")
}
}()
// Step #2 : Create empty Managed Instance Group using template.
createMIGArgs := []string{
"compute", "instance-groups", "managed", "create", migVM.ManagedInstanceGroupName(),
"--project=" + migVM.Project,
"--zone=" + migVM.Zone,
"--size=0",
"--template=" + migVM.InstanceTemplateName(),
"--format=json",
}
output, err = RunGcloud(ctx, logger, "", createMIGArgs)
if err != nil {
return nil, err
}
// Step #3 : Create test VM in Managed Instance Group.
createVMArgs := []string{
"compute", "instance-groups", "managed", "create-instance", migVM.ManagedInstanceGroupName(),
"--instance=" + migVM.Name,
"--project=" + migVM.Project,
"--zone=" + migVM.Zone,
"--format=json",
}
output, err = RunGcloud(ctx, logger, "", createVMArgs)
if err != nil {
return nil, err
}
// Step #4 : Wait until Managed Instance Group is stable with a 300s timeout.
waitUntilStableArgs := []string{
"compute", "instance-groups", "managed", "wait-until", migVM.ManagedInstanceGroupName(),
"--stable",
"--timeout=300",
"--project=" + migVM.Project,
"--zone=" + migVM.Zone,
"--format=json",
}
output, err = RunGcloud(ctx, logger, "", waitUntilStableArgs)
if err != nil {
return nil, err
}
// Step #5 : Query newly created VM metadata.
listVMArgs := []string{
"compute", "instances", "list",
"--filter=name=( '" + migVM.Name + "' ... )",
"--project=" + migVM.Project,
"--zones=" + migVM.Zone,
"--format=json",
}
output, err = RunGcloud(ctx, logger, "", listVMArgs)
if err != nil {
return nil, err
}
// Pull the instance ID and external IP address out of the output.
id, err := extractID(output.Stdout)
if err != nil {
return nil, err
}
migVM.ID = id
logger.Printf("Instance Log: %v", instanceLogURL(migVM.VM))
ipAddress, err := extractIPAddress(output.Stdout)
if err != nil {
return nil, err
}
migVM.IPAddress = ipAddress
// This is just informational, so it's ok if it fails. Just warn and proceed.
if _, err := DescribeVMDisk(ctx, logger, migVM.VM); err != nil {
logger.Printf("Unable to retrieve information about the VM's boot disk: %v", err)
}
if err := verifyVMCreation(ctx, logger, migVM.VM); err != nil {
return nil, err
}
return migVM, nil
}