Add 'force' param for DeploySelectedNodesWithTasks

DeploySelectedNodesWithTasks is intended to run only specified set of
tasks on specified nodes. In Fuel 9.0 LCM serializers have been
introduced, hence tasks are skipped if their condition return 'False'
(and it does, since no changes may introduced).

This introduces inconvenience for operators, who want to run particular
task on nodes and do not care if there were changes or not. That's why
this commit introduces the '?force' HTTP parameter for the mentioned
handler. If 'force' is true, the task will be executed unconditionally.

(cherry picked from commit 8bfb0255a1)

Closes-Bug: #1578974

Depends-On: Icbaa2bd72c5ff2fc128a0dab4b22d6db77dd36fb
Change-Id: Iaf005341468a4e35cd82586ba3f7b585fdf4752c
This commit is contained in:
Igor Kalnitsky
2016-05-11 19:58:23 +03:00
committed by Igor Kalnitsky
parent 5b1bda2cff
commit fa053d0768
4 changed files with 29 additions and 7 deletions

View File

@@ -254,6 +254,7 @@ class NodeAction(Action):
def execute_tasks(self, params):
"""Execute deployment tasks
fuel node --node 2 --tasks hiera netconfig
fuel node --node 2 --tasks netconfig --force
fuel node --node 2 --skip hiera netconfig
fuel node --node 2 --skip rsync --end pre_deployment_end
fuel node --node 2 --end netconfig
@@ -266,6 +267,7 @@ class NodeAction(Action):
env = Environment(env_id_to_start)
tasks = params.tasks or None
force = params.force or None
if params.skip or params.end or params.start:
tasks = env.get_tasks(
@@ -278,7 +280,8 @@ class NodeAction(Action):
self.serializer.print_to_output({}, "Nothing to run.")
return
task = env.execute_tasks(node_collection.collection, tasks=tasks)
task = env.execute_tasks(
node_collection.collection, tasks=tasks, force=force)
self.serializer.print_to_output(
task.data,

View File

@@ -456,12 +456,17 @@ class Environment(BaseObject):
)
)
def _get_method_url(self, method_type, nodes):
return "clusters/{0}/{1}/?nodes={2}".format(
def _get_method_url(self, method_type, nodes, force=False):
endpoint = "clusters/{0}/{1}/?nodes={2}".format(
self.id,
method_type,
','.join(map(lambda n: str(n.id), nodes)))
if force:
endpoint += '&force=1'
return endpoint
def install_selected_nodes(self, method_type, nodes):
return Task.init_with_data(
self.connection.put_request(
@@ -470,10 +475,10 @@ class Environment(BaseObject):
)
)
def execute_tasks(self, nodes, tasks):
def execute_tasks(self, nodes, tasks, force):
return Task.init_with_data(
self.connection.put_request(
self._get_method_url('deploy_tasks', nodes),
self._get_method_url('deploy_tasks', nodes=nodes, force=force),
tasks
)
)

View File

@@ -161,11 +161,11 @@ class NodeCollection(object):
@classmethod
def init_with_ids(cls, ids):
return cls(map(Node, ids))
return cls(list(map(Node, ids)))
@classmethod
def init_with_data(cls, data):
return cls(map(Node.init_with_data, data))
return cls(list(map(Node.init_with_data, data)))
def __str__(self):
return "nodes [{0}]".format(

View File

@@ -36,6 +36,20 @@ class TestNodeExecuteTasksAction(base.UnitTestCase):
put = self.m_request.put(rm.ANY, json={'id': 43})
self.execute(['fuel', 'node', '--node', '1,2', '--tasks'] + self.tasks)
self.assertEqual(
put.last_request.url,
'http://127.0.0.1:8000/api/v1/clusters/1/deploy_tasks/?nodes=1,2')
self.assertEqual(put.last_request.json(), self.tasks)
def test_execute_provided_list_of_tasks_w_force(self):
put = self.m_request.put(rm.ANY, json={'id': 43})
self.execute((['fuel', 'node', '--node', '1,2', '--tasks']
+ self.tasks + ['--force']))
self.assertEqual(
put.last_request.url,
'http://127.0.0.1:8000/api/v1/clusters/1/deploy_tasks/?nodes=1,2'
'&force=1')
self.assertEqual(put.last_request.json(), self.tasks)
@patch('fuelclient.objects.environment.Environment.get_deployment_tasks')