[OSC] Implement Share Migration Start Command

This commit adds 'openstack share migration start'
command, that implement the same functionality as 'manila migration-start'
command.

Partially-implements: bp openstack-client-support
Change-Id: I3e8a04904ba387161841a677442b00b4a5456c4d
This commit is contained in:
Namrata Sitlani 2022-04-03 08:32:11 +00:00 committed by Maari Tamm
parent 8f60f6928f
commit fa84d6118c
4 changed files with 215 additions and 5 deletions

View File

@ -61,6 +61,13 @@ share access rules
.. autoprogram-cliff:: openstack.share.v2
:command: share access *
===============
share migration
===============
.. autoprogram-cliff:: openstack.share.v2
:command: share migration start
==============
share networks
==============
@ -170,4 +177,4 @@ share group types
=================
.. autoprogram-cliff:: openstack.share.v2
:command: share group type *
:command: share group type *

View File

@ -1194,3 +1194,105 @@ class RevertShare(command.Command):
except Exception as e:
raise exceptions.CommandError(_(
"Failed to revert share to snapshot: %s" % (e)))
class ShareMigrationStart(command.Command):
"""Migrates share to a new host (Admin only, Experimental)."""
_description = _("Migrates share to a new host.")
def get_parser(self, prog_name):
parser = super(ShareMigrationStart, self).get_parser(prog_name)
parser.add_argument(
'share',
metavar="<share>",
help=_('Name or ID of share to migrate.')
)
parser.add_argument(
'host',
metavar="<host>",
help=_("Destination host where share will be migrated to. Use the "
"format 'host@backend#pool'.")
)
parser.add_argument(
'--force-host-assisted-migration',
metavar="<force-host-assisted-migration>",
choices=['True', 'False'],
default=False,
help=_("Enforces the use of the host-assisted migration approach, "
"which bypasses driver optimizations. Default=False.")
)
parser.add_argument(
'--preserve-metadata',
metavar="<preserve-metadata>",
required=True,
choices=['True', 'False'],
help=_("Enforces migration to preserve all file metadata when "
"moving its contents. If set to True, host-assisted"
"migration will not be attempted.")
)
parser.add_argument(
'--preserve-snapshots',
metavar="<preserve-snapshots>",
required=True,
choices=['True', 'False'],
help=_("Enforces migration of the share snapshots to the "
"destination. If set to True, host-assisted migration"
"will not be attempted.")
)
parser.add_argument(
'--writable',
metavar="<writable>",
required=True,
choices=['True', 'False'],
help=_("Enforces migration to keep the share writable while "
"contents are being moved. If set to True, host-assisted"
"migration will not be attempted.")
)
parser.add_argument(
'--nondisruptive',
metavar="<nondisruptive>",
choices=['True', 'False'],
required=True,
help=_("Enforces migration to be nondisruptive. If set to True, "
"host-assisted migration will not be attempted.")
)
parser.add_argument(
'--new-share-network',
metavar="<new_share_network>",
default=None,
help=_("Specify the new share network for the share. Do not "
"specify this parameter if the migrating share has to be"
"retained within its current share network.")
)
parser.add_argument(
'--new-share-type',
metavar="<new-share-type>",
default=None,
help=_("Specify the new share type for the share. Do not specify "
"this parameter if the migrating share has to be retained "
"with its current share type.")
)
return parser
def take_action(self, parsed_args):
share_client = self.app.client_manager.share
new_share_net_id = None
if parsed_args.new_share_network:
new_share_net_id = apiutils.find_resource(
share_client.share_networks,
parsed_args.new_share_network).id
new_share_type_id = None
if parsed_args.new_share_type:
new_share_type_id = apiutils.find_resource(
share_client.share_types,
parsed_args.new_share_type).id
share = apiutils.find_resource(share_client.shares,
parsed_args.share)
share.migration_start(parsed_args.host,
parsed_args.force_host_assisted_migration,
parsed_args.preserve_metadata,
parsed_args.writable,
parsed_args.nondisruptive,
parsed_args.preserve_snapshots,
new_share_net_id, new_share_type_id)

View File

