foreman-tasks 7.0.0 → 7.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/js_tests.yml +3 -1
- data/.github/workflows/ruby_tests.yml +1 -1
- data/app/lib/actions/foreman/host/import_facts.rb +1 -6
- data/app/lib/actions/helpers/with_delegated_action.rb +2 -2
- data/app/lib/actions/proxy_action.rb +19 -5
- data/app/lib/actions/trigger_proxy_batch.rb +4 -1
- data/app/models/foreman_tasks/remote_task.rb +3 -2
- data/app/models/foreman_tasks/task/dynflow_task.rb +10 -5
- data/app/views/foreman_tasks/recurring_logics/index.html.erb +11 -11
- data/app/views/foreman_tasks/task_groups/_common.html.erb +2 -2
- data/app/views/foreman_tasks/task_groups/recurring_logic_task_groups/_recurring_logic_task_group.html.erb +11 -11
- data/lib/foreman_tasks/cleaner.rb +1 -1
- data/lib/foreman_tasks/dynflow/configuration.rb +1 -1
- data/lib/foreman_tasks/engine.rb +4 -1
- data/lib/foreman_tasks/version.rb +1 -1
- data/lib/tasks/gettext.rake +1 -0
- data/locale/action_names.rb +2 -3
- data/locale/de/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/de/foreman_tasks.po +873 -0
- data/locale/en/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/en/foreman_tasks.po +4 -7
- data/locale/es/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/es/foreman_tasks.po +874 -0
- data/locale/foreman_tasks.pot +20 -25
- data/locale/fr/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/fr/foreman_tasks.po +71 -72
- data/locale/ja/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/ja/foreman_tasks.po +70 -74
- data/locale/ka/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/ka/foreman_tasks.po +871 -0
- data/locale/ko/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/ko/foreman_tasks.po +869 -0
- data/locale/pt_BR/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/pt_BR/foreman_tasks.po +874 -0
- data/locale/ru/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/ru/foreman_tasks.po +873 -0
- data/locale/zh_CN/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/zh_CN/foreman_tasks.po +157 -161
- data/locale/zh_TW/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/zh_TW/foreman_tasks.po +870 -0
- data/test/unit/task_test.rb +5 -8
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c5d611523d1262879b33177bf9c1f4c394142fee8433c2fda798cb4063b60f99
|
4
|
+
data.tar.gz: 1e7974c6fde725d0fe46dcffd6793c7f4b078c3c6e2e3429dce42180e61e4044
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f358b767cf2c8f2f6d31a43aa6c1fca27a6db053311d4540cea15d11c7c76758db192d5b39ecef17fcfc9d89e9e99a233c6b3d14fadd41efcca709aea37704b
|
7
|
+
data.tar.gz: 9c08bf19e2f8bdc05add76a9b8e9b783407b03ba99f0c47325454468a4654e44296f8dafd87e40a5d58ed771edb58900c0ac41738202efce5043193b5580a50c
|
@@ -8,12 +8,7 @@ module Actions
|
|
8
8
|
|
9
9
|
def plan(_host_type, host_name, facts, certname, proxy_id)
|
10
10
|
facts['domain'].try(:downcase!)
|
11
|
-
host =
|
12
|
-
::Host::Managed.import_host(host_name, certname)
|
13
|
-
else
|
14
|
-
# backwards compatibility
|
15
|
-
::Host::Managed.import_host(host_name, facts['_type'], certname, proxy_id)
|
16
|
-
end
|
11
|
+
host = ::Host::Managed.import_host(host_name, certname)
|
17
12
|
host.save(:validate => false) if host.new_record?
|
18
13
|
action_subject(host, :facts => facts.to_unsafe_h, :proxy_id => proxy_id)
|
19
14
|
if host.build?
|
@@ -3,7 +3,7 @@ module Actions
|
|
3
3
|
module WithDelegatedAction
|
4
4
|
include ::Actions::Helpers::WithContinuousOutput
|
5
5
|
|
6
|
-
def plan_delegated_action(proxy, klass, options)
|
6
|
+
def plan_delegated_action(proxy, klass, options, proxy_action_class: ::Actions::ProxyAction)
|
7
7
|
case proxy
|
8
8
|
when :not_defined
|
9
9
|
if klass.is_a?(String)
|
@@ -14,7 +14,7 @@ module Actions
|
|
14
14
|
when :not_available
|
15
15
|
raise Foreman::Exception, _('All proxies with the required feature are unavailable at the moment')
|
16
16
|
when ::SmartProxy
|
17
|
-
delegated_action = plan_action(
|
17
|
+
delegated_action = plan_action(proxy_action_class, proxy, klass, options)
|
18
18
|
end
|
19
19
|
|
20
20
|
input[:delegated_action_id] = delegated_action.id
|
@@ -22,7 +22,15 @@ module Actions
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
class ProxyActionStopped
|
25
|
+
class ProxyActionStopped < RuntimeError
|
26
|
+
def backtrace
|
27
|
+
[]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
ProxyActionStoppedEvent = ::Algebrick.type do
|
32
|
+
fields! exception: type { variants NilClass, Exception }
|
33
|
+
end
|
26
34
|
|
27
35
|
def plan(proxy, klass, options)
|
28
36
|
options[:connection_options] ||= {}
|
@@ -52,8 +60,8 @@ module Actions
|
|
52
60
|
on_data(event.data, event.meta)
|
53
61
|
when ProxyActionMissing
|
54
62
|
on_proxy_action_missing
|
55
|
-
when
|
56
|
-
on_proxy_action_stopped
|
63
|
+
when ProxyActionStoppedEvent
|
64
|
+
on_proxy_action_stopped(event)
|
57
65
|
else
|
58
66
|
raise "Unexpected event #{event.inspect}"
|
59
67
|
end
|
@@ -94,6 +102,8 @@ module Actions
|
|
94
102
|
else
|
95
103
|
suspend
|
96
104
|
end
|
105
|
+
rescue RestClient::NotFound
|
106
|
+
on_proxy_action_missing
|
97
107
|
end
|
98
108
|
|
99
109
|
def cancel_proxy_task
|
@@ -133,8 +143,12 @@ module Actions
|
|
133
143
|
error! ProxyActionMissing.new(_('Proxy task gone missing from the smart proxy'))
|
134
144
|
end
|
135
145
|
|
136
|
-
def on_proxy_action_stopped
|
137
|
-
|
146
|
+
def on_proxy_action_stopped(event)
|
147
|
+
if event.exception
|
148
|
+
error! ProxyActionStopped.new(_('Failed to trigger task on the smart proxy: ') + event.exception.message)
|
149
|
+
else
|
150
|
+
check_task_status
|
151
|
+
end
|
138
152
|
end
|
139
153
|
|
140
154
|
# @override String name of an action to be triggered on server
|
@@ -42,7 +42,10 @@ module Actions
|
|
42
42
|
rescue => e
|
43
43
|
action_logger.warn "Could not trigger task on the smart proxy"
|
44
44
|
action_logger.warn e
|
45
|
-
|
45
|
+
# The response contains non-serializable objects
|
46
|
+
# TypeError: no _dump_data is defined for class Monitor
|
47
|
+
e.response = nil
|
48
|
+
batch.each { |remote_task| remote_task.update_from_batch_trigger({ 'exception' => e }) }
|
46
49
|
output[:failed_count] += batch.size
|
47
50
|
end
|
48
51
|
|
@@ -7,7 +7,7 @@ module ForemanTasks
|
|
7
7
|
:foreign_key => :execution_plan_id,
|
8
8
|
:inverse_of => :remote_tasks
|
9
9
|
|
10
|
-
scope :triggered, -> { where(:state => 'triggered') }
|
10
|
+
scope :triggered, -> { where(:state => ['triggered', 'parent-triggered']) }
|
11
11
|
scope :pending, -> { where(:state => 'new') }
|
12
12
|
scope :external, -> { where(:state => 'external') }
|
13
13
|
|
@@ -49,10 +49,11 @@ module ForemanTasks
|
|
49
49
|
self.parent_task_id = parent['task_id']
|
50
50
|
self.state = 'parent-triggered'
|
51
51
|
else
|
52
|
+
exception = data['exception']
|
52
53
|
# Tell the action the task on the smart proxy stopped
|
53
54
|
ForemanTasks.dynflow.world.event execution_plan_id,
|
54
55
|
step_id,
|
55
|
-
::Actions::ProxyAction::
|
56
|
+
::Actions::ProxyAction::ProxyActionStoppedEvent[exception],
|
56
57
|
optional: true
|
57
58
|
end
|
58
59
|
save!
|
@@ -219,19 +219,24 @@ module ForemanTasks
|
|
219
219
|
def self.consistency_check
|
220
220
|
fixed_count = 0
|
221
221
|
logger = Foreman::Logging.logger('foreman-tasks')
|
222
|
-
|
223
|
-
|
222
|
+
|
223
|
+
# Dynflow execution plans which are not stopped at this point should
|
224
|
+
# eventually get moving and their tasks should eventually get back in sync
|
225
|
+
# as the execution plans run
|
226
|
+
joins('LEFT JOIN dynflow_execution_plans ON foreman_tasks_tasks.external_id = dynflow_execution_plans.uuid::varchar')
|
227
|
+
.where('foreman_tasks_tasks.state_updated_at < dynflow_execution_plans.ended_at')
|
228
|
+
.find_each do |task|
|
229
|
+
changes = task.update_from_dynflow(task.execution_plan.to_hash)
|
224
230
|
unless changes.empty?
|
225
231
|
fixed_count += 1
|
226
232
|
logger.warn('Task %s updated at consistency check: %s' % [task.id, changes.inspect])
|
227
233
|
end
|
228
234
|
rescue => e
|
229
|
-
# if we fail updating the data from dynflow, it usually means there is something
|
230
|
-
# odd with the data consistency and at this point it is not possible to resume, switching
|
231
|
-
# the task to stopped/error
|
232
235
|
task.update(:state => 'stopped', :result => 'error')
|
233
236
|
Foreman::Logging.exception("Failed at consistency check for task #{task.id}", e, :logger => 'foreman-tasks')
|
234
237
|
end
|
238
|
+
# Wipe tasks left behind by now stopped tasks
|
239
|
+
ForemanTasks::Lock.left_joins(:task).merge(where(:state => 'stopped')).destroy_all
|
235
240
|
fixed_count
|
236
241
|
end
|
237
242
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<% title _("Recurring logics") %>
|
2
|
-
<% title_actions
|
2
|
+
<% title_actions help_button %>
|
3
3
|
|
4
4
|
<% if @errors %>
|
5
5
|
<%= alert(:class => 'alert-info', :id => 'multiple-alert', :close => false, :header => '', :text => @errors) %>
|
@@ -38,16 +38,16 @@
|
|
38
38
|
<table class="<%= table_css_classes('table-condensed table-fixed') %>">
|
39
39
|
<thead>
|
40
40
|
<th class="col-md-1"><%= N_("ID") %></th>
|
41
|
-
<th><%=
|
42
|
-
<th><%=
|
43
|
-
<th><%=
|
44
|
-
<th><%=
|
45
|
-
<th><%=
|
46
|
-
<th><%=
|
47
|
-
<th><%=
|
48
|
-
<th><%=
|
49
|
-
<th><%=
|
50
|
-
<th><%=
|
41
|
+
<th><%= _("Cron line") %></th>
|
42
|
+
<th><%= _("Task count") %></th>
|
43
|
+
<th><%= _("Action") %></th>
|
44
|
+
<th><%= _("Last occurrence") %></th>
|
45
|
+
<th><%= _("Next occurrence") %></th>
|
46
|
+
<th><%= _("Current iteration") %></th>
|
47
|
+
<th><%= _("Iteration limit") %></th>
|
48
|
+
<th><%= _("Repeat until") %></th>
|
49
|
+
<th><%= _("State") %></th>
|
50
|
+
<th><%= _("Purpose") %></th>
|
51
51
|
<th/>
|
52
52
|
</thead>
|
53
53
|
<% @recurring_logics.each do |recurring_logic| %>
|
@@ -1,11 +1,11 @@
|
|
1
1
|
<div>
|
2
2
|
<table class='<%= table_css_classes('table-condensed') %>'>
|
3
3
|
<tr>
|
4
|
-
<th><%=
|
4
|
+
<th><%= _('ID') %></th>
|
5
5
|
<td><%= link_to(task_group.id, foreman_tasks_task_group_url(task_group)) %></td>
|
6
6
|
</tr>
|
7
7
|
<tr>
|
8
|
-
<th><%=
|
8
|
+
<th><%= _('Task count') %></th>
|
9
9
|
<td><%= link_to(task_group.tasks.count, foreman_tasks_tasks_url(:search => "task_group.id = #{task_group.id}")) %></td>
|
10
10
|
</tr>
|
11
11
|
</table>
|
@@ -1,47 +1,47 @@
|
|
1
1
|
<% recurring_logic = task_group.recurring_logic -%>
|
2
2
|
<table class='<%= table_css_classes('table-condensed') %>'>
|
3
3
|
<tr>
|
4
|
-
<th
|
4
|
+
<th><%= _('ID') %></th>
|
5
5
|
<td><%= link_to(recurring_logic.id, recurring_logic) %></td>
|
6
6
|
</tr>
|
7
7
|
<tr>
|
8
|
-
<th><%=
|
8
|
+
<th><%= _("Cron line") %></th>
|
9
9
|
<td><%= recurring_logic.cron_line %></td>
|
10
10
|
</tr>
|
11
11
|
<tr>
|
12
|
-
<th><%=
|
12
|
+
<th><%= _("Action") %></th>
|
13
13
|
<td><%= format_task_input(recurring_logic.tasks.last) %></td>
|
14
14
|
</tr>
|
15
15
|
<tr>
|
16
|
-
<th><%=
|
16
|
+
<th><%= _("Last occurrence") %></th>
|
17
17
|
<td><%= recurring_logic.tasks.order(:started_at).where('started_at IS NOT NULL').last.try(:started_at) || '-' %></td>
|
18
18
|
</tr>
|
19
19
|
<tr>
|
20
|
-
<th><%=
|
20
|
+
<th><%= _("Next occurrence") %></th>
|
21
21
|
<td><%= recurring_logic_next_occurrence recurring_logic %></td>
|
22
22
|
</tr>
|
23
23
|
<tr>
|
24
|
-
<th><%=
|
24
|
+
<th><%= _("Current iteration") %></th>
|
25
25
|
<td><%= recurring_logic.iteration %></td>
|
26
26
|
</tr>
|
27
27
|
<tr>
|
28
|
-
<th><%=
|
28
|
+
<th><%= _("Iteration limit") %></th>
|
29
29
|
<td><%= format_recurring_logic_limit recurring_logic.max_iteration %></td>
|
30
30
|
</tr>
|
31
31
|
<tr>
|
32
|
-
<th><%=
|
32
|
+
<th><%= _("Repeat until") %></th>
|
33
33
|
<td><%= format_recurring_logic_limit recurring_logic.end_time.try(:in_time_zone) %></td>
|
34
34
|
</tr>
|
35
35
|
<tr>
|
36
|
-
<th><%=
|
36
|
+
<th><%= _("State") %></th>
|
37
37
|
<td><%= recurring_logic_state(recurring_logic) %></td>
|
38
38
|
</tr>
|
39
39
|
<tr>
|
40
|
-
<th><%=
|
40
|
+
<th><%= _("Purpose") %></th>
|
41
41
|
<td><%= recurring_logic.purpose %></td>
|
42
42
|
</tr>
|
43
43
|
<tr>
|
44
|
-
<th><%=
|
44
|
+
<th><%= _("Task count") %></th>
|
45
45
|
<td><%= link_to(task_group.tasks.count, foreman_tasks_tasks_url(:search => "task_group.id = #{task_group.id}")) %></td>
|
46
46
|
</tr>
|
47
47
|
</table>
|
@@ -84,7 +84,7 @@ module ForemanTasks
|
|
84
84
|
|
85
85
|
def self.cleanup_settings
|
86
86
|
return @cleanup_settings if @cleanup_settings
|
87
|
-
@cleanup_settings = SETTINGS
|
87
|
+
@cleanup_settings = SETTINGS.dig(:'foreman-tasks', :cleanup) || {}
|
88
88
|
end
|
89
89
|
|
90
90
|
def self.actions_by_rules(action_rules)
|
@@ -16,7 +16,7 @@ module ForemanTasks
|
|
16
16
|
:backup_deleted_plans => true,
|
17
17
|
:backup_dir => default_backup_dir,
|
18
18
|
}
|
19
|
-
settings = SETTINGS
|
19
|
+
settings = SETTINGS.dig(:'foreman-tasks', :backup)
|
20
20
|
backup_options.merge!(settings) if settings
|
21
21
|
@backup_settings = with_environment_override backup_options
|
22
22
|
end
|
data/lib/foreman_tasks/engine.rb
CHANGED
@@ -166,7 +166,10 @@ module ForemanTasks
|
|
166
166
|
world.middleware.use Actions::Middleware::KeepCurrentUser, :before => ::Dynflow::Middleware::Common::Transaction
|
167
167
|
world.middleware.use Actions::Middleware::KeepCurrentTimezone
|
168
168
|
world.middleware.use Actions::Middleware::KeepCurrentRequestID
|
169
|
-
world.middleware.use ::Actions::Middleware::LoadSettingValues
|
169
|
+
world.middleware.use ::Actions::Middleware::LoadSettingValues
|
170
|
+
end
|
171
|
+
::ForemanTasks.dynflow.config.on_init(true) do
|
172
|
+
::ForemanTasks::Task::DynflowTask.consistency_check
|
170
173
|
end
|
171
174
|
end
|
172
175
|
|
data/lib/tasks/gettext.rake
CHANGED
data/locale/action_names.rb
CHANGED
Binary file
|