foreman-tasks 0.6.9 → 0.6.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/app/controllers/foreman_tasks/tasks_controller.rb +12 -3
- data/app/lib/actions/base.rb +4 -0
- data/app/lib/actions/bulk_action.rb +166 -0
- data/app/lib/actions/helpers/lock.rb +0 -4
- data/app/lib/actions/middleware/keep_current_user.rb +41 -0
- data/app/models/foreman_tasks/task.rb +2 -0
- data/app/views/foreman_tasks/tasks/_details.html.erb +10 -0
- data/config/routes.rb +1 -0
- data/db/migrate/20140813215942_add_parent_task_id.rb +5 -0
- data/lib/foreman_tasks/version.rb +1 -1
- metadata +5 -2
@@ -8,9 +8,13 @@ module ForemanTasks
|
|
8
8
|
|
9
9
|
def index
|
10
10
|
params[:order] ||= 'started_at DESC'
|
11
|
-
@tasks = Task
|
12
|
-
|
13
|
-
|
11
|
+
@tasks = filter(Task)
|
12
|
+
end
|
13
|
+
|
14
|
+
def sub_tasks
|
15
|
+
task = Task.find(params[:id])
|
16
|
+
@tasks = filter(task.sub_tasks)
|
17
|
+
render :index
|
14
18
|
end
|
15
19
|
|
16
20
|
def cancel_step
|
@@ -62,5 +66,10 @@ module ForemanTasks
|
|
62
66
|
ForemanTasks::Task::DynflowTask.find(params[:id])
|
63
67
|
end
|
64
68
|
|
69
|
+
def filter(scope)
|
70
|
+
scope.search_for(params[:search], :order => params[:order]).
|
71
|
+
paginate(:page => params[:page])
|
72
|
+
end
|
73
|
+
|
65
74
|
end
|
66
75
|
end
|
data/app/lib/actions/base.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
module Actions
|
2
2
|
class Base < Dynflow::Action
|
3
3
|
|
4
|
+
def task
|
5
|
+
@task ||= ::ForemanTasks::Task::DynflowTask.find_by_external_id!(execution_plan_id)
|
6
|
+
end
|
7
|
+
|
4
8
|
# This method says what data form input gets into the task details in Rest API
|
5
9
|
# By default, it sends the whole input there.
|
6
10
|
def task_input
|
@@ -0,0 +1,166 @@
|
|
1
|
+
module Actions
|
2
|
+
|
3
|
+
class BulkAction < Actions::EntryAction
|
4
|
+
|
5
|
+
middleware.use Actions::Middleware::KeepCurrentUser
|
6
|
+
|
7
|
+
SubPlanFinished = Algebrick.type do
|
8
|
+
fields! :execution_plan_id => String,
|
9
|
+
:success => type { variants TrueClass, FalseClass }
|
10
|
+
end
|
11
|
+
|
12
|
+
# == Parameters:
|
13
|
+
# actions_class::
|
14
|
+
# Class of action to trigger on targets
|
15
|
+
# targets::
|
16
|
+
# Array of objects on which the action_class should be triggered
|
17
|
+
# *args::
|
18
|
+
# Arguments that all the targets share
|
19
|
+
def plan(action_class, targets, *args)
|
20
|
+
check_targets!(targets)
|
21
|
+
plan_self(:action_class => action_class.to_s,
|
22
|
+
:target_ids => targets.map(&:id),
|
23
|
+
:target_class => targets.first.class.to_s,
|
24
|
+
:args => args)
|
25
|
+
end
|
26
|
+
|
27
|
+
def humanized_name
|
28
|
+
_("Bulk action")
|
29
|
+
end
|
30
|
+
|
31
|
+
def humanized_input
|
32
|
+
a_sub_task = task.sub_tasks.first
|
33
|
+
if a_sub_task
|
34
|
+
[a_sub_task.humanized[:action].to_s.downcase] +
|
35
|
+
Array(a_sub_task.humanized[:input]) + ['...']
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def humanized_output
|
40
|
+
return unless counts_set?
|
41
|
+
_("%{total} tasks, %{success} success, %{failed} fail") %
|
42
|
+
{ total: output[:total_count],
|
43
|
+
success: output[:success_count],
|
44
|
+
failed: output[:failed_count] }
|
45
|
+
end
|
46
|
+
|
47
|
+
def run(event = nil)
|
48
|
+
case(event)
|
49
|
+
when nil
|
50
|
+
if output[:total_count]
|
51
|
+
resume
|
52
|
+
else
|
53
|
+
initiate_sub_plans
|
54
|
+
end
|
55
|
+
when SubPlanFinished
|
56
|
+
mark_as_done(event.execution_plan_id, event.success)
|
57
|
+
if done?
|
58
|
+
check_for_errors!
|
59
|
+
else
|
60
|
+
suspend
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# @api override when the logic for the initiation of the subtasks
|
66
|
+
# is different from the default one
|
67
|
+
def create_sub_plans
|
68
|
+
action_class = input[:action_class].constantize
|
69
|
+
target_class = input[:target_class].constantize
|
70
|
+
targets = target_class.where(:id => input[:target_ids])
|
71
|
+
|
72
|
+
targets.map do |target|
|
73
|
+
ForemanTasks.trigger(action_class, target, *input[:args])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def initiate_sub_plans
|
78
|
+
output.update(total_count: 0,
|
79
|
+
failed_count: 0,
|
80
|
+
success_count: 0)
|
81
|
+
|
82
|
+
planned, failed = create_sub_plans.partition(&:planned?)
|
83
|
+
|
84
|
+
sub_plan_ids = ((planned + failed).map(&:execution_plan_id))
|
85
|
+
set_parent_task_id(sub_plan_ids)
|
86
|
+
|
87
|
+
output[:total_count] = sub_plan_ids.size
|
88
|
+
output[:failed_count] = failed.size
|
89
|
+
|
90
|
+
if planned.any?
|
91
|
+
wait_for_sub_plans(planned)
|
92
|
+
else
|
93
|
+
check_for_errors!
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def resume
|
98
|
+
if task.sub_tasks.active.any?
|
99
|
+
fail _("Some sub tasks are still not finished")
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def rescue_strategy
|
104
|
+
Dynflow::Action::Rescue::Skip
|
105
|
+
end
|
106
|
+
|
107
|
+
def wait_for_sub_plans(plans)
|
108
|
+
suspend do |suspended_action|
|
109
|
+
plans.each do |plan|
|
110
|
+
plan.finished.do_then do |value|
|
111
|
+
suspended_action << SubPlanFinished[plan.execution_plan_id,
|
112
|
+
value.result == :success]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def mark_as_done(plan_id, success)
|
119
|
+
if success
|
120
|
+
output[:success_count] += 1
|
121
|
+
else
|
122
|
+
output[:failed_count] += 1
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def done?
|
127
|
+
if counts_set?
|
128
|
+
output[:total_count] - output[:success_count] - output[:failed_count] <= 0
|
129
|
+
else
|
130
|
+
false
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def run_progress
|
135
|
+
if counts_set?
|
136
|
+
(output[:success_count] + output[:failed_count]).to_f / output[:total_count]
|
137
|
+
else
|
138
|
+
0.1
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def counts_set?
|
143
|
+
output[:total_count] && output[:success_count] && output[:failed_count]
|
144
|
+
end
|
145
|
+
|
146
|
+
def set_parent_task_id(sub_plan_ids)
|
147
|
+
ForemanTasks::Task::DynflowTask.
|
148
|
+
where(external_id: sub_plan_ids).
|
149
|
+
update_all(parent_task_id: task.id)
|
150
|
+
end
|
151
|
+
|
152
|
+
def check_targets!(targets)
|
153
|
+
if targets.empty?
|
154
|
+
fail _("Empty bulk action")
|
155
|
+
end
|
156
|
+
if targets.map(&:class).uniq.length > 1
|
157
|
+
fail _("The targets are of different types")
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def check_for_errors!
|
162
|
+
fail _("A sub task failed") if output[:failed_count] > 0
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Copyright 2014 Red Hat, Inc.
|
4
|
+
#
|
5
|
+
# This software is licensed to you under the GNU General Public
|
6
|
+
# License as published by the Free Software Foundation; either version
|
7
|
+
# 2 of the License (GPLv2) or (at your option) any later version.
|
8
|
+
# There is NO WARRANTY for this software, express or implied,
|
9
|
+
# including the implied warranties of MERCHANTABILITY,
|
10
|
+
# NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should
|
11
|
+
# have received a copy of GPLv2 along with this software; if not, see
|
12
|
+
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
|
13
|
+
|
14
|
+
module Actions
|
15
|
+
module Middleware
|
16
|
+
|
17
|
+
class KeepCurrentUser < Dynflow::Middleware
|
18
|
+
def plan(*args)
|
19
|
+
pass(*args).tap { action.input[:current_user_id] = User.current.id }
|
20
|
+
end
|
21
|
+
|
22
|
+
def run(*args)
|
23
|
+
restore_curent_user { pass(*args) }
|
24
|
+
end
|
25
|
+
|
26
|
+
def finalize
|
27
|
+
restore_curent_user { pass }
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def restore_curent_user
|
33
|
+
User.current = User.find(action.input[:current_user_id])
|
34
|
+
yield
|
35
|
+
ensure
|
36
|
+
User.current = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -8,6 +8,8 @@ module ForemanTasks
|
|
8
8
|
self.primary_key = :id
|
9
9
|
before_create :generate_id
|
10
10
|
|
11
|
+
belongs_to :parent_task, :class_name => 'ForemanTasks::Task'
|
12
|
+
has_many :sub_tasks, :class_name => 'ForemanTasks::Task', :foreign_key => :parent_task_id
|
11
13
|
has_many :locks
|
12
14
|
|
13
15
|
# in fact, the task has only one owner but Rails don't let you to
|
@@ -101,6 +101,16 @@
|
|
101
101
|
<span class="param-name"><%= _("Params") %>:</span>
|
102
102
|
<span class="param-value"><%= format_task_input(@task) %></span>
|
103
103
|
</div>
|
104
|
+
<% if @task.parent_task %>
|
105
|
+
<div>
|
106
|
+
<span class="param-name"><%= link_to(_("Parent task"), foreman_tasks_task_path(@task.parent_task)) %></span>
|
107
|
+
</div>
|
108
|
+
<% end %>
|
109
|
+
<% if @task.sub_tasks.any? %>
|
110
|
+
<div>
|
111
|
+
<span class="param-name"><%= link_to(_("Sub tasks"), sub_tasks_foreman_tasks_task_path(@task)) %></span>
|
112
|
+
</div>
|
113
|
+
<% end %>
|
104
114
|
<div class="row">
|
105
115
|
<div class="col-xs-11">
|
106
116
|
<div class="progress progress-striped <%= 'active' if @task.state == 'running' %>">
|
data/config/routes.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman-tasks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.10
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-09-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -133,6 +133,8 @@ files:
|
|
133
133
|
- app/lib/actions/helpers/lock.rb
|
134
134
|
- app/lib/actions/entry_action.rb
|
135
135
|
- app/lib/actions/base.rb
|
136
|
+
- app/lib/actions/bulk_action.rb
|
137
|
+
- app/lib/actions/middleware/keep_current_user.rb
|
136
138
|
- app/lib/actions/foreman/host/import_facts.rb
|
137
139
|
- app/lib/actions/foreman/architecture/create.rb
|
138
140
|
- app/lib/actions/foreman/architecture/update.rb
|
@@ -162,6 +164,7 @@ files:
|
|
162
164
|
- db/migrate/20131209122644_create_foreman_tasks_locks.rb
|
163
165
|
- db/migrate/20131205204140_create_foreman_tasks.rb
|
164
166
|
- db/migrate/20140324104010_remove_foreman_tasks_progress.rb
|
167
|
+
- db/migrate/20140813215942_add_parent_task_id.rb
|
165
168
|
- deploy/foreman-tasks.init
|
166
169
|
- deploy/foreman-tasks.service
|
167
170
|
- deploy/foreman-tasks.sysconfig
|