multi ephemeral support

This commit adds the ability to specify multiple ephemeral disks through the
bootfromvolume extension.
diff --git a/openstack/compute/v2/extensions/bootfromvolume/requests.go b/openstack/compute/v2/extensions/bootfromvolume/requests.go
index c8edee0..dceff3d 100644
--- a/openstack/compute/v2/extensions/bootfromvolume/requests.go
+++ b/openstack/compute/v2/extensions/bootfromvolume/requests.go
@@ -15,6 +15,7 @@
 	Volume   SourceType = "volume"
 	Snapshot SourceType = "snapshot"
 	Image    SourceType = "image"
+	Blank    SourceType = "blank"
 )
 
 // BlockDevice is a structure with options for booting a server instance
@@ -32,6 +33,9 @@
 	// and "local".
 	DestinationType string `json:"destination_type"`
 
+	// GuestFormat [optional] specifies the format of the block device.
+	GuestFormat string `json:"guest_format"`
+
 	// SourceType [required] must be one of: "volume", "snapshot", "image".
 	SourceType SourceType `json:"source_type"`
 
@@ -82,6 +86,9 @@
 		if bd.DestinationType != "" {
 			blockDevice[i]["destination_type"] = bd.DestinationType
 		}
+		if bd.GuestFormat != "" {
+			blockDevice[i]["guest_format"] = bd.GuestFormat
+		}
 
 	}
 	serverMap["block_device_mapping_v2"] = blockDevice
diff --git a/openstack/compute/v2/extensions/bootfromvolume/requests_test.go b/openstack/compute/v2/extensions/bootfromvolume/requests_test.go
index 8a7fa74..2c8bf49 100644
--- a/openstack/compute/v2/extensions/bootfromvolume/requests_test.go
+++ b/openstack/compute/v2/extensions/bootfromvolume/requests_test.go
@@ -32,8 +32,8 @@
         "name": "createdserver",
         "imageRef": "asdfasdfasdf",
         "flavorRef": "performance1-1",
-	"flavorName": "",
-	"imageName": "",
+        "flavorName": "",
+        "imageName": "",
         "block_device_mapping_v2":[
           {
             "uuid":"123456",
@@ -51,3 +51,81 @@
 	th.AssertNoErr(t, err)
 	th.CheckJSONEquals(t, expected, actual)
 }
+
+func TestCreateMultiEphemeralOpts(t *testing.T) {
+	base := servers.CreateOpts{
+		Name:      "createdserver",
+		ImageRef:  "asdfasdfasdf",
+		FlavorRef: "performance1-1",
+	}
+
+	ext := CreateOptsExt{
+		CreateOptsBuilder: base,
+		BlockDevice: []BlockDevice{
+			BlockDevice{
+				BootIndex:           0,
+				DeleteOnTermination: true,
+				DestinationType:     "local",
+				SourceType:          Image,
+				UUID:                "123456",
+			},
+			BlockDevice{
+				BootIndex:           -1,
+				DeleteOnTermination: true,
+				DestinationType:     "local",
+				GuestFormat:         "ext4",
+				SourceType:          Blank,
+				VolumeSize:          1,
+			},
+			BlockDevice{
+				BootIndex:           -1,
+				DeleteOnTermination: true,
+				DestinationType:     "local",
+				GuestFormat:         "ext4",
+				SourceType:          Blank,
+				VolumeSize:          1,
+			},
+		},
+	}
+
+	expected := `
+    {
+      "server": {
+        "name": "createdserver",
+        "imageRef": "asdfasdfasdf",
+        "flavorRef": "performance1-1",
+        "flavorName": "",
+        "imageName": "",
+        "block_device_mapping_v2":[
+          {
+            "boot_index": "0",
+            "delete_on_termination": "true",
+            "destination_type":"local",
+            "source_type":"image",
+            "uuid":"123456",
+            "volume_size": "0"
+          },
+          {
+            "boot_index": "-1",
+            "delete_on_termination": "true",
+            "destination_type":"local",
+            "guest_format":"ext4",
+            "source_type":"blank",
+            "volume_size": "1"
+          },
+          {
+            "boot_index": "-1",
+            "delete_on_termination": "true",
+            "destination_type":"local",
+            "guest_format":"ext4",
+            "source_type":"blank",
+            "volume_size": "1"
+          }
+        ]
+      }
+    }
+  `
+	actual, err := ext.ToServerCreateMap()
+	th.AssertNoErr(t, err)
+	th.CheckJSONEquals(t, expected, actual)
+}