diff --git a/cinderclient/tests/unit/v1/fakes.py b/cinderclient/tests/unit/v1/fakes.py index e391dc927..35043d2c1 100644 --- a/cinderclient/tests/unit/v1/fakes.py +++ b/cinderclient/tests/unit/v1/fakes.py @@ -330,9 +330,9 @@ class FakeHTTPClient(base_client.HTTPClient): assert len(list(body)) == 1 action = list(body)[0] if action == 'os-attach': - assert sorted(list(body[action])) == ['instance_uuid', - 'mode', - 'mountpoint'] + keys = sorted(list(body[action])) + assert (keys == ['instance_uuid', 'mode', 'mountpoint'] or + keys == ['host_name', 'mode', 'mountpoint']) elif action == 'os-detach': assert body[action] is None elif action == 'os-reserve': diff --git a/cinderclient/tests/unit/v1/test_volumes.py b/cinderclient/tests/unit/v1/test_volumes.py index 75c81bd5f..8906a4eba 100644 --- a/cinderclient/tests/unit/v1/test_volumes.py +++ b/cinderclient/tests/unit/v1/test_volumes.py @@ -38,6 +38,11 @@ class VolumesTest(utils.TestCase): cs.volumes.attach(v, 1, '/dev/vdc', mode='rw') 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): v = cs.volumes.get('1234') cs.volumes.detach(v) diff --git a/cinderclient/tests/unit/v2/fakes.py b/cinderclient/tests/unit/v2/fakes.py index 82cdc9c57..a9e404143 100644 --- a/cinderclient/tests/unit/v2/fakes.py +++ b/cinderclient/tests/unit/v2/fakes.py @@ -411,9 +411,9 @@ class FakeHTTPClient(base_client.HTTPClient): assert len(list(body)) == 1 action = list(body)[0] if action == 'os-attach': - assert sorted(list(body[action])) == ['instance_uuid', - 'mode', - 'mountpoint'] + keys = sorted(list(body[action])) + assert (keys == ['instance_uuid', 'mode', 'mountpoint'] or + keys == ['host_name', 'mode', 'mountpoint']) elif action == 'os-detach': assert body[action] is None elif action == 'os-reserve': diff --git a/cinderclient/tests/unit/v2/test_volumes.py b/cinderclient/tests/unit/v2/test_volumes.py index d94b47187..8ddb59ed8 100644 --- a/cinderclient/tests/unit/v2/test_volumes.py +++ b/cinderclient/tests/unit/v2/test_volumes.py @@ -104,6 +104,11 @@ class VolumesTest(utils.TestCase): cs.volumes.attach(v, 1, '/dev/vdc', mode='ro') 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): v = cs.volumes.get('1234') cs.volumes.detach(v) diff --git a/cinderclient/v1/volumes.py b/cinderclient/v1/volumes.py index 3ef3181c2..22cf5aad2 100644 --- a/cinderclient/v1/volumes.py +++ b/cinderclient/v1/volumes.py @@ -40,14 +40,17 @@ class Volume(base.Resource): """Update the display_name or display_description for this volume.""" 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. :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 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): """Clear attachment metadata.""" @@ -255,21 +258,24 @@ class VolumeManager(base.ManagerWithFind): url = '/volumes/%s/action' % base.getid(volume) 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. :param volume: The :class:`Volume` (or its ID) 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 mode: the access mode. + :param host_name: name of the attaching host. """ - return self._action('os-attach', - volume, - {'instance_uuid': instance_uuid, - 'mountpoint': mountpoint, - 'mode': mode}) + body = {'mountpoint': mountpoint, 'mode': mode} + if instance_uuid is not None: + body.update({'instance_uuid': instance_uuid}) + if host_name is not None: + body.update({'host_name': host_name}) + return self._action('os-attach', volume, body) def detach(self, volume): """ diff --git a/cinderclient/v2/volumes.py b/cinderclient/v2/volumes.py index 28e812954..e2e5368b6 100644 --- a/cinderclient/v2/volumes.py +++ b/cinderclient/v2/volumes.py @@ -45,14 +45,16 @@ class Volume(base.Resource): """Update the name or description for this volume.""" 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. :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 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): """Clear attachment metadata.""" @@ -374,20 +376,23 @@ class VolumeManager(base.ManagerWithFind): url = '/volumes/%s/action' % base.getid(volume) 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. :param volume: The :class:`Volume` (or its ID) you would like to attach. :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 host_name: name of the attaching host. """ - return self._action('os-attach', - volume, - {'instance_uuid': instance_uuid, - 'mountpoint': mountpoint, - 'mode': mode}) + body = {'mountpoint': mountpoint, 'mode': mode} + if instance_uuid is not None: + body.update({'instance_uuid': instance_uuid}) + if host_name is not None: + body.update({'host_name': host_name}) + return self._action('os-attach', volume, body) def detach(self, volume): """Clear attachment metadata.