Add support for module-reapply command
To facilitate the concept of live-update, a new command 'reapply' has been added to reapply a given module to all instances that it had previously been applied to. Originally, a module designated live-update would automatically be re-applied whenever it was updated. Adding a specific command however, allows operators/users more control over how the new payload would be distributed. Old 'modules' could be left if desired, or updated with the new command. Change-Id: Ic4cc9e9085cb40f1afbec05caeb04886137027a4 Partial-Bug: #1554903 Depends-On: I4caf4a57226dd711575cde766076fa25d16792e2
This commit is contained in:
6
releasenotes/notes/add_module_reapply-7645e34256d4c.yaml
Normal file
6
releasenotes/notes/add_module_reapply-7645e34256d4c.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- Add module-reapply command to facilitate
|
||||||
|
applying a module again to all instances
|
||||||
|
where it was previously applied. Bug 1554903
|
||||||
|
|
@@ -494,6 +494,9 @@ class FakeHTTPClient(base_client.HTTPClient):
|
|||||||
return self.get_instance_counts()
|
return self.get_instance_counts()
|
||||||
return self.get_instances()
|
return self.get_instances()
|
||||||
|
|
||||||
|
def put_modules_4321_instances(self, **kw):
|
||||||
|
return (202, {}, None)
|
||||||
|
|
||||||
def get_instances_modules(self, **kw):
|
def get_instances_modules(self, **kw):
|
||||||
return (200, {}, None)
|
return (200, {}, None)
|
||||||
|
|
||||||
|
@@ -145,3 +145,13 @@ class TestModules(testtools.TestCase):
|
|||||||
def test_instances(self):
|
def test_instances(self):
|
||||||
expected_query = {'include_clustered': True}
|
expected_query = {'include_clustered': True}
|
||||||
self._test_instances(expected_query)
|
self._test_instances(expected_query)
|
||||||
|
|
||||||
|
def test_reapply(self):
|
||||||
|
resp = mock.Mock()
|
||||||
|
resp.status_code = 200
|
||||||
|
body = None
|
||||||
|
self.modules.api.client.put = mock.Mock(return_value=(resp, body))
|
||||||
|
self.modules.reapply(self.module_name)
|
||||||
|
self.modules.reapply(self.module)
|
||||||
|
resp.status_code = 500
|
||||||
|
self.assertRaises(Exception, self.modules.reapply, self.module_name)
|
||||||
|
@@ -737,6 +737,12 @@ class ShellTest(utils.TestCase):
|
|||||||
'GET', '/modules/4321/instances?count_only=True&'
|
'GET', '/modules/4321/instances?count_only=True&'
|
||||||
'include_clustered=True')
|
'include_clustered=True')
|
||||||
|
|
||||||
|
def test_module_reapply(self):
|
||||||
|
with mock.patch.object(troveclient.v1.modules.Module, '__repr__',
|
||||||
|
mock.Mock(return_value='4321')):
|
||||||
|
self.run_command('module-reapply 4321 --delay=5')
|
||||||
|
self.assert_called_anytime('PUT', '/modules/4321/instances')
|
||||||
|
|
||||||
def test_cluster_modules(self):
|
def test_cluster_modules(self):
|
||||||
self.run_command('cluster-modules cls-1234')
|
self.run_command('cluster-modules cls-1234')
|
||||||
self.assert_called_anytime('GET', '/clusters/cls-1234')
|
self.assert_called_anytime('GET', '/clusters/cls-1234')
|
||||||
|
@@ -167,3 +167,24 @@ class Modules(base.ManagerWithFind):
|
|||||||
query_strings['count_only'] = count_only
|
query_strings['count_only'] = count_only
|
||||||
return self._paginated(url, "instances", limit, marker,
|
return self._paginated(url, "instances", limit, marker,
|
||||||
query_strings=query_strings)
|
query_strings=query_strings)
|
||||||
|
|
||||||
|
def reapply(self, module, md5=None, include_clustered=None,
|
||||||
|
batch_size=None, delay=None, force=None):
|
||||||
|
"""Reapplies the specified module."""
|
||||||
|
url = "/modules/%s/instances" % base.getid(module)
|
||||||
|
body = {
|
||||||
|
"reapply": {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if md5:
|
||||||
|
body["reapply"]["md5"] = md5
|
||||||
|
if include_clustered is not None:
|
||||||
|
body["reapply"]["include_clustered"] = int(include_clustered)
|
||||||
|
if batch_size is not None:
|
||||||
|
body["reapply"]["batch_size"] = batch_size
|
||||||
|
if delay is not None:
|
||||||
|
body["reapply"]["batch_delay"] = delay
|
||||||
|
if force is not None:
|
||||||
|
body["reapply"]["force"] = int(force)
|
||||||
|
resp, body = self.api.client.put(url, body=body)
|
||||||
|
common.check_for_exceptions(resp, body, url)
|
||||||
|
@@ -1799,8 +1799,7 @@ def do_module_show(cs, args):
|
|||||||
'Admin only.'))
|
'Admin only.'))
|
||||||
@utils.arg('--live_update', action='store_true', default=False,
|
@utils.arg('--live_update', action='store_true', default=False,
|
||||||
help=_('Allow module to be updated even if it is already applied '
|
help=_('Allow module to be updated even if it is already applied '
|
||||||
'to a current instance or cluster. Automatically attempt to '
|
'to a current instance or cluster.'))
|
||||||
'reapply this module if the contents change.'))
|
|
||||||
@utils.arg('--priority_apply', action='store_true', default=False,
|
@utils.arg('--priority_apply', action='store_true', default=False,
|
||||||
help=_('Sets a priority for applying the module. All priority '
|
help=_('Sets a priority for applying the module. All priority '
|
||||||
'modules will be applied before non-priority ones. '
|
'modules will be applied before non-priority ones. '
|
||||||
@@ -1880,9 +1879,7 @@ def do_module_create(cs, args):
|
|||||||
help=_('Allow all users to see this module. Admin only.'))
|
help=_('Allow all users to see this module. Admin only.'))
|
||||||
@utils.arg('--live_update', action='store_true', default=None,
|
@utils.arg('--live_update', action='store_true', default=None,
|
||||||
help=_('Allow module to be updated or deleted even if it is '
|
help=_('Allow module to be updated or deleted even if it is '
|
||||||
'already applied to a current instance or cluster. '
|
'already applied to a current instance or cluster.'))
|
||||||
'Automatically attempt to reapply this module if the '
|
|
||||||
'contents change.'))
|
|
||||||
@utils.arg('--no_live_update', dest='live_update', action='store_false',
|
@utils.arg('--no_live_update', dest='live_update', action='store_false',
|
||||||
default=None,
|
default=None,
|
||||||
help=_('Restricts a module from being updated or deleted if it is '
|
help=_('Restricts a module from being updated or deleted if it is '
|
||||||
@@ -1925,6 +1922,33 @@ def do_module_update(cs, args):
|
|||||||
_print_object(updated_module)
|
_print_object(updated_module)
|
||||||
|
|
||||||
|
|
||||||
|
@utils.arg('module', metavar='<module>', type=str,
|
||||||
|
help=_('Name or ID of the module.'))
|
||||||
|
@utils.arg('--md5', metavar='<md5>', type=str,
|
||||||
|
default=None,
|
||||||
|
help=_('Reapply the module only to instances applied '
|
||||||
|
'with the specific md5.'))
|
||||||
|
@utils.arg('--include_clustered', action='store_true', default=False,
|
||||||
|
help=_('Include instances that are part of a cluster '
|
||||||
|
'(default %(default)s).'))
|
||||||
|
@utils.arg('--batch_size', metavar='<batch_size>', type=int,
|
||||||
|
default=None,
|
||||||
|
help=_('Number of instances to reapply the module to before '
|
||||||
|
'sleeping.'))
|
||||||
|
@utils.arg('--delay', metavar='<delay>', type=int,
|
||||||
|
default=None,
|
||||||
|
help=_('Time to sleep in seconds between applying batches.'))
|
||||||
|
@utils.arg('--force', action='store_true', default=False,
|
||||||
|
help=_('Force reapply even on modules already having the '
|
||||||
|
'current MD5'))
|
||||||
|
@utils.service_type('database')
|
||||||
|
def do_module_reapply(cs, args):
|
||||||
|
"""Reapply a module."""
|
||||||
|
module = _find_module(cs, args.module)
|
||||||
|
cs.modules.reapply(module, args.md5, args.include_clustered,
|
||||||
|
args.batch_size, args.delay, args.force)
|
||||||
|
|
||||||
|
|
||||||
@utils.arg('module', metavar='<module>',
|
@utils.arg('module', metavar='<module>',
|
||||||
help=_('ID or name of the module.'))
|
help=_('ID or name of the module.'))
|
||||||
@utils.service_type('database')
|
@utils.service_type('database')
|
||||||
|
Reference in New Issue
Block a user