blob: 28fef941ca0576ee3edad490534e4e1c23a3222c [file] [log] [blame]
Jon Perritt654fb0e2014-10-23 20:54:14 -05001package bootfromvolume
2
3import (
Jon Perritt27249f42016-02-18 10:35:59 -06004 "github.com/gophercloud/gophercloud"
5 "github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
Jon Perritt654fb0e2014-10-23 20:54:14 -05006)
7
Jon Perritt01686cd2014-10-24 14:10:16 -05008// SourceType represents the type of medium being used to create the volume.
9type SourceType string
10
11const (
Jon Perrittdb0ae142016-03-13 00:33:41 -060012 // Volume SourceType
13 Volume SourceType = "volume"
14 // Snapshot SourceType
Jon Perritt01686cd2014-10-24 14:10:16 -050015 Snapshot SourceType = "snapshot"
Jon Perrittdb0ae142016-03-13 00:33:41 -060016 // Image SourceType
17 Image SourceType = "image"
18 // Blank SourceType
19 Blank SourceType = "blank"
Jon Perritt01686cd2014-10-24 14:10:16 -050020)
21
Jon Perrittd9a4bf72014-10-23 23:44:04 -050022// BlockDevice is a structure with options for booting a server instance
23// from a volume. The volume may be created from an image, snapshot, or another
24// volume.
25type BlockDevice struct {
Jon Perrittdb0ae142016-03-13 00:33:41 -060026 // SourceType must be one of: "volume", "snapshot", "image".
27 SourceType SourceType `json:"source_type" required:"true"`
28 // UUID is the unique identifier for the volume, snapshot, or image (see above)
29 UUID string `json:"uuid,omitempty"`
30 // BootIndex is the boot index. It defaults to 0.
Jon Perritt8dd49db2014-10-24 12:39:07 -050031 BootIndex int `json:"boot_index"`
Jon Perrittdb0ae142016-03-13 00:33:41 -060032 // DeleteOnTermination specifies whether or not to delete the attached volume
Jon Perrittd9a4bf72014-10-23 23:44:04 -050033 // when the server is deleted. Defaults to `false`.
Jon Perritt8dd49db2014-10-24 12:39:07 -050034 DeleteOnTermination bool `json:"delete_on_termination"`
Jon Perrittdb0ae142016-03-13 00:33:41 -060035 // DestinationType is the type that gets created. Possible values are "volume"
Jon Perrittd9a4bf72014-10-23 23:44:04 -050036 // and "local".
Jon Perrittdb0ae142016-03-13 00:33:41 -060037 DestinationType string `json:"destination_type,omitempty"`
38 // GuestFormat specifies the format of the block device.
39 GuestFormat string `json:"guest_format,omitempty"`
40 // VolumeSize is the size of the volume to create (in gigabytes).
Jon Perritt8dd49db2014-10-24 12:39:07 -050041 VolumeSize int `json:"volume_size"`
Jon Perrittd9a4bf72014-10-23 23:44:04 -050042}
43
44// CreateOptsExt is a structure that extends the server `CreateOpts` structure
45// by allowing for a block device mapping.
Jon Perritt654fb0e2014-10-23 20:54:14 -050046type CreateOptsExt struct {
47 servers.CreateOptsBuilder
Jon Perritt01686cd2014-10-24 14:10:16 -050048 BlockDevice []BlockDevice `json:"block_device_mapping_v2,omitempty"`
Jon Perritt654fb0e2014-10-23 20:54:14 -050049}
50
51// ToServerCreateMap adds the block device mapping option to the base server
52// creation options.
53func (opts CreateOptsExt) ToServerCreateMap() (map[string]interface{}, error) {
Jon Perritt8dd49db2014-10-24 12:39:07 -050054 base, err := opts.CreateOptsBuilder.ToServerCreateMap()
55 if err != nil {
56 return nil, err
57 }
58
Jon Perritt01686cd2014-10-24 14:10:16 -050059 if len(opts.BlockDevice) == 0 {
Jon Perrittf094fef2016-03-07 01:41:59 -060060 err := gophercloud.ErrMissingInput{}
Jon Perrittf094fef2016-03-07 01:41:59 -060061 err.Argument = "bootfromvolume.CreateOptsExt.BlockDevice"
62 return nil, err
Jon Perritt4149d7c2014-10-23 21:23:46 -050063 }
Jon Perritt654fb0e2014-10-23 20:54:14 -050064
Jon Perritt4149d7c2014-10-23 21:23:46 -050065 serverMap := base["server"].(map[string]interface{})
Jon Perrittd9a4bf72014-10-23 23:44:04 -050066
Jon Perritt01686cd2014-10-24 14:10:16 -050067 blockDevice := make([]map[string]interface{}, len(opts.BlockDevice))
Jon Perrittd9a4bf72014-10-23 23:44:04 -050068
Jon Perritt01686cd2014-10-24 14:10:16 -050069 for i, bd := range opts.BlockDevice {
Jon Perrittdb0ae142016-03-13 00:33:41 -060070 b, err := gophercloud.BuildRequestBody(bd, "")
71 if err != nil {
Jon Perrittf094fef2016-03-07 01:41:59 -060072 return nil, err
Jon Perritt01686cd2014-10-24 14:10:16 -050073 }
Jon Perrittdb0ae142016-03-13 00:33:41 -060074 blockDevice[i] = b
Jon Perritt01686cd2014-10-24 14:10:16 -050075 }
76 serverMap["block_device_mapping_v2"] = blockDevice
Jon Perritt654fb0e2014-10-23 20:54:14 -050077
Jon Perritt4149d7c2014-10-23 21:23:46 -050078 return base, nil
Jon Perritt654fb0e2014-10-23 20:54:14 -050079}
Jon Perrittd9a4bf72014-10-23 23:44:04 -050080
81// Create requests the creation of a server from the given block device mapping.
Jon Perritt3860b512016-03-29 12:01:48 -050082func Create(client *gophercloud.ServiceClient, opts servers.CreateOptsBuilder) (r servers.CreateResult) {
Jon Perrittdb0ae142016-03-13 00:33:41 -060083 b, err := opts.ToServerCreateMap()
Jon Perrittd9a4bf72014-10-23 23:44:04 -050084 if err != nil {
Jon Perrittdb0ae142016-03-13 00:33:41 -060085 r.Err = err
Jon Perritt3860b512016-03-29 12:01:48 -050086 return
Jon Perrittd9a4bf72014-10-23 23:44:04 -050087 }
Jon Perrittdb0ae142016-03-13 00:33:41 -060088 _, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
Jamie Hannaford6a3a78f2015-03-24 14:56:12 +010089 OkCodes: []int{200, 202},
Jon Perrittd9a4bf72014-10-23 23:44:04 -050090 })
jrperritt29ae6b32016-04-13 12:59:37 -050091 return
Jon Perrittd9a4bf72014-10-23 23:44:04 -050092}