api: Introduce microverion 2.87 allowing boot from volume rescue
Building on Ic2ad1468d31b7707b7f8f2b845a9cf47d9d076d5, when requested this microversion will allow boot from volume requests to proceed when the COMPUTE_RESCUE_BFV trait is also reported by the compute the instance currently resides on. Implements: blueprint virt-bfv-instance-rescue Change-Id: I3242fec1547693078cf36c3637116f8c41f1d0bc
This commit is contained in:
parent
5b6f44efff
commit
24106290e6
87
doc/api_samples/os-rescue/v2.87/server-get-resp-rescue.json
Normal file
87
doc/api_samples/os-rescue/v2.87/server-get-resp-rescue.json
Normal file
@ -0,0 +1,87 @@
|
||||
{
|
||||
"server": {
|
||||
"OS-DCF:diskConfig": "AUTO",
|
||||
"OS-EXT-AZ:availability_zone": "us-west",
|
||||
"OS-EXT-SRV-ATTR:host": "compute",
|
||||
"OS-EXT-SRV-ATTR:hostname": "new-server-test",
|
||||
"OS-EXT-SRV-ATTR:hypervisor_hostname": "fake-mini",
|
||||
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",
|
||||
"OS-EXT-SRV-ATTR:kernel_id": "",
|
||||
"OS-EXT-SRV-ATTR:launch_index": 0,
|
||||
"OS-EXT-SRV-ATTR:ramdisk_id": "",
|
||||
"OS-EXT-SRV-ATTR:reservation_id": "r-d0bls59j",
|
||||
"OS-EXT-SRV-ATTR:root_device_name": "/dev/sda",
|
||||
"OS-EXT-SRV-ATTR:user_data": "IyEvYmluL2Jhc2gKL2Jpbi9zdQplY2hvICJJIGFtIGluIHlvdSEiCg==",
|
||||
"OS-EXT-STS:power_state": 4,
|
||||
"OS-EXT-STS:task_state": null,
|
||||
"OS-EXT-STS:vm_state": "rescued",
|
||||
"OS-SRV-USG:launched_at": "2020-02-07T17:39:49.259481",
|
||||
"OS-SRV-USG:terminated_at": null,
|
||||
"accessIPv4": "1.2.3.4",
|
||||
"accessIPv6": "80fe::",
|
||||
"addresses": {
|
||||
"private": [
|
||||
{
|
||||
"OS-EXT-IPS-MAC:mac_addr": "00:0c:29:0d:11:74",
|
||||
"OS-EXT-IPS:type": "fixed",
|
||||
"addr": "192.168.1.30",
|
||||
"version": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
"config_drive": "",
|
||||
"created": "2020-02-07T17:39:48Z",
|
||||
"description": null,
|
||||
"flavor": {
|
||||
"disk": 1,
|
||||
"ephemeral": 0,
|
||||
"extra_specs": {},
|
||||
"original_name": "m1.tiny",
|
||||
"ram": 512,
|
||||
"swap": 0,
|
||||
"vcpus": 1
|
||||
},
|
||||
"hostId": "2091634baaccdc4c5a1d57069c833e402921df696b7f970791b12ec6",
|
||||
"host_status": "UP",
|
||||
"id": "69bebe1c-3bdb-4feb-9b79-afa3d4782d95",
|
||||
"image": {
|
||||
"id": "70a599e0-31e7-49b7-b260-868f441e862b",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/images/70a599e0-31e7-49b7-b260-868f441e862b",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
]
|
||||
},
|
||||
"key_name": null,
|
||||
"links": [
|
||||
{
|
||||
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/servers/69bebe1c-3bdb-4feb-9b79-afa3d4782d95",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/servers/69bebe1c-3bdb-4feb-9b79-afa3d4782d95",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"locked": false,
|
||||
"locked_reason": null,
|
||||
"metadata": {
|
||||
"My Server Name": "Apache1"
|
||||
},
|
||||
"name": "new-server-test",
|
||||
"os-extended-volumes:volumes_attached": [],
|
||||
"security_groups": [
|
||||
{
|
||||
"name": "default"
|
||||
}
|
||||
],
|
||||
"server_groups": [],
|
||||
"status": "RESCUE",
|
||||
"tags": [],
|
||||
"tenant_id": "6f70656e737461636b20342065766572",
|
||||
"trusted_image_certificates": null,
|
||||
"updated": "2020-02-07T17:39:49Z",
|
||||
"user_id": "fake"
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
{
|
||||
"server": {
|
||||
"OS-DCF:diskConfig": "AUTO",
|
||||
"OS-EXT-AZ:availability_zone": "us-west",
|
||||
"OS-EXT-SRV-ATTR:host": "compute",
|
||||
"OS-EXT-SRV-ATTR:hostname": "new-server-test",
|
||||
"OS-EXT-SRV-ATTR:hypervisor_hostname": "fake-mini",
|
||||
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",
|
||||
"OS-EXT-SRV-ATTR:kernel_id": "",
|
||||
"OS-EXT-SRV-ATTR:launch_index": 0,
|
||||
"OS-EXT-SRV-ATTR:ramdisk_id": "",
|
||||
"OS-EXT-SRV-ATTR:reservation_id": "r-g20x6pwt",
|
||||
"OS-EXT-SRV-ATTR:root_device_name": "/dev/sda",
|
||||
"OS-EXT-SRV-ATTR:user_data": "IyEvYmluL2Jhc2gKL2Jpbi9zdQplY2hvICJJIGFtIGluIHlvdSEiCg==",
|
||||
"OS-EXT-STS:power_state": 1,
|
||||
"OS-EXT-STS:task_state": null,
|
||||
"OS-EXT-STS:vm_state": "active",
|
||||
"OS-SRV-USG:launched_at": "2020-02-07T17:39:55.632592",
|
||||
"OS-SRV-USG:terminated_at": null,
|
||||
"accessIPv4": "1.2.3.4",
|
||||
"accessIPv6": "80fe::",
|
||||
"addresses": {
|
||||
"private": [
|
||||
{
|
||||
"OS-EXT-IPS-MAC:mac_addr": "00:0c:29:0d:11:74",
|
||||
"OS-EXT-IPS:type": "fixed",
|
||||
"addr": "192.168.1.30",
|
||||
"version": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
"config_drive": "",
|
||||
"created": "2020-02-07T17:39:54Z",
|
||||
"description": null,
|
||||
"flavor": {
|
||||
"disk": 1,
|
||||
"ephemeral": 0,
|
||||
"extra_specs": {},
|
||||
"original_name": "m1.tiny",
|
||||
"ram": 512,
|
||||
"swap": 0,
|
||||
"vcpus": 1
|
||||
},
|
||||
"hostId": "2091634baaccdc4c5a1d57069c833e402921df696b7f970791b12ec6",
|
||||
"host_status": "UP",
|
||||
"id": "5a0ffa96-ae59-4f82-b7a6-e0c9007cd576",
|
||||
"image": {
|
||||
"id": "70a599e0-31e7-49b7-b260-868f441e862b",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/images/70a599e0-31e7-49b7-b260-868f441e862b",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
]
|
||||
},
|
||||
"key_name": null,
|
||||
"links": [
|
||||
{
|
||||
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/servers/5a0ffa96-ae59-4f82-b7a6-e0c9007cd576",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "http://openstack.example.com/6f70656e737461636b20342065766572/servers/5a0ffa96-ae59-4f82-b7a6-e0c9007cd576",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"locked": false,
|
||||
"locked_reason": null,
|
||||
"metadata": {
|
||||
"My Server Name": "Apache1"
|
||||
},
|
||||
"name": "new-server-test",
|
||||
"os-extended-volumes:volumes_attached": [],
|
||||
"progress": 0,
|
||||
"security_groups": [
|
||||
{
|
||||
"name": "default"
|
||||
}
|
||||
],
|
||||
"server_groups": [],
|
||||
"status": "ACTIVE",
|
||||
"tags": [],
|
||||
"tenant_id": "6f70656e737461636b20342065766572",
|
||||
"trusted_image_certificates": null,
|
||||
"updated": "2020-02-07T17:39:56Z",
|
||||
"user_id": "fake"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"rescue": {
|
||||
"adminPass": "MySecretPass",
|
||||
"rescue_image_ref": "70a599e0-31e7-49b7-b260-868f441e862b"
|
||||
}
|
||||
}
|
5
doc/api_samples/os-rescue/v2.87/server-rescue-req.json
Normal file
5
doc/api_samples/os-rescue/v2.87/server-rescue-req.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"rescue": {
|
||||
"adminPass": "MySecretPass"
|
||||
}
|
||||
}
|
3
doc/api_samples/os-rescue/v2.87/server-rescue.json
Normal file
3
doc/api_samples/os-rescue/v2.87/server-rescue.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"adminPass": "MySecretPass"
|
||||
}
|
3
doc/api_samples/os-rescue/v2.87/server-unrescue-req.json
Normal file
3
doc/api_samples/os-rescue/v2.87/server-unrescue-req.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"unrescue": null
|
||||
}
|
@ -19,7 +19,7 @@
|
||||
}
|
||||
],
|
||||
"status": "CURRENT",
|
||||
"version": "2.86",
|
||||
"version": "2.87",
|
||||
"min_version": "2.1",
|
||||
"updated": "2013-07-23T11:33:21Z"
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
}
|
||||
],
|
||||
"status": "CURRENT",
|
||||
"version": "2.86",
|
||||
"version": "2.87",
|
||||
"min_version": "2.1",
|
||||
"updated": "2013-07-23T11:33:21Z"
|
||||
}
|
||||
|
@ -234,6 +234,8 @@ REST_API_VERSION_HISTORY = """REST API Version History:
|
||||
* 2.86 - Add support for validation of known extra specs to the
|
||||
``POST /flavors/{flavor_id}/os-extra_specs`` and
|
||||
``PUT /flavors/{flavor_id}/os-extra_specs/{id}`` APIs.
|
||||
* 2.87 - Adds support for rescuing boot from volume instances when the
|
||||
compute host reports the COMPUTE_BFV_RESCUE capability trait.
|
||||
"""
|
||||
|
||||
# The minimum and maximum versions of the API supported
|
||||
@ -242,7 +244,7 @@ REST_API_VERSION_HISTORY = """REST API Version History:
|
||||
# Note(cyeoh): This only applies for the v2.1 API once microversions
|
||||
# support is fully merged. It does not affect the V2 API.
|
||||
_MIN_API_VERSION = '2.1'
|
||||
_MAX_API_VERSION = '2.86'
|
||||
_MAX_API_VERSION = '2.87'
|
||||
DEFAULT_API_VERSION = _MIN_API_VERSION
|
||||
|
||||
# Almost all proxy APIs which are related to network, images and baremetal
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack import api_version_request
|
||||
from nova.api.openstack import common
|
||||
from nova.api.openstack.compute.schemas import rescue
|
||||
from nova.api.openstack import wsgi
|
||||
@ -56,11 +57,12 @@ class RescueController(wsgi.Controller):
|
||||
rescue_image_ref = None
|
||||
if body['rescue']:
|
||||
rescue_image_ref = body['rescue'].get('rescue_image_ref')
|
||||
|
||||
allow_bfv_rescue = api_version_request.is_supported(req, '2.87')
|
||||
try:
|
||||
self.compute_api.rescue(context, instance,
|
||||
rescue_password=password,
|
||||
rescue_image_ref=rescue_image_ref)
|
||||
rescue_image_ref=rescue_image_ref,
|
||||
allow_bfv_rescue=allow_bfv_rescue)
|
||||
except exception.InstanceIsLocked as e:
|
||||
raise exc.HTTPConflict(explanation=e.format_message())
|
||||
except exception.InstanceInvalidState as state_error:
|
||||
|
@ -1134,3 +1134,9 @@ Validation is only used for recognized extra spec namespaces, namely:
|
||||
``accel``, ``aggregate_instance_extra_specs``, ``capabilities``, ``hw``,
|
||||
``hw_rng``, ``hw_video``, ``os``, ``pci_passthrough``, ``powervm``, ``quota``,
|
||||
``resources``, ``trait``, and ``vmware``.
|
||||
|
||||
2.87
|
||||
----
|
||||
|
||||
Adds support for rescuing boot from volume instances when the compute host
|
||||
reports the ``COMPUTE_BFV_RESCUE`` capability trait.
|
||||
|
@ -0,0 +1,87 @@
|
||||
{
|
||||
"server": {
|
||||
"OS-DCF:diskConfig": "AUTO",
|
||||
"OS-EXT-AZ:availability_zone": "us-west",
|
||||
"OS-EXT-SRV-ATTR:host": "compute",
|
||||
"OS-EXT-SRV-ATTR:hostname": "new-server-test",
|
||||
"OS-EXT-SRV-ATTR:hypervisor_hostname": "fake-mini",
|
||||
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",
|
||||
"OS-EXT-SRV-ATTR:kernel_id": "",
|
||||
"OS-EXT-SRV-ATTR:launch_index": 0,
|
||||
"OS-EXT-SRV-ATTR:ramdisk_id": "",
|
||||
"OS-EXT-SRV-ATTR:reservation_id": "%(reservation_id)s",
|
||||
"OS-EXT-SRV-ATTR:root_device_name": "/dev/sda",
|
||||
"OS-EXT-SRV-ATTR:user_data": "IyEvYmluL2Jhc2gKL2Jpbi9zdQplY2hvICJJIGFtIGluIHlvdSEiCg==",
|
||||
"OS-EXT-STS:power_state": 4,
|
||||
"OS-EXT-STS:task_state": null,
|
||||
"OS-EXT-STS:vm_state": "rescued",
|
||||
"OS-SRV-USG:launched_at": "%(strtime)s",
|
||||
"OS-SRV-USG:terminated_at": null,
|
||||
"accessIPv4": "1.2.3.4",
|
||||
"accessIPv6": "80fe::",
|
||||
"addresses": {
|
||||
"private": [
|
||||
{
|
||||
"OS-EXT-IPS-MAC:mac_addr": "00:0c:29:0d:11:74",
|
||||
"OS-EXT-IPS:type": "fixed",
|
||||
"addr": "192.168.1.30",
|
||||
"version": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
"config_drive": "",
|
||||
"created": "%(isotime)s",
|
||||
"description": null,
|
||||
"flavor": {
|
||||
"disk": 1,
|
||||
"ephemeral": 0,
|
||||
"extra_specs": {},
|
||||
"original_name": "m1.tiny",
|
||||
"ram": 512,
|
||||
"swap": 0,
|
||||
"vcpus": 1
|
||||
},
|
||||
"hostId": "2091634baaccdc4c5a1d57069c833e402921df696b7f970791b12ec6",
|
||||
"host_status": "UP",
|
||||
"id": "%(id)s",
|
||||
"image": {
|
||||
"id": "%(uuid)s",
|
||||
"links": [
|
||||
{
|
||||
"href": "%(compute_endpoint)s/images/%(uuid)s",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
]
|
||||
},
|
||||
"key_name": null,
|
||||
"links": [
|
||||
{
|
||||
"href": "%(versioned_compute_endpoint)s/servers/%(uuid)s",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "%(compute_endpoint)s/servers/%(id)s",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"locked": false,
|
||||
"locked_reason": null,
|
||||
"metadata": {
|
||||
"My Server Name": "Apache1"
|
||||
},
|
||||
"name": "new-server-test",
|
||||
"os-extended-volumes:volumes_attached": [],
|
||||
"security_groups": [
|
||||
{
|
||||
"name": "default"
|
||||
}
|
||||
],
|
||||
"server_groups": [],
|
||||
"status": "RESCUE",
|
||||
"tags": [],
|
||||
"tenant_id": "6f70656e737461636b20342065766572",
|
||||
"trusted_image_certificates": null,
|
||||
"updated": "%(isotime)s",
|
||||
"user_id": "fake"
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
{
|
||||
"server": {
|
||||
"OS-DCF:diskConfig": "AUTO",
|
||||
"OS-EXT-AZ:availability_zone": "us-west",
|
||||
"OS-EXT-SRV-ATTR:host": "compute",
|
||||
"OS-EXT-SRV-ATTR:hostname": "new-server-test",
|
||||
"OS-EXT-SRV-ATTR:hypervisor_hostname": "fake-mini",
|
||||
"OS-EXT-SRV-ATTR:instance_name": "instance-00000001",
|
||||
"OS-EXT-SRV-ATTR:kernel_id": "",
|
||||
"OS-EXT-SRV-ATTR:launch_index": 0,
|
||||
"OS-EXT-SRV-ATTR:ramdisk_id": "",
|
||||
"OS-EXT-SRV-ATTR:reservation_id": "%(reservation_id)s",
|
||||
"OS-EXT-SRV-ATTR:root_device_name": "/dev/sda",
|
||||
"OS-EXT-SRV-ATTR:user_data": "IyEvYmluL2Jhc2gKL2Jpbi9zdQplY2hvICJJIGFtIGluIHlvdSEiCg==",
|
||||
"OS-EXT-STS:power_state": 1,
|
||||
"OS-EXT-STS:task_state": null,
|
||||
"OS-EXT-STS:vm_state": "active",
|
||||
"OS-SRV-USG:launched_at": "%(strtime)s",
|
||||
"OS-SRV-USG:terminated_at": null,
|
||||
"accessIPv4": "1.2.3.4",
|
||||
"accessIPv6": "80fe::",
|
||||
"addresses": {
|
||||
"private": [
|
||||
{
|
||||
"OS-EXT-IPS-MAC:mac_addr": "00:0c:29:0d:11:74",
|
||||
"OS-EXT-IPS:type": "fixed",
|
||||
"addr": "192.168.1.30",
|
||||
"version": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
"config_drive": "",
|
||||
"created": "%(isotime)s",
|
||||
"description": null,
|
||||
"flavor": {
|
||||
"disk": 1,
|
||||
"ephemeral": 0,
|
||||
"extra_specs": {},
|
||||
"original_name": "m1.tiny",
|
||||
"ram": 512,
|
||||
"swap": 0,
|
||||
"vcpus": 1
|
||||
},
|
||||
"hostId": "2091634baaccdc4c5a1d57069c833e402921df696b7f970791b12ec6",
|
||||
"host_status": "UP",
|
||||
"id": "%(id)s",
|
||||
"image": {
|
||||
"id": "%(uuid)s",
|
||||
"links": [
|
||||
{
|
||||
"href": "%(compute_endpoint)s/images/%(uuid)s",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
]
|
||||
},
|
||||
"key_name": null,
|
||||
"links": [
|
||||
{
|
||||
"href": "%(versioned_compute_endpoint)s/servers/%(uuid)s",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "%(compute_endpoint)s/servers/%(id)s",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
"locked": false,
|
||||
"locked_reason": null,
|
||||
"metadata": {
|
||||
"My Server Name": "Apache1"
|
||||
},
|
||||
"name": "new-server-test",
|
||||
"os-extended-volumes:volumes_attached": [],
|
||||
"security_groups": [
|
||||
{
|
||||
"name": "default"
|
||||
}
|
||||
],
|
||||
"server_groups": [],
|
||||
"status": "ACTIVE",
|
||||
"tags": [],
|
||||
"tenant_id": "6f70656e737461636b20342065766572",
|
||||
"trusted_image_certificates": null,
|
||||
"updated": "%(isotime)s",
|
||||
"user_id": "fake",
|
||||
"progress": 0
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"rescue": {
|
||||
"adminPass": "MySecretPass",
|
||||
"rescue_image_ref": "70a599e0-31e7-49b7-b260-868f441e862b"
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"rescue": {
|
||||
"adminPass": "%(password)s"
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"adminPass": "%(password)s"
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"unrescue": null
|
||||
}
|
@ -92,3 +92,9 @@ class RescueJsonTest(test_servers.ServersSampleBase):
|
||||
subs['hypervisor_hostname'] = r'[\w\.\-]+'
|
||||
subs['cdrive'] = '.*'
|
||||
self._verify_response('server-get-resp-unrescue', subs, response, 200)
|
||||
|
||||
|
||||
class Rescuev287JsonTest(RescueJsonTest):
|
||||
"""2.87 adds support for rescuing boot from volume instances"""
|
||||
microversion = '2.87'
|
||||
scenarios = [('v2_87', {'api_major_version': 'v2.1'})]
|
||||
|
100
nova/tests/functional/test_server_rescue.py
Normal file
100
nova/tests/functional/test_server_rescue.py
Normal file
@ -0,0 +1,100 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nova.tests import fixtures as nova_fixtures
|
||||
from nova.tests.functional.api import client
|
||||
from nova.tests.functional import integrated_helpers
|
||||
|
||||
|
||||
class BFVRescue(integrated_helpers.ProviderUsageBaseTestCase):
|
||||
"""Base class for various boot from volume rescue tests."""
|
||||
|
||||
def setUp(self):
|
||||
super(BFVRescue, self).setUp()
|
||||
self.useFixture(nova_fixtures.CinderFixture(self))
|
||||
self._start_compute(host='host1')
|
||||
|
||||
def _create_bfv_server(self):
|
||||
server_request = self._build_server(networks=[])
|
||||
server_request.pop('imageRef')
|
||||
server_request['block_device_mapping_v2'] = [{
|
||||
'boot_index': 0,
|
||||
'uuid': nova_fixtures.CinderFixture.IMAGE_BACKED_VOL,
|
||||
'source_type': 'volume',
|
||||
'destination_type': 'volume'}]
|
||||
server = self.api.post_server({'server': server_request})
|
||||
self._wait_for_state_change(server, 'ACTIVE')
|
||||
return server
|
||||
|
||||
|
||||
class DisallowBFVRescuev286(BFVRescue):
|
||||
"""Asserts that BFV rescue requests fail prior to microversion 2.87.
|
||||
"""
|
||||
compute_driver = 'fake.MediumFakeDriver'
|
||||
microversion = '2.86'
|
||||
|
||||
def test_bfv_rescue_not_supported(self):
|
||||
server = self._create_bfv_server()
|
||||
ex = self.assertRaises(client.OpenStackApiException,
|
||||
self.api.post_server_action, server['id'], {'rescue': {
|
||||
'rescue_image_ref': '155d900f-4e14-4e4c-a73d-069cbf4541e6'}})
|
||||
self.assertEqual(400, ex.response.status_code)
|
||||
self.assertIn('Cannot rescue a volume-backed instance',
|
||||
ex.response.text)
|
||||
|
||||
|
||||
class DisallowBFVRescuev286WithTrait(BFVRescue):
|
||||
"""Asserts that BFV rescue requests fail prior to microversion 2.87 even
|
||||
when the required COMPUTE_RESCUE_BFV trait is reported by the compute.
|
||||
"""
|
||||
compute_driver = 'fake.RescueBFVDriver'
|
||||
microversion = '2.86'
|
||||
|
||||
def test_bfv_rescue_not_supported(self):
|
||||
server = self._create_bfv_server()
|
||||
ex = self.assertRaises(client.OpenStackApiException,
|
||||
self.api.post_server_action, server['id'], {'rescue': {
|
||||
'rescue_image_ref': '155d900f-4e14-4e4c-a73d-069cbf4541e6'}})
|
||||
self.assertEqual(400, ex.response.status_code)
|
||||
self.assertIn('Cannot rescue a volume-backed instance',
|
||||
ex.response.text)
|
||||
|
||||
|
||||
class DisallowBFVRescuev287WithoutTrait(BFVRescue):
|
||||
"""Asserts that BFV rescue requests fail with microversion 2.87 (or later)
|
||||
when the required COMPUTE_RESCUE_BFV trait is not reported by the compute.
|
||||
"""
|
||||
compute_driver = 'fake.MediumFakeDriver'
|
||||
microversion = '2.87'
|
||||
|
||||
def test_bfv_rescue_not_supported(self):
|
||||
server = self._create_bfv_server()
|
||||
ex = self.assertRaises(client.OpenStackApiException,
|
||||
self.api.post_server_action, server['id'], {'rescue': {
|
||||
'rescue_image_ref': '155d900f-4e14-4e4c-a73d-069cbf4541e6'}})
|
||||
self.assertEqual(400, ex.response.status_code)
|
||||
self.assertIn('Host unable to rescue a volume-backed instance',
|
||||
ex.response.text)
|
||||
|
||||
|
||||
class AllowBFVRescuev287WithTrait(BFVRescue):
|
||||
"""Asserts that BFV rescue requests pass with microversion 2.87 (or later)
|
||||
when the required COMPUTE_RESCUE_BFV trait is reported by the compute.
|
||||
"""
|
||||
compute_driver = 'fake.RescueBFVDriver'
|
||||
microversion = '2.87'
|
||||
|
||||
def test_bfv_rescue_supported(self):
|
||||
server = self._create_bfv_server()
|
||||
self.api.post_server_action(server['id'], {'rescue': {
|
||||
'rescue_image_ref': '155d900f-4e14-4e4c-a73d-069cbf4541e6'}})
|
||||
self._wait_for_state_change(server, 'RESCUE')
|
@ -15,6 +15,9 @@
|
||||
import mock
|
||||
import webob
|
||||
|
||||
from oslo_utils.fixture import uuidsentinel as uuids
|
||||
|
||||
from nova.api.openstack import api_version_request
|
||||
from nova.api.openstack.compute import rescue as rescue_v21
|
||||
from nova import compute
|
||||
import nova.conf
|
||||
@ -28,7 +31,7 @@ UUID = '70f6db34-de8d-4fbd-aafb-4065bdfa6114'
|
||||
|
||||
|
||||
def rescue(self, context, instance, rescue_password=None,
|
||||
rescue_image_ref=None):
|
||||
rescue_image_ref=None, allow_bfv_rescue=False):
|
||||
pass
|
||||
|
||||
|
||||
@ -57,6 +60,9 @@ class RescueTestV21(test.NoDBTestCase):
|
||||
def _set_up_controller(self):
|
||||
return rescue_v21.RescueController()
|
||||
|
||||
def _allow_bfv_rescue(self):
|
||||
return api_version_request.is_supported(self.fake_req, '2.87')
|
||||
|
||||
@mock.patch.object(compute.api.API, "rescue")
|
||||
def test_rescue_from_locked_server(self, mock_rescue):
|
||||
mock_rescue.side_effect = exception.InstanceIsLocked(
|
||||
@ -173,7 +179,8 @@ class RescueTestV21(test.NoDBTestCase):
|
||||
mock.ANY,
|
||||
instance,
|
||||
rescue_password=u'ABC123',
|
||||
rescue_image_ref=self.image_uuid)
|
||||
rescue_image_ref=self.image_uuid,
|
||||
allow_bfv_rescue=self._allow_bfv_rescue())
|
||||
|
||||
@mock.patch('nova.compute.api.API.rescue')
|
||||
@mock.patch('nova.api.openstack.common.get_instance')
|
||||
@ -187,9 +194,9 @@ class RescueTestV21(test.NoDBTestCase):
|
||||
resp_json = self.controller._rescue(self.fake_req, UUID, body=body)
|
||||
self.assertEqual("ABC123", resp_json['adminPass'])
|
||||
|
||||
mock_compute_api_rescue.assert_called_with(mock.ANY, instance,
|
||||
rescue_password=u'ABC123',
|
||||
rescue_image_ref=None)
|
||||
mock_compute_api_rescue.assert_called_with(
|
||||
mock.ANY, instance, rescue_password=u'ABC123',
|
||||
rescue_image_ref=None, allow_bfv_rescue=self._allow_bfv_rescue())
|
||||
|
||||
def test_rescue_with_none(self):
|
||||
body = dict(rescue=None)
|
||||
@ -212,3 +219,28 @@ class RescueTestV21(test.NoDBTestCase):
|
||||
self.assertRaises(exception.ValidationError,
|
||||
self.controller._rescue,
|
||||
self.fake_req, UUID, body=body)
|
||||
|
||||
|
||||
class RescueTestV287(RescueTestV21):
|
||||
|
||||
def setUp(self):
|
||||
super(RescueTestV287, self).setUp()
|
||||
v287_req = api_version_request.APIVersionRequest('2.87')
|
||||
self.fake_req.api_version_request = v287_req
|
||||
|
||||
@mock.patch('nova.compute.api.API.rescue')
|
||||
@mock.patch('nova.api.openstack.common.get_instance')
|
||||
def test_allow_bfv_rescue(self, mock_get_instance, mock_compute_rescue):
|
||||
instance = fake_instance.fake_instance_obj(
|
||||
self.fake_req.environ['nova.context'])
|
||||
mock_get_instance.return_value = instance
|
||||
|
||||
body = {"rescue": {"adminPass": "ABC123"}}
|
||||
self.controller._rescue(self.fake_req, uuids.instance, body=body)
|
||||
|
||||
# Assert that allow_bfv_rescue is True for this 2.87 request
|
||||
mock_get_instance.assert_called_once_with(
|
||||
mock.ANY, mock.ANY, uuids.instance)
|
||||
mock_compute_rescue.assert_called_with(
|
||||
mock.ANY, instance, rescue_image_ref=None,
|
||||
rescue_password=u'ABC123', allow_bfv_rescue=True)
|
||||
|
@ -711,6 +711,10 @@ class SameHostColdMigrateDriver(MediumFakeDriver):
|
||||
supports_migrate_to_same_host=True)
|
||||
|
||||
|
||||
class RescueBFVDriver(MediumFakeDriver):
|
||||
capabilities = dict(FakeDriver.capabilities, supports_bfv_rescue=True)
|
||||
|
||||
|
||||
class PowerUpdateFakeDriver(SmallFakeDriver):
|
||||
# A specific fake driver for the power-update external event testing.
|
||||
|
||||
|
10
releasenotes/notes/stable_rescue_bfv-cd0e9f0f7e9eaa25.yaml
Normal file
10
releasenotes/notes/stable_rescue_bfv-cd0e9f0f7e9eaa25.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Stable device rescue for boot from volume instances is now supported
|
||||
through the use of the 2.87 microversion when the compute hosting the
|
||||
instance also reports the ``COMPUTE_RESCUE_BFV`` trait such as the libvirt
|
||||
driver.
|
||||
|
||||
No changes have been made to the request or reponse parameters of the
|
||||
rescue API itself.
|
Loading…
Reference in New Issue
Block a user