@@ -181,13 +181,13 @@ func resourceComputeInstanceV2() *schema.Resource {
181
181
ForceNew : true ,
182
182
Elem : & schema.Resource {
183
183
Schema : map [string ]* schema.Schema {
184
- "uuid " : & schema.Schema {
184
+ "source_type " : & schema.Schema {
185
185
Type : schema .TypeString ,
186
186
Required : true ,
187
187
},
188
- "source_type " : & schema.Schema {
188
+ "uuid " : & schema.Schema {
189
189
Type : schema .TypeString ,
190
- Required : true ,
190
+ Optional : true ,
191
191
},
192
192
"volume_size" : & schema.Schema {
193
193
Type : schema .TypeInt ,
@@ -206,6 +206,10 @@ func resourceComputeInstanceV2() *schema.Resource {
206
206
Optional : true ,
207
207
Default : false ,
208
208
},
209
+ "guest_format" : & schema.Schema {
210
+ Type : schema .TypeString ,
211
+ Optional : true ,
212
+ },
209
213
},
210
214
},
211
215
},
@@ -344,14 +348,10 @@ func resourceComputeInstanceV2Create(d *schema.ResourceData, meta interface{}) e
344
348
}
345
349
346
350
if vL , ok := d .GetOk ("block_device" ); ok {
347
- for _ , v := range vL .([]interface {}) {
348
- blockDeviceRaw := v .(map [string ]interface {})
349
- blockDevice := resourceInstanceBlockDeviceV2 (d , blockDeviceRaw )
350
- createOpts = & bootfromvolume.CreateOptsExt {
351
- createOpts ,
352
- blockDevice ,
353
- }
354
- log .Printf ("[DEBUG] Create BFV Options: %+v" , createOpts )
351
+ blockDevices := resourceInstanceBlockDevicesV2 (d , vL .([]interface {}))
352
+ createOpts = & bootfromvolume.CreateOptsExt {
353
+ createOpts ,
354
+ blockDevices ,
355
355
}
356
356
}
357
357
@@ -926,20 +926,24 @@ func resourceInstanceMetadataV2(d *schema.ResourceData) map[string]string {
926
926
return m
927
927
}
928
928
929
- func resourceInstanceBlockDeviceV2 (d * schema.ResourceData , bd map [string ]interface {}) []bootfromvolume.BlockDevice {
930
- sourceType := bootfromvolume .SourceType (bd ["source_type" ].(string ))
931
- bfvOpts := []bootfromvolume.BlockDevice {
932
- bootfromvolume.BlockDevice {
933
- UUID : bd ["uuid" ].(string ),
929
+ func resourceInstanceBlockDevicesV2 (d * schema.ResourceData , bds []interface {}) []bootfromvolume.BlockDevice {
930
+ blockDeviceOpts := make ([]bootfromvolume.BlockDevice , len (bds ))
931
+ for i , bd := range bds {
932
+ bdM := bd .(map [string ]interface {})
933
+ sourceType := bootfromvolume .SourceType (bdM ["source_type" ].(string ))
934
+ blockDeviceOpts [i ] = bootfromvolume.BlockDevice {
935
+ UUID : bdM ["uuid" ].(string ),
934
936
SourceType : sourceType ,
935
- VolumeSize : bd ["volume_size" ].(int ),
936
- DestinationType : bd ["destination_type" ].(string ),
937
- BootIndex : bd ["boot_index" ].(int ),
938
- DeleteOnTermination : bd ["delete_on_termination" ].(bool ),
939
- },
937
+ VolumeSize : bdM ["volume_size" ].(int ),
938
+ DestinationType : bdM ["destination_type" ].(string ),
939
+ BootIndex : bdM ["boot_index" ].(int ),
940
+ DeleteOnTermination : bdM ["delete_on_termination" ].(bool ),
941
+ GuestFormat : bdM ["guest_format" ].(string ),
942
+ }
940
943
}
941
944
942
- return bfvOpts
945
+ log .Printf ("[DEBUG] Block Device Options: %+v" , blockDeviceOpts )
946
+ return blockDeviceOpts
943
947
}
944
948
945
949
func resourceInstanceSchedulerHintsV2 (d * schema.ResourceData , schedulerHintsRaw map [string ]interface {}) schedulerhints.SchedulerHints {
@@ -977,10 +981,19 @@ func resourceInstanceSchedulerHintsV2(d *schema.ResourceData, schedulerHintsRaw
977
981
}
978
982
979
983
func getImageIDFromConfig (computeClient * gophercloud.ServiceClient , d * schema.ResourceData ) (string , error ) {
980
- // If block_device was used, an Image does not need to be specified.
981
- // If an Image was specified, ignore it
982
- if _ , ok := d .GetOk ("block_device" ); ok {
983
- return "" , nil
984
+ // If block_device was used, an Image does not need to be specified, unless an image/local
985
+ // combination was used. This emulates normal boot behavior. Otherwise, ignore the image altogether.
986
+ if vL , ok := d .GetOk ("block_device" ); ok {
987
+ needImage := false
988
+ for _ , v := range vL .([]interface {}) {
989
+ vM := v .(map [string ]interface {})
990
+ if vM ["source_type" ] == "image" && vM ["destination_type" ] == "local" {
991
+ needImage = true
992
+ }
993
+ }
994
+ if ! needImage {
995
+ return "" , nil
996
+ }
984
997
}
985
998
986
999
if imageId := d .Get ("image_id" ).(string ); imageId != "" {
@@ -1012,11 +1025,20 @@ func getImageIDFromConfig(computeClient *gophercloud.ServiceClient, d *schema.Re
1012
1025
}
1013
1026
1014
1027
func setImageInformation (computeClient * gophercloud.ServiceClient , server * servers.Server , d * schema.ResourceData ) error {
1015
- // If block_device was used, an Image does not need to be specified.
1016
- // If an Image was specified, ignore it
1017
- if _ , ok := d .GetOk ("block_device" ); ok {
1018
- d .Set ("image_id" , "Attempt to boot from volume - no image supplied" )
1019
- return nil
1028
+ // If block_device was used, an Image does not need to be specified, unless an image/local
1029
+ // combination was used. This emulates normal boot behavior. Otherwise, ignore the image altogether.
1030
+ if vL , ok := d .GetOk ("block_device" ); ok {
1031
+ needImage := false
1032
+ for _ , v := range vL .([]interface {}) {
1033
+ vM := v .(map [string ]interface {})
1034
+ if vM ["source_type" ] == "image" && vM ["destination_type" ] == "local" {
1035
+ needImage = true
1036
+ }
1037
+ }
1038
+ if ! needImage {
1039
+ d .Set ("image_id" , "Attempt to boot from volume - no image supplied" )
1040
+ return nil
1041
+ }
1020
1042
}
1021
1043
1022
1044
imageId := server .Image ["id" ].(string )
@@ -1230,8 +1252,11 @@ func checkVolumeConfig(d *schema.ResourceData) error {
1230
1252
}
1231
1253
1232
1254
if vL , ok := d .GetOk ("block_device" ); ok {
1233
- if len (vL .([]interface {})) > 1 {
1234
- return fmt .Errorf ("Can only specify one block device to boot from." )
1255
+ for _ , v := range vL .([]interface {}) {
1256
+ vM := v .(map [string ]interface {})
1257
+ if vM ["source_type" ] != "blank" && vM ["uuid" ] == "" {
1258
+ return fmt .Errorf ("You must specify a uuid for %s block device types" , vM ["source_type" ])
1259
+ }
1235
1260
}
1236
1261
}
1237
1262
0 commit comments