blob: fa1992dcc8634e0f0c4f236fd7f3ed899676486e [file] [log] [blame]
Jon Perritt654fb0e2014-10-23 20:54:14 -05001package bootfromvolume
2
3import (
Krzysztof Szukiełojć3f41d082017-05-07 14:43:06 +02004 "gerrit.mcp.mirantis.net/debian/gophercloud.git"
Krzysztof Szukiełojć24a29ce2017-05-07 14:24:02 +02005 "gerrit.mcp.mirantis.net/debian/gophercloud.git/openstack/compute/v2/servers"
Jon Perritt654fb0e2014-10-23 20:54:14 -05006)
7
Joe Topjianf1f40412016-10-13 17:42:25 -06008type (
9 // DestinationType represents the type of medium being used as the
10 // destination of the bootable device.
11 DestinationType string
Jon Perritt01686cd2014-10-24 14:10:16 -050012
Joe Topjianf1f40412016-10-13 17:42:25 -060013 // SourceType represents the type of medium being used as the source of the
14 // bootable device.
15 SourceType string
Jon Perritt01686cd2014-10-24 14:10:16 -050016)
17
Joe Topjianf1f40412016-10-13 17:42:25 -060018const (
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.
Jon Perrittd9a4bf72014-10-23 23:44:04 -050045type BlockDevice struct {
Joe Topjianf1f40412016-10-13 17:42:25 -060046 // SourceType must be one of: "volume", "snapshot", "image", or "blank".
Jon Perrittdb0ae142016-03-13 00:33:41 -060047 SourceType SourceType `json:"source_type" required:"true"`
Joe Topjianf1f40412016-10-13 17:42:25 -060048
49 // UUID is the unique identifier for the existing volume, snapshot, or
50 // image (see above).
Jon Perrittdb0ae142016-03-13 00:33:41 -060051 UUID string `json:"uuid,omitempty"`
Joe Topjianf1f40412016-10-13 17:42:25 -060052
Jon Perrittdb0ae142016-03-13 00:33:41 -060053 // BootIndex is the boot index. It defaults to 0.
Jon Perritt8dd49db2014-10-24 12:39:07 -050054 BootIndex int `json:"boot_index"`
Joe Topjianf1f40412016-10-13 17:42:25 -060055
Jon Perrittdb0ae142016-03-13 00:33:41 -060056 // DeleteOnTermination specifies whether or not to delete the attached volume
Jon Perrittd9a4bf72014-10-23 23:44:04 -050057 // when the server is deleted. Defaults to `false`.
Jon Perritt8dd49db2014-10-24 12:39:07 -050058 DeleteOnTermination bool `json:"delete_on_termination"`
Joe Topjianf1f40412016-10-13 17:42:25 -060059
Jon Perrittdb0ae142016-03-13 00:33:41 -060060 // DestinationType is the type that gets created. Possible values are "volume"
Jon Perrittd9a4bf72014-10-23 23:44:04 -050061 // and "local".
Joe Topjianf1f40412016-10-13 17:42:25 -060062 DestinationType DestinationType `json:"destination_type,omitempty"`
63
Jon Perrittdb0ae142016-03-13 00:33:41 -060064 // GuestFormat specifies the format of the block device.
65 GuestFormat string `json:"guest_format,omitempty"`
Joe Topjianf1f40412016-10-13 17:42:25 -060066
67 // VolumeSize is the size of the volume to create (in gigabytes). This can be
68 // omitted for existing volumes.
69 VolumeSize int `json:"volume_size,omitempty"`
Jon Perrittd9a4bf72014-10-23 23:44:04 -050070}
71
72// CreateOptsExt is a structure that extends the server `CreateOpts` structure
73// by allowing for a block device mapping.
Jon Perritt654fb0e2014-10-23 20:54:14 -050074type CreateOptsExt struct {
75 servers.CreateOptsBuilder
Jon Perritt01686cd2014-10-24 14:10:16 -050076 BlockDevice []BlockDevice `json:"block_device_mapping_v2,omitempty"`
Jon Perritt654fb0e2014-10-23 20:54:14 -050077}
78
79// ToServerCreateMap adds the block device mapping option to the base server
80// creation options.
81func (opts CreateOptsExt) ToServerCreateMap() (map[string]interface{}, error) {
Jon Perritt8dd49db2014-10-24 12:39:07 -050082 base, err := opts.CreateOptsBuilder.ToServerCreateMap()
83 if err != nil {
84 return nil, err
85 }
86
Jon Perritt01686cd2014-10-24 14:10:16 -050087 if len(opts.BlockDevice) == 0 {
Jon Perrittf094fef2016-03-07 01:41:59 -060088 err := gophercloud.ErrMissingInput{}
Jon Perrittf094fef2016-03-07 01:41:59 -060089 err.Argument = "bootfromvolume.CreateOptsExt.BlockDevice"
90 return nil, err
Jon Perritt4149d7c2014-10-23 21:23:46 -050091 }
Jon Perritt654fb0e2014-10-23 20:54:14 -050092
Jon Perritt4149d7c2014-10-23 21:23:46 -050093 serverMap := base["server"].(map[string]interface{})
Jon Perrittd9a4bf72014-10-23 23:44:04 -050094
Jon Perritt01686cd2014-10-24 14:10:16 -050095 blockDevice := make([]map[string]interface{}, len(opts.BlockDevice))
Jon Perrittd9a4bf72014-10-23 23:44:04 -050096
Jon Perritt01686cd2014-10-24 14:10:16 -050097 for i, bd := range opts.BlockDevice {
Jon Perrittdb0ae142016-03-13 00:33:41 -060098 b, err := gophercloud.BuildRequestBody(bd, "")
99 if err != nil {
Jon Perrittf094fef2016-03-07 01:41:59 -0600100 return nil, err
Jon Perritt01686cd2014-10-24 14:10:16 -0500101 }
Jon Perrittdb0ae142016-03-13 00:33:41 -0600102 blockDevice[i] = b
Jon Perritt01686cd2014-10-24 14:10:16 -0500103 }
104 serverMap["block_device_mapping_v2"] = blockDevice
Jon Perritt654fb0e2014-10-23 20:54:14 -0500105
Jon Perritt4149d7c2014-10-23 21:23:46 -0500106 return base, nil
Jon Perritt654fb0e2014-10-23 20:54:14 -0500107}
Jon Perrittd9a4bf72014-10-23 23:44:04 -0500108
109// Create requests the creation of a server from the given block device mapping.
Jon Perritt3860b512016-03-29 12:01:48 -0500110func Create(client *gophercloud.ServiceClient, opts servers.CreateOptsBuilder) (r servers.CreateResult) {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600111 b, err := opts.ToServerCreateMap()
Jon Perrittd9a4bf72014-10-23 23:44:04 -0500112 if err != nil {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600113 r.Err = err
Jon Perritt3860b512016-03-29 12:01:48 -0500114 return
Jon Perrittd9a4bf72014-10-23 23:44:04 -0500115 }
Jon Perrittdb0ae142016-03-13 00:33:41 -0600116 _, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
Jamie Hannaford6a3a78f2015-03-24 14:56:12 +0100117 OkCodes: []int{200, 202},
Jon Perrittd9a4bf72014-10-23 23:44:04 -0500118 })
jrperritt29ae6b32016-04-13 12:59:37 -0500119 return
Jon Perrittd9a4bf72014-10-23 23:44:04 -0500120}