@ -35,7 +35,6 @@ class TestShare(manila_fakes.TestShare):
def setUp(self):
super(TestShare, self).setUp()
self.shares_mock = self.app.client_manager.share.shares
self.shares_mock.reset_mock()
@ -56,6 +55,9 @@ class TestShare(manila_fakes.TestShare):
self.share_types_mock = self.app.client_manager.share.share_types
self.share_types_mock.reset_mock()
self.share_networks_mock = self.app.client_manager.share.share_networks
self.share_networks_mock.reset_mock()
self.app.client_manager.share.api_version = api_versions.APIVersion(
MAX_VERSION)
@ -106,7 +108,6 @@ class TestShareCreate(TestShare):
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.shares_mock.create.assert_called_with(
@ -1469,7 +1470,6 @@ class TestAdoptShare(TestShare):
('protocol', 'NFS'),
('export_path', '10.0.0.1:/example_path')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.shares_mock.manage.assert_called_with(
@ -1815,7 +1815,6 @@ class TestShareRevert(TestShare):
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.shares_mock.get.assert_called_with(self.share_snapshot.share_id)
self.share.revert_to_snapshot.assert_called_with(self.share_snapshot)
self.assertIsNone(result)
@ -1832,3 +1831,104 @@ class TestShareRevert(TestShare):
self.share.revert_to_snapshot.side_effect = Exception()
self.assertRaises(
osc_exceptions.CommandError, self.cmd.take_action, parsed_args)
class TestShareMigrationStart(TestShare):
def setUp(self):
super(TestShareMigrationStart, self).setUp()
self.new_share_type = manila_fakes.FakeShareType.create_one_sharetype()
self.share_types_mock.get.return_value = self.new_share_type
self.new_share_network = manila_fakes.FakeShareNetwork \
.create_one_share_network()
self.share_networks_mock.get.return_value = self.new_share_network
self._share = manila_fakes.FakeShare.create_one_share(
attrs={
'status': 'available'},
methods={'migration_start': None})
self.shares_mock.get.return_value = self._share
self.shares_mock.manage.return_value = self._share
# Get the command objects to test
self.cmd = osc_shares.ShareMigrationStart(self.app, None)
def test_migration_start_with_new_share_type(self):
"""Test with new_share_type"""
arglist = [
self._share.id,
'host@driver#pool',
'--preserve-metadata', 'False',
'--preserve-snapshots', 'False',
'--writable', 'False',
'--nondisruptive', 'False',
'--new-share-type', self.new_share_type.id,
'--force-host-assisted-migration', 'False'
]
verifylist = [
('share', self._share.id),
('host', 'host@driver#pool'),
('preserve_metadata', 'False'),
('preserve_snapshots', 'False'),
('writable', 'False'),
('nondisruptive', 'False'),
('new_share_type', self.new_share_type.id),
('force_host_assisted_migration', 'False')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self._share.migration_start.assert_called_with(
"host@driver#pool",
'False',
'False',
'False',
'False',
'False',
None,
self.new_share_type.id
)
self.assertIsNone(result)
def test_migration_start_with_new_share_network(self):
"""Test with new_share_network"""
arglist = [
self._share.id,
'host@driver#pool',
'--preserve-metadata', 'False',
'--preserve-snapshots', 'False',
'--writable', 'False',
'--nondisruptive', 'False',
'--new-share-network', self.new_share_network.id,
'--force-host-assisted-migration', 'False'
]
verifylist = [
('share', self._share.id),
('host', 'host@driver#pool'),
('preserve_metadata', 'False'),
('preserve_snapshots', 'False'),
('writable', 'False'),
('nondisruptive', 'False'),
('new_share_network', self.new_share_network.id),
('force_host_assisted_migration', 'False')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self._share.migration_start.assert_called_with(
"host@driver#pool",
'False',
'False',
'False',
'False',
'False',
self.new_share_network.id,
None
)
self.assertIsNone(result)

View File

@ -44,6 +44,7 @@ openstack.share.v2 =
share_resize = manilaclient.osc.v2.share:ResizeShare
share_adopt = manilaclient.osc.v2.share:AdoptShare
share_abandon = manilaclient.osc.v2.share:AbandonShare
share_migration_start = manilaclient.osc.v2.share:ShareMigrationStart
share_export_location_show = manilaclient.osc.v2.share:ShareExportLocationShow
share_export_location_list = manilaclient.osc.v2.share:ShareExportLocationList
share_properties_show = manilaclient.osc.v2.share:ShowShareProperties