foreman-tasks 5.2.2 → 6.0.1
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/.github/workflows/ruby_tests.yml +7 -18
- data/.rubocop.yml +1 -0
- data/app/lib/actions/base.rb +1 -0
- data/app/lib/actions/foreman/host/import_facts.rb +1 -1
- data/app/lib/actions/helpers/lifecycle_logging.rb +1 -1
- data/app/lib/actions/middleware/rails_executor_wrap.rb +2 -2
- data/app/lib/actions/middleware/watch_delegated_proxy_sub_tasks.rb +18 -11
- data/app/lib/actions/proxy_action.rb +2 -2
- data/app/lib/actions/task_synchronization.rb +65 -0
- data/app/lib/actions/trigger_proxy_batch.rb +1 -1
- data/app/models/foreman_tasks/lock.rb +1 -1
- data/app/models/foreman_tasks/remote_task.rb +10 -3
- data/app/models/foreman_tasks/task/dynflow_task.rb +20 -21
- data/app/views/foreman_tasks/api/locks/show.json.rabl +4 -0
- data/config/routes.rb +1 -1
- data/db/migrate/20210708123832_add_parent_task_id_to_remote_tasks.foreman_tasks.rb +5 -0
- data/db/migrate/20211123170430_tasks_settings_to_dsl_category.rb +5 -0
- data/foreman-tasks.gemspec +1 -1
- data/lib/foreman_tasks/dynflow/configuration.rb +1 -6
- data/lib/foreman_tasks/dynflow.rb +1 -1
- data/lib/foreman_tasks/engine.rb +56 -9
- data/lib/foreman_tasks/test_helpers.rb +1 -1
- data/lib/foreman_tasks/version.rb +1 -1
- data/locale/action_names.rb +2 -3
- data/locale/en/foreman_tasks.po +27 -3
- data/locale/foreman_tasks.pot +230 -176
- data/locale/fr/foreman_tasks.po +27 -3
- data/locale/ja/foreman_tasks.po +27 -3
- data/locale/zh_CN/foreman_tasks.po +27 -3
- data/test/controllers/api/tasks_controller_test.rb +1 -2
- data/test/factories/task_factory.rb +1 -1
- data/test/lib/actions/middleware/keep_current_taxonomies_test.rb +9 -1
- data/test/support/dummy_dynflow_action.rb +1 -1
- data/test/support/dummy_proxy_action.rb +1 -1
- data/test/unit/actions/proxy_action_test.rb +19 -13
- data/test/unit/actions/trigger_proxy_batch_test.rb +0 -1
- data/test/unit/troubleshooting_help_generator_test.rb +0 -1
- data/test/unit/ui_notifications_test.rb +0 -1
- data/webpack/ForemanTasks/Components/TaskActions/TaskActionHelpers.js +1 -1
- data/webpack/ForemanTasks/Components/TaskActions/index.js +1 -1
- data/webpack/ForemanTasks/Components/TaskDetails/Components/Locks.js +28 -14
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Locks.test.js.snap +50 -42
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +1 -1
- data/webpack/ForemanTasks/Components/TasksTable/TasksBulkActions.js +1 -1
- data/webpack/ForemanTasks/Components/TasksTable/TasksTable.js +2 -28
- data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +5 -9
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableReducer.js +1 -5
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableSelectors.js +2 -2
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +1 -4
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +1 -6
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +1 -6
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTable.test.js.snap +2 -22
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +2 -12
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableReducer.test.js.snap +1 -4
- data/webpack/ForemanTasks/Components/TasksTable/index.js +2 -2
- data/webpack/__mocks__/foremanReact/components/Pagination/index.js +2 -0
- data/webpack/__mocks__/foremanReact/{redux/actions/toasts.js → components/ToastsList/index.js} +0 -0
- metadata +8 -7
- data/app/models/setting/foreman_tasks.rb +0 -29
- data/lib/foreman_tasks/dynflow/persistence.rb +0 -46
- data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7fe4afd0fbe9eaa5cb5587310ddddd1538453e733b48b6f927e6bc14fa4ad42e
|
4
|
+
data.tar.gz: 27591131ac0329e66625a15c4b512fa7a24b23b3623abdc1eaef40fee7bdea9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 042c221e1f3c01b2d38b2011165479282165846d9b46923b5ef7cc4fc8f91c3ab6ff5921bd229a4a26dbf661dccff3a9d0f0d474e11eb18b074880fc8fc25870
|
7
|
+
data.tar.gz: 4fdf7dfc1836bd8b4ea0490f8c7a894569c7ccf9eca811945b517f7aedface6b04c0c6bbe9c7f34a7b7bbea77328edaadd27ebb624bc29c4acae2eb86bc25624
|
@@ -4,6 +4,7 @@ env:
|
|
4
4
|
RAILS_ENV: test
|
5
5
|
DATABASE_URL: postgresql://postgres:@localhost/test
|
6
6
|
DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL: true
|
7
|
+
BUNDLE_WITHOUT: "journald:development:console:mysql2:sqlite:libvirt"
|
7
8
|
jobs:
|
8
9
|
rubocop:
|
9
10
|
runs-on: ubuntu-latest
|
@@ -13,10 +14,7 @@ jobs:
|
|
13
14
|
uses: ruby/setup-ruby@v1
|
14
15
|
with:
|
15
16
|
ruby-version: 2.7
|
16
|
-
|
17
|
-
run: |
|
18
|
-
gem install bundler
|
19
|
-
bundle install --jobs=3 --retry=3
|
17
|
+
bundler-cache: true
|
20
18
|
- name: Run rubocop
|
21
19
|
run: bundle exec rubocop
|
22
20
|
test_ruby:
|
@@ -43,30 +41,21 @@ jobs:
|
|
43
41
|
- uses: actions/checkout@v2
|
44
42
|
with:
|
45
43
|
path: foreman-tasks
|
44
|
+
- name: Setup Plugin in Foreman
|
45
|
+
run: |
|
46
|
+
echo "gem 'foreman-tasks', path: './foreman-tasks'" > bundler.d/foreman-tasks.local.rb
|
47
|
+
echo "gem 'sqlite3'" >> bundler.d/foreman-tasks.local.rb
|
46
48
|
- name: Setup Ruby
|
47
49
|
uses: ruby/setup-ruby@v1
|
48
50
|
with:
|
49
51
|
ruby-version: ${{ matrix.ruby-version }}
|
52
|
+
bundler-cache: true
|
50
53
|
- name: Setup Node
|
51
54
|
uses: actions/setup-node@v1
|
52
55
|
with:
|
53
56
|
node-version: ${{ matrix.node-version }}
|
54
|
-
- uses: actions/cache@v2
|
55
|
-
with:
|
56
|
-
path: vendor/bundle
|
57
|
-
key: ${{ runner.os }}-fgems-${{ matrix.ruby-version }}-${{ hashFiles('Gemfile.lock') }}
|
58
|
-
restore-keys: |
|
59
|
-
${{ runner.os }}-fgems-${{ matrix.ruby-version }}-
|
60
|
-
- name: Setup Bundler
|
61
|
-
run: |
|
62
|
-
echo "gem 'foreman-tasks', path: './foreman-tasks'" > bundler.d/foreman-tasks.local.rb
|
63
|
-
echo "gem 'sqlite3'" >> bundler.d/foreman-tasks.local.rb
|
64
|
-
gem install bundler
|
65
|
-
bundle config set without journald development console libvirt
|
66
|
-
bundle config set path vendor/bundle
|
67
57
|
- name: Prepare test env
|
68
58
|
run: |
|
69
|
-
bundle install --jobs=3 --retry=3
|
70
59
|
bundle exec rake db:create
|
71
60
|
bundle exec rake db:migrate
|
72
61
|
- name: Run plugin tests
|
data/.rubocop.yml
CHANGED
data/app/lib/actions/base.rb
CHANGED
@@ -26,7 +26,7 @@ module Actions
|
|
26
26
|
def run
|
27
27
|
::User.as :admin do
|
28
28
|
host = ::Host.find(input[:host][:id])
|
29
|
-
state = host.import_facts(input[:facts], proxy)
|
29
|
+
state = ::HostFactImporter.new(host).import_facts(input[:facts], proxy)
|
30
30
|
output[:state] = state
|
31
31
|
end
|
32
32
|
rescue ::Foreman::Exception => e
|
@@ -7,7 +7,7 @@ module Actions
|
|
7
7
|
|
8
8
|
def log_task_state_change(execution_plan)
|
9
9
|
return unless root_action?
|
10
|
-
logger = Rails.application.dynflow.world.action_logger
|
10
|
+
logger = ::Rails.application.dynflow.world.action_logger
|
11
11
|
task_id = ForemanTasks::Task::DynflowTask.where(external_id: execution_plan.id).pluck(:id).first
|
12
12
|
|
13
13
|
task_id_parts = []
|
@@ -10,13 +10,13 @@ module Actions
|
|
10
10
|
# for more details.
|
11
11
|
class RailsExecutorWrap < Dynflow::Middleware
|
12
12
|
def run(*args)
|
13
|
-
Rails.application.executor.wrap do
|
13
|
+
::Rails.application.executor.wrap do
|
14
14
|
pass(*args)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
def finalize
|
19
|
-
Rails.application.executor.wrap do
|
19
|
+
::Rails.application.executor.wrap do
|
20
20
|
pass
|
21
21
|
end
|
22
22
|
end
|
@@ -26,17 +26,26 @@ module Actions
|
|
26
26
|
def check_triggered
|
27
27
|
in_remote_task_batches(remote_tasks.triggered) do |batch|
|
28
28
|
batch.group_by(&:proxy_url).each do |(url, tasks)|
|
29
|
-
|
30
|
-
process_task_results tasks
|
29
|
+
results = poll_proxy_tasks(url, tasks)
|
30
|
+
process_task_results tasks, results
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
def process_task_results(tasks)
|
36
|
-
|
35
|
+
def process_task_results(tasks, results)
|
36
|
+
possibly_missing, present = tasks.partition { |task| !results.key?(task.remote_task_id) }
|
37
|
+
missing = possibly_missing.select do |task|
|
38
|
+
# Really missing are tasks which are missing and:
|
39
|
+
# don't have a remote parent
|
40
|
+
# had a remote parent but the proxy doesn't have the remote parent anymore
|
41
|
+
# has a remote parent, proxy has the remote parent but it is stopped or paused
|
42
|
+
task.parent_task_id.nil? ||
|
43
|
+
!results.key?(task.parent_task_id) ||
|
44
|
+
%(stopped paused).include?(results[task.parent_task_id]['state'])
|
45
|
+
end
|
37
46
|
notify ::Actions::ProxyAction::ProxyActionMissing.new, missing if missing.any?
|
38
47
|
|
39
|
-
stopped = present.select { |task| %w[stopped paused].include? task.
|
48
|
+
stopped = present.select { |task| %w[stopped paused].include? results.dig(task.remote_task_id, 'state') }
|
40
49
|
notify ::Actions::ProxyAction::ProxyActionStopped.new, stopped if stopped.any?
|
41
50
|
end
|
42
51
|
|
@@ -52,15 +61,13 @@ module Actions
|
|
52
61
|
|
53
62
|
def poll_proxy_tasks(url, tasks)
|
54
63
|
proxy = ProxyAPI::ForemanDynflow::DynflowProxy.new(:url => url)
|
55
|
-
|
56
|
-
tasks.map
|
57
|
-
|
58
|
-
task
|
59
|
-
end
|
64
|
+
# Get statuses of tasks and their optional parent tasks
|
65
|
+
ids = (tasks.map(&:remote_task_id) + tasks.map(&:parent_task_id)).uniq
|
66
|
+
proxy.task_states(ids)
|
60
67
|
rescue => e
|
61
68
|
# We could not reach the remote task, we'll try again next time
|
62
69
|
action.action_logger.warn(_('Failed to check on tasks on proxy at %{url}: %{exception}') % { :url => url, :exception => e.message })
|
63
|
-
|
70
|
+
{}
|
64
71
|
end
|
65
72
|
|
66
73
|
def in_remote_task_batches(scope)
|
@@ -67,7 +67,7 @@ module Actions
|
|
67
67
|
def trigger_proxy_task
|
68
68
|
suspend do |_suspended_action|
|
69
69
|
remote_task = prepare_remote_task
|
70
|
-
remote_task.
|
70
|
+
ForemanTasks::RemoteTask.batch_trigger(remote_task.operation, [remote_task])
|
71
71
|
output[:proxy_task_id] = remote_task.remote_task_id
|
72
72
|
end
|
73
73
|
end
|
@@ -263,7 +263,7 @@ module Actions
|
|
263
263
|
end
|
264
264
|
|
265
265
|
def proxy_task_id
|
266
|
-
output[:proxy_task_id]
|
266
|
+
output[:proxy_task_id] || remote_task.try(:remote_task_id) || @execution_plan_id
|
267
267
|
end
|
268
268
|
end
|
269
269
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Actions
|
2
|
+
# Examples:
|
3
|
+
|
4
|
+
# # Action A which emits an event when it successfully finishes.
|
5
|
+
# class A
|
6
|
+
# include ::Actions::ObservableAction
|
7
|
+
# # ... rest ...
|
8
|
+
# end
|
9
|
+
|
10
|
+
# # Action B which emits an event when it successfully finishes or fails.
|
11
|
+
# class B
|
12
|
+
# include ::Actions::ObservableAction
|
13
|
+
#
|
14
|
+
# execution_plan_hooks.use :emit_event_failure, :on => [:failure]
|
15
|
+
#
|
16
|
+
# def self.event_names
|
17
|
+
# super + [event_name_base + '_' + event_name_suffix(:failure)]
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# def emit_event_failure(plan)
|
21
|
+
# emit_event(plan, :failure)
|
22
|
+
# end
|
23
|
+
# # ... rest ...
|
24
|
+
# end
|
25
|
+
module TaskSynchronization
|
26
|
+
def self.included(base)
|
27
|
+
base.execution_plan_hooks.use :sync_execution_plan_to_task, on: ::Dynflow::ExecutionPlan.states
|
28
|
+
end
|
29
|
+
|
30
|
+
def sync_execution_plan_to_task(plan)
|
31
|
+
return unless root_action?
|
32
|
+
on_execution_plan_save(plan)
|
33
|
+
rescue => e
|
34
|
+
::Foreman::Logging.exception('Error on on_execution_plan_save event', e,
|
35
|
+
:logger => 'dynflow')
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def on_execution_plan_save(execution_plan)
|
41
|
+
# We can load the data unless the execution plan was properly planned and saved
|
42
|
+
# including its steps
|
43
|
+
case execution_plan.state
|
44
|
+
when :pending
|
45
|
+
task = ForemanTasks::Task::DynflowTask.new_for_execution_plan(execution_plan)
|
46
|
+
task.start_at ||= Time.zone.now
|
47
|
+
task.save!
|
48
|
+
when :scheduled
|
49
|
+
delayed_plan = world.persistence.load_delayed_plan(execution_plan.id)
|
50
|
+
raise ::Foreman::Exception, 'Plan is delayed but the delay record is missing' if delayed_plan.nil?
|
51
|
+
task = ::ForemanTasks::Task::DynflowTask.find_by!(:external_id => execution_plan.id)
|
52
|
+
task.update_from_dynflow(execution_plan, delayed_plan)
|
53
|
+
when :planning
|
54
|
+
task = ::ForemanTasks::Task::DynflowTask.where(:external_id => execution_plan.id).first
|
55
|
+
task.update_from_dynflow(execution_plan)
|
56
|
+
else
|
57
|
+
if (task = ::ForemanTasks::Task::DynflowTask.where(:external_id => execution_plan.id).first)
|
58
|
+
unless task.state.to_s == execution_plan.state.to_s
|
59
|
+
task.update_from_dynflow(execution_plan)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -37,8 +37,8 @@ module Actions
|
|
37
37
|
# Group the tasks by operation, in theory there should be only one operation
|
38
38
|
batch.group_by(&:operation).each do |operation, group|
|
39
39
|
ForemanTasks::RemoteTask.batch_trigger(operation, group)
|
40
|
+
output[:planned_count] += group.size
|
40
41
|
end
|
41
|
-
output[:planned_count] += batch.size
|
42
42
|
rescue => e
|
43
43
|
action_logger.warn "Could not trigger task on the smart proxy"
|
44
44
|
action_logger.warn e
|
@@ -33,20 +33,27 @@ module ForemanTasks
|
|
33
33
|
:action_class => remote_task.proxy_action_name })
|
34
34
|
end
|
35
35
|
results = group.first.proxy.launch_tasks(operation, input_hash)
|
36
|
-
group.each
|
36
|
+
group.each do |remote_task|
|
37
|
+
remote_task.update_from_batch_trigger results.fetch(remote_task.execution_plan_id, {}),
|
38
|
+
results.fetch('parent', {})
|
39
|
+
end
|
37
40
|
end
|
38
41
|
remote_tasks
|
39
42
|
end
|
40
43
|
|
41
|
-
def update_from_batch_trigger(data)
|
44
|
+
def update_from_batch_trigger(data, parent = {})
|
42
45
|
if data['result'] == 'success'
|
43
46
|
self.remote_task_id = data['task_id']
|
44
47
|
self.state = 'triggered'
|
48
|
+
elsif !parent.empty?
|
49
|
+
self.parent_task_id = parent['task_id']
|
50
|
+
self.state = 'parent-triggered'
|
45
51
|
else
|
46
52
|
# Tell the action the task on the smart proxy stopped
|
47
53
|
ForemanTasks.dynflow.world.event execution_plan_id,
|
48
54
|
step_id,
|
49
|
-
::Actions::ProxyAction::ProxyActionStopped.new
|
55
|
+
::Actions::ProxyAction::ProxyActionStopped.new,
|
56
|
+
optional: true
|
50
57
|
end
|
51
58
|
save!
|
52
59
|
end
|
@@ -5,15 +5,14 @@ module ForemanTasks
|
|
5
5
|
scope :for_action, ->(action_class) { where(label: action_class.name) }
|
6
6
|
after_validation :set_action_field
|
7
7
|
|
8
|
-
def update_from_dynflow(
|
9
|
-
|
10
|
-
self.
|
11
|
-
self.
|
12
|
-
self.
|
13
|
-
self.
|
14
|
-
self.
|
15
|
-
self.
|
16
|
-
self.start_before = string_to_time(utc_zone, data[:start_before]) if data[:start_before]
|
8
|
+
def update_from_dynflow(plan, delayed_plan = nil)
|
9
|
+
self.external_id = plan.id
|
10
|
+
self.result = map_result(plan).to_s
|
11
|
+
self.state = plan.state.to_s
|
12
|
+
self.started_at = plan.started_at unless plan.started_at.nil?
|
13
|
+
self.ended_at = plan.ended_at unless plan.ended_at.nil?
|
14
|
+
self.start_at = delayed_plan.start_at if delayed_plan
|
15
|
+
self.start_before = delayed_plan.start_before if delayed_plan
|
17
16
|
self.parent_task_id ||= begin
|
18
17
|
if main_action.try(:caller_execution_plan_id)
|
19
18
|
DynflowTask.where(:external_id => main_action.caller_execution_plan_id).first!.id
|
@@ -221,7 +220,7 @@ module ForemanTasks
|
|
221
220
|
fixed_count = 0
|
222
221
|
logger = Foreman::Logging.logger('foreman-tasks')
|
223
222
|
running.each do |task|
|
224
|
-
changes = task.update_from_dynflow(task.execution_plan
|
223
|
+
changes = task.update_from_dynflow(task.execution_plan)
|
225
224
|
unless changes.empty?
|
226
225
|
fixed_count += 1
|
227
226
|
logger.warn('Task %s updated at consistency check: %s' % [task.id, changes.inspect])
|
@@ -236,10 +235,10 @@ module ForemanTasks
|
|
236
235
|
fixed_count
|
237
236
|
end
|
238
237
|
|
239
|
-
def self.new_for_execution_plan(
|
240
|
-
new(:external_id =>
|
241
|
-
:state =>
|
242
|
-
:result =>
|
238
|
+
def self.new_for_execution_plan(execution_plan)
|
239
|
+
new(:external_id => execution_plan.id,
|
240
|
+
:state => execution_plan.state.to_s,
|
241
|
+
:result => execution_plan.result.to_s,
|
243
242
|
:user_id => User.current.try(:id))
|
244
243
|
end
|
245
244
|
|
@@ -258,20 +257,20 @@ module ForemanTasks
|
|
258
257
|
self.action = to_label
|
259
258
|
end
|
260
259
|
|
261
|
-
def map_result(
|
262
|
-
if state_result_transitioned?(%w[planned pending], %w[stopped error],
|
263
|
-
(
|
260
|
+
def map_result(plan)
|
261
|
+
if state_result_transitioned?(%w[planned pending], %w[stopped error], plan) ||
|
262
|
+
(plan.result == :error && cancelled?)
|
264
263
|
:cancelled
|
265
264
|
else
|
266
|
-
|
265
|
+
plan.result
|
267
266
|
end
|
268
267
|
end
|
269
268
|
|
270
|
-
def state_result_transitioned?(from, to,
|
269
|
+
def state_result_transitioned?(from, to, plan)
|
271
270
|
oldstate, oldresult = from
|
272
271
|
newstate, newresult = to
|
273
|
-
state == oldstate &&
|
274
|
-
result == oldresult &&
|
272
|
+
state == oldstate && plan.state.to_s == newstate &&
|
273
|
+
result == oldresult && plan.result.to_s == newresult
|
275
274
|
end
|
276
275
|
|
277
276
|
def cancelled?
|
data/config/routes.rb
CHANGED
@@ -70,7 +70,7 @@ Foreman::Application.routes.draw do
|
|
70
70
|
mount ForemanTasks.dynflow.web_console => '/dynflow'
|
71
71
|
if defined? ::Sidekiq
|
72
72
|
require 'sidekiq/web'
|
73
|
-
redis_url = SETTINGS.dig(:dynflow, :redis_url)
|
73
|
+
redis_url = ENV['DYNFLOW_REDIS_URL'] || SETTINGS.dig(:dynflow, :redis_url)
|
74
74
|
Sidekiq.redis = { url: redis_url }
|
75
75
|
Sidekiq::Web.set :sessions, false
|
76
76
|
mount Sidekiq::Web => '/sidekiq', :constraints => ForemanTasks::Dynflow::SidekiqConsoleConstraint.new
|
data/foreman-tasks.gemspec
CHANGED
@@ -26,7 +26,7 @@ same resource. It also optionally provides Dynflow infrastructure for using it f
|
|
26
26
|
s.test_files = `git ls-files test`.split("\n")
|
27
27
|
s.extra_rdoc_files = Dir['README*', 'LICENSE']
|
28
28
|
|
29
|
-
s.add_dependency "dynflow", '>= 1.
|
29
|
+
s.add_dependency "dynflow", '>= 1.6.0'
|
30
30
|
s.add_dependency "get_process_mem" # for memory polling
|
31
31
|
s.add_dependency "parse-cron", '~> 0.1.4'
|
32
32
|
s.add_dependency "sinatra" # for Dynflow web console
|
@@ -1,5 +1,4 @@
|
|
1
|
-
require File.expand_path('lib/foreman/dynflow/configuration', Rails.root)
|
2
|
-
require 'foreman_tasks/dynflow/persistence'
|
1
|
+
require File.expand_path('lib/foreman/dynflow/configuration', ::Rails.root)
|
3
2
|
|
4
3
|
module ForemanTasks
|
5
4
|
# Import all Dynflow configuration from Foreman, and add our own for Tasks
|
@@ -34,9 +33,5 @@ module ForemanTasks
|
|
34
33
|
end
|
35
34
|
options
|
36
35
|
end
|
37
|
-
|
38
|
-
def persistence_class
|
39
|
-
ForemanTasks::Dynflow::Persistence
|
40
|
-
end
|
41
36
|
end
|
42
37
|
end
|
@@ -17,7 +17,7 @@ module ForemanTasks
|
|
17
17
|
set(:custom_navigation) do
|
18
18
|
{ _('Back to tasks') => "/#{ForemanTasks::TasksController.controller_path}" }
|
19
19
|
end
|
20
|
-
set(:world) { Rails.application.dynflow.world }
|
20
|
+
set(:world) { ::Rails.application.dynflow.world }
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
data/lib/foreman_tasks/engine.rb
CHANGED
@@ -5,14 +5,6 @@ module ForemanTasks
|
|
5
5
|
class Engine < ::Rails::Engine
|
6
6
|
engine_name 'foreman_tasks'
|
7
7
|
|
8
|
-
initializer 'foreman_tasks.load_default_settings', :before => :load_config_initializers do
|
9
|
-
require_dependency File.expand_path('../../app/models/setting/foreman_tasks.rb', __dir__) if begin
|
10
|
-
Setting.table_exists?
|
11
|
-
rescue
|
12
|
-
false
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
8
|
assets_to_precompile = %w[foreman_tasks/foreman_tasks.css
|
17
9
|
foreman_tasks/foreman_tasks.js]
|
18
10
|
|
@@ -33,7 +25,7 @@ module ForemanTasks
|
|
33
25
|
|
34
26
|
initializer 'foreman_tasks.register_plugin', :before => :finisher_hook do |_app|
|
35
27
|
Foreman::Plugin.register :"foreman-tasks" do
|
36
|
-
requires_foreman '>= 2.
|
28
|
+
requires_foreman '>= 3.2.0'
|
37
29
|
divider :top_menu, :parent => :monitor_menu, :last => true, :caption => N_('Foreman Tasks')
|
38
30
|
menu :top_menu, :tasks,
|
39
31
|
:url_hash => { :controller => 'foreman_tasks/tasks', :action => :index },
|
@@ -65,6 +57,60 @@ module ForemanTasks
|
|
65
57
|
|
66
58
|
add_all_permissions_to_default_roles
|
67
59
|
|
60
|
+
settings do
|
61
|
+
category(:tasks, N_('Tasks')) do
|
62
|
+
setting('foreman_tasks_sync_task_timeout',
|
63
|
+
type: :integer,
|
64
|
+
description: N_('Number of seconds to wait for synchronous task to finish.'),
|
65
|
+
default: 120,
|
66
|
+
full_name: N_('Sync task timeout'))
|
67
|
+
setting('dynflow_enable_console',
|
68
|
+
type: :boolean,
|
69
|
+
description: N_('Enable the dynflow console (/foreman_tasks/dynflow) for debugging'),
|
70
|
+
default: true,
|
71
|
+
full_name: N_('Enable dynflow console'))
|
72
|
+
setting('dynflow_console_require_auth',
|
73
|
+
type: :boolean,
|
74
|
+
description: N_('Require user to be authenticated as user with admin rights when accessing dynflow console'),
|
75
|
+
default: true,
|
76
|
+
full_name: N_('Require auth for dynflow console'))
|
77
|
+
setting('foreman_tasks_proxy_action_retry_count',
|
78
|
+
type: :integer,
|
79
|
+
description: N_('Number of attempts to start a task on the smart proxy before failing'),
|
80
|
+
default: 4,
|
81
|
+
full_name: N_('Proxy action retry count'))
|
82
|
+
setting('foreman_tasks_proxy_action_retry_interval',
|
83
|
+
type: :integer,
|
84
|
+
description: N_('Time in seconds between retries'),
|
85
|
+
default: 15,
|
86
|
+
full_name: N_('Proxy action retry interval'))
|
87
|
+
setting('foreman_tasks_proxy_batch_trigger',
|
88
|
+
type: :boolean,
|
89
|
+
description: N_('Allow triggering tasks on the smart proxy in batches'),
|
90
|
+
default: true,
|
91
|
+
full_name: N_('Allow proxy batch tasks'))
|
92
|
+
setting('foreman_tasks_proxy_batch_size',
|
93
|
+
type: :integer,
|
94
|
+
description: N_('Number of tasks which should be sent to the smart proxy in one request, if foreman_tasks_proxy_batch_trigger is enabled'),
|
95
|
+
default: 100,
|
96
|
+
full_name: N_('Proxy tasks batch size'))
|
97
|
+
setting('foreman_tasks_troubleshooting_url',
|
98
|
+
type: :string,
|
99
|
+
description: N_('Url pointing to the task troubleshooting documentation. '\
|
100
|
+
'It should contain %{label} placeholder, that will be replaced with normalized task label '\
|
101
|
+
'(restricted to only alphanumeric characters)). %{version} placeholder is also available.'),
|
102
|
+
default: nil,
|
103
|
+
full_name: N_('Tasks troubleshooting URL'))
|
104
|
+
setting('foreman_tasks_polling_multiplier',
|
105
|
+
type: :integer,
|
106
|
+
description: N_('Polling multiplier which is used to multiply the default polling intervals. '\
|
107
|
+
'This can be used to prevent polling too frequently for long running tasks.'),
|
108
|
+
default: 1,
|
109
|
+
full_name: N_("Polling intervals multiplier"),
|
110
|
+
validate: { numericality: { greater_than: 0 } })
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
68
114
|
register_graphql_query_field :task, '::Types::Task', :record_field
|
69
115
|
register_graphql_query_field :tasks, '::Types::Task', :collection_field
|
70
116
|
register_graphql_query_field :recurring_logic, '::Types::RecurringLogic', :record_field
|
@@ -138,6 +184,7 @@ module ForemanTasks
|
|
138
184
|
Authorizer.prepend AuthorizerExt
|
139
185
|
User.include ForemanTasks::Concerns::UserExtensions
|
140
186
|
::Dynflow::Action::Polling.prepend ForemanTasks::Concerns::PollingActionExtensions
|
187
|
+
::Dynflow::ActiveJob::QueueAdapters::JobWrapper.include Actions::TaskSynchronization
|
141
188
|
end
|
142
189
|
|
143
190
|
rake_tasks do
|
@@ -11,7 +11,7 @@ module ForemanTasks
|
|
11
11
|
world_config = ForemanTasks.dynflow.config.world_config
|
12
12
|
if @use_in_memory_sqlite
|
13
13
|
world_config.persistence_adapter = lambda do |*_args|
|
14
|
-
::
|
14
|
+
::Dynflow::PersistenceAdapters::Sequel.new('adapter' => 'sqlite', 'database' => ':memory:')
|
15
15
|
end
|
16
16
|
end
|
17
17
|
@test_in_thread_world = ::Dynflow::Testing::InThreadWorld.new(world_config)
|