Use disk_bus and device_type in attaching volumes
This patch enables users to pass disk_bus and device_type parameters to attach action api call of the extended-volumes plugin (v3 API only). It also implements this functionality inside the libvirt driver. Implements blueprint: use-new-bdm-format-in-attach Change-Id: I7895974def7057fbaddf2b3715a8b72a76f88f3e
This commit is contained in:
parent
e404bb9522
commit
0ec5e32dc7
@ -1,6 +1,8 @@
|
||||
{
|
||||
"attach": {
|
||||
"volume_id": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
|
||||
"device": "/dev/vdd"
|
||||
"device": "/dev/vdd",
|
||||
"disk_bus": "ide",
|
||||
"device_type": "cdrom"
|
||||
}
|
||||
}
|
@ -129,6 +129,8 @@ class ExtendedVolumesController(wsgi.Controller):
|
||||
|
||||
volume_id = body['attach']['volume_id']
|
||||
device = body['attach'].get('device')
|
||||
disk_bus = body['attach'].get('disk_bus')
|
||||
device_type = body['attach'].get('device_type')
|
||||
|
||||
LOG.audit(_("Attach volume %(volume_id)s to instance %(server_id)s "
|
||||
"at %(device)s"),
|
||||
@ -141,7 +143,9 @@ class ExtendedVolumesController(wsgi.Controller):
|
||||
want_objects=True)
|
||||
try:
|
||||
self.compute_api.attach_volume(context, instance,
|
||||
volume_id, device)
|
||||
volume_id, device,
|
||||
disk_bus=disk_bus,
|
||||
device_type=device_type)
|
||||
except exception.VolumeNotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
except exception.InstanceIsLocked as e:
|
||||
|
@ -49,6 +49,12 @@ attach = {
|
||||
# nova/block_device.py.
|
||||
'pattern': '(^/dev/x{0,1}[a-z]{0,1}d{0,1})([a-z]+)[0-9]*$'
|
||||
},
|
||||
'disk_bus': {
|
||||
'type': 'string'
|
||||
},
|
||||
'device_type': {
|
||||
'type': 'string',
|
||||
}
|
||||
},
|
||||
'required': ['volume_id'],
|
||||
'additionalProperties': False,
|
||||
|
@ -53,28 +53,32 @@ def fake_compute_get_instance_bdms(*args, **kwargs):
|
||||
return [{'volume_id': UUID1}, {'volume_id': UUID2}]
|
||||
|
||||
|
||||
def fake_attach_volume(self, context, instance, volume_id, device):
|
||||
def fake_attach_volume(self, context, instance, volume_id,
|
||||
device, disk_bus, device_type):
|
||||
pass
|
||||
|
||||
|
||||
def fake_attach_volume_not_found_vol(self, context, instance, volume_id,
|
||||
device):
|
||||
device, disk_bus, device_type):
|
||||
raise exception.VolumeNotFound(volume_id=volume_id)
|
||||
|
||||
|
||||
def fake_attach_volume_invalid_device_path(self, context, instance,
|
||||
volume_id, device):
|
||||
volume_id, device, disk_bus,
|
||||
device_type):
|
||||
raise exception.InvalidDevicePath(path=device)
|
||||
|
||||
|
||||
def fake_attach_volume_instance_invalid_state(self, context, instance,
|
||||
volume_id, device):
|
||||
volume_id, device, disk_bus,
|
||||
device_type):
|
||||
raise exception.InstanceInvalidState(instance_uuid=UUID1, state='',
|
||||
method='', attr='')
|
||||
|
||||
|
||||
def fake_attach_volume_invalid_volume(self, context, instance,
|
||||
volume_id, device):
|
||||
volume_id, device, disk_bus,
|
||||
device_type):
|
||||
raise exception.InvalidVolume(reason='')
|
||||
|
||||
|
||||
@ -101,6 +105,12 @@ def fake_detach_volume_invalid_volume(self, context, instance, volume):
|
||||
raise exception.InvalidVolume(reason='')
|
||||
|
||||
|
||||
def fake_swap_volume_instance_invalid_state(self, context, instance,
|
||||
volume_id, device):
|
||||
raise exception.InstanceInvalidState(instance_uuid=UUID1, state='',
|
||||
method='', attr='')
|
||||
|
||||
|
||||
def fake_volume_get(*args, **kwargs):
|
||||
pass
|
||||
|
||||
@ -225,6 +235,13 @@ class ExtendedVolumesTest(test.TestCase):
|
||||
res = self._make_request(url, {"attach": {"volume_id": UUID1}})
|
||||
self.assertEqual(res.status_int, 409)
|
||||
|
||||
def test_attach_volume_disk_bus_and_disk_dev(self):
|
||||
url = "/v3/servers/%s/action" % UUID1
|
||||
res = self._make_request(url, {"attach": {"volume_id": UUID1,
|
||||
"device": "/dev/vdb",
|
||||
"disk_bus": "ide",
|
||||
"device_type": "cdrom"}})
|
||||
|
||||
def test_attach_volume_with_bad_id(self):
|
||||
url = "/v3/servers/%s/action" % UUID1
|
||||
res = self._make_request(url, {"attach": {"volume_id": 'xxx'}})
|
||||
@ -339,7 +356,7 @@ class ExtendedVolumesTest(test.TestCase):
|
||||
|
||||
def test_swap_volume_with_bad_state_instance(self):
|
||||
self.stubs.Set(compute.api.API, 'swap_volume',
|
||||
fake_attach_volume_instance_invalid_state)
|
||||
fake_swap_volume_instance_invalid_state)
|
||||
self.assertRaises(webob.exc.HTTPConflict, self._test_swap)
|
||||
|
||||
def test_swap_volume_no_attachment(self):
|
||||
|
@ -443,7 +443,7 @@ def fake_instance_get(**kwargs):
|
||||
return _return_server
|
||||
|
||||
|
||||
def fake_actions_to_locked_server(self, context, instance, *args):
|
||||
def fake_actions_to_locked_server(self, context, instance, *args, **kwargs):
|
||||
raise exc.InstanceIsLocked(instance_uuid=instance['uuid'])
|
||||
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
{
|
||||
"attach": {
|
||||
"volume_id": "%(volume_id)s",
|
||||
"device": "%(device)s"
|
||||
"device": "%(device)s",
|
||||
"disk_bus": "%(disk_bus)s",
|
||||
"device_type": "%(device_type)s"
|
||||
}
|
||||
}
|
||||
|
@ -70,6 +70,8 @@ class ExtendedVolumesSampleJsonTests(test_servers.ServersSampleBase):
|
||||
|
||||
def test_attach_volume(self):
|
||||
device_name = '/dev/vdd'
|
||||
disk_bus = 'ide'
|
||||
device_type = 'cdrom'
|
||||
self.stubs.Set(cinder.API, 'get', fakes.stub_volume_get)
|
||||
self.stubs.Set(cinder.API, 'check_attach', lambda *a, **k: None)
|
||||
self.stubs.Set(cinder.API, 'reserve_volume', lambda *a, **k: None)
|
||||
@ -86,7 +88,9 @@ class ExtendedVolumesSampleJsonTests(test_servers.ServersSampleBase):
|
||||
'a26887c6-c47b-4654-abb5-dfadf7d3f803')
|
||||
subs = {
|
||||
'volume_id': volume['id'],
|
||||
'device': device_name
|
||||
'device': device_name,
|
||||
'disk_bus': 'ide',
|
||||
'device_type': 'cdrom'
|
||||
}
|
||||
server_id = self._post_server()
|
||||
response = self._do_post('servers/%s/action'
|
||||
|
@ -1154,12 +1154,10 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
instance_name = instance['name']
|
||||
virt_dom = self._lookup_by_name(instance_name)
|
||||
disk_dev = mountpoint.rpartition("/")[2]
|
||||
disk_info = {
|
||||
'dev': disk_dev,
|
||||
'bus': blockinfo.get_disk_bus_for_disk_dev(
|
||||
CONF.libvirt.virt_type, disk_dev),
|
||||
'type': 'disk',
|
||||
}
|
||||
bdm = {
|
||||
'device_name': disk_dev,
|
||||
'disk_bus': disk_bus,
|
||||
'device_type': device_type}
|
||||
|
||||
# Note(cfb): If the volume has a custom block size, check that
|
||||
# that we are using QEMU/KVM and libvirt >= 0.10.2. The
|
||||
@ -1182,6 +1180,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
"required.") % ver
|
||||
raise exception.Invalid(msg)
|
||||
|
||||
disk_info = blockinfo.get_info_from_bdm(CONF.libvirt.virt_type, bdm)
|
||||
conf = self.volume_driver_method('connect_volume',
|
||||
connection_info,
|
||||
disk_info)
|
||||
|
Loading…
x
Reference in New Issue
Block a user