foreman-tasks 0.8.6 → 0.9.0
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +35 -0
- data/.rubocop_todo.yml +138 -0
- data/app/controllers/foreman_tasks/api/recurring_logics_controller.rb +3 -4
- data/app/controllers/foreman_tasks/api/tasks_controller.rb +56 -72
- data/app/controllers/foreman_tasks/concerns/hosts_controller_extension.rb +2 -4
- data/app/controllers/foreman_tasks/recurring_logics_controller.rb +2 -5
- data/app/controllers/foreman_tasks/tasks_controller.rb +7 -8
- data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +44 -46
- data/app/helpers/foreman_tasks/tasks_helper.rb +1 -1
- data/app/lib/actions/action_with_sub_plans.rb +6 -8
- data/app/lib/actions/base.rb +6 -7
- data/app/lib/actions/bulk_action.rb +13 -9
- data/app/lib/actions/entry_action.rb +1 -3
- data/app/lib/actions/foreman/host/import_facts.rb +2 -5
- data/app/lib/actions/foreman/puppetclass/import.rb +1 -1
- data/app/lib/actions/helpers/args_serialization.rb +0 -1
- data/app/lib/actions/helpers/humanizer.rb +16 -21
- data/app/lib/actions/helpers/with_continuous_output.rb +0 -1
- data/app/lib/actions/helpers/with_delegated_action.rb +2 -2
- data/app/lib/actions/middleware/inherit_task_groups.rb +3 -5
- data/app/lib/actions/middleware/keep_current_user.rb +0 -3
- data/app/lib/actions/middleware/recurring_logic.rb +0 -1
- data/app/lib/actions/proxy_action.rb +8 -8
- data/app/lib/actions/serializers/active_record_serializer.rb +0 -3
- data/app/lib/proxy_api/foreman_dynflow/dynflow_proxy.rb +3 -3
- data/app/models/foreman_tasks/concerns/action_subject.rb +4 -6
- data/app/models/foreman_tasks/concerns/action_triggering.rb +20 -33
- data/app/models/foreman_tasks/concerns/host_action_subject.rb +5 -5
- data/app/models/foreman_tasks/lock.rb +29 -37
- data/app/models/foreman_tasks/recurring_logic.rb +23 -24
- data/app/models/foreman_tasks/task.rb +65 -39
- data/app/models/foreman_tasks/task/dynflow_task.rb +23 -24
- data/app/models/foreman_tasks/task/status_explicator.rb +3 -3
- data/app/models/foreman_tasks/task/summarizer.rb +3 -3
- data/app/models/foreman_tasks/task_group.rb +0 -2
- data/app/models/foreman_tasks/task_group_member.rb +0 -2
- data/app/models/foreman_tasks/task_groups/recurring_logic_task_group.rb +1 -4
- data/app/models/foreman_tasks/triggering.rb +19 -19
- data/app/models/setting/foreman_tasks.rb +8 -11
- data/app/services/foreman_tasks/proxy_selector.rb +4 -5
- data/app/views/foreman_tasks/tasks/_details.html.erb +1 -1
- data/bin/dynflow-executor +1 -1
- data/bin/foreman-tasks +1 -1
- data/config/routes.rb +1 -1
- data/db/migrate/20150814204140_add_task_type_value_index.rb +1 -1
- data/db/migrate/20160924213030_change_tasks_widget_names.rb +8 -8
- data/db/seeds.d/61-foreman_tasks_bookmarks.rb +3 -3
- data/deploy/foreman-tasks.sysconfig +6 -0
- data/extra/dynflow-debug.sh +12 -0
- data/foreman-tasks.gemspec +1 -1
- data/lib/foreman_tasks.rb +3 -3
- data/lib/foreman_tasks/authorizer_ext.rb +1 -1
- data/lib/foreman_tasks/cleaner.rb +14 -16
- data/lib/foreman_tasks/dynflow.rb +11 -9
- data/lib/foreman_tasks/dynflow/configuration.rb +8 -10
- data/lib/foreman_tasks/dynflow/console_authorizer.rb +4 -5
- data/lib/foreman_tasks/dynflow/daemon.rb +17 -19
- data/lib/foreman_tasks/dynflow/persistence.rb +5 -8
- data/lib/foreman_tasks/engine.rb +30 -31
- data/lib/foreman_tasks/task_error.rb +1 -3
- data/lib/foreman_tasks/tasks/cleanup.rake +7 -19
- data/lib/foreman_tasks/tasks/dynflow.rake +1 -1
- data/lib/foreman_tasks/tasks/export_tasks.rake +51 -59
- data/lib/foreman_tasks/test_extensions.rb +1 -1
- data/lib/foreman_tasks/version.rb +1 -1
- data/lib/tasks/gettext.rake +10 -7
- data/locale/action_names.rb +3 -6
- data/locale/en/foreman_tasks.po +189 -177
- data/locale/foreman_tasks.pot +177 -137
- data/test/controllers/api/recurring_logics_controller_test.rb +3 -5
- data/test/controllers/api/tasks_controller_test.rb +5 -7
- data/test/factories/task_factory.rb +8 -8
- data/test/factories/triggering_factory.rb +2 -3
- data/test/helpers/foreman_tasks/tasks_helper_test.rb +11 -11
- data/test/support/dummy_proxy_action.rb +3 -4
- data/test/unit/actions/action_with_sub_plans_test.rb +5 -6
- data/test/unit/actions/proxy_action_test.rb +5 -8
- data/test/unit/cleaner_test.rb +11 -12
- data/test/unit/dynflow_console_authorizer_test.rb +4 -4
- data/test/unit/proxy_selector_test.rb +3 -3
- data/test/unit/recurring_logic_test.rb +19 -17
- data/test/unit/task_groups_test.rb +3 -4
- data/test/unit/task_test.rb +72 -5
- data/test/unit/triggering_test.rb +0 -1
- metadata +7 -6
- data/app/controllers/foreman_tasks/concerns/environments_extension.rb +0 -24
@@ -1,8 +1,6 @@
|
|
1
1
|
module Actions
|
2
2
|
module Helpers
|
3
|
-
|
4
3
|
class Humanizer
|
5
|
-
|
6
4
|
def initialize(action)
|
7
5
|
@action = action
|
8
6
|
@input = action.respond_to?(:task_input) ? action.task_input : action.input
|
@@ -20,7 +18,7 @@ module Actions
|
|
20
18
|
end
|
21
19
|
|
22
20
|
def self.default_parts
|
23
|
-
|
21
|
+
resource_classes_order.map { |klass| klass.new.name }
|
24
22
|
end
|
25
23
|
|
26
24
|
# Registers the resource class to the humanizer. Usually, this
|
@@ -29,25 +27,23 @@ module Actions
|
|
29
27
|
# The `register_resource` can be run more times for the same class,
|
30
28
|
# effectively moving the resource to the end of the humanized form.
|
31
29
|
def self.register_resource(resource_class)
|
32
|
-
|
33
|
-
|
30
|
+
resource_classes_order.delete_if { |klass| klass.name == resource_class.name }
|
31
|
+
resource_classes_order << resource_class
|
34
32
|
end
|
35
33
|
|
36
34
|
def input(*parts)
|
37
|
-
if parts.empty?
|
38
|
-
parts = self.class.default_parts
|
39
|
-
end
|
35
|
+
parts = self.class.default_parts if parts.empty?
|
40
36
|
included_parts(parts, @input).map do |part|
|
41
37
|
[part, humanize_resource(part, @input)]
|
42
38
|
end
|
43
39
|
end
|
44
40
|
|
45
41
|
def included_parts(parts, data)
|
46
|
-
parts.select { |part| data.
|
42
|
+
parts.select { |part| data.key?(part) }
|
47
43
|
end
|
48
44
|
|
49
45
|
def humanize_resource(name, data)
|
50
|
-
if resource = self.class.resource(name)
|
46
|
+
if (resource = self.class.resource(name))
|
51
47
|
{ text: "#{resource.humanized_name} '#{resource.humanized_value(data)}'",
|
52
48
|
link: resource.link(data) }
|
53
49
|
end
|
@@ -62,13 +58,12 @@ module Actions
|
|
62
58
|
name
|
63
59
|
end
|
64
60
|
|
65
|
-
def link(data)
|
66
|
-
end
|
61
|
+
def link(data); end
|
67
62
|
|
68
63
|
def humanized_value(data)
|
69
64
|
fetch_data(data, name, :name) ||
|
70
|
-
|
71
|
-
|
65
|
+
fetch_data(data, name, :label) ||
|
66
|
+
fetch_data(data, name, :id)
|
72
67
|
end
|
73
68
|
|
74
69
|
def self.inherited(klass)
|
@@ -79,10 +74,10 @@ module Actions
|
|
79
74
|
|
80
75
|
def fetch_data(data, *subkeys)
|
81
76
|
if subkeys.empty?
|
82
|
-
|
77
|
+
data
|
83
78
|
else
|
84
79
|
head, *tail = subkeys
|
85
|
-
if data.is_a?(Hash) && data.
|
80
|
+
if data.is_a?(Hash) && data.key?(head)
|
86
81
|
return fetch_data(data[head], *tail)
|
87
82
|
else
|
88
83
|
return nil
|
@@ -101,7 +96,7 @@ module Actions
|
|
101
96
|
end
|
102
97
|
|
103
98
|
def link(data)
|
104
|
-
if ackey_id = fetch_data(data, :activation_key, :id)
|
99
|
+
if (ackey_id = fetch_data(data, :activation_key, :id))
|
105
100
|
"/activation_keys/#{ackey_id}/info"
|
106
101
|
end
|
107
102
|
end
|
@@ -156,7 +151,7 @@ module Actions
|
|
156
151
|
end
|
157
152
|
|
158
153
|
def link(data)
|
159
|
-
if content_view_id = fetch_data(data, :content_view, :id)
|
154
|
+
if (content_view_id = fetch_data(data, :content_view, :id))
|
160
155
|
"#/content_views/#{content_view_id}/versions"
|
161
156
|
end
|
162
157
|
end
|
@@ -172,7 +167,7 @@ module Actions
|
|
172
167
|
end
|
173
168
|
|
174
169
|
def link(data)
|
175
|
-
if product_id = fetch_data(data, :product, :id)
|
170
|
+
if (product_id = fetch_data(data, :product, :id))
|
176
171
|
"#/products/#{product_id}/info"
|
177
172
|
end
|
178
173
|
end
|
@@ -188,7 +183,7 @@ module Actions
|
|
188
183
|
end
|
189
184
|
|
190
185
|
def link(data)
|
191
|
-
if system_uuid = fetch_data(data, :system, :uuid)
|
186
|
+
if (system_uuid = fetch_data(data, :system, :uuid))
|
192
187
|
"#/systems/#{system_uuid}/info"
|
193
188
|
end
|
194
189
|
end
|
@@ -204,7 +199,7 @@ module Actions
|
|
204
199
|
end
|
205
200
|
|
206
201
|
def link(data)
|
207
|
-
if org_id = fetch_data(data, :organization, :id)
|
202
|
+
if (org_id = fetch_data(data, :organization, :id))
|
208
203
|
"/organizations/#{org_id}/edit"
|
209
204
|
end
|
210
205
|
end
|
@@ -7,12 +7,12 @@ module Actions
|
|
7
7
|
case proxy
|
8
8
|
when :not_defined
|
9
9
|
if klass.is_a?(String)
|
10
|
-
raise
|
10
|
+
raise Foreman::Exception, _('No proxy defined for execution')
|
11
11
|
else
|
12
12
|
delegated_action = plan_action(klass, options)
|
13
13
|
end
|
14
14
|
when :not_available
|
15
|
-
raise
|
15
|
+
raise Foreman::Exception, _('All proxies with the required feature are unavailable at the moment')
|
16
16
|
when ::SmartProxy
|
17
17
|
delegated_action = plan_action(::Actions::ProxyAction, proxy, klass, options)
|
18
18
|
end
|
@@ -1,18 +1,17 @@
|
|
1
1
|
module Actions
|
2
2
|
module Middleware
|
3
3
|
class InheritTaskGroups < Dynflow::Middleware
|
4
|
-
|
5
4
|
def delay(*args)
|
6
|
-
pass
|
5
|
+
pass(*args)
|
7
6
|
end
|
8
7
|
|
9
8
|
def plan(*args)
|
10
9
|
inherit_task_groups
|
11
|
-
pass
|
10
|
+
pass(*args)
|
12
11
|
end
|
13
12
|
|
14
13
|
def run(*args)
|
15
|
-
pass
|
14
|
+
pass(*args)
|
16
15
|
collect_children_task_groups
|
17
16
|
end
|
18
17
|
|
@@ -36,4 +35,3 @@ module Actions
|
|
36
35
|
end
|
37
36
|
end
|
38
37
|
end
|
39
|
-
|
@@ -13,9 +13,7 @@
|
|
13
13
|
|
14
14
|
module Actions
|
15
15
|
module Middleware
|
16
|
-
|
17
16
|
class KeepCurrentUser < Dynflow::Middleware
|
18
|
-
|
19
17
|
def delay(*args)
|
20
18
|
pass(*args).tap { store_current_user }
|
21
19
|
end
|
@@ -54,7 +52,6 @@ module Actions
|
|
54
52
|
ensure
|
55
53
|
User.current = nil
|
56
54
|
end
|
57
|
-
|
58
55
|
end
|
59
56
|
end
|
60
57
|
end
|
@@ -47,7 +47,7 @@ module Actions
|
|
47
47
|
response = proxy.trigger_task(proxy_action_name,
|
48
48
|
input.merge(:callback => { :task_id => task.id,
|
49
49
|
:step_id => run_step_id }))
|
50
|
-
output[:proxy_task_id] = response[
|
50
|
+
output[:proxy_task_id] = response['task_id']
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
@@ -56,7 +56,7 @@ module Actions
|
|
56
56
|
response = proxy.status_of_task(output[:proxy_task_id])
|
57
57
|
if %w(stopped paused).include? response['state']
|
58
58
|
if response['result'] == 'error'
|
59
|
-
raise ::Foreman::Exception, _(
|
59
|
+
raise ::Foreman::Exception, _('The smart proxy task %s failed.') % output[:proxy_task_id]
|
60
60
|
else
|
61
61
|
on_data(response['actions'].find { |block_action| block_action['class'] == proxy_action_name }['output'])
|
62
62
|
end
|
@@ -70,7 +70,7 @@ module Actions
|
|
70
70
|
|
71
71
|
def cancel_proxy_task
|
72
72
|
if output[:cancel_sent]
|
73
|
-
error! ForemanTasks::Task::TaskCancelledException.new(_(
|
73
|
+
error! ForemanTasks::Task::TaskCancelledException.new(_('Cancel enforced: the task might be still running on the proxy'))
|
74
74
|
else
|
75
75
|
proxy.cancel_task(output[:proxy_task_id])
|
76
76
|
output[:cancel_sent] = true
|
@@ -112,7 +112,7 @@ module Actions
|
|
112
112
|
def fill_continuous_output(continuous_output)
|
113
113
|
failed_proxy_tasks.each do |failure_data|
|
114
114
|
message = _('Initialization error: %s') %
|
115
|
-
|
115
|
+
"#{failure_data[:exception_class]} - #{failure_data[:exception_message]}"
|
116
116
|
continuous_output.add_output(message, 'debug', failure_data[:timestamp])
|
117
117
|
end
|
118
118
|
end
|
@@ -136,7 +136,7 @@ module Actions
|
|
136
136
|
end
|
137
137
|
|
138
138
|
def set_timeout!
|
139
|
-
time = Time.now + input[:connection_options][:timeout]
|
139
|
+
time = Time.zone.now + input[:connection_options][:timeout]
|
140
140
|
schedule_timeout(time)
|
141
141
|
metadata[:timeout] = time.to_s
|
142
142
|
end
|
@@ -145,8 +145,8 @@ module Actions
|
|
145
145
|
# Fails if the plan is not finished within 60 seconds from the first task trigger attempt on the smart proxy
|
146
146
|
# If the triggering fails, it retries 3 more times with 15 second delays
|
147
147
|
{ :retry_interval => Setting['foreman_tasks_proxy_action_retry_interval'] || 15,
|
148
|
-
:retry_count => Setting['foreman_tasks_proxy_action_retry_count'
|
149
|
-
:timeout => Setting['foreman_tasks_proxy_action_start_timeout']
|
148
|
+
:retry_count => Setting['foreman_tasks_proxy_action_retry_count'] || 4,
|
149
|
+
:timeout => Setting['foreman_tasks_proxy_action_start_timeout'] || 60 }
|
150
150
|
end
|
151
151
|
|
152
152
|
private
|
@@ -179,7 +179,7 @@ module Actions
|
|
179
179
|
if failed_proxy_tasks.count < options[:retry_count]
|
180
180
|
suspend do |suspended_action|
|
181
181
|
@world.clock.ping suspended_action,
|
182
|
-
Time.now + options[:retry_interval],
|
182
|
+
Time.zone.now + options[:retry_interval],
|
183
183
|
event
|
184
184
|
end
|
185
185
|
else
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module ProxyAPI
|
2
2
|
module ForemanDynflow
|
3
3
|
class DynflowProxy
|
4
|
-
PREFIX = 'dynflow'
|
4
|
+
PREFIX = 'dynflow'.freeze
|
5
5
|
|
6
6
|
class Task < ProxyAPI::Resource
|
7
7
|
def initialize(args)
|
@@ -24,11 +24,11 @@ module ProxyAPI
|
|
24
24
|
|
25
25
|
# Cancel the command
|
26
26
|
def cancel_task(proxy_task_id)
|
27
|
-
MultiJson.load(Task.new(@args).send(:post,
|
27
|
+
MultiJson.load(Task.new(@args).send(:post, '', "#{proxy_task_id}/cancel"))
|
28
28
|
end
|
29
29
|
|
30
30
|
def status_of_task(proxy_task_id)
|
31
|
-
MultiJson.load(Task.new(@args).send(:get, "#{
|
31
|
+
MultiJson.load(Task.new(@args).send(:get, "#{proxy_task_id}/status"))
|
32
32
|
end
|
33
33
|
|
34
34
|
def tasks_count(state)
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module ForemanTasks
|
2
2
|
module Concerns
|
3
3
|
module ActionSubject
|
4
|
-
|
5
4
|
extend ActiveSupport::Concern
|
6
5
|
|
7
6
|
module ClassMethods
|
@@ -15,10 +14,10 @@ module ForemanTasks
|
|
15
14
|
end
|
16
15
|
|
17
16
|
def to_action_input
|
18
|
-
raise 'The resource needs to be saved first' if
|
17
|
+
raise 'The resource needs to be saved first' if new_record?
|
19
18
|
|
20
19
|
{ id: id, name: name }.tap do |hash|
|
21
|
-
hash.update(label: label) if
|
20
|
+
hash.update(label: label) if respond_to? :label
|
22
21
|
end
|
23
22
|
end
|
24
23
|
|
@@ -36,13 +35,12 @@ module ForemanTasks
|
|
36
35
|
def all_related_resources
|
37
36
|
mine = Set.new Array(related_resources)
|
38
37
|
|
39
|
-
get_all_related_resources =
|
38
|
+
get_all_related_resources = lambda do |resource|
|
40
39
|
resource.is_a?(ActionSubject) ? resource.all_related_resources : []
|
41
40
|
end
|
42
41
|
|
43
|
-
mine + mine.reduce(Set.new) { |s, resource| s + get_all_related_resources.(resource) }
|
42
|
+
mine + mine.reduce(Set.new) { |s, resource| s + get_all_related_resources.call(resource) }
|
44
43
|
end
|
45
|
-
|
46
44
|
end
|
47
45
|
end
|
48
46
|
end
|
@@ -1,29 +1,25 @@
|
|
1
1
|
module ForemanTasks
|
2
2
|
module Concerns
|
3
3
|
module ActionTriggering
|
4
|
-
|
5
4
|
extend ActiveSupport::Concern
|
6
5
|
|
7
6
|
included do
|
8
|
-
after_create :
|
9
|
-
after_update :
|
10
|
-
after_destroy :
|
7
|
+
after_create :plan_hook_action
|
8
|
+
after_update :plan_hook_action
|
9
|
+
after_destroy :plan_hook_action
|
11
10
|
|
12
11
|
alias_method_chain :save, :dynflow_task_wrap
|
13
12
|
end
|
14
13
|
|
14
|
+
# These three *_action methods are called before the save/destroy actually occurs
|
15
15
|
# @override
|
16
|
-
def create_action
|
17
|
-
end
|
16
|
+
def create_action; end
|
18
17
|
|
19
18
|
# @override
|
20
|
-
def update_action
|
21
|
-
end
|
19
|
+
def update_action; end
|
22
20
|
|
23
21
|
# @override
|
24
|
-
def destroy_action
|
25
|
-
end
|
26
|
-
|
22
|
+
def destroy_action; end
|
27
23
|
|
28
24
|
def save_with_dynflow_task_wrap(*args)
|
29
25
|
dynflow_task_wrap(:save) { save_without_dynflow_task_wrap(*args) }
|
@@ -48,12 +44,12 @@ module ForemanTasks
|
|
48
44
|
# this can be used when HostActionSubject is used for orchestration but you want to avoid
|
49
45
|
# triggering more tasks by ActiveRecord callbacks within run/finalize phase of your task
|
50
46
|
# e.g. host.disable_dynflow_hooks { |h| h.save }
|
51
|
-
def disable_dynflow_hooks
|
47
|
+
def disable_dynflow_hooks
|
52
48
|
@_disable_dynflow_hooks = true
|
53
49
|
|
54
50
|
if block_given?
|
55
51
|
begin
|
56
|
-
|
52
|
+
yield(self)
|
57
53
|
ensure
|
58
54
|
@_disable_dynflow_hooks = false
|
59
55
|
end
|
@@ -75,19 +71,9 @@ module ForemanTasks
|
|
75
71
|
@dynflow_sync_action = true
|
76
72
|
end
|
77
73
|
|
78
|
-
def
|
79
|
-
plan_action(
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
def plan_update_action
|
84
|
-
plan_action(update_action, self) if update_action
|
85
|
-
return true
|
86
|
-
end
|
87
|
-
|
88
|
-
def plan_destroy_action
|
89
|
-
plan_action(destroy_action, self) if destroy_action
|
90
|
-
return true
|
74
|
+
def plan_hook_action
|
75
|
+
plan_action(@_dynflow_hook_action, self) if @_dynflow_hook_action
|
76
|
+
true
|
91
77
|
end
|
92
78
|
|
93
79
|
# Perform planning phase of the action tied with the model event.
|
@@ -115,26 +101,27 @@ module ForemanTasks
|
|
115
101
|
# to unexpected results.
|
116
102
|
def dynflow_task_wrap(method)
|
117
103
|
if ForemanTasks.dynflow.config.disable_active_record_actions ||
|
118
|
-
|
119
|
-
|
104
|
+
@_disable_dynflow_hooks ||
|
105
|
+
@_dynflow_task_wrapped
|
120
106
|
return yield
|
121
107
|
end
|
122
108
|
@_dynflow_task_wrapped = true
|
123
109
|
|
124
|
-
|
110
|
+
@_dynflow_hook_action = case method
|
125
111
|
when :save
|
126
|
-
|
112
|
+
new_record? ? create_action : update_action
|
127
113
|
when :destroy
|
128
114
|
destroy_action
|
129
115
|
else
|
130
116
|
raise 'unexpected method'
|
131
117
|
end
|
132
|
-
ensure_not_in_transaction! if
|
118
|
+
ensure_not_in_transaction! if @_dynflow_hook_action
|
133
119
|
yield.tap do |result|
|
134
120
|
execute_planned_action if result
|
135
121
|
sync_action_flag_reset!
|
136
122
|
end
|
137
123
|
ensure
|
124
|
+
@_dynflow_hook_action = nil
|
138
125
|
@_dynflow_task_wrapped = false
|
139
126
|
end
|
140
127
|
|
@@ -143,7 +130,7 @@ module ForemanTasks
|
|
143
130
|
def ensure_not_in_transaction!
|
144
131
|
# we don't care about transactions when using InThreadWorld
|
145
132
|
if defined?(::Dynflow::Testing::InThreadWorld) &&
|
146
|
-
|
133
|
+
ForemanTasks.dynflow.world.is_a?(::Dynflow::Testing::InThreadWorld)
|
147
134
|
return
|
148
135
|
end
|
149
136
|
if self.class.connection.open_transactions > 0
|
@@ -159,7 +146,7 @@ module ForemanTasks
|
|
159
146
|
run.wait
|
160
147
|
if run.value.error?
|
161
148
|
task = ForemanTasks::Task::DynflowTask.where(:external_id => @execution_plan.id).first!
|
162
|
-
raise ForemanTasks::TaskError
|
149
|
+
raise ForemanTasks::TaskError, task
|
163
150
|
end
|
164
151
|
end
|
165
152
|
end
|