Added support for a server action to create a server image / snapshot
diff --git a/openstack/compute/v2/servers/fixtures.go b/openstack/compute/v2/servers/fixtures.go
index e47bc0e..4339a16 100644
--- a/openstack/compute/v2/servers/fixtures.go
+++ b/openstack/compute/v2/servers/fixtures.go
@@ -651,3 +651,14 @@
 			}`)
 	})
 }
+
+// HandleCreateServerImageSuccessfully sets up the test server to respond to a TestCreateServerImage request.
+func HandleCreateServerImageSuccessfully(t *testing.T) {
+	th.Mux.HandleFunc("/servers/serverimage/action", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "POST")
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
+		w.Header().Add("Location", "https://0.0.0.0/images/xxxx-xxxxx-xxxxx-xxxx")
+		w.WriteHeader(http.StatusAccepted)
+	})
+}
+
diff --git a/openstack/compute/v2/servers/requests.go b/openstack/compute/v2/servers/requests.go
index e0950e4..caeb946 100644
--- a/openstack/compute/v2/servers/requests.go
+++ b/openstack/compute/v2/servers/requests.go
@@ -4,6 +4,7 @@
 	"encoding/base64"
 	"errors"
 	"fmt"
+	"strings"
 
 	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/pagination"
@@ -14,7 +15,6 @@
 type ListOptsBuilder interface {
 	ToServerListQuery() (string, error)
 }
-
 // ListOpts allows the filtering and sorting of paginated collections through
 // the API. Filtering is achieved by passing in struct field values that map to
 // the server attributes you want to see returned. Marker and Limit are used
@@ -701,3 +701,68 @@
 	}
 	return pagination.NewPager(client, listAddressesByNetworkURL(client, id, network), createPageFn)
 }
+
+type CreateServerImageOpts struct {
+	// Name [required] of the image/snapshot
+	Name string
+	// Metadata [optional] contains key-value pairs (up to 255 bytes each) to attach to the created image.
+	Metadata map[string]string
+}
+
+type CreateServerImageOptsBuilder interface {
+	ToCreateServerImageMap() (map[string]interface{}, error)
+}
+
+// ToServerImageCreateMap formats an ServerImageCreateOpts structure into a request body.
+func (opts CreateServerImageOpts) ToCreateServerImageMap() (map[string]interface{}, error) {
+	var err error
+	img := make(map[string]interface{})
+	if opts.Name == "" {
+		err = fmt.Errorf("Cannot create a server image without a name")
+	}
+	img["name"] = opts.Name
+	if opts.Metadata != nil {
+		img["metadata"] = opts.Metadata
+	}
+	createImage := make(map[string]interface{})
+	createImage["createImage"] = img
+	return createImage, err
+}
+
+// ExtractImageID gets the ID of the newly created server image from the header
+func (res CreateServerImageResult) ExtractImageID() (string, error) {
+	var err error
+	if res.Err != nil {
+		return "", res.Err
+	}
+	// Get the image id from the header
+	rawUrl := res.Header.Get("Location")
+	fmt.Println("RawUrl:", rawUrl)
+	if rawUrl != "" {
+		split := strings.Split(rawUrl, "/")
+		if len(split) > 0 {
+			id := split[len(split)-1]
+			return id, nil
+		}
+	}
+	err = fmt.Errorf("Failed to parse the ID of newly created image")
+	return "", err
+}
+
+// CreateServerImage makes a request against the nova API to schedule an image to be created of the server
+func CreateServerImage(client *gophercloud.ServiceClient, serverId string, opts CreateServerImageOptsBuilder) CreateServerImageResult {
+	var res CreateServerImageResult
+	reqBody, err := opts.ToCreateServerImageMap()
+	if err != nil {
+		res.Err = err
+		return res
+	}
+	response, err := client.Post(actionURL(client, serverId), reqBody, nil, &gophercloud.RequestOpts{
+		OkCodes: []int{202},
+	})
+	res.Err = err
+	if err == nil {
+		res.Header = response.Header
+	}
+	return res	
+}
diff --git a/openstack/compute/v2/servers/requests_test.go b/openstack/compute/v2/servers/requests_test.go
index 62b89e0..466bbf7 100644
--- a/openstack/compute/v2/servers/requests_test.go
+++ b/openstack/compute/v2/servers/requests_test.go
@@ -325,3 +325,13 @@
 	th.AssertNoErr(t, err)
 	th.CheckEquals(t, 1, pages)
 }
+
+func TestCreateServerImage(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandleCreateServerImageSuccessfully(t)
+
+	_, err := CreateServerImage(client.ServiceClient(), "serverimage", CreateServerImageOpts{Name: "test"}).ExtractImageID()
+	th.AssertNoErr(t, err)
+	
+}
diff --git a/openstack/compute/v2/servers/results.go b/openstack/compute/v2/servers/results.go
index e2be6ba..26e099a 100644
--- a/openstack/compute/v2/servers/results.go
+++ b/openstack/compute/v2/servers/results.go
@@ -74,6 +74,11 @@
 	ActionResult
 }
 
+// RescueResult represents the result of a server rescue operation
+type CreateServerImageResult struct {
+	gophercloud.Result
+}
+
 // Extract interprets any RescueResult as an AdminPass, if possible.
 func (r RescueResult) Extract() (string, error) {
 	if r.Err != nil {