diff --git a/cinderclient/tests/v2/fakes.py b/cinderclient/tests/v2/fakes.py index 70c5840d0..086034aac 100644 --- a/cinderclient/tests/v2/fakes.py +++ b/cinderclient/tests/v2/fakes.py @@ -360,6 +360,8 @@ class FakeHTTPClient(base_client.HTTPClient): assert 'force_host_copy' in body[action] elif action == 'os-update_readonly_flag': assert list(body[action]) == ['readonly'] + elif action == 'os-retype': + assert 'new_type' in body[action] else: raise AssertionError("Unexpected action: %s" % action) return (resp, {}, _body) diff --git a/cinderclient/tests/v2/test_shell.py b/cinderclient/tests/v2/test_shell.py index d203c07f8..85a230ac9 100644 --- a/cinderclient/tests/v2/test_shell.py +++ b/cinderclient/tests/v2/test_shell.py @@ -325,7 +325,19 @@ class ShellTest(utils.TestCase): self.assert_called('PUT', '/os-services/disable', {"binary": "cinder-volume", "host": "host"}) - def test_service_disable(self): + def test_service_enable(self): self.run_command('service-enable host cinder-volume') self.assert_called('PUT', '/os-services/enable', {"binary": "cinder-volume", "host": "host"}) + + def test_retype_with_policy(self): + self.run_command('retype 1234 foo --migration-policy=on-demand') + expected = {'os-retype': {'new_type': 'foo', + 'migration_policy': 'on-demand'}} + self.assert_called('POST', '/volumes/1234/action', body=expected) + + def test_retype_default_policy(self): + self.run_command('retype 1234 foo') + expected = {'os-retype': {'new_type': 'foo', + 'migration_policy': 'never'}} + self.assert_called('POST', '/volumes/1234/action', body=expected) diff --git a/cinderclient/tests/v2/test_volumes.py b/cinderclient/tests/v2/test_volumes.py index 0ec345c0d..5e128123f 100644 --- a/cinderclient/tests/v2/test_volumes.py +++ b/cinderclient/tests/v2/test_volumes.py @@ -109,3 +109,10 @@ class VolumesTest(utils.TestCase): v = cs.volumes.get('1234') cs.volumes.update_readonly_flag(v, True) cs.assert_called('POST', '/volumes/1234/action') + + def test_retype(self): + v = cs.volumes.get('1234') + cs.volumes.retype(v, 'foo', 'on-demand') + cs.assert_called('POST', '/volumes/1234/action', + {'os-retype': {'new_type': 'foo', + 'migration_policy': 'on-demand'}}) diff --git a/cinderclient/v2/shell.py b/cinderclient/v2/shell.py index 55ceb5b56..5c1e86f92 100644 --- a/cinderclient/v2/shell.py +++ b/cinderclient/v2/shell.py @@ -899,6 +899,19 @@ def do_migrate(cs, args): volume.migrate_volume(args.host, args.force_host_copy) +@utils.arg('volume', metavar='', + help='Name or ID of the volume to retype') +@utils.arg('new_type', metavar='', help='New volume type') +@utils.arg('--migration-policy', metavar='', required=False, + choices=['never', 'on-demand'], default='never', + help='Policy on migrating the volume during the retype.') +@utils.service_type('volumev2') +def do_retype(cs, args): + """Change the volume's type.""" + volume = utils.find_volume(cs, args.volume) + volume.retype(args.new_type, args.migration_policy) + + @utils.arg('volume', metavar='', help='Name or ID of the volume to backup.') @utils.arg('--container', metavar='', diff --git a/cinderclient/v2/volumes.py b/cinderclient/v2/volumes.py index 4f4a2bba9..524456d6e 100644 --- a/cinderclient/v2/volumes.py +++ b/cinderclient/v2/volumes.py @@ -117,10 +117,9 @@ class Volume(base.Resource): """Migrate the volume to a new host.""" self.manager.migrate_volume(self, host, force_host_copy) -# def migrate_volume_completion(self, old_volume, new_volume, error): -# """Complete the migration of the volume.""" -# self.manager.migrate_volume_completion(self, old_volume, -# new_volume, error) + def retype(self, volume_type, policy): + """Change a volume's type.""" + self.manager.retype(self, volume_type, policy) def update_all_metadata(self, metadata): """Update all metadata of this volume.""" @@ -408,3 +407,15 @@ class VolumeManager(base.ManagerWithFind): return self._action('os-update_readonly_flag', base.getid(volume), {'readonly': flag}) + + def retype(self, volume, volume_type, policy): + """Change a volume's type. + + :param volume: The :class:`Volume` to retype + :param volume_type: New volume type + :param policy: Policy for migration during the retype + """ + return self._action('os-retype', + volume, + {'new_type': volume_type, + 'migration_policy': policy})