foreman-tasks 0.11.3 → 0.12.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 +3 -0
- data/app/controllers/foreman_tasks/concerns/hosts_controller_extension.rb +7 -1
- data/app/controllers/foreman_tasks/tasks_controller.rb +1 -1
- data/app/helpers/foreman_tasks/tasks_helper.rb +2 -1
- data/app/models/foreman_tasks/task.rb +5 -0
- data/app/models/foreman_tasks/task/dynflow_task.rb +5 -0
- data/app/views/foreman_tasks/recurring_logics/index.html.erb +1 -1
- data/app/views/foreman_tasks/task_groups/_common.html.erb +1 -1
- data/app/views/foreman_tasks/task_groups/recurring_logic_task_groups/_recurring_logic_task_group.html.erb +1 -1
- data/app/views/foreman_tasks/tasks/_details.html.erb +2 -1
- data/app/views/foreman_tasks/tasks/dashboard/_latest_tasks_in_error_warning.html.erb +1 -1
- data/app/views/foreman_tasks/tasks/dashboard/_tasks_status.html.erb +1 -1
- data/app/views/foreman_tasks/tasks/index.html.erb +2 -2
- data/db/migrate/20171026082635_add_task_action.foreman_tasks.rb +9 -0
- data/db/migrate/20180216092715_use_uuid.rb +44 -0
- data/lib/foreman_tasks/engine.rb +17 -2
- data/lib/foreman_tasks/tasks/generate_task_actions.rake +41 -0
- data/lib/foreman_tasks/version.rb +1 -1
- data/test/controllers/api/tasks_controller_test.rb +1 -1
- data/test/helpers/foreman_tasks/tasks_helper_test.rb +2 -0
- data/test/support/dummy_proxy_action.rb +6 -3
- data/test/tasks/generate_task_actions_test.rb +43 -0
- data/test/unit/actions/proxy_action_test.rb +2 -2
- data/test/unit/task_test.rb +3 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7c6574c1c5525bc889cdc026a5604229f0807b9
|
4
|
+
data.tar.gz: 4c79cb7a232ea3115f09c06e619667b7a203d821
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a4b956c2dd74d1cd3c20499636bcaf794accdd6442a21565bc2912c8c112827f5c1fdc709334393631e4e1d1d8460e090c6a9ea9a6904c072657a1743d21de0
|
7
|
+
data.tar.gz: 1b31d911db9af5260d56754779c068f53d66a9936e90a73b2b5889cdd2321d6aefdde41bfc6a3e68152d908312e2101c7e1fe971fd4851969bb4d51b11e05e08
|
data/.rubocop.yml
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
module ForemanTasks
|
2
2
|
module Concerns
|
3
3
|
module HostsControllerExtension
|
4
|
-
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
alias_method_chain :facts, :dynflow
|
8
|
+
end
|
9
|
+
|
10
|
+
def facts_with_dynflow
|
5
11
|
task = ForemanTasks.async_task(::Actions::Foreman::Host::ImportFacts,
|
6
12
|
detect_host_type,
|
7
13
|
params[:name],
|
@@ -17,7 +17,7 @@ module ForemanTasks
|
|
17
17
|
render :index
|
18
18
|
end
|
19
19
|
format.csv do
|
20
|
-
csv_response(@tasks, [:
|
20
|
+
csv_response(@tasks, [:action_label, :state, :result, 'started_at.in_time_zone', 'ended_at.in_time_zone', :username], ['Action', 'State', 'Result', 'Started At', 'Ended At', 'User'])
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -36,6 +36,7 @@ module ForemanTasks
|
|
36
36
|
end
|
37
37
|
|
38
38
|
scoped_search :on => :id, :complete_value => false
|
39
|
+
scoped_search :on => :action, :complete_value => false
|
39
40
|
scoped_search :on => :label, :complete_value => true
|
40
41
|
scoped_search :on => :state, :complete_value => true
|
41
42
|
scoped_search :on => :result, :complete_value => true
|
@@ -202,6 +203,10 @@ module ForemanTasks
|
|
202
203
|
result.symbolize_keys
|
203
204
|
end
|
204
205
|
|
206
|
+
def action
|
207
|
+
super || to_label
|
208
|
+
end
|
209
|
+
|
205
210
|
def to_label
|
206
211
|
parts = []
|
207
212
|
parts << get_humanized(:name)
|
@@ -3,6 +3,7 @@ module ForemanTasks
|
|
3
3
|
include Algebrick::TypeCheck
|
4
4
|
|
5
5
|
scope :for_action, ->(action_class) { where(label: action_class.name) }
|
6
|
+
after_validation :set_action_field
|
6
7
|
|
7
8
|
def update_from_dynflow(data)
|
8
9
|
utc_zone = ActiveSupport::TimeZone.new('UTC')
|
@@ -152,6 +153,10 @@ module ForemanTasks
|
|
152
153
|
|
153
154
|
private
|
154
155
|
|
156
|
+
def set_action_field
|
157
|
+
self.action = to_label
|
158
|
+
end
|
159
|
+
|
155
160
|
def map_result(data)
|
156
161
|
if state_result_transitioned?(%w[planned pending], %w[stopped error], data) ||
|
157
162
|
(data[:result] == :error && cancelled?)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<% title _("Recurring logics") %>
|
2
2
|
<% title_actions SETTINGS[:version].short <= '1.13' ? help_path : help_button %>
|
3
3
|
|
4
|
-
<table class="
|
4
|
+
<table class="<%= table_css_classes('table-condensed table-fixed') %>">
|
5
5
|
<thead>
|
6
6
|
<th><%= N_("Cron line") %></th>
|
7
7
|
<th><%= N_("Task count") %></th>
|
@@ -89,7 +89,8 @@
|
|
89
89
|
<div class="col-md-6">
|
90
90
|
<div>
|
91
91
|
<span class="param-name list-group-item-heading"><%= _("Name") %>:</span>
|
92
|
-
|
92
|
+
<% task_label = format_task_input(@task) %>
|
93
|
+
<span class="param-value" data-original-title="<%= task_label %>" rel="twipsy"> <%= truncate(task_label, :length => 50) %></span>
|
93
94
|
</div>
|
94
95
|
<div>
|
95
96
|
<span class="param-name list-group-item-heading"><%= _("Result") %>:</span>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<h4><%= link_to _("Latest Warning/Error Tasks"), foreman_tasks_tasks_path(:order=>'started_at DESC') %></h4>
|
2
|
-
<table class="
|
2
|
+
<table class="<%= table_css_classes('table-fixed') %>">
|
3
3
|
<tr>
|
4
4
|
<th class="col-md-5"><%= _("Name") %></th>
|
5
5
|
<th class="col-md-2"><%= _("State") %></th>
|
@@ -27,8 +27,8 @@ $(document).on('click', ".table-two-pane td.two-pane-link", function(e) {
|
|
27
27
|
<% for task in @tasks %>
|
28
28
|
<tr>
|
29
29
|
<td class="task-id two-pane-link ellipsis">
|
30
|
-
<%= link_to_if_authorized(task
|
31
|
-
|
30
|
+
<%= link_to_if_authorized(format_task_input(task),
|
31
|
+
hash_for_foreman_tasks_task_path(:id => task)) %>
|
32
32
|
</td>
|
33
33
|
<td class="ellipsis"><%= task.state %></td>
|
34
34
|
<td class="ellipsis"><%= task.result %></td>
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class UseUuid < ActiveRecord::Migration[5.0]
|
2
|
+
# PostgreSQL has a special column type for storing UUIDs.
|
3
|
+
# Using this type instead of generic string should lead to having
|
4
|
+
# smaller DB and possibly better overall performance.
|
5
|
+
def up
|
6
|
+
if on_postgresql?
|
7
|
+
change_table :foreman_tasks_tasks do |t|
|
8
|
+
t.change :id, :uuid, :using => 'id::uuid'
|
9
|
+
t.change :parent_task_id, :uuid, :using => 'parent_task_id::uuid'
|
10
|
+
end
|
11
|
+
|
12
|
+
change_table :foreman_tasks_task_group_members do |t|
|
13
|
+
t.change :task_id, :uuid, :using => 'task_id::uuid'
|
14
|
+
end
|
15
|
+
|
16
|
+
change_table :foreman_tasks_locks do |t|
|
17
|
+
t.change :task_id, :uuid, :using => 'task_id::uuid'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def down
|
23
|
+
if on_postgresql?
|
24
|
+
change_table :foreman_tasks_tasks do |t|
|
25
|
+
t.change :id, :string
|
26
|
+
t.change :parent_task_id, :string
|
27
|
+
end
|
28
|
+
|
29
|
+
change_table :foreman_tasks_task_group_members do |t|
|
30
|
+
t.change :task_id, :string
|
31
|
+
end
|
32
|
+
|
33
|
+
change_table :foreman_tasks_locks do |t|
|
34
|
+
t.change :task_id, :string
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def on_postgresql?
|
42
|
+
ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
|
43
|
+
end
|
44
|
+
end
|
data/lib/foreman_tasks/engine.rb
CHANGED
@@ -133,7 +133,7 @@ module ForemanTasks
|
|
133
133
|
# to enable async Foreman operations using Dynflow
|
134
134
|
if ENV['FOREMAN_TASKS_MONKEYS'] == 'true'
|
135
135
|
config.to_prepare do
|
136
|
-
::Api::V2::HostsController.send :
|
136
|
+
::Api::V2::HostsController.send :include, ForemanTasks::Concerns::HostsControllerExtension
|
137
137
|
::Host::Base.send :include, ForemanTasks::Concerns::HostActionSubject
|
138
138
|
end
|
139
139
|
end
|
@@ -144,8 +144,23 @@ module ForemanTasks
|
|
144
144
|
Authorizer.send(:prepend, AuthorizerExt)
|
145
145
|
end
|
146
146
|
|
147
|
+
config.after_initialize do
|
148
|
+
ForemanTasks.dynflow.eager_load_actions!
|
149
|
+
ForemanTasks.dynflow.config.increase_db_pool_size
|
150
|
+
|
151
|
+
unless ForemanTasks.dynflow.config.lazy_initialization
|
152
|
+
if defined?(PhusionPassenger)
|
153
|
+
PhusionPassenger.on_event(:starting_worker_process) do |forked|
|
154
|
+
ForemanTasks.dynflow.initialize! if forked
|
155
|
+
end
|
156
|
+
else
|
157
|
+
ForemanTasks.dynflow.initialize!
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
147
162
|
rake_tasks do
|
148
|
-
%w[dynflow.rake test.rake export_tasks.rake cleanup.rake].each do |rake_file|
|
163
|
+
%w[dynflow.rake test.rake export_tasks.rake cleanup.rake generate_task_actions.rake].each do |rake_file|
|
149
164
|
full_path = File.expand_path("../tasks/#{rake_file}", __FILE__)
|
150
165
|
load full_path if File.exist?(full_path)
|
151
166
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#
|
2
|
+
# generate_task_actions.rake is a data migration task to properly fill the missing
|
3
|
+
# values into the foreman_tasks_tasks table.
|
4
|
+
#
|
5
|
+
# Run "foreman-rake foreman_tasks:generate_task_actions" to generate missing values.
|
6
|
+
|
7
|
+
namespace :foreman_tasks do
|
8
|
+
desc 'Generate missing values for action column in foreman_tasks_tasks table.'
|
9
|
+
|
10
|
+
BATCH_SIZE = 100
|
11
|
+
|
12
|
+
task :generate_task_actions => :environment do
|
13
|
+
class ProgressReporter
|
14
|
+
def initialize(count, message = nil)
|
15
|
+
@count = count
|
16
|
+
@processed = 0
|
17
|
+
puts message % { :count => count } unless message.nil?
|
18
|
+
end
|
19
|
+
|
20
|
+
def progress(count)
|
21
|
+
@processed += count
|
22
|
+
end
|
23
|
+
|
24
|
+
def report
|
25
|
+
puts _('Processed %{processed}/%{count} tasks') % { :processed => @processed, :count => @count }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
scope = ::ForemanTasks::Task.where(:action => nil).order(:started_at => :desc)
|
30
|
+
count = scope.count
|
31
|
+
reporter = ProgressReporter.new count, _('Generating action for %{count} tasks.')
|
32
|
+
scope.find_in_batches(:batch_size => BATCH_SIZE) do |group|
|
33
|
+
group.each do |task|
|
34
|
+
task.action = task.to_label
|
35
|
+
task.save!
|
36
|
+
end
|
37
|
+
reporter.progress group.size
|
38
|
+
reporter.report
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -41,7 +41,7 @@ module ForemanTasks
|
|
41
41
|
task.reload
|
42
42
|
task.state.must_equal 'stopped'
|
43
43
|
task.result.must_equal 'success'
|
44
|
-
task.main_action.output['proxy_task_id'].must_equal
|
44
|
+
task.main_action.output['proxy_task_id'].must_equal Support::DummyProxyAction.proxy.uuid
|
45
45
|
task.main_action.output['proxy_output'].must_equal('result' => 'success')
|
46
46
|
end
|
47
47
|
end
|
@@ -8,6 +8,7 @@ module ForemanTasks
|
|
8
8
|
humanized = { :humanized_name => 'Create', :humanized_input => [[:user, { :text => "user 'Anonymous Admin'", :link => nil }]] }
|
9
9
|
@task.instance_variable_set('@humanized_cache', humanized)
|
10
10
|
@task.stubs(:input).returns('user' => { 'id' => 1, 'name' => 'Anonymous Admin' }, 'locale' => 'en')
|
11
|
+
@task.stubs(:action).returns(@task.to_label)
|
11
12
|
end
|
12
13
|
|
13
14
|
it 'formats the task input properly' do
|
@@ -31,6 +32,7 @@ module ForemanTasks
|
|
31
32
|
'cp_id' => '1412251033866',
|
32
33
|
'locale' => 'en' }
|
33
34
|
@task.stubs(:input).returns(input)
|
35
|
+
@task.stubs(:action).returns(@task.to_label)
|
34
36
|
end
|
35
37
|
|
36
38
|
it 'formats the task input properly' do
|
@@ -1,17 +1,20 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
1
3
|
module Support
|
2
4
|
class DummyProxyAction < Actions::ProxyAction
|
3
5
|
class DummyProxy
|
4
|
-
attr_reader :log, :task_triggered
|
6
|
+
attr_reader :log, :task_triggered, :uuid
|
5
7
|
|
6
8
|
def initialize
|
7
9
|
@log = Hash.new { |h, k| h[k] = [] }
|
8
10
|
@task_triggered = Concurrent.future
|
11
|
+
@uuid = SecureRandom.uuid
|
9
12
|
end
|
10
13
|
|
11
14
|
def trigger_task(*args)
|
12
15
|
@log[:trigger_task] << args
|
13
16
|
@task_triggered.success(true)
|
14
|
-
{ 'task_id' =>
|
17
|
+
{ 'task_id' => @uuid }
|
15
18
|
end
|
16
19
|
|
17
20
|
def cancel_task(*args)
|
@@ -36,7 +39,7 @@ module Support
|
|
36
39
|
def task
|
37
40
|
super
|
38
41
|
rescue ActiveRecord::RecordNotFound
|
39
|
-
ForemanTasks::Task::DynflowTask.new.tap { |task| task.id =
|
42
|
+
ForemanTasks::Task::DynflowTask.new.tap { |task| task.id = proxy.uuid }
|
40
43
|
end
|
41
44
|
|
42
45
|
class << self
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'foreman_tasks_test_helper'
|
3
|
+
|
4
|
+
class GenerateTaskActionsTest < ActiveSupport::TestCase
|
5
|
+
TASK_NAME = 'foreman_tasks:generate_task_actions'.freeze
|
6
|
+
|
7
|
+
setup do
|
8
|
+
Rake.application.rake_require 'foreman_tasks/tasks/generate_task_actions'
|
9
|
+
|
10
|
+
Rake::Task.define_task(:environment)
|
11
|
+
Rake::Task[TASK_NAME].reenable
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:tasks) do
|
15
|
+
(1..5).map { FactoryBot.build(:dynflow_task) }
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'fixes the tasks' do
|
19
|
+
label = 'a label'
|
20
|
+
tasks
|
21
|
+
ForemanTasks::Task.update_all(:action => nil)
|
22
|
+
ForemanTasks::Task.any_instance.stubs(:to_label).returns(label)
|
23
|
+
|
24
|
+
stdout, _stderr = capture_io do
|
25
|
+
Rake.application.invoke_task TASK_NAME
|
26
|
+
end
|
27
|
+
|
28
|
+
assert_match(%r{Generating action for #{tasks.count} tasks}, stdout)
|
29
|
+
ForemanTasks::Task.where(:action => label).count.must_equal tasks.count
|
30
|
+
assert_match(%r{Processed #{tasks.count}/#{tasks.count} tasks}, stdout)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'fixes only tasks with missing action' do
|
34
|
+
tasks
|
35
|
+
ForemanTasks::Task.any_instance.expects(:save!).never
|
36
|
+
|
37
|
+
stdout, _stderr = capture_io do
|
38
|
+
Rake.application.invoke_task TASK_NAME
|
39
|
+
end
|
40
|
+
|
41
|
+
assert_match(%r{Generating action for 0 tasks}, stdout)
|
42
|
+
end
|
43
|
+
end
|
@@ -29,7 +29,7 @@ module ForemanTasks
|
|
29
29
|
{ 'retry_interval' => 15, 'retry_count' => 4, 'timeout' => 60 },
|
30
30
|
'proxy_url' => 'proxy.example.com',
|
31
31
|
'proxy_action_name' => 'Proxy::DummyAction',
|
32
|
-
'callback' => { 'task_id' =>
|
32
|
+
'callback' => { 'task_id' => Support::DummyProxyAction.proxy.uuid, 'step_id' => @action.run_step_id } }]
|
33
33
|
proxy_call.must_equal(expected_call)
|
34
34
|
end
|
35
35
|
end
|
@@ -52,7 +52,7 @@ module ForemanTasks
|
|
52
52
|
describe 'cancel' do
|
53
53
|
it 'sends the cancel event to the proxy when the cancel event is sent for the first time' do
|
54
54
|
action = run_action(@action, ::Dynflow::Action::Cancellable::Cancel)
|
55
|
-
Support::DummyProxyAction.proxy.log[:cancel_task].first.must_equal [
|
55
|
+
Support::DummyProxyAction.proxy.log[:cancel_task].first.must_equal [Support::DummyProxyAction.proxy.uuid]
|
56
56
|
action.state.must_equal :suspended
|
57
57
|
end
|
58
58
|
|
data/test/unit/task_test.rb
CHANGED
@@ -58,9 +58,11 @@ class TasksTest < ActiveSupport::TestCase
|
|
58
58
|
|
59
59
|
describe 'task without valid execution plan' do
|
60
60
|
let(:task) do
|
61
|
-
FactoryBot.create(:dynflow_task).tap do |task|
|
61
|
+
task = FactoryBot.create(:dynflow_task).tap do |task|
|
62
62
|
task.external_id = 'missing-task'
|
63
|
+
task.save
|
63
64
|
end
|
65
|
+
ForemanTasks::Task.find(task.id)
|
64
66
|
end
|
65
67
|
|
66
68
|
it 'handles the error while loading the task and does not propagate errors unless necessary' do
|
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.12.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: 2018-
|
11
|
+
date: 2018-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: foreman-tasks-core
|
@@ -200,6 +200,8 @@ files:
|
|
200
200
|
- db/migrate/20160920151810_add_more_lock_indexes.rb
|
201
201
|
- db/migrate/20160924213030_change_tasks_widget_names.rb
|
202
202
|
- db/migrate/20161003091412_add_missing_indexes.rb
|
203
|
+
- db/migrate/20171026082635_add_task_action.foreman_tasks.rb
|
204
|
+
- db/migrate/20180216092715_use_uuid.rb
|
203
205
|
- db/seeds.d/20-foreman_tasks_permissions.rb
|
204
206
|
- db/seeds.d/60-dynflow_proxy_feature.rb
|
205
207
|
- db/seeds.d/61-foreman_tasks_bookmarks.rb
|
@@ -220,6 +222,7 @@ files:
|
|
220
222
|
- lib/foreman_tasks/task_error.rb
|
221
223
|
- lib/foreman_tasks/tasks/cleanup.rake
|
222
224
|
- lib/foreman_tasks/tasks/export_tasks.rake
|
225
|
+
- lib/foreman_tasks/tasks/generate_task_actions.rake
|
223
226
|
- lib/foreman_tasks/test_extensions.rb
|
224
227
|
- lib/foreman_tasks/test_helpers.rb
|
225
228
|
- lib/foreman_tasks/triggers.rb
|
@@ -243,6 +246,7 @@ files:
|
|
243
246
|
- test/support/dummy_dynflow_action.rb
|
244
247
|
- test/support/dummy_proxy_action.rb
|
245
248
|
- test/support/dummy_task_group.rb
|
249
|
+
- test/tasks/generate_task_actions_test.rb
|
246
250
|
- test/unit/actions/action_with_sub_plans_test.rb
|
247
251
|
- test/unit/actions/proxy_action_test.rb
|
248
252
|
- test/unit/cleaner_test.rb
|
@@ -291,6 +295,7 @@ test_files:
|
|
291
295
|
- test/support/dummy_dynflow_action.rb
|
292
296
|
- test/support/dummy_proxy_action.rb
|
293
297
|
- test/support/dummy_task_group.rb
|
298
|
+
- test/tasks/generate_task_actions_test.rb
|
294
299
|
- test/unit/actions/action_with_sub_plans_test.rb
|
295
300
|
- test/unit/actions/proxy_action_test.rb
|
296
301
|
- test/unit/cleaner_test.rb
|