Allow user to specify image to use during rescue - V3 API changes
This commit includes the V3 changes. Making changes in V3 API to take an extra parameter rescue_image_ref as part of the rescue action API. If specified, this image_ref will be used to rescue the instance. If the image is not specified, then the base image ref is used by default. Partially Implements: blueprint allow-image-to-be-specified-during-rescue DocImpact Change-Id: I7a9d88bf4dfe73879247f5b82a52928fdde76510
This commit is contained in:
parent
d4813b01a3
commit
001f865c3c
@ -0,0 +1,6 @@
|
||||
{
|
||||
"rescue": {
|
||||
"admin_password": "MySecretPass",
|
||||
"image_ref": "70a599e0-31e7-49b7-b260-868f441e862b"
|
||||
}
|
||||
}
|
@ -58,9 +58,14 @@ class RescueController(wsgi.Controller):
|
||||
|
||||
instance = common.get_instance(self.compute_api, context, id,
|
||||
want_objects=True)
|
||||
rescue_image_ref = None
|
||||
if body['rescue'] and 'image_ref' in body['rescue']:
|
||||
rescue_image_ref = body['rescue']['image_ref']
|
||||
|
||||
try:
|
||||
self.compute_api.rescue(context, instance,
|
||||
rescue_password=password)
|
||||
rescue_password=password,
|
||||
rescue_image_ref=rescue_image_ref)
|
||||
except exception.InstanceIsLocked as e:
|
||||
raise exc.HTTPConflict(explanation=e.format_message())
|
||||
except exception.InstanceInvalidState as state_error:
|
||||
|
@ -22,6 +22,7 @@ rescue = {
|
||||
'type': ['object', 'null'],
|
||||
'properties': {
|
||||
'admin_password': parameter_types.admin_password,
|
||||
'image_ref': parameter_types.image_ref,
|
||||
},
|
||||
'additionalProperties': False,
|
||||
},
|
||||
|
@ -73,3 +73,8 @@ admin_password = {
|
||||
# and string pattern.
|
||||
'type': 'string',
|
||||
}
|
||||
|
||||
|
||||
image_ref = {
|
||||
'type': 'string',
|
||||
}
|
||||
|
@ -26,7 +26,8 @@ CONF = cfg.CONF
|
||||
CONF.import_opt('password_length', 'nova.utils')
|
||||
|
||||
|
||||
def rescue(self, context, instance, rescue_password=None):
|
||||
def rescue(self, context, instance, rescue_password=None,
|
||||
rescue_image_ref=None):
|
||||
pass
|
||||
|
||||
|
||||
@ -34,14 +35,15 @@ def unrescue(self, context, instance):
|
||||
pass
|
||||
|
||||
|
||||
def fake_compute_get(*args, **kwargs):
|
||||
uuid = '70f6db34-de8d-4fbd-aafb-4065bdfa6114'
|
||||
return {'id': 1, 'uuid': uuid}
|
||||
|
||||
|
||||
class RescueTest(test.NoDBTestCase):
|
||||
def setUp(self):
|
||||
super(RescueTest, self).setUp()
|
||||
|
||||
def fake_compute_get(*args, **kwargs):
|
||||
uuid = '70f6db34-de8d-4fbd-aafb-4065bdfa6114'
|
||||
return {'id': 1, 'uuid': uuid}
|
||||
|
||||
self.stubs.Set(compute.api.API, "get", fake_compute_get)
|
||||
self.stubs.Set(compute.api.API, "rescue", rescue)
|
||||
self.stubs.Set(compute.api.API, "unrescue", unrescue)
|
||||
@ -64,6 +66,44 @@ class RescueTest(test.NoDBTestCase):
|
||||
resp = req.get_response(self.app)
|
||||
self.assertEqual(resp.status_int, 409)
|
||||
|
||||
@mock.patch('nova.compute.api.API.rescue')
|
||||
def test_rescue_with_image_specified(self, mock_compute_api_rescue):
|
||||
instance = fake_compute_get()
|
||||
body = {"rescue": {"admin_password": "ABC123",
|
||||
"image_ref": "img-id"}}
|
||||
req = webob.Request.blank('/v3/servers/test_inst/action')
|
||||
req.method = "POST"
|
||||
req.body = jsonutils.dumps(body)
|
||||
req.headers["content-type"] = "application/json"
|
||||
|
||||
resp = req.get_response(self.app)
|
||||
self.assertEqual(resp.status_int, 202)
|
||||
resp_json = jsonutils.loads(resp.body)
|
||||
self.assertEqual("ABC123", resp_json['admin_password'])
|
||||
|
||||
mock_compute_api_rescue.assert_called_with(mock.ANY, instance,
|
||||
rescue_password=u'ABC123',
|
||||
rescue_image_ref=u'img-id')
|
||||
|
||||
@mock.patch('nova.compute.api.API.rescue')
|
||||
def test_rescue_without_image_specified(self, mock_compute_api_rescue):
|
||||
instance = fake_compute_get()
|
||||
body = {"rescue": {"admin_password": "ABC123"}}
|
||||
|
||||
req = webob.Request.blank('/v3/servers/test_inst/action')
|
||||
req.method = "POST"
|
||||
req.body = jsonutils.dumps(body)
|
||||
req.headers["content-type"] = "application/json"
|
||||
|
||||
resp = req.get_response(self.app)
|
||||
self.assertEqual(resp.status_int, 202)
|
||||
resp_json = jsonutils.loads(resp.body)
|
||||
self.assertEqual("ABC123", resp_json['admin_password'])
|
||||
|
||||
mock_compute_api_rescue.assert_called_with(mock.ANY, instance,
|
||||
rescue_password=u'ABC123',
|
||||
rescue_image_ref=None)
|
||||
|
||||
def test_rescue_with_preset_password(self):
|
||||
body = {"rescue": {"admin_password": "AABBCC112233"}}
|
||||
req = webob.Request.blank('/v3/servers/test_inst/action')
|
||||
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"rescue": {
|
||||
"admin_password": "%(password)s",
|
||||
"image_ref": "%(image_ref)s"
|
||||
}
|
||||
}
|
@ -46,6 +46,26 @@ class RescueJsonTest(test_servers.ServersSampleBase):
|
||||
|
||||
self._verify_response('server-get-resp-rescue', subs, response, 200)
|
||||
|
||||
def test_server_rescue_with_image_ref_specified(self):
|
||||
uuid = self._post_server()
|
||||
|
||||
req_subs = {
|
||||
'password': 'MySecretPass',
|
||||
'image_ref': '2341-Abc'
|
||||
}
|
||||
response = self._do_post('servers/%s/action' % uuid,
|
||||
'server-rescue-req-with-image-ref', req_subs)
|
||||
self._verify_response('server-rescue', req_subs, response, 202)
|
||||
|
||||
# Do a server get to make sure that the 'RESCUE' state is set
|
||||
response = self._do_get('servers/%s' % uuid)
|
||||
subs = self._get_regexes()
|
||||
subs['hostid'] = '[a-f0-9]+'
|
||||
subs['id'] = uuid
|
||||
subs['status'] = 'RESCUE'
|
||||
|
||||
self._verify_response('server-get-resp-rescue', subs, response, 200)
|
||||
|
||||
def test_server_unrescue(self):
|
||||
uuid = self._post_server()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user