foreman-tasks 0.3.6 → 0.4.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.
- data/app/models/foreman_tasks/concerns/action_subject.rb +1 -116
- data/app/models/foreman_tasks/concerns/action_triggering.rb +129 -0
- data/app/models/foreman_tasks/concerns/architecture_action_subject.rb +1 -0
- data/app/views/foreman_tasks/tasks/show.html.erb +6 -1
- data/lib/foreman_tasks/version.rb +1 -1
- metadata +3 -2
@@ -1,15 +1,9 @@
|
|
1
1
|
module ForemanTasks
|
2
2
|
module Concerns
|
3
|
-
module ActionSubject
|
3
|
+
module ActionSubject
|
4
4
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
|
-
included do
|
8
|
-
after_create :plan_create_action
|
9
|
-
after_update :plan_update_action
|
10
|
-
after_destroy :plan_destroy_action
|
11
|
-
end
|
12
|
-
|
13
7
|
module ClassMethods
|
14
8
|
def available_locks
|
15
9
|
[:read, :write]
|
@@ -49,115 +43,6 @@ module ForemanTasks
|
|
49
43
|
mine + mine.reduce(Set.new) { |s, resource| s + get_all_related_resources.(resource) }
|
50
44
|
end
|
51
45
|
|
52
|
-
# to make the triggered action synchronous
|
53
|
-
def sync_action!
|
54
|
-
@dynflow_sync_action = true
|
55
|
-
end
|
56
|
-
|
57
|
-
def sync_action_flag_reset!
|
58
|
-
@dynflow_sync_action = false
|
59
|
-
end
|
60
|
-
|
61
|
-
def create_action
|
62
|
-
end
|
63
|
-
|
64
|
-
def update_action
|
65
|
-
end
|
66
|
-
|
67
|
-
def destroy_action
|
68
|
-
end
|
69
|
-
|
70
|
-
def plan_create_action
|
71
|
-
plan_action(create_action, self) if create_action
|
72
|
-
return true
|
73
|
-
end
|
74
|
-
|
75
|
-
def plan_update_action
|
76
|
-
plan_action(update_action, self) if update_action
|
77
|
-
return true
|
78
|
-
end
|
79
|
-
|
80
|
-
def plan_destroy_action
|
81
|
-
plan_action(destroy_action, self) if destroy_action
|
82
|
-
return true
|
83
|
-
end
|
84
|
-
|
85
|
-
# Perform planning phase of the action tied with the model event.
|
86
|
-
# We do it separately from the execution phase, because the transaction
|
87
|
-
# of planning phase is expected to be commited when execution occurs. Also
|
88
|
-
# we want to be able to rollback the whole db operation when planning fails.
|
89
|
-
def plan_action(action_class, *args)
|
90
|
-
@execution_plan = ::ForemanTasks.dynflow.world.plan(action_class, *args)
|
91
|
-
raise @execution_plan.errors.first if @execution_plan.error?
|
92
|
-
end
|
93
|
-
|
94
|
-
def save(*)
|
95
|
-
dynflow_task_wrap(:save) { super }
|
96
|
-
end
|
97
|
-
|
98
|
-
def save!(*)
|
99
|
-
dynflow_task_wrap(:save) { super }
|
100
|
-
end
|
101
|
-
|
102
|
-
def destroy
|
103
|
-
dynflow_task_wrap(:destroy) { super }
|
104
|
-
end
|
105
|
-
|
106
|
-
# Makes sure the execution plan is executed AFTER the transaction is commited.
|
107
|
-
# We can't user after_commit filters because they don't allow to raise
|
108
|
-
# exceptions in there, so we would not be able to report that something
|
109
|
-
# went wrong when running a sync_task.:
|
110
|
-
#
|
111
|
-
# http://guides.rubyonrails.org/v3.2.14/active_record_validations_callbacks.html#transaction-callbacks
|
112
|
-
#
|
113
|
-
# That's why we need to override save and destroy methods instead.
|
114
|
-
# Another reason why one should avoid callbacks for orchestration.
|
115
|
-
#
|
116
|
-
# Also, it makes sure the save is not run inside other transaction because
|
117
|
-
# we would start the execution phase inside this transaction which would lead
|
118
|
-
# to unexpected results.
|
119
|
-
def dynflow_task_wrap(method)
|
120
|
-
action = case method
|
121
|
-
when :save
|
122
|
-
self.new_record? ? create_action : update_action
|
123
|
-
when :destroy
|
124
|
-
destroy_action
|
125
|
-
else
|
126
|
-
raise 'unexpected method'
|
127
|
-
end
|
128
|
-
if action
|
129
|
-
ensure_not_in_transaction!
|
130
|
-
yield.tap do |result|
|
131
|
-
execute_planned_action if result
|
132
|
-
sync_action_flag_reset!
|
133
|
-
end
|
134
|
-
else
|
135
|
-
yield
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
# we don't want to start executing the task calling to external services
|
140
|
-
# when inside some other transaction. Might lead to unexpected results
|
141
|
-
def ensure_not_in_transaction!
|
142
|
-
if self.class.connection.open_transactions > 0
|
143
|
-
raise "Executing dynflow action inside a transaction is not a good idea"
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
# Execute the prepared execution plan after the db transaction was commited
|
148
|
-
def execute_planned_action
|
149
|
-
if @execution_plan
|
150
|
-
run = ::ForemanTasks.dynflow.world.execute(@execution_plan.id)
|
151
|
-
if @dynflow_sync_action
|
152
|
-
run.wait
|
153
|
-
if run.value.error?
|
154
|
-
task = ForemanTasks::Task::DynflowTask.find_by_external_id!(@execution_plan.id)
|
155
|
-
raise ForemanTasks::TaskError.new(task)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
return true
|
160
|
-
end
|
161
46
|
end
|
162
47
|
end
|
163
48
|
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module ForemanTasks
|
2
|
+
module Concerns
|
3
|
+
module ActionTriggering
|
4
|
+
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
after_create :plan_create_action
|
9
|
+
after_update :plan_update_action
|
10
|
+
after_destroy :plan_destroy_action
|
11
|
+
end
|
12
|
+
|
13
|
+
# @override
|
14
|
+
def create_action
|
15
|
+
end
|
16
|
+
|
17
|
+
# @override
|
18
|
+
def update_action
|
19
|
+
end
|
20
|
+
|
21
|
+
# @override
|
22
|
+
def destroy_action
|
23
|
+
end
|
24
|
+
|
25
|
+
def save(*)
|
26
|
+
dynflow_task_wrap(:save) { super }
|
27
|
+
end
|
28
|
+
|
29
|
+
def save!(*)
|
30
|
+
dynflow_task_wrap(:save) { super }
|
31
|
+
end
|
32
|
+
|
33
|
+
def destroy
|
34
|
+
dynflow_task_wrap(:destroy) { super }
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
def sync_action_flag_reset!
|
40
|
+
@dynflow_sync_action = false
|
41
|
+
end
|
42
|
+
|
43
|
+
# to make the triggered action synchronous
|
44
|
+
def sync_action!
|
45
|
+
@dynflow_sync_action = true
|
46
|
+
end
|
47
|
+
|
48
|
+
def plan_create_action
|
49
|
+
plan_action(create_action, self) if create_action
|
50
|
+
return true
|
51
|
+
end
|
52
|
+
|
53
|
+
def plan_update_action
|
54
|
+
plan_action(update_action, self) if update_action
|
55
|
+
return true
|
56
|
+
end
|
57
|
+
|
58
|
+
def plan_destroy_action
|
59
|
+
plan_action(destroy_action, self) if destroy_action
|
60
|
+
return true
|
61
|
+
end
|
62
|
+
|
63
|
+
# Perform planning phase of the action tied with the model event.
|
64
|
+
# We do it separately from the execution phase, because the transaction
|
65
|
+
# of planning phase is expected to be commited when execution occurs. Also
|
66
|
+
# we want to be able to rollback the whole db operation when planning fails.
|
67
|
+
def plan_action(action_class, *args)
|
68
|
+
@execution_plan = ::ForemanTasks.dynflow.world.plan(action_class, *args)
|
69
|
+
raise @execution_plan.errors.first if @execution_plan.error?
|
70
|
+
end
|
71
|
+
|
72
|
+
# Makes sure the execution plan is executed AFTER the transaction is commited.
|
73
|
+
# We can't user after_commit filters because they don't allow to raise
|
74
|
+
# exceptions in there, so we would not be able to report that something
|
75
|
+
# went wrong when running a sync_task.:
|
76
|
+
#
|
77
|
+
# http://guides.rubyonrails.org/v3.2.14/active_record_validations_callbacks.html#transaction-callbacks
|
78
|
+
#
|
79
|
+
# That's why we need to override save and destroy methods instead.
|
80
|
+
# Another reason why one should avoid callbacks for orchestration.
|
81
|
+
#
|
82
|
+
# Also, it makes sure the save is not run inside other transaction because
|
83
|
+
# we would start the execution phase inside this transaction which would lead
|
84
|
+
# to unexpected results.
|
85
|
+
def dynflow_task_wrap(method)
|
86
|
+
action = case method
|
87
|
+
when :save
|
88
|
+
self.new_record? ? create_action : update_action
|
89
|
+
when :destroy
|
90
|
+
destroy_action
|
91
|
+
else
|
92
|
+
raise 'unexpected method'
|
93
|
+
end
|
94
|
+
if action
|
95
|
+
ensure_not_in_transaction!
|
96
|
+
yield.tap do |result|
|
97
|
+
execute_planned_action if result
|
98
|
+
sync_action_flag_reset!
|
99
|
+
end
|
100
|
+
else
|
101
|
+
yield
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# we don't want to start executing the task calling to external services
|
106
|
+
# when inside some other transaction. Might lead to unexpected results
|
107
|
+
def ensure_not_in_transaction!
|
108
|
+
if self.class.connection.open_transactions > 0
|
109
|
+
raise "Executing dynflow action inside a transaction is not a good idea"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Execute the prepared execution plan after the db transaction was commited
|
114
|
+
def execute_planned_action
|
115
|
+
if @execution_plan
|
116
|
+
run = ::ForemanTasks.dynflow.world.execute(@execution_plan.id)
|
117
|
+
if @dynflow_sync_action
|
118
|
+
run.wait
|
119
|
+
if run.value.error?
|
120
|
+
task = ForemanTasks::Task::DynflowTask.find_by_external_id!(@execution_plan.id)
|
121
|
+
raise ForemanTasks::TaskError.new(task)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
return true
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -40,8 +40,13 @@
|
|
40
40
|
<span class="param-name"><%= _("Progress") %>:</span>
|
41
41
|
<span class="param-value">
|
42
42
|
<div class="progress progress-striped">
|
43
|
-
|
43
|
+
<% progress = 100 * @task.progress %>
|
44
|
+
<div class="progress-bar" role="progressbar" aria-valuenow="<%= progress %>"
|
45
|
+
aria-valuemin="0" aria-valuemax="100" style="width: <%= progress %>%">
|
46
|
+
<span class="sr-only"><%= progress %>% Complete</span>
|
47
|
+
</div>
|
44
48
|
</div>
|
49
|
+
</span>
|
45
50
|
</div>
|
46
51
|
<% if @task.cli_example %>
|
47
52
|
<div>
|
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.
|
4
|
+
version: 0.4.0
|
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-03-
|
12
|
+
date: 2014-03-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -143,6 +143,7 @@ files:
|
|
143
143
|
- app/controllers/foreman_tasks/tasks_controller.rb
|
144
144
|
- app/controllers/foreman_tasks/concerns/hosts_controller_extension.rb
|
145
145
|
- app/models/foreman_tasks/concerns/architecture_action_subject.rb
|
146
|
+
- app/models/foreman_tasks/concerns/action_triggering.rb
|
146
147
|
- app/models/foreman_tasks/concerns/host_action_subject.rb
|
147
148
|
- app/models/foreman_tasks/concerns/action_subject.rb
|
148
149
|
- app/models/foreman_tasks/task/dynflow_task.rb
|