From 6490524874143e88ceb227ebf8d3d4243c4b7d6a Mon Sep 17 00:00:00 2001 From: Daniil Rutskiy Date: Wed, 17 Jan 2018 18:17:37 +0300 Subject: [PATCH 1/3] Add support for server live-migration --- .../compute/v2/extensions/migrate/doc.go | 18 ++++++++- .../compute/v2/extensions/migrate/requests.go | 40 +++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/openstack/compute/v2/extensions/migrate/doc.go b/openstack/compute/v2/extensions/migrate/doc.go index 86750d6c6f..c32328a759 100644 --- a/openstack/compute/v2/extensions/migrate/doc.go +++ b/openstack/compute/v2/extensions/migrate/doc.go @@ -2,12 +2,28 @@ Package migrate provides functionality to migrate servers that have been provisioned by the OpenStack Compute service. -Example to Migrate a Server +Example of Migrate Server (migrate Action) serverID := "b16ba811-199d-4ffd-8839-ba96c1185a67" err := migrate.Migrate(computeClient, serverID).ExtractErr() if err != nil { panic(err) } + +Example of Live-Migrate Server (os-migrateLive Action) + + serverID := "b16ba811-199d-4ffd-8839-ba96c1185a67" + blockMigration := false + + migrationOpts := migrate.LiveMigrateOpts{ + Host: "01c0cadef72d47e28a672a76060d492c", + BlockMigration: &blockMigration, + } + + err := migrate.LiveMigrate(computeClient, serverID, migrationOpts).ExtractErr() + if err != nil { + panic(err) + } + */ package migrate diff --git a/openstack/compute/v2/extensions/migrate/requests.go b/openstack/compute/v2/extensions/migrate/requests.go index 9f263fa3ba..79ffd751b6 100644 --- a/openstack/compute/v2/extensions/migrate/requests.go +++ b/openstack/compute/v2/extensions/migrate/requests.go @@ -9,3 +9,43 @@ func Migrate(client *gophercloud.ServiceClient, id string) (r MigrateResult) { _, r.Err = client.Post(actionURL(client, id), map[string]interface{}{"migrate": nil}, nil, nil) return } + +// LiveMigrateOptsBuilder allows extensions to add additional parameters to the +// LiveMigrate request. +type LiveMigrateOptsBuilder interface { + ToLiveMigrateMap() (map[string]interface{}, error) +} + +// LiveMigrateOpts specifies parameters of live migrate action. +type LiveMigrateOpts struct { + + // The host to which to migrate the server. + // If this parameter is None, the scheduler chooses a host. + Host string `json:"host,omitempty"` + + // Set to True to migrate local disks by using block migration. + // If the source or destination host uses shared storage and you set + // this value to True, the live migration fails. + BlockMigration *bool `json:"block_migration,omitempty"` + + // Set to True to enable over commit when the destination host is checked + // for available disk space. Set to False to disable over commit. This setting + // affects only the libvirt virt driver. + DiskOverCommit *bool `json:"disk_over_commit,omitempty"` +} + +// ToLiveMigrateMap constructs a request body from LiveMigrateOpts. +func (opts LiveMigrateOpts) ToLiveMigrateMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "os-migrateLive") +} + +// LiveMigrate will initiate a live-migration (without rebooting) of the instance to another host. +func LiveMigrate(client *gophercloud.ServiceClient, id string, opts LiveMigrateOptsBuilder) (r MigrateResult) { + b, err := opts.ToLiveMigrateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(actionURL(client, id), b, nil, nil) + return +} From 8e53312033e9ead5a67bf1d66e6cfef484b76a7a Mon Sep 17 00:00:00 2001 From: Daniil Rutskiy Date: Wed, 17 Jan 2018 18:18:11 +0300 Subject: [PATCH 2/3] Add unit test --- .../v2/extensions/migrate/testing/fixtures.go | 15 +++++++++++++++ .../migrate/testing/requests_test.go | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/openstack/compute/v2/extensions/migrate/testing/fixtures.go b/openstack/compute/v2/extensions/migrate/testing/fixtures.go index 8a59aa3478..1d2f5902c2 100644 --- a/openstack/compute/v2/extensions/migrate/testing/fixtures.go +++ b/openstack/compute/v2/extensions/migrate/testing/fixtures.go @@ -16,3 +16,18 @@ func mockMigrateResponse(t *testing.T, id string) { w.WriteHeader(http.StatusAccepted) }) } + +func mockLiveMigrateResponse(t *testing.T, id string) { + th.Mux.HandleFunc("/servers/"+id+"/action", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "POST") + th.TestHeader(t, r, "X-Auth-Token", client.TokenID) + th.TestJSONRequest(t, r, `{ + "os-migrateLive": { + "host": "01c0cadef72d47e28a672a76060d492c", + "block_migration": false, + "disk_over_commit": true + } + }`) + w.WriteHeader(http.StatusAccepted) + }) +} diff --git a/openstack/compute/v2/extensions/migrate/testing/requests_test.go b/openstack/compute/v2/extensions/migrate/testing/requests_test.go index 7d14365d6a..adb76461fb 100644 --- a/openstack/compute/v2/extensions/migrate/testing/requests_test.go +++ b/openstack/compute/v2/extensions/migrate/testing/requests_test.go @@ -19,3 +19,22 @@ func TestMigrate(t *testing.T) { err := migrate.Migrate(client.ServiceClient(), serverID).ExtractErr() th.AssertNoErr(t, err) } + +func TestLiveMigrate(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + mockLiveMigrateResponse(t, serverID) + + blockMigration := false + diskOverCommit := true + + migrationOpts := migrate.LiveMigrateOpts{ + Host: "01c0cadef72d47e28a672a76060d492c", + BlockMigration: &blockMigration, + DiskOverCommit: &diskOverCommit, + } + + err := migrate.LiveMigrate(client.ServiceClient(), serverID, migrationOpts).ExtractErr() + th.AssertNoErr(t, err) +} From 36c6c90fbde4b52ab05bcc4c40a35f8598bc9ce5 Mon Sep 17 00:00:00 2001 From: Daniil Rutskiy Date: Fri, 19 Jan 2018 17:10:29 +0300 Subject: [PATCH 3/3] Fix 'Host' type `string` -> `*string` to be able to set it to nil --- openstack/compute/v2/extensions/migrate/doc.go | 3 ++- openstack/compute/v2/extensions/migrate/requests.go | 2 +- .../compute/v2/extensions/migrate/testing/requests_test.go | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/openstack/compute/v2/extensions/migrate/doc.go b/openstack/compute/v2/extensions/migrate/doc.go index c32328a759..cf3067716d 100644 --- a/openstack/compute/v2/extensions/migrate/doc.go +++ b/openstack/compute/v2/extensions/migrate/doc.go @@ -13,10 +13,11 @@ Example of Migrate Server (migrate Action) Example of Live-Migrate Server (os-migrateLive Action) serverID := "b16ba811-199d-4ffd-8839-ba96c1185a67" + host := "01c0cadef72d47e28a672a76060d492c" blockMigration := false migrationOpts := migrate.LiveMigrateOpts{ - Host: "01c0cadef72d47e28a672a76060d492c", + Host: &host, BlockMigration: &blockMigration, } diff --git a/openstack/compute/v2/extensions/migrate/requests.go b/openstack/compute/v2/extensions/migrate/requests.go index 79ffd751b6..0cb6f8100b 100644 --- a/openstack/compute/v2/extensions/migrate/requests.go +++ b/openstack/compute/v2/extensions/migrate/requests.go @@ -21,7 +21,7 @@ type LiveMigrateOpts struct { // The host to which to migrate the server. // If this parameter is None, the scheduler chooses a host. - Host string `json:"host,omitempty"` + Host *string `json:"host"` // Set to True to migrate local disks by using block migration. // If the source or destination host uses shared storage and you set diff --git a/openstack/compute/v2/extensions/migrate/testing/requests_test.go b/openstack/compute/v2/extensions/migrate/testing/requests_test.go index adb76461fb..b6906b7839 100644 --- a/openstack/compute/v2/extensions/migrate/testing/requests_test.go +++ b/openstack/compute/v2/extensions/migrate/testing/requests_test.go @@ -26,11 +26,12 @@ func TestLiveMigrate(t *testing.T) { mockLiveMigrateResponse(t, serverID) + host := "01c0cadef72d47e28a672a76060d492c" blockMigration := false diskOverCommit := true migrationOpts := migrate.LiveMigrateOpts{ - Host: "01c0cadef72d47e28a672a76060d492c", + Host: &host, BlockMigration: &blockMigration, DiskOverCommit: &diskOverCommit, }