Merge "Support host-attach of volumes"

This commit is contained in:
Jenkins
2015-06-09 20:12:07 +00:00
committed by Gerrit Code Review
6 changed files with 47 additions and 26 deletions

View File

@@ -330,9 +330,9 @@ class FakeHTTPClient(base_client.HTTPClient):
assert len(list(body)) == 1 assert len(list(body)) == 1
action = list(body)[0] action = list(body)[0]
if action == 'os-attach': if action == 'os-attach':
assert sorted(list(body[action])) == ['instance_uuid', keys = sorted(list(body[action]))
'mode', assert (keys == ['instance_uuid', 'mode', 'mountpoint'] or
'mountpoint'] keys == ['host_name', 'mode', 'mountpoint'])
elif action == 'os-detach': elif action == 'os-detach':
assert body[action] is None assert body[action] is None
elif action == 'os-reserve': elif action == 'os-reserve':

View File

@@ -38,6 +38,11 @@ class VolumesTest(utils.TestCase):
cs.volumes.attach(v, 1, '/dev/vdc', mode='rw') cs.volumes.attach(v, 1, '/dev/vdc', mode='rw')
cs.assert_called('POST', '/volumes/1234/action') cs.assert_called('POST', '/volumes/1234/action')
def test_attach_to_host(self):
v = cs.volumes.get('1234')
cs.volumes.attach(v, None, None, host_name='test', mode='rw')
cs.assert_called('POST', '/volumes/1234/action')
def test_detach(self): def test_detach(self):
v = cs.volumes.get('1234') v = cs.volumes.get('1234')
cs.volumes.detach(v) cs.volumes.detach(v)

View File

@@ -411,9 +411,9 @@ class FakeHTTPClient(base_client.HTTPClient):
assert len(list(body)) == 1 assert len(list(body)) == 1
action = list(body)[0] action = list(body)[0]
if action == 'os-attach': if action == 'os-attach':
assert sorted(list(body[action])) == ['instance_uuid', keys = sorted(list(body[action]))
'mode', assert (keys == ['instance_uuid', 'mode', 'mountpoint'] or
'mountpoint'] keys == ['host_name', 'mode', 'mountpoint'])
elif action == 'os-detach': elif action == 'os-detach':
assert body[action] is None assert body[action] is None
elif action == 'os-reserve': elif action == 'os-reserve':

View File

@@ -104,6 +104,11 @@ class VolumesTest(utils.TestCase):
cs.volumes.attach(v, 1, '/dev/vdc', mode='ro') cs.volumes.attach(v, 1, '/dev/vdc', mode='ro')
cs.assert_called('POST', '/volumes/1234/action') cs.assert_called('POST', '/volumes/1234/action')
def test_attach_to_host(self):
v = cs.volumes.get('1234')
cs.volumes.attach(v, None, None, host_name='test', mode='rw')
cs.assert_called('POST', '/volumes/1234/action')
def test_detach(self): def test_detach(self):
v = cs.volumes.get('1234') v = cs.volumes.get('1234')
cs.volumes.detach(v) cs.volumes.detach(v)

View File

