Fix nova rebuild not support vm use boot volume
Change-Id: Ic7b9b9b96db79e0b6e0c8ec3412d3eef172c5652 Closes-Bug: 1740977
This commit is contained in:
parent
ca12b67688
commit
33231f869f
|
@ -1491,30 +1491,51 @@ class ServerProfile(base.Profile):
|
|||
return None
|
||||
|
||||
server_id = obj.physical_id
|
||||
driver = self.compute(obj)
|
||||
nova_driver = self.compute(obj)
|
||||
try:
|
||||
server = driver.server_get(server_id)
|
||||
server = nova_driver.server_get(server_id)
|
||||
except exc.InternalError as ex:
|
||||
raise exc.EResourceOperation(op='rebuilding', type='server',
|
||||
id=server_id,
|
||||
message=six.text_type(ex))
|
||||
|
||||
if server is None or server.image is None:
|
||||
if server is None:
|
||||
return None
|
||||
# when booting a nova server from volume, the image property
|
||||
# can be ignored.
|
||||
# we try find a volume which is bootable and use its image_id
|
||||
# for the server.
|
||||
if server.image:
|
||||
image_id = server.image
|
||||
elif server.attached_volumes:
|
||||
cinder_driver = self.block_storage(obj)
|
||||
for volume_ids in server.attached_volumes:
|
||||
try:
|
||||
vs = cinder_driver.volume_get(volume_ids['id'])
|
||||
if vs.is_bootable:
|
||||
image_id = vs.volume_image_metadata['image_id']
|
||||
except exc.InternalError as ex:
|
||||
raise exc.EResourceOperation(op='rebuild', type='server',
|
||||
id=obj.physical_id,
|
||||
message=six.text_type(ex))
|
||||
else:
|
||||
msg = _("server doesn't have an image and it has no "
|
||||
"bootable volume")
|
||||
raise exc.EResourceOperation(op="rebuild", type="server",
|
||||
id=obj.physical_id,
|
||||
message=msg)
|
||||
|
||||
image_id = server.image['id']
|
||||
admin_pass = self.properties.get(self.ADMIN_PASS)
|
||||
name = self.properties[self.NAME] or obj.name
|
||||
try:
|
||||
driver.server_rebuild(server_id, image_id,
|
||||
name, admin_pass)
|
||||
driver.wait_for_server(server_id, 'ACTIVE')
|
||||
nova_driver.server_rebuild(server_id, image_id,
|
||||
name, admin_pass)
|
||||
nova_driver.wait_for_server(server_id, 'ACTIVE')
|
||||
return server_id
|
||||
except exc.InternalError as ex:
|
||||
raise exc.EResourceOperation(op='rebuilding', type='server',
|
||||
id=server_id,
|
||||
message=six.text_type(ex))
|
||||
return None
|
||||
|
||||
def handle_change_password(self, obj, **options):
|
||||
"""Handler for the change_password operation."""
|
||||
|
|
|
@ -1237,9 +1237,48 @@ class TestNovaServerBasic(base.SenlinTestCase):
|
|||
res = profile.handle_reboot(obj, type='foo')
|
||||
self.assertFalse(res)
|
||||
|
||||
def test_handle_rebuild(self):
|
||||
def test_handle_rebuild_with_image(self):
|
||||
profile = server.ServerProfile('t', self.spec)
|
||||
x_image = {'id': '123'}
|
||||
x_image = '123'
|
||||
x_server = mock.Mock(image=x_image)
|
||||
cc = mock.Mock()
|
||||
cc.server_get.return_value = x_server
|
||||
cc.server_rebuild.return_value = True
|
||||
profile._computeclient = cc
|
||||
node_obj = mock.Mock(physical_id='FAKE_ID')
|
||||
|
||||
res = profile.handle_rebuild(node_obj)
|
||||
|
||||
self.assertEqual('FAKE_ID', res)
|
||||
cc.server_get.assert_called_with('FAKE_ID')
|
||||
cc.server_rebuild.assert_called_once_with('FAKE_ID', '123',
|
||||
'FAKE_SERVER_NAME',
|
||||
'adminpass')
|
||||
cc.wait_for_server.assert_called_once_with('FAKE_ID', 'ACTIVE')
|
||||
|
||||
def test_handle_rebuild_with_bdm(self):
|
||||
bdm_v2 = [
|
||||
{
|
||||
'volume_size': 1,
|
||||
'uuid': '123',
|
||||
'source_type': 'image',
|
||||
'destination_type': 'volume',
|
||||
'boot_index': 0,
|
||||
}
|
||||
]
|
||||
spec = {
|
||||
'type': 'os.nova.server',
|
||||
'version': '1.0',
|
||||
'properties': {
|
||||
'flavor': 'FLAV',
|
||||
'admin_pass': 'adminpass',
|
||||
'name': 'FAKE_SERVER_NAME',
|
||||
'security_groups': ['HIGH_SECURITY_GROUP'],
|
||||
'block_device_mapping_v2': bdm_v2,
|
||||
}
|
||||
}
|
||||
profile = server.ServerProfile('t', spec)
|
||||
x_image = '123'
|
||||
x_server = mock.Mock(image=x_image)
|
||||
cc = mock.Mock()
|
||||
cc.server_get.return_value = x_server
|
||||
|
@ -1275,7 +1314,7 @@ class TestNovaServerBasic(base.SenlinTestCase):
|
|||
|
||||
def test_handle_rebuild_failed_rebuild(self):
|
||||
profile = server.ServerProfile('t', self.spec)
|
||||
x_image = {'id': '123'}
|
||||
x_image = '123'
|
||||
x_server = mock.Mock(image=x_image)
|
||||
cc = mock.Mock()
|
||||
cc.server_get.return_value = x_server
|
||||
|
@ -1299,7 +1338,7 @@ class TestNovaServerBasic(base.SenlinTestCase):
|
|||
|
||||
def test_handle_rebuild_failed_waiting(self):
|
||||
profile = server.ServerProfile('t', self.spec)
|
||||
x_image = {'id': '123'}
|
||||
x_image = '123'
|
||||
x_server = mock.Mock(image=x_image)
|
||||
cc = mock.Mock()
|
||||
cc.server_get.return_value = x_server
|
||||
|
@ -1348,7 +1387,7 @@ class TestNovaServerBasic(base.SenlinTestCase):
|
|||
def test_handle_rebuild_failed_with_name(self):
|
||||
self.spec['properties']['name'] = None
|
||||
profile = server.ServerProfile('t', self.spec)
|
||||
x_image = {'id': '123'}
|
||||
x_image = '123'
|
||||
x_server = mock.Mock(image=x_image)
|
||||
cc = mock.Mock()
|
||||
cc.server_get.return_value = x_server
|
||||
|
|
Loading…
Reference in New Issue