support for snapshot management
Add support to manage/unmanage snapshot cinder snapshot-manage volume identifier option args is --id-type, --name, --description, --metadata. cinder snapshot-unmanage snapshot DocImpact Implements: blueprint support-for-snapshot-management Change-Id: Id4d73fa0ff0c0c05c0c69924968aa2154da64118
This commit is contained in:
@@ -346,6 +346,8 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
assert 'status' in body['os-reset_status']
|
||||
elif action == 'os-update_snapshot_status':
|
||||
assert 'status' in body['os-update_snapshot_status']
|
||||
elif action == 'os-unmanage':
|
||||
assert body[action] is None
|
||||
else:
|
||||
raise AssertionError('Unexpected action: %s' % action)
|
||||
return (resp, {}, _body)
|
||||
@@ -1074,6 +1076,11 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
volume.update(kw['body']['volume'])
|
||||
return (202, {}, {'volume': volume})
|
||||
|
||||
def post_os_snapshot_manage(self, **kw):
|
||||
snapshot = _stub_snapshot(id='1234', volume_id='volume_id1')
|
||||
snapshot.update(kw['body']['snapshot'])
|
||||
return (202, {}, {'snapshot': snapshot})
|
||||
|
||||
def post_os_promote_replica_1234(self, **kw):
|
||||
return (202, {}, {})
|
||||
|
||||
|
@@ -1151,3 +1151,21 @@ class ShellTest(utils.TestCase):
|
||||
pass
|
||||
expected = {"os-show_image_metadata": None}
|
||||
self.assert_called('POST', '/volumes/1234/action', body=expected)
|
||||
|
||||
def test_snapshot_manage(self):
|
||||
self.run_command('snapshot-manage 1234 some_fake_name '
|
||||
'--name foo --description bar '
|
||||
'--metadata k1=v1 k2=v2')
|
||||
expected = {'snapshot': {'volume_id': 1234,
|
||||
'ref': {'source-name': 'some_fake_name'},
|
||||
'name': 'foo',
|
||||
'description': 'bar',
|
||||
'metadata': {'k1': 'v1', 'k2': 'v2'}
|
||||
}}
|
||||
self.assert_called_anytime('POST', '/os-snapshot-manage',
|
||||
body=expected)
|
||||
|
||||
def test_snapshot_unmanage(self):
|
||||
self.run_command('snapshot-unmanage 1234')
|
||||
self.assert_called('POST', '/snapshots/1234/action',
|
||||
body={'os-unmanage': None})
|
||||
|
@@ -42,3 +42,9 @@ class SnapshotActionsTest(utils.FixturedTestCase):
|
||||
def test_list_snapshots_with_sort(self):
|
||||
self.cs.volume_snapshots.list(sort="id")
|
||||
self.assert_called('GET', '/snapshots/detail?sort=id')
|
||||
|
||||
def test_snapshot_unmanage(self):
|
||||
s = self.cs.volume_snapshots.get('1234')
|
||||
self.cs.volume_snapshots.unmanage(s)
|
||||
self.assert_called('POST', '/snapshots/1234/action',
|
||||
{'os-unmanage': None})
|
||||
|
@@ -227,6 +227,12 @@ class VolumesTest(utils.TestCase):
|
||||
cs.volumes.unmanage(v)
|
||||
cs.assert_called('POST', '/volumes/1234/action', {'os-unmanage': None})
|
||||
|
||||
def test_snapshot_manage(self):
|
||||
cs.volume_snapshots.manage('volume_id1', {'k': 'v'})
|
||||
expected = {'volume_id': 'volume_id1', 'name': None,
|
||||
'description': None, 'metadata': None, 'ref': {'k': 'v'}}
|
||||
cs.assert_called('POST', '/os-snapshot-manage', {'snapshot': expected})
|
||||
|
||||
def test_replication_promote(self):
|
||||
v = cs.volumes.get('1234')
|
||||
cs.volumes.promote(v)
|
||||
|
@@ -2535,3 +2535,63 @@ def do_get_capabilities(cs, args):
|
||||
prop = infos.pop('properties', None)
|
||||
utils.print_dict(infos, "Volume stats")
|
||||
utils.print_dict(prop, "Backend properties")
|
||||
|
||||
|
||||
@utils.arg('volume',
|
||||
metavar='<volume>',
|
||||
help='Cinder volume already exists in volume backend')
|
||||
@utils.arg('identifier',
|
||||
metavar='<identifier>',
|
||||
help='Name or other Identifier for existing snapshot')
|
||||
@utils.arg('--id-type',
|
||||
metavar='<id-type>',
|
||||
default='source-name',
|
||||
help='Type of backend device identifier provided, '
|
||||
'typically source-name or source-id (Default=source-name)')
|
||||
@utils.arg('--name',
|
||||
metavar='<name>',
|
||||
help='Snapshot name (Default=None)')
|
||||
@utils.arg('--description',
|
||||
metavar='<description>',
|
||||
help='Snapshot description (Default=None)')
|
||||
@utils.arg('--metadata',
|
||||
type=str,
|
||||
nargs='*',
|
||||
metavar='<key=value>',
|
||||
help='Metadata key=value pairs (Default=None)')
|
||||
@utils.service_type('volumev2')
|
||||
def do_snapshot_manage(cs, args):
|
||||
"""Manage an existing snapshot."""
|
||||
snapshot_metadata = None
|
||||
if args.metadata is not None:
|
||||
snapshot_metadata = _extract_metadata(args)
|
||||
|
||||
# Build a dictionary of key/value pairs to pass to the API.
|
||||
ref_dict = {args.id_type: args.identifier}
|
||||
|
||||
if hasattr(args, 'source_name') and args.source_name is not None:
|
||||
ref_dict['source-name'] = args.source_name
|
||||
if hasattr(args, 'source_id') and args.source_id is not None:
|
||||
ref_dict['source-id'] = args.source_id
|
||||
|
||||
volume = utils.find_volume(cs, args.volume)
|
||||
snapshot = cs.volume_snapshots.manage(volume_id=volume.id,
|
||||
ref=ref_dict,
|
||||
name=args.name,
|
||||
description=args.description,
|
||||
metadata=snapshot_metadata)
|
||||
|
||||
info = {}
|
||||
snapshot = cs.volume_snapshots.get(snapshot.id)
|
||||
info.update(snapshot._info)
|
||||
info.pop('links', None)
|
||||
utils.print_dict(info)
|
||||
|
||||
|
||||
@utils.arg('snapshot', metavar='<snapshot>',
|
||||
help='Name or ID of the snapshot to unmanage.')
|
||||
@utils.service_type('volumev2')
|
||||
def do_snapshot_unmanage(cs, args):
|
||||
"""Stop managing a snapshot."""
|
||||
snapshot = _find_volume_snapshot(cs, args.snapshot)
|
||||
cs.volume_snapshots.unmanage(snapshot.id)
|
||||
|
@@ -56,6 +56,16 @@ class Snapshot(base.Resource):
|
||||
"""Update_all metadata of this snapshot."""
|
||||
return self.manager.update_all_metadata(self, metadata)
|
||||
|
||||
def manage(self, volume_id, ref, name=None, description=None,
|
||||
metadata=None):
|
||||
"""Manage an existing snapshot."""
|
||||
self.manager.manage(volume_id=volume_id, ref=ref, name=name,
|
||||
description=description, metadata=metadata)
|
||||
|
||||
def unmanage(self, snapshot):
|
||||
"""Unmanage a snapshot."""
|
||||
self.manager.unmanage(snapshot)
|
||||
|
||||
|
||||
class SnapshotManager(base.ManagerWithFind):
|
||||
"""Manage :class:`Snapshot` resources."""
|
||||
@@ -170,3 +180,19 @@ class SnapshotManager(base.ManagerWithFind):
|
||||
body = {'metadata': metadata}
|
||||
return self._update("/snapshots/%s/metadata" % base.getid(snapshot),
|
||||
body)
|
||||
|
||||
def manage(self, volume_id, ref, name=None, description=None,
|
||||
metadata=None):
|
||||
"""Manage an existing snapshot."""
|
||||
body = {'snapshot': {'volume_id': volume_id,
|
||||
'ref': ref,
|
||||
'name': name,
|
||||
'description': description,
|
||||
'metadata': metadata
|
||||
}
|
||||
}
|
||||
return self._create('/os-snapshot-manage', body, 'snapshot')
|
||||
|
||||
def unmanage(self, snapshot):
|
||||
"""Unmanage a snapshot."""
|
||||
return self._action('os-unmanage', snapshot, None)
|
||||
|
Reference in New Issue
Block a user