@@ -40,14 +40,17 @@ class Volume(base.Resource):
"""Update the display_name or display_description for this volume.""" """Update the display_name or display_description for this volume."""
self.manager.update(self, **kwargs) self.manager.update(self, **kwargs)
def attach(self, instance_uuid, mountpoint, mode='rw'): def attach(self, instance_uuid, mountpoint, mode='rw',
host_name=None):
"""Set attachment metadata. """Set attachment metadata.
:param instance_uuid: uuid of the attaching instance. :param instance_uuid: uuid of the attaching instance.
:param mountpoint: mountpoint on the attaching instance. :param mountpoint: mountpoint on the attaching instance or host.
:param mode: the access mode :param mode: the access mode
:param host_name: name of the attaching host.
""" """
return self.manager.attach(self, instance_uuid, mountpoint, mode) return self.manager.attach(self, instance_uuid, mountpoint, mode,
host_name)
def detach(self): def detach(self):
"""Clear attachment metadata.""" """Clear attachment metadata."""
@@ -255,21 +258,24 @@ class VolumeManager(base.ManagerWithFind):
url = '/volumes/%s/action' % base.getid(volume) url = '/volumes/%s/action' % base.getid(volume)
return self.api.client.post(url, body=body) return self.api.client.post(url, body=body)
def attach(self, volume, instance_uuid, mountpoint, mode='rw'): def attach(self, volume, instance_uuid, mountpoint, mode='rw',
host_name=None):
""" """
Set attachment metadata. Set attachment metadata.
:param volume: The :class:`Volume` (or its ID) :param volume: The :class:`Volume` (or its ID)
you would like to attach. you would like to attach.
:param instance_uuid: uuid of the attaching instance. :param instance_uuid: uuid of the attaching instance or host.
:param mountpoint: mountpoint on the attaching instance. :param mountpoint: mountpoint on the attaching instance.
:param mode: the access mode. :param mode: the access mode.
:param host_name: name of the attaching host.
""" """
return self._action('os-attach', body = {'mountpoint': mountpoint, 'mode': mode}
volume, if instance_uuid is not None:
{'instance_uuid': instance_uuid, body.update({'instance_uuid': instance_uuid})
'mountpoint': mountpoint, if host_name is not None:
'mode': mode}) body.update({'host_name': host_name})
return self._action('os-attach', volume, body)
def detach(self, volume): def detach(self, volume):
""" """

View File

@@ -45,14 +45,16 @@ class Volume(base.Resource):
"""Update the name or description for this volume.""" """Update the name or description for this volume."""
self.manager.update(self, **kwargs) self.manager.update(self, **kwargs)
def attach(self, instance_uuid, mountpoint, mode='rw'): def attach(self, instance_uuid, mountpoint, mode='rw', host_name=None):
"""Set attachment metadata. """Set attachment metadata.
:param instance_uuid: uuid of the attaching instance. :param instance_uuid: uuid of the attaching instance.
:param mountpoint: mountpoint on the attaching instance. :param mountpoint: mountpoint on the attaching instance or host.
:param mode: the access mode. :param mode: the access mode.
:param host_name: name of the attaching host.
""" """
return self.manager.attach(self, instance_uuid, mountpoint, mode) return self.manager.attach(self, instance_uuid, mountpoint, mode,
host_name)
def detach(self): def detach(self):
"""Clear attachment metadata.""" """Clear attachment metadata."""
@@ -373,20 +375,23 @@ class VolumeManager(base.ManagerWithFind):
url = '/volumes/%s/action' % base.getid(volume) url = '/volumes/%s/action' % base.getid(volume)
return self.api.client.post(url, body=body) return self.api.client.post(url, body=body)
def attach(self, volume, instance_uuid, mountpoint, mode='rw'): def attach(self, volume, instance_uuid, mountpoint, mode='rw',
host_name=None):
"""Set attachment metadata. """Set attachment metadata.
:param volume: The :class:`Volume` (or its ID) :param volume: The :class:`Volume` (or its ID)
you would like to attach. you would like to attach.
:param instance_uuid: uuid of the attaching instance. :param instance_uuid: uuid of the attaching instance.
:param mountpoint: mountpoint on the attaching instance. :param mountpoint: mountpoint on the attaching instance or host.
:param mode: the access mode. :param mode: the access mode.
:param host_name: name of the attaching host.
""" """
return self._action('os-attach', body = {'mountpoint': mountpoint, 'mode': mode}
volume, if instance_uuid is not None:
{'instance_uuid': instance_uuid, body.update({'instance_uuid': instance_uuid})
'mountpoint': mountpoint, if host_name is not None:
'mode': mode}) body.update({'host_name': host_name})
return self._action('os-attach', volume, body)
def detach(self, volume): def detach(self, volume):
"""Clear attachment metadata. """Clear attachment metadata.