foreman-tasks 0.9.6 → 0.10.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/app/controllers/foreman_tasks/tasks_controller.rb +1 -11
- data/app/lib/actions/proxy_action.rb +0 -7
- data/app/models/foreman_tasks/task.rb +2 -5
- data/app/models/foreman_tasks/task/dynflow_task.rb +4 -19
- data/app/views/foreman_tasks/tasks/_details.html.erb +1 -1
- data/app/views/foreman_tasks/tasks/dashboard/_latest_tasks_in_error_warning.html.erb +7 -5
- data/config/foreman-tasks.yaml.example +2 -27
- data/config/routes.rb +0 -1
- data/foreman-tasks.gemspec +1 -1
- data/lib/foreman_tasks/cleaner.rb +4 -47
- data/lib/foreman_tasks/dynflow/configuration.rb +0 -26
- data/lib/foreman_tasks/engine.rb +1 -1
- data/lib/foreman_tasks/tasks/cleanup.rake +2 -22
- data/lib/foreman_tasks/version.rb +1 -1
- data/locale/action_names.rb +5 -3
- data/locale/en/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/en/foreman_tasks.po +4 -1
- data/locale/foreman_tasks.pot +12 -6
- data/test/unit/cleaner_test.rb +0 -51
- metadata +5 -7
- data/test/unit/otp_manager_test.rb +0 -70
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: acd7b0adebf587957c53c75ff415ae872d5b5995
|
4
|
+
data.tar.gz: e682ae90a94614bae6d1cf7b1014e39bce5fa82e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd0a1edea81a4b634fea1f4e81ab7b2778a11d68cb5cc2d8c35974c60db2d9cc58ac12b85904fb0943ba22a1540b19d513504aefac6f285f1703cba8f4ce3217
|
7
|
+
data.tar.gz: 036bb166af540a7509a590fa8f5de2d056d93c8c77bf8311e92705d3e8936097365449b60b4f025fe6814df9ca8f6e5fc3e70d58fdc6a6ee74e9682a52351e13
|
@@ -36,16 +36,6 @@ module ForemanTasks
|
|
36
36
|
redirect_to :back
|
37
37
|
end
|
38
38
|
|
39
|
-
def abort
|
40
|
-
task = find_dynflow_task
|
41
|
-
if task.abort
|
42
|
-
flash[:notice] = _('Trying to abort the task')
|
43
|
-
else
|
44
|
-
flash[:warning] = _('The task cannot be aborted at the moment.')
|
45
|
-
end
|
46
|
-
redirect_to :back
|
47
|
-
end
|
48
|
-
|
49
39
|
def resume
|
50
40
|
task = find_dynflow_task
|
51
41
|
if task.resumable?
|
@@ -96,7 +86,7 @@ module ForemanTasks
|
|
96
86
|
case params[:action]
|
97
87
|
when 'sub_tasks'
|
98
88
|
:view
|
99
|
-
when 'resume', 'unlock', 'force_unlock', 'cancel_step', 'cancel'
|
89
|
+
when 'resume', 'unlock', 'force_unlock', 'cancel_step', 'cancel'
|
100
90
|
:edit
|
101
91
|
else
|
102
92
|
super
|
@@ -31,8 +31,6 @@ module Actions
|
|
31
31
|
# do nothing
|
32
32
|
when ::Dynflow::Action::Cancellable::Cancel
|
33
33
|
cancel_proxy_task
|
34
|
-
when ::Dynflow::Action::Cancellable::Abort
|
35
|
-
abort_proxy_task
|
36
34
|
when CallbackData
|
37
35
|
on_data(event.data)
|
38
36
|
when ::Dynflow::Action::Timeouts::Timeout
|
@@ -80,11 +78,6 @@ module Actions
|
|
80
78
|
end
|
81
79
|
end
|
82
80
|
|
83
|
-
def abort_proxy_task
|
84
|
-
proxy.cancel_task(output[:proxy_task_id])
|
85
|
-
error! ForemanTasks::Task::TaskCancelledException.new(_('Task aborted: the task might be still running on the proxy'))
|
86
|
-
end
|
87
|
-
|
88
81
|
def on_resume
|
89
82
|
# TODO: add logic to load the data from the external action
|
90
83
|
suspend
|
@@ -7,11 +7,8 @@ module ForemanTasks
|
|
7
7
|
def check_permissions_after_save
|
8
8
|
# there's no create_tasks permission, tasks are created as a result of internal actions, in such case we
|
9
9
|
# don't do authorization, that should have been performed on wrapping action level
|
10
|
-
|
11
|
-
|
12
|
-
else
|
13
|
-
super
|
14
|
-
end
|
10
|
+
# the same applies for updating
|
11
|
+
true
|
15
12
|
end
|
16
13
|
|
17
14
|
# TODO: missing validation of states
|
@@ -9,8 +9,8 @@ module ForemanTasks
|
|
9
9
|
self.external_id = data[:id]
|
10
10
|
self.started_at = utc_zone.parse(data[:started_at]) unless data[:started_at].nil?
|
11
11
|
self.ended_at = utc_zone.parse(data[:ended_at]) unless data[:ended_at].nil?
|
12
|
-
self.result = map_result(data).to_s
|
13
12
|
self.state = data[:state].to_s
|
13
|
+
self.result = map_result(data[:result])
|
14
14
|
self.start_at = utc_zone.parse(data[:start_at]) if data[:start_at]
|
15
15
|
self.start_before = utc_zone.parse(data[:start_before]) if data[:start_before]
|
16
16
|
self.parent_task_id ||= begin
|
@@ -32,10 +32,6 @@ module ForemanTasks
|
|
32
32
|
execution_plan!.cancel.any?
|
33
33
|
end
|
34
34
|
|
35
|
-
def abort
|
36
|
-
execution_plan!.cancel(true).any?
|
37
|
-
end
|
38
|
-
|
39
35
|
def resumable?
|
40
36
|
execution_plan.try(:state) == :paused
|
41
37
|
end
|
@@ -152,20 +148,9 @@ module ForemanTasks
|
|
152
148
|
|
153
149
|
private
|
154
150
|
|
155
|
-
def map_result(
|
156
|
-
if
|
157
|
-
|
158
|
-
:cancelled
|
159
|
-
else
|
160
|
-
data[:result]
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
def state_result_transitioned?(from, to, data)
|
165
|
-
oldstate, oldresult = from
|
166
|
-
newstate, newresult = to
|
167
|
-
state == oldstate && data[:state].to_s == newstate &&
|
168
|
-
result == oldresult && data[:result].to_s == newresult
|
151
|
+
def map_result(result)
|
152
|
+
result = :cancelled if result == :error && cancelled?
|
153
|
+
result.to_s
|
169
154
|
end
|
170
155
|
|
171
156
|
def cancelled?
|
@@ -3,7 +3,7 @@
|
|
3
3
|
<% if authorized_for(:permission => :edit_foreman_tasks, :auth_object => @task) %>
|
4
4
|
<%= link_to(_('Dynflow console'),
|
5
5
|
format((defined?(Rails) ? request.script_name : '') + '/foreman_tasks/dynflow/%s', @task.external_id),
|
6
|
-
class: %w(btn btn-sm btn-default)) if Setting['dynflow_enable_console'] %>
|
6
|
+
class: %w(btn btn-sm btn-default), target: '_blank') if Setting['dynflow_enable_console'] %>
|
7
7
|
|
8
8
|
<%= link_to(_('Resume'),
|
9
9
|
resume_foreman_tasks_task_path(@task),
|
@@ -1,15 +1,17 @@
|
|
1
1
|
<h4><%= link_to _("Latest Warning/Error Tasks"), foreman_tasks_tasks_path(:order=>'started_at DESC') %></h4>
|
2
|
-
<table class="table table-striped">
|
2
|
+
<table class="table table-striped table-fixed">
|
3
3
|
<tr>
|
4
|
-
<th><%= _("Name") %></th>
|
5
|
-
<th><%= _("State") %></th>
|
6
|
-
<th><%= _("Result") %></th>
|
4
|
+
<th class="col-md-5"><%= _("Name") %></th>
|
5
|
+
<th class="col-md-2"><%= _("State") %></th>
|
6
|
+
<th class="col-md-2"><%= _("Result") %></th>
|
7
|
+
<th class="col-md-3"><%= _("Started") %></th>
|
7
8
|
</tr>
|
8
9
|
<% ForemanTasks::Task::Summarizer.new.latest_tasks_in_errors_warning.each do |task| %>
|
9
10
|
<tr class="<%= ForemanTasks::Task::StatusExplicator.new.is_erroneous(task) ? 'text-danger' : '' %>">
|
10
|
-
<td><%= link_to task.humanized[:action], defined?(main_app) ? main_app.foreman_tasks_task_path(task.id) : foreman_tasks_task_path(task.id) %></td>
|
11
|
+
<td class="ellipsis"><%= link_to task.humanized[:action], defined?(main_app) ? main_app.foreman_tasks_task_path(task.id) : foreman_tasks_task_path(task.id) %></td>
|
11
12
|
<td><%= task.state %></td>
|
12
13
|
<td><%= task.result %></td>
|
14
|
+
<td><%= _('%s ago') % time_ago_in_words(task.started_at) %></td>
|
13
15
|
</tr>
|
14
16
|
<% end %>
|
15
17
|
</table>
|
@@ -9,43 +9,18 @@
|
|
9
9
|
# :action:
|
10
10
|
# :enabled: true
|
11
11
|
|
12
|
-
# Task backup configuration can be changed by altering the values in
|
13
|
-
# the backup section
|
14
|
-
#
|
15
|
-
:backup:
|
16
|
-
#
|
17
|
-
# Whether to back up tasks when they are removed
|
18
|
-
#
|
19
|
-
:backup_deleted_tasks: true
|
20
|
-
#
|
21
|
-
# Where to put the tasks which were backed up
|
22
|
-
#
|
23
|
-
:backup_dir: /var/lib/foreman/tasks-backup
|
24
12
|
|
25
13
|
# Cleaning configuration: how long should the actions be kept before deleted
|
26
14
|
# by `rake foreman_tasks:clean` task
|
27
15
|
#
|
28
|
-
:cleanup:
|
16
|
+
# :cleanup:
|
29
17
|
#
|
30
18
|
# the period after which to delete all the tasks (by default all tasks are not being deleted after some period)
|
31
|
-
# will be deprecated in Foreman 1.18 and the use of rules is recommended.
|
32
19
|
#
|
33
|
-
#
|
20
|
+
# :after: 365d
|
34
21
|
#
|
35
22
|
# per action settings to override the default defined in the actions (self.cleanup_after method)
|
36
23
|
#
|
37
24
|
# :actions:
|
38
25
|
# - :name: Actions::Foreman::Host::ImportFacts
|
39
26
|
# :after: 10d
|
40
|
-
#
|
41
|
-
# Rules defined in this section by default don't operate
|
42
|
-
# on tasks specified in the actions section. This behavior
|
43
|
-
# can be overriden by setting the override_actions to true
|
44
|
-
:rules:
|
45
|
-
# Delete successful tasks after a month
|
46
|
-
- :filter: result = success
|
47
|
-
:after: 30d
|
48
|
-
# Delete everything (any action, any state) after one year
|
49
|
-
- :states: all # Either list of state names or all
|
50
|
-
:after: 1y
|
51
|
-
:override_actions: true
|
data/config/routes.rb
CHANGED
data/foreman-tasks.gemspec
CHANGED
@@ -29,7 +29,7 @@ same resource. It also optionally provides Dynflow infrastructure for using it f
|
|
29
29
|
s.extra_rdoc_files = Dir['README*', 'LICENSE']
|
30
30
|
|
31
31
|
s.add_dependency "foreman-tasks-core"
|
32
|
-
s.add_dependency "dynflow", '~> 0.8.
|
32
|
+
s.add_dependency "dynflow", '~> 0.8.24'
|
33
33
|
s.add_dependency "sequel" # for Dynflow process persistence
|
34
34
|
s.add_dependency "sinatra" # for Dynflow web console
|
35
35
|
s.add_dependency "daemons" # for running remote executor
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'csv'
|
2
|
-
|
3
1
|
module ForemanTasks
|
4
2
|
# Represents the cleanup mechanism for tasks
|
5
3
|
class Cleaner
|
@@ -13,16 +11,11 @@ module ForemanTasks
|
|
13
11
|
end
|
14
12
|
end
|
15
13
|
if cleanup_settings[:after]
|
16
|
-
Foreman::Deprecation.deprecation_warning('1.18', _(':after setting in tasks cleanup section is deprecated, use :after in :rules section to set the value. to cleanup rules'))
|
17
14
|
new(options.merge(:filter => '', :after => cleanup_settings[:after])).delete
|
18
15
|
end
|
19
|
-
|
20
|
-
with_periods.each do |action_class, period|
|
16
|
+
actions_with_default_cleanup.each do |action_class, period|
|
21
17
|
new(options.merge(:filter => "label = #{action_class.name}", :after => period)).delete
|
22
18
|
end
|
23
|
-
actions_by_rules(with_periods).each do |hash|
|
24
|
-
new(options.merge(hash)).delete
|
25
|
-
end
|
26
19
|
end
|
27
20
|
end
|
28
21
|
|
@@ -51,19 +44,6 @@ module ForemanTasks
|
|
51
44
|
@cleanup_settings = SETTINGS[:'foreman-tasks'] && SETTINGS[:'foreman-tasks'][:cleanup] || {}
|
52
45
|
end
|
53
46
|
|
54
|
-
def self.actions_by_rules(actions_with_periods)
|
55
|
-
disable_actions_with_periods = "label !^ (#{actions_with_periods.keys.join(', ')})"
|
56
|
-
cleanup_settings.fetch(:rules, []).map do |hash|
|
57
|
-
next if hash[:after].nil?
|
58
|
-
conditions = []
|
59
|
-
conditions << disable_actions_with_periods unless hash[:override_actions]
|
60
|
-
conditions << hash[:filter] if hash[:filter]
|
61
|
-
hash[:states] = [] if hash[:states] == 'all'
|
62
|
-
hash[:filter] = conditions.map { |condition| "(#{condition})" }.join(' AND ')
|
63
|
-
hash
|
64
|
-
end.compact
|
65
|
-
end
|
66
|
-
|
67
47
|
attr_reader :filter, :after, :states, :verbose, :batch_size, :noop, :full_filter
|
68
48
|
|
69
49
|
# @param filter [String] scoped search matching the tasks to be deleted
|
@@ -76,8 +56,7 @@ module ForemanTasks
|
|
76
56
|
:verbose => false,
|
77
57
|
:batch_size => 1000,
|
78
58
|
:noop => false,
|
79
|
-
:states => ['stopped']
|
80
|
-
:backup_dir => ForemanTasks.dynflow.world.persistence.current_backup_dir }
|
59
|
+
:states => ['stopped'] }
|
81
60
|
options = default_options.merge(options)
|
82
61
|
|
83
62
|
@filter = options[:filter]
|
@@ -86,7 +65,6 @@ module ForemanTasks
|
|
86
65
|
@verbose = options[:verbose]
|
87
66
|
@batch_size = options[:batch_size]
|
88
67
|
@noop = options[:noop]
|
89
|
-
@backup_dir = options[:backup_dir]
|
90
68
|
|
91
69
|
raise ArgumentError, 'filter not speficied' if @filter.nil?
|
92
70
|
|
@@ -113,33 +91,12 @@ module ForemanTasks
|
|
113
91
|
end
|
114
92
|
|
115
93
|
def delete_tasks(chunk)
|
116
|
-
|
117
|
-
tasks_to_csv(tasks, @backup_dir, 'foreman_tasks.csv') if @backup_dir
|
118
|
-
tasks.delete_all
|
119
|
-
end
|
120
|
-
|
121
|
-
def tasks_to_csv(dataset, backup_dir, file_name)
|
122
|
-
with_backup_file(backup_dir, file_name) do |csv, appending|
|
123
|
-
csv << ForemanTasks::Task.attribute_names.to_csv unless appending
|
124
|
-
dataset.each do |row|
|
125
|
-
csv << row.attributes.values.to_csv
|
126
|
-
end
|
127
|
-
end
|
128
|
-
dataset
|
129
|
-
end
|
130
|
-
|
131
|
-
def with_backup_file(backup_dir, file_name)
|
132
|
-
FileUtils.mkdir_p(backup_dir) unless File.directory?(backup_dir)
|
133
|
-
csv_file = File.join(backup_dir, file_name)
|
134
|
-
appending = File.exist?(csv_file)
|
135
|
-
File.open(csv_file, 'a') do |f|
|
136
|
-
yield f, appending
|
137
|
-
end
|
94
|
+
ForemanTasks::Task.where(:id => chunk.map(&:id)).delete_all
|
138
95
|
end
|
139
96
|
|
140
97
|
def delete_dynflow_plans(chunk)
|
141
98
|
dynflow_ids = chunk.find_all { |task| task.is_a? Task::DynflowTask }.map(&:external_id)
|
142
|
-
ForemanTasks.dynflow.world.persistence.delete_execution_plans({ 'uuid' => dynflow_ids }, batch_size
|
99
|
+
ForemanTasks.dynflow.world.persistence.delete_execution_plans({ 'uuid' => dynflow_ids }, batch_size)
|
143
100
|
end
|
144
101
|
|
145
102
|
def prepare_filter
|
@@ -103,8 +103,6 @@ module ForemanTasks
|
|
103
103
|
config.transaction_adapter = transaction_adapter
|
104
104
|
config.executor = ->(world, _) { initialize_executor(world) }
|
105
105
|
config.connector = ->(world, _) { initialize_connector(world) }
|
106
|
-
config.backup_deleted_plans = backup_settings[:backup_deleted_plans]
|
107
|
-
config.backup_dir = backup_settings[:backup_dir]
|
108
106
|
|
109
107
|
# we can't do any operation until the ForemanTasks.dynflow.world is set
|
110
108
|
config.auto_execute = false
|
@@ -146,29 +144,5 @@ module ForemanTasks
|
|
146
144
|
def initialize_persistence
|
147
145
|
ForemanTasks::Dynflow::Persistence.new(default_sequel_adapter_options)
|
148
146
|
end
|
149
|
-
|
150
|
-
def backup_settings
|
151
|
-
return @backup_settings if @backup_settings
|
152
|
-
backup_options = {
|
153
|
-
:backup_deleted_plans => true,
|
154
|
-
:backup_dir => default_backup_dir
|
155
|
-
}
|
156
|
-
settings = SETTINGS[:'foreman-tasks'] && SETTINGS[:'foreman-tasks'][:backup]
|
157
|
-
backup_options.merge!(settings) if settings
|
158
|
-
@backup_settings = with_environment_override backup_options
|
159
|
-
end
|
160
|
-
|
161
|
-
def default_backup_dir
|
162
|
-
File.join(Rails.root, 'tmp', 'task-backup')
|
163
|
-
end
|
164
|
-
|
165
|
-
def with_environment_override(options)
|
166
|
-
env_var = ENV['TASK_BACKUP']
|
167
|
-
unless env_var.nil?
|
168
|
-
# Everything except 0, n, no, false is considered to be a truthy value
|
169
|
-
options[:backup_deleted_plans] = !%w[0 n no false].include?(env_var.downcase)
|
170
|
-
end
|
171
|
-
options
|
172
|
-
end
|
173
147
|
end
|
174
148
|
end
|
data/lib/foreman_tasks/engine.rb
CHANGED
@@ -58,7 +58,7 @@ module ForemanTasks
|
|
58
58
|
security_block :foreman_tasks do |_map|
|
59
59
|
permission :view_foreman_tasks, { :'foreman_tasks/tasks' => [:auto_complete_search, :sub_tasks, :index, :show],
|
60
60
|
:'foreman_tasks/api/tasks' => [:bulk_search, :show, :index, :summary] }, :resource_type => ForemanTasks::Task.name
|
61
|
-
permission :edit_foreman_tasks, { :'foreman_tasks/tasks' => [:resume, :unlock, :force_unlock, :cancel_step, :cancel
|
61
|
+
permission :edit_foreman_tasks, { :'foreman_tasks/tasks' => [:resume, :unlock, :force_unlock, :cancel_step, :cancel],
|
62
62
|
:'foreman_tasks/api/tasks' => [:bulk_resume] }, :resource_type => ForemanTasks::Task.name
|
63
63
|
|
64
64
|
permission :create_recurring_logics, {}, :resource_type => ForemanTasks::RecurringLogic.name
|
@@ -5,11 +5,10 @@ namespace :foreman_tasks do
|
|
5
5
|
|
6
6
|
* TASK_SEARCH : scoped search filter (example: 'label = "Actions::Foreman::Host::ImportFacts"')
|
7
7
|
* AFTER : delete tasks created after *AFTER* period. Expected format is a number followed by the time unit (s,h,m,y), such as '10d' for 10 days
|
8
|
-
* STATES : comma separated list of task states to touch with the cleanup, by default only stopped tasks are covered
|
9
|
-
* NOOP : set to "true" if the task should not
|
8
|
+
* STATES : comma separated list of task states to touch with the cleanup, by default only stopped tasks are covered
|
9
|
+
* NOOP : set to "true" if the task should not actuall perform the deletion
|
10
10
|
* VERBOSE : set to "true" for more verbose output
|
11
11
|
* BATCH_SIZE : the size of batches the tasks get processed in (1000 by default)
|
12
|
-
* TASK_BACKUP : set to "true" or "false" to enable/disable task backup
|
13
12
|
|
14
13
|
If none of TASK_SEARCH, BEFORE, STATES is specified, the tasks will be cleaned based
|
15
14
|
configuration in settings
|
@@ -22,7 +21,6 @@ namespace :foreman_tasks do
|
|
22
21
|
options[:after] = ENV['AFTER'] if ENV['AFTER']
|
23
22
|
|
24
23
|
options[:states] = ENV['STATES'].to_s.split(',') if ENV['STATES']
|
25
|
-
options[:states] = [] if options[:states] == ['all']
|
26
24
|
|
27
25
|
options[:noop] = true if ENV['NOOP']
|
28
26
|
|
@@ -54,24 +52,6 @@ namespace :foreman_tasks do
|
|
54
52
|
printf("%-50s %s\n", action.name, after)
|
55
53
|
end
|
56
54
|
end
|
57
|
-
puts
|
58
|
-
by_rules = ForemanTasks::Cleaner.actions_by_rules(ForemanTasks::Cleaner.actions_with_default_cleanup)
|
59
|
-
if by_rules.empty?
|
60
|
-
puts _('No cleanup rules are configured')
|
61
|
-
else
|
62
|
-
printf("%-50s %-15s %s\n", _('states'), _('delete after'), _('filter'))
|
63
|
-
by_rules.each do |hash|
|
64
|
-
state = case hash[:states]
|
65
|
-
when []
|
66
|
-
_('ANY')
|
67
|
-
when nil
|
68
|
-
'stopped'
|
69
|
-
else
|
70
|
-
hash[:states]
|
71
|
-
end
|
72
|
-
printf("%-50s %-15s %s\n", state, hash[:after], hash[:filter])
|
73
|
-
end
|
74
|
-
end
|
75
55
|
end
|
76
56
|
end
|
77
57
|
|
data/locale/action_names.rb
CHANGED
Binary file
|
data/locale/en/foreman_tasks.po
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
#
|
6
6
|
msgid ""
|
7
7
|
msgstr ""
|
8
|
-
"Project-Id-Version: foreman_tasks 0.1.
|
8
|
+
"Project-Id-Version: foreman_tasks 0.1.2\n"
|
9
9
|
"Report-Msgid-Bugs-To: \n"
|
10
10
|
"PO-Revision-Date: 2016-02-03 09:55-0500\n"
|
11
11
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
@@ -370,6 +370,9 @@ msgstr ""
|
|
370
370
|
msgid "Start before"
|
371
371
|
msgstr ""
|
372
372
|
|
373
|
+
msgid "Started"
|
374
|
+
msgstr ""
|
375
|
+
|
373
376
|
msgid "Started at"
|
374
377
|
msgstr ""
|
375
378
|
|
data/locale/foreman_tasks.pot
CHANGED
@@ -8,8 +8,8 @@ msgid ""
|
|
8
8
|
msgstr ""
|
9
9
|
"Project-Id-Version: foreman_tasks 1.0.0\n"
|
10
10
|
"Report-Msgid-Bugs-To: \n"
|
11
|
-
"POT-Creation-Date: 2017-07-
|
12
|
-
"PO-Revision-Date: 2017-07-
|
11
|
+
"POT-Creation-Date: 2017-07-19 17:30+0200\n"
|
12
|
+
"PO-Revision-Date: 2017-07-19 17:30+0200\n"
|
13
13
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14
14
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
15
15
|
"Language: \n"
|
@@ -146,11 +146,12 @@ msgid "N/A"
|
|
146
146
|
msgstr ""
|
147
147
|
|
148
148
|
#: ../app/helpers/foreman_tasks/foreman_tasks_helper.rb:40
|
149
|
-
msgid "%s
|
149
|
+
msgid "in %s"
|
150
150
|
msgstr ""
|
151
151
|
|
152
152
|
#: ../app/helpers/foreman_tasks/foreman_tasks_helper.rb:40
|
153
|
-
|
153
|
+
#: ../app/views/foreman_tasks/tasks/dashboard/_latest_tasks_in_error_warning.html.erb:14
|
154
|
+
msgid "%s ago"
|
154
155
|
msgstr ""
|
155
156
|
|
156
157
|
#: ../app/helpers/foreman_tasks/foreman_tasks_helper.rb:50
|
@@ -394,11 +395,11 @@ msgstr ""
|
|
394
395
|
msgid "Finished"
|
395
396
|
msgstr ""
|
396
397
|
|
397
|
-
#: ../app/models/foreman_tasks/task.rb:
|
398
|
+
#: ../app/models/foreman_tasks/task.rb:84
|
398
399
|
msgid "Delayed"
|
399
400
|
msgstr ""
|
400
401
|
|
401
|
-
#: ../app/models/foreman_tasks/task.rb:
|
402
|
+
#: ../app/models/foreman_tasks/task.rb:84
|
402
403
|
msgid "Immediate"
|
403
404
|
msgstr ""
|
404
405
|
|
@@ -703,6 +704,11 @@ msgstr ""
|
|
703
704
|
msgid "Latest Warning/Error Tasks"
|
704
705
|
msgstr ""
|
705
706
|
|
707
|
+
#:
|
708
|
+
#: ../app/views/foreman_tasks/tasks/dashboard/_latest_tasks_in_error_warning.html.erb:7
|
709
|
+
msgid "Started"
|
710
|
+
msgstr ""
|
711
|
+
|
706
712
|
#: ../app/views/foreman_tasks/tasks/dashboard/_tasks_status.html.erb:1
|
707
713
|
#: ../lib/foreman_tasks/engine.rb:81
|
708
714
|
msgid "Task Status"
|
data/test/unit/cleaner_test.rb
CHANGED
@@ -1,11 +1,6 @@
|
|
1
1
|
require 'foreman_tasks_test_helper'
|
2
2
|
|
3
3
|
class TasksTest < ActiveSupport::TestCase
|
4
|
-
before do
|
5
|
-
# To stop dynflow from backing up actions, execution_plans and steps
|
6
|
-
ForemanTasks.dynflow.world.persistence.adapter.stubs(:backup_to_csv)
|
7
|
-
end
|
8
|
-
|
9
4
|
describe ForemanTasks::Cleaner do
|
10
5
|
it 'is able to delete tasks (including the dynflow plans) based on filter' do
|
11
6
|
cleaner = ForemanTasks::Cleaner.new(:filter => 'label = "Actions::User::Create"', :after => '10d')
|
@@ -17,7 +12,6 @@ class TasksTest < ActiveSupport::TestCase
|
|
17
12
|
task.save
|
18
13
|
end,
|
19
14
|
FactoryGirl.create(:dynflow_task, :product_create_task)]
|
20
|
-
cleaner.expects(:tasks_to_csv)
|
21
15
|
cleaner.delete
|
22
16
|
ForemanTasks::Task.where(id: tasks_to_delete).must_be_empty
|
23
17
|
ForemanTasks::Task.where(id: tasks_to_keep).order(:id).map(&:id).must_equal tasks_to_keep.map(&:id).sort
|
@@ -38,7 +32,6 @@ class TasksTest < ActiveSupport::TestCase
|
|
38
32
|
end]
|
39
33
|
|
40
34
|
tasks_to_keep = [FactoryGirl.create(:dynflow_task, :product_create_task)]
|
41
|
-
cleaner.expects(:tasks_to_csv)
|
42
35
|
cleaner.delete
|
43
36
|
ForemanTasks::Task.where(id: tasks_to_delete).must_be_empty
|
44
37
|
ForemanTasks::Task.where(id: tasks_to_keep).must_equal tasks_to_keep
|
@@ -53,32 +46,11 @@ class TasksTest < ActiveSupport::TestCase
|
|
53
46
|
task.started_at = task.ended_at = Time.zone.now
|
54
47
|
task.save
|
55
48
|
end]
|
56
|
-
cleaner.expects(:tasks_to_csv)
|
57
49
|
cleaner.delete
|
58
50
|
ForemanTasks::Task.where(id: tasks_to_delete).must_be_empty
|
59
51
|
ForemanTasks::Task.where(id: tasks_to_keep).must_equal tasks_to_keep
|
60
52
|
end
|
61
53
|
|
62
|
-
it 'backs tasks up before deleting' do
|
63
|
-
dir = '/tmp'
|
64
|
-
cleaner = ForemanTasks::Cleaner.new(:filter => '', :after => '10d', :backup_dir => dir)
|
65
|
-
tasks_to_delete = [FactoryGirl.create(:dynflow_task, :user_create_task),
|
66
|
-
FactoryGirl.create(:dynflow_task, :product_create_task)]
|
67
|
-
|
68
|
-
r, w = IO.pipe
|
69
|
-
cleaner.expects(:with_backup_file)
|
70
|
-
.with(dir, 'foreman_tasks.csv')
|
71
|
-
.yields(w, false)
|
72
|
-
cleaner.delete
|
73
|
-
w.close
|
74
|
-
header, *data = r.readlines.map(&:chomp)
|
75
|
-
header.must_equal ForemanTasks::Task.attribute_names.join(',')
|
76
|
-
expected_lines = tasks_to_delete.map { |task| task.attributes.values.join(',') }
|
77
|
-
data.count.must_equal expected_lines.count
|
78
|
-
expected_lines.each { |line| data.must_include line }
|
79
|
-
ForemanTasks::Task.where(id: tasks_to_delete).must_be_empty
|
80
|
-
end
|
81
|
-
|
82
54
|
class ActionWithCleanup < Actions::Base
|
83
55
|
def self.cleanup_after
|
84
56
|
'15d'
|
@@ -96,29 +68,6 @@ class TasksTest < ActiveSupport::TestCase
|
|
96
68
|
{ :actions => [{ :name => ActionWithCleanup.name, :after => '5d' }] })
|
97
69
|
ForemanTasks::Cleaner.actions_with_default_cleanup[ActionWithCleanup].must_equal '5d'
|
98
70
|
end
|
99
|
-
|
100
|
-
it 'deprecates the usage of :after' do
|
101
|
-
Foreman::Deprecation.expects(:deprecation_warning)
|
102
|
-
ForemanTasks::Cleaner.any_instance.expects(:delete)
|
103
|
-
ForemanTasks::Cleaner.stubs(:cleanup_settings =>
|
104
|
-
{ :after => '1d' })
|
105
|
-
ForemanTasks::Cleaner.stubs(:actions_with_default_cleanup).returns({})
|
106
|
-
ForemanTasks::Cleaner.run({})
|
107
|
-
end
|
108
|
-
|
109
|
-
it 'generates filters from rules properly' do
|
110
|
-
actions_with_default = { 'action1' => nil, 'action2' => nil }
|
111
|
-
rules = [{ :after => nil },
|
112
|
-
{ :after => '10d', :filter => 'label = something', :states => %w[stopped paused] },
|
113
|
-
{ :after => '15d', :filter => 'label = something_else',
|
114
|
-
:override_actions => true, :states => 'all' }]
|
115
|
-
ForemanTasks::Cleaner.stubs(:cleanup_settings).returns(:rules => rules)
|
116
|
-
r1, r2 = ForemanTasks::Cleaner.actions_by_rules actions_with_default
|
117
|
-
r1[:filter].must_equal '(label !^ (action1, action2)) AND (label = something)'
|
118
|
-
r1[:states].must_equal %w[stopped paused]
|
119
|
-
r2[:filter].must_equal '(label = something_else)'
|
120
|
-
r2[:states].must_equal []
|
121
|
-
end
|
122
71
|
end
|
123
72
|
end
|
124
73
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman-tasks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Nečas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: foreman-tasks-core
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.8.
|
33
|
+
version: 0.8.24
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.8.
|
40
|
+
version: 0.8.24
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: sequel
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -261,7 +261,6 @@ files:
|
|
261
261
|
- test/unit/config/environment.rb
|
262
262
|
- test/unit/daemon_test.rb
|
263
263
|
- test/unit/dynflow_console_authorizer_test.rb
|
264
|
-
- test/unit/otp_manager_test.rb
|
265
264
|
- test/unit/proxy_selector_test.rb
|
266
265
|
- test/unit/recurring_logic_test.rb
|
267
266
|
- test/unit/task_groups_test.rb
|
@@ -286,7 +285,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
286
285
|
version: '0'
|
287
286
|
requirements: []
|
288
287
|
rubyforge_project:
|
289
|
-
rubygems_version: 2.
|
288
|
+
rubygems_version: 2.4.5
|
290
289
|
signing_key:
|
291
290
|
specification_version: 4
|
292
291
|
summary: Foreman plugin for showing tasks information for resoruces and users
|
@@ -306,7 +305,6 @@ test_files:
|
|
306
305
|
- test/unit/config/environment.rb
|
307
306
|
- test/unit/daemon_test.rb
|
308
307
|
- test/unit/dynflow_console_authorizer_test.rb
|
309
|
-
- test/unit/otp_manager_test.rb
|
310
308
|
- test/unit/proxy_selector_test.rb
|
311
309
|
- test/unit/recurring_logic_test.rb
|
312
310
|
- test/unit/task_groups_test.rb
|
@@ -1,70 +0,0 @@
|
|
1
|
-
require 'foreman_tasks_test_helper'
|
2
|
-
require 'foreman_tasks_core/otp_manager'
|
3
|
-
|
4
|
-
module ForemanTasksCore
|
5
|
-
class OtpManagerTest < ActiveSupport::TestCase
|
6
|
-
class TestOtpManager < OtpManager
|
7
|
-
def self.reset!
|
8
|
-
@passwords = nil
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
before do
|
13
|
-
TestOtpManager.reset!
|
14
|
-
end
|
15
|
-
|
16
|
-
let(:username) { 'myuser' }
|
17
|
-
let(:password) { '123456789' }
|
18
|
-
let(:base64) { 'bXl1c2VyOjEyMzQ1Njc4OQ==' }
|
19
|
-
|
20
|
-
it 'it doesn\'t raise when no passwords were generated yet' do
|
21
|
-
assert_nil TestOtpManager.drop_otp('missing', 'password')
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'generates OTPs using SecureRandom.hex and converts them to strings' do
|
25
|
-
otp = 4
|
26
|
-
SecureRandom.stubs(:hex).returns(otp)
|
27
|
-
TestOtpManager.generate_otp(username).must_equal otp.to_s
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'removes OTP only when correct username and password is provided' do
|
31
|
-
otp = TestOtpManager.generate_otp(username)
|
32
|
-
assert_nil TestOtpManager.drop_otp('wrong_username', 'wrong_password')
|
33
|
-
assert_nil TestOtpManager.drop_otp(username, 'wrong_password')
|
34
|
-
assert_nil TestOtpManager.drop_otp('wrong_username', otp)
|
35
|
-
TestOtpManager.drop_otp(username, otp).must_equal otp
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'parses the hash correctly' do
|
39
|
-
SecureRandom.stubs(:hex).returns(password)
|
40
|
-
TestOtpManager.expects(:drop_otp).with(username, password.to_s)
|
41
|
-
TestOtpManager.authenticate(base64)
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'authenticates correctly' do
|
45
|
-
SecureRandom.stubs(:hex).returns(password)
|
46
|
-
generated = TestOtpManager.generate_otp(username)
|
47
|
-
|
48
|
-
TestOtpManager.authenticate(base64).must_equal generated
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'OTPs can be used only once' do
|
52
|
-
SecureRandom.stubs(:hex).returns(password)
|
53
|
-
generated = TestOtpManager.generate_otp(username)
|
54
|
-
|
55
|
-
TestOtpManager.authenticate(base64).must_equal generated
|
56
|
-
assert_nil TestOtpManager.authenticate(base64)
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'creates token from username and password correctly' do
|
60
|
-
TestOtpManager.tokenize(username, password).must_equal base64
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'overwrites old OTP when generating a new one for the same username' do
|
64
|
-
old = TestOtpManager.generate_otp(username)
|
65
|
-
new = TestOtpManager.generate_otp(username)
|
66
|
-
assert_nil TestOtpManager.drop_otp(username, old)
|
67
|
-
TestOtpManager.drop_otp(username, new).must_equal new
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|