func TestMultiEphemeral(t *testing.T) { client, err := newClient() th.AssertNoErr(t, err) if testing.Short() { t.Skip("Skipping test that requires server creation in short mode.") } choices, err := ComputeChoicesFromEnv() if err != nil { t.Fatal(err) } name := tools.RandomString("Gophercloud-", 8) t.Logf("Creating server [%s].", name) bd := []bootfromvolume.BlockDevice{ bootfromvolume.BlockDevice{ BootIndex: 0, UUID: choices.ImageID, SourceType: bootfromvolume.Image, DestinationType: "local", DeleteOnTermination: true, }, bootfromvolume.BlockDevice{ BootIndex: -1, SourceType: bootfromvolume.Blank, DestinationType: "local", DeleteOnTermination: true, GuestFormat: "ext4", VolumeSize: 1, }, bootfromvolume.BlockDevice{ BootIndex: -1, SourceType: bootfromvolume.Blank, DestinationType: "local", DeleteOnTermination: true, GuestFormat: "ext4", VolumeSize: 1, }, } serverCreateOpts := servers.CreateOpts{ Name: name, FlavorRef: choices.FlavorID, ImageRef: choices.ImageID, } server, err := bootfromvolume.Create(client, bootfromvolume.CreateOptsExt{ serverCreateOpts, bd, }).Extract() th.AssertNoErr(t, err) if err = waitForStatus(client, server, "ACTIVE"); err != nil { t.Fatal(err) } t.Logf("Created server: %+v\n", server) defer servers.Delete(client, server.ID) t.Logf("Deleting server [%s]...", name) }
func TestBootFromVolume(t *testing.T) { client, err := newClient() th.AssertNoErr(t, err) if testing.Short() { t.Skip("Skipping test that requires server creation in short mode.") } choices, err := ComputeChoicesFromEnv() if err != nil { t.Fatal(err) } name := tools.RandomString("Gophercloud-", 8) t.Logf("Creating server [%s].", name) bd := []bootfromvolume.BlockDevice{ bootfromvolume.BlockDevice{ UUID: choices.ImageID, SourceType: bootfromvolume.Image, VolumeSize: 10, }, } serverCreateOpts := servers.CreateOpts{ Name: name, FlavorRef: "3", } server, err := bootfromvolume.Create(client, bootfromvolume.CreateOptsExt{ serverCreateOpts, bd, }).Extract() th.AssertNoErr(t, err) t.Logf("Created server: %+v\n", server) //defer deleteServer(t, client, server) t.Logf("Deleting server [%s]...", name) }
func resourceComputeInstanceV2Create(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) computeClient, err := config.computeV2Client(d.Get("region").(string)) if err != nil { return fmt.Errorf("Error creating OpenStack compute client: %s", err) } var createOpts servers.CreateOptsBuilder // Determines the Image ID using the following rules: // If a bootable block_device was specified, ignore the image altogether. // If an image_id was specified, use it. // If an image_name was specified, look up the image ID, report if error. imageId, err := getImageIDFromConfig(computeClient, d) if err != nil { return err } flavorId, err := getFlavorID(computeClient, d) if err != nil { return err } // determine if volume/block_device configuration is correct // this includes ensuring volume_ids are set // and if only one block_device was specified. if err := checkVolumeConfig(d); err != nil { return err } // check if floating IP configuration is correct if err := checkInstanceFloatingIPs(d); err != nil { return err } // Build a list of networks with the information given upon creation. // Error out if an invalid network configuration was used. networkDetails, err := getInstanceNetworks(computeClient, d) if err != nil { return err } networks := make([]servers.Network, len(networkDetails)) for i, net := range networkDetails { networks[i] = servers.Network{ UUID: net["uuid"].(string), Port: net["port"].(string), FixedIP: net["fixed_ip_v4"].(string), } } createOpts = &servers.CreateOpts{ Name: d.Get("name").(string), ImageRef: imageId, FlavorRef: flavorId, SecurityGroups: resourceInstanceSecGroupsV2(d), AvailabilityZone: d.Get("availability_zone").(string), Networks: networks, Metadata: resourceInstanceMetadataV2(d), ConfigDrive: d.Get("config_drive").(bool), AdminPass: d.Get("admin_pass").(string), UserData: []byte(d.Get("user_data").(string)), Personality: resourceInstancePersonalityV2(d), } if keyName, ok := d.Get("key_pair").(string); ok && keyName != "" { createOpts = &keypairs.CreateOptsExt{ createOpts, keyName, } } if vL, ok := d.GetOk("block_device"); ok { for _, v := range vL.([]interface{}) { blockDeviceRaw := v.(map[string]interface{}) blockDevice := resourceInstanceBlockDeviceV2(d, blockDeviceRaw) createOpts = &bootfromvolume.CreateOptsExt{ createOpts, blockDevice, } log.Printf("[DEBUG] Create BFV Options: %+v", createOpts) } } schedulerHintsRaw := d.Get("scheduler_hints").(*schema.Set).List() if len(schedulerHintsRaw) > 0 { log.Printf("[DEBUG] schedulerhints: %+v", schedulerHintsRaw) schedulerHints := resourceInstanceSchedulerHintsV2(d, schedulerHintsRaw[0].(map[string]interface{})) createOpts = &schedulerhints.CreateOptsExt{ createOpts, schedulerHints, } } log.Printf("[DEBUG] Create Options: %#v", createOpts) // If a block_device is used, use the bootfromvolume.Create function as it allows an empty ImageRef. // Otherwise, use the normal servers.Create function. var server *servers.Server if _, ok := d.GetOk("block_device"); ok { server, err = bootfromvolume.Create(computeClient, createOpts).Extract() } else { server, err = servers.Create(computeClient, createOpts).Extract() } if err != nil { return fmt.Errorf("Error creating OpenStack server: %s", err) } log.Printf("[INFO] Instance ID: %s", server.ID) // Store the ID now d.SetId(server.ID) // Wait for the instance to become running so we can get some attributes // that aren't available until later. log.Printf( "[DEBUG] Waiting for instance (%s) to become running", server.ID) stateConf := &resource.StateChangeConf{ Pending: []string{"BUILD"}, Target: []string{"ACTIVE"}, Refresh: ServerV2StateRefreshFunc(computeClient, server.ID), Timeout: 30 * time.Minute, Delay: 10 * time.Second, MinTimeout: 3 * time.Second, } _, err = stateConf.WaitForState() if err != nil { return fmt.Errorf( "Error waiting for instance (%s) to become ready: %s", server.ID, err) } // Now that the instance has been created, we need to do an early read on the // networks in order to associate floating IPs _, err = getInstanceNetworksAndAddresses(computeClient, d) // If floating IPs were specified, associate them after the instance has launched. err = associateFloatingIPsToInstance(computeClient, d) if err != nil { return err } // if volumes were specified, attach them after the instance has launched. if v, ok := d.GetOk("volume"); ok { vols := v.(*schema.Set).List() if blockClient, err := config.blockStorageV1Client(d.Get("region").(string)); err != nil { return fmt.Errorf("Error creating OpenStack block storage client: %s", err) } else { if err := attachVolumesToInstance(computeClient, blockClient, d.Id(), vols); err != nil { return err } } } return resourceComputeInstanceV2Read(d, meta) }
// Create requests the creation of a server from the given block device mapping. func Create(client *gophercloud.ServiceClient, opts osServers.CreateOptsBuilder) osServers.CreateResult { return osBFV.Create(client, opts) }