github.com/gophercloud/gophercloud@v1.11.0/openstack/compute/v2/extensions/bootfromvolume/requests.go (about)

     1  package bootfromvolume
     2  
     3  import (
     4  	"github.com/gophercloud/gophercloud"
     5  	"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
     6  )
     7  
     8  type (
     9  	// DestinationType represents the type of medium being used as the
    10  	// destination of the bootable device.
    11  	DestinationType string
    12  
    13  	// SourceType represents the type of medium being used as the source of the
    14  	// bootable device.
    15  	SourceType string
    16  )
    17  
    18  const (
    19  	// DestinationLocal DestinationType is for using an ephemeral disk as the
    20  	// destination.
    21  	DestinationLocal DestinationType = "local"
    22  
    23  	// DestinationVolume DestinationType is for using a volume as the destination.
    24  	DestinationVolume DestinationType = "volume"
    25  
    26  	// SourceBlank SourceType is for a "blank" or empty source.
    27  	SourceBlank SourceType = "blank"
    28  
    29  	// SourceImage SourceType is for using images as the source of a block device.
    30  	SourceImage SourceType = "image"
    31  
    32  	// SourceSnapshot SourceType is for using a volume snapshot as the source of
    33  	// a block device.
    34  	SourceSnapshot SourceType = "snapshot"
    35  
    36  	// SourceVolume SourceType is for using a volume as the source of block
    37  	// device.
    38  	SourceVolume SourceType = "volume"
    39  )
    40  
    41  // BlockDevice is a structure with options for creating block devices in a
    42  // server. The block device may be created from an image, snapshot, new volume,
    43  // or existing volume. The destination may be a new volume, existing volume
    44  // which will be attached to the instance, ephemeral disk, or boot device.
    45  type BlockDevice struct {
    46  	// SourceType must be one of: "volume", "snapshot", "image", or "blank".
    47  	SourceType SourceType `json:"source_type" required:"true"`
    48  
    49  	// UUID is the unique identifier for the existing volume, snapshot, or
    50  	// image (see above).
    51  	UUID string `json:"uuid,omitempty"`
    52  
    53  	// BootIndex is the boot index. It defaults to 0.
    54  	BootIndex int `json:"boot_index"`
    55  
    56  	// DeleteOnTermination specifies whether or not to delete the attached volume
    57  	// when the server is deleted. Defaults to `false`.
    58  	DeleteOnTermination bool `json:"delete_on_termination"`
    59  
    60  	// DestinationType is the type that gets created. Possible values are "volume"
    61  	// and "local".
    62  	DestinationType DestinationType `json:"destination_type,omitempty"`
    63  
    64  	// GuestFormat specifies the format of the block device.
    65  	// Not specifying this will cause the device to be formatted to the default in Nova
    66  	// which is currently vfat.
    67  	// https://opendev.org/openstack/nova/src/commit/d0b459423dd81644e8d9382b6c87fabaa4f03ad4/nova/privsep/fs.py#L257
    68  	GuestFormat string `json:"guest_format,omitempty"`
    69  
    70  	// VolumeSize is the size of the volume to create (in gigabytes). This can be
    71  	// omitted for existing volumes.
    72  	VolumeSize int `json:"volume_size,omitempty"`
    73  
    74  	// DeviceType specifies the device type of the block devices.
    75  	// Examples of this are disk, cdrom, floppy, lun, etc.
    76  	DeviceType string `json:"device_type,omitempty"`
    77  
    78  	// DiskBus is the bus type of the block devices.
    79  	// Examples of this are ide, usb, virtio, scsi, etc.
    80  	DiskBus string `json:"disk_bus,omitempty"`
    81  
    82  	// VolumeType is the volume type of the block device.
    83  	// This requires Compute API microversion 2.67 or later.
    84  	VolumeType string `json:"volume_type,omitempty"`
    85  
    86  	// Tag is an arbitrary string that can be applied to a block device.
    87  	// Information about the device tags can be obtained from the metadata API
    88  	// and the config drive, allowing devices to be easily identified.
    89  	// This requires Compute API microversion 2.42 or later.
    90  	Tag string `json:"tag,omitempty"`
    91  }
    92  
    93  // CreateOptsExt is a structure that extends the server `CreateOpts` structure
    94  // by allowing for a block device mapping.
    95  type CreateOptsExt struct {
    96  	servers.CreateOptsBuilder
    97  	BlockDevice []BlockDevice `json:"block_device_mapping_v2,omitempty"`
    98  }
    99  
   100  // ToServerCreateMap adds the block device mapping option to the base server
   101  // creation options.
   102  func (opts CreateOptsExt) ToServerCreateMap() (map[string]interface{}, error) {
   103  	base, err := opts.CreateOptsBuilder.ToServerCreateMap()
   104  	if err != nil {
   105  		return nil, err
   106  	}
   107  
   108  	if len(opts.BlockDevice) == 0 {
   109  		err := gophercloud.ErrMissingInput{}
   110  		err.Argument = "bootfromvolume.CreateOptsExt.BlockDevice"
   111  		return nil, err
   112  	}
   113  
   114  	serverMap := base["server"].(map[string]interface{})
   115  
   116  	blockDevice := make([]map[string]interface{}, len(opts.BlockDevice))
   117  
   118  	for i, bd := range opts.BlockDevice {
   119  		b, err := gophercloud.BuildRequestBody(bd, "")
   120  		if err != nil {
   121  			return nil, err
   122  		}
   123  		blockDevice[i] = b
   124  	}
   125  	serverMap["block_device_mapping_v2"] = blockDevice
   126  
   127  	return base, nil
   128  }
   129  
   130  // Create requests the creation of a server from the given block device mapping.
   131  func Create(client *gophercloud.ServiceClient, opts servers.CreateOptsBuilder) (r servers.CreateResult) {
   132  	b, err := opts.ToServerCreateMap()
   133  	if err != nil {
   134  		r.Err = err
   135  		return
   136  	}
   137  	resp, err := client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
   138  		OkCodes: []int{200, 202},
   139  	})
   140  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   141  	return
   142  }