foreman-tasks 1.2.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (154) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/js_tests.yml +31 -0
  3. data/.github/workflows/ruby_tests.yml +74 -0
  4. data/.rubocop.yml +12 -4
  5. data/.rubocop_todo.yml +32 -25
  6. data/Gemfile +5 -0
  7. data/README.md +2 -0
  8. data/app/controllers/foreman_tasks/api/tasks_controller.rb +36 -60
  9. data/app/controllers/foreman_tasks/concerns/parameters/triggering.rb +1 -1
  10. data/app/controllers/foreman_tasks/recurring_logics_controller.rb +7 -0
  11. data/app/controllers/foreman_tasks/tasks_controller.rb +6 -3
  12. data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +3 -3
  13. data/app/lib/actions/proxy_action.rb +1 -1
  14. data/app/models/foreman_tasks/recurring_logic.rb +1 -1
  15. data/app/models/foreman_tasks/task.rb +11 -0
  16. data/app/models/foreman_tasks/task/dynflow_task.rb +29 -33
  17. data/app/models/foreman_tasks/task/status_explicator.rb +1 -1
  18. data/app/models/foreman_tasks/triggering.rb +1 -1
  19. data/app/models/setting/foreman_tasks.rb +9 -9
  20. data/app/services/foreman_tasks/dashboard_table_filter.rb +5 -1
  21. data/app/views/foreman_tasks/api/tasks/index.json.rabl +2 -0
  22. data/app/views/foreman_tasks/api/tasks/show.json.rabl +2 -0
  23. data/app/views/foreman_tasks/recurring_logics/index.html.erb +3 -1
  24. data/config/routes.rb +2 -1
  25. data/db/migrate/20200517215015_rename_bookmarks_controller.rb +2 -2
  26. data/db/migrate/20200611090846_add_task_lock_index_on_resource_type_and_task_id.rb +9 -0
  27. data/db/seeds.d/30-notification_blueprints.rb +7 -7
  28. data/db/seeds.d/61-foreman_tasks_bookmarks.rb +1 -1
  29. data/lib/foreman_tasks/cleaner.rb +4 -6
  30. data/lib/foreman_tasks/dynflow/configuration.rb +1 -1
  31. data/lib/foreman_tasks/dynflow/persistence.rb +4 -6
  32. data/lib/foreman_tasks/engine.rb +2 -7
  33. data/lib/foreman_tasks/tasks/cleanup.rake +2 -2
  34. data/lib/foreman_tasks/tasks/dynflow.rake +6 -0
  35. data/lib/foreman_tasks/tasks/export_tasks.rake +1 -1
  36. data/lib/foreman_tasks/version.rb +1 -1
  37. data/locale/en/LC_MESSAGES/foreman_tasks.mo +0 -0
  38. data/locale/en/foreman_tasks.po +50 -20
  39. data/locale/foreman_tasks.pot +173 -126
  40. data/locale/fr/LC_MESSAGES/foreman_tasks.mo +0 -0
  41. data/locale/fr/foreman_tasks.po +817 -0
  42. data/locale/ja/LC_MESSAGES/foreman_tasks.mo +0 -0
  43. data/locale/ja/foreman_tasks.po +817 -0
  44. data/locale/zh_CN/LC_MESSAGES/foreman_tasks.mo +0 -0
  45. data/locale/zh_CN/foreman_tasks.po +816 -0
  46. data/package.json +1 -1
  47. data/script/npm_link_foreman_js.sh +26 -0
  48. data/test/controllers/api/recurring_logics_controller_test.rb +1 -1
  49. data/test/controllers/api/tasks_controller_test.rb +17 -7
  50. data/test/controllers/tasks_controller_test.rb +6 -6
  51. data/test/core/unit/runner_test.rb +20 -20
  52. data/test/core/unit/task_launcher_test.rb +8 -8
  53. data/test/helpers/foreman_tasks/foreman_tasks_helper_test.rb +7 -7
  54. data/test/helpers/foreman_tasks/tasks_helper_test.rb +3 -3
  55. data/test/lib/actions/middleware/keep_current_request_id_test.rb +3 -3
  56. data/test/support/history_tasks_builder.rb +1 -1
  57. data/test/tasks/generate_task_actions_test.rb +1 -1
  58. data/test/unit/actions/action_with_sub_plans_test.rb +2 -2
  59. data/test/unit/actions/bulk_action_test.rb +6 -6
  60. data/test/unit/actions/proxy_action_test.rb +20 -20
  61. data/test/unit/actions/recurring_action_test.rb +30 -32
  62. data/test/unit/cleaner_test.rb +24 -24
  63. data/test/unit/dashboard_table_filter_test.rb +5 -5
  64. data/test/unit/otp_manager_test.rb +2 -2
  65. data/test/unit/proxy_selector_test.rb +9 -9
  66. data/test/unit/recurring_logic_test.rb +32 -32
  67. data/test/unit/remote_task_test.rb +2 -2
  68. data/test/unit/task_groups_test.rb +4 -4
  69. data/test/unit/task_test.rb +18 -18
  70. data/test/unit/triggering_test.rb +8 -8
  71. data/test/unit/troubleshooting_help_generator_test.rb +6 -6
  72. data/test/unit/ui_notifications_test.rb +11 -11
  73. data/webpack/ForemanTasks/Components/TaskActions/TaskAction.test.js +2 -2
  74. data/webpack/ForemanTasks/Components/TaskActions/index.js +1 -1
  75. data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +17 -3
  76. data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +8 -153
  77. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskButtons.js +168 -0
  78. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +6 -7
  79. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskSkeleton.js +48 -0
  80. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +8 -1
  81. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +13 -70
  82. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskButtons.test.js +95 -0
  83. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/RunningSteps.test.js.snap +1 -1
  84. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +78 -208
  85. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskButtons.test.js.snap +212 -0
  86. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +8 -4
  87. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +100 -53
  88. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.scss +3 -14
  89. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +57 -95
  90. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsConstants.js +3 -12
  91. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +57 -28
  92. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.fixtures.js +8 -0
  93. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +8 -1
  94. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +6 -6
  95. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +84 -12
  96. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +25 -21
  97. data/webpack/ForemanTasks/Components/TaskDetails/index.js +8 -3
  98. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.scss +4 -0
  99. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/OtherInfo.js +53 -0
  100. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/OtherInfo.test.js +14 -0
  101. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.js +27 -19
  102. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.scss +14 -0
  103. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.test.js +1 -34
  104. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/{StoppedTasksCardHelper.js → StoppedTasksCardTable.js} +28 -1
  105. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCardTable.test.js +54 -0
  106. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/OtherInfo.test.js.snap +48 -0
  107. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/StoppedTasksCard.test.js.snap +60 -1367
  108. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/StoppedTasksCardTable.test.js.snap +960 -0
  109. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/__snapshots__/TasksCardsGrid.test.js.snap +14 -11
  110. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardActions.js +1 -1
  111. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardConstants.js +2 -0
  112. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardSelectors.js +17 -11
  113. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardActions.test.js +2 -2
  114. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardSelectors.test.js +26 -14
  115. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboard.test.js.snap +14 -11
  116. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboardSelectors.test.js.snap +38 -22
  117. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalSelectors.js +1 -0
  118. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalSelectors.test.js +1 -0
  119. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalSelectors.test.js.snap +2 -0
  120. data/webpack/ForemanTasks/Components/TasksTable/TasksBulkActions.js +25 -8
  121. data/webpack/ForemanTasks/Components/TasksTable/TasksTableActions.js +3 -3
  122. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +6 -2
  123. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSelectors.js +1 -0
  124. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksBulkActions.test.js +15 -2
  125. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +1 -0
  126. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTablePage.test.js +2 -1
  127. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +1 -0
  128. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksBulkActions.test.js.snap +48 -0
  129. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +1 -0
  130. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +39 -5
  131. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionCellFormatter.test.js.snap +1 -0
  132. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/selectionCellFormatter.test.js.snap +2 -0
  133. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/actionCellFormatter.test.js +1 -1
  134. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/selectionCellFormatter.test.js +1 -1
  135. data/webpack/ForemanTasks/Components/TasksTable/formatters/actionCellFormatter.js +10 -7
  136. data/webpack/ForemanTasks/Components/TasksTable/formatters/selectionCellFormatter.js +7 -0
  137. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.js +39 -31
  138. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.test.js +17 -8
  139. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ActionButton.test.js.snap +8 -0
  140. data/webpack/ForemanTasks/Components/common/urlHelpers.js +7 -0
  141. data/webpack/ForemanTasks/ForemanTasksReducers.js +0 -2
  142. data/webpack/__mocks__/foremanReact/common/helpers.js +2 -0
  143. data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +10 -0
  144. data/webpack/__mocks__/foremanReact/redux/API/index.js +10 -0
  145. data/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware.js +5 -0
  146. metadata +29 -11
  147. data/.travis.yml +0 -5
  148. data/script/travis_run_js_tests.sh +0 -7
  149. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsReducer.js +0 -38
  150. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsReducer.test.js +0 -33
  151. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsReducer.test.js.snap +0 -26
  152. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/integration.test.js.snap +0 -122
  153. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/integration.test.js +0 -67
  154. data/webpack/__mocks__/foremanReact/API.js +0 -7
@@ -31,9 +31,12 @@ module ForemanTasks
31
31
 
32
32
  def cancel_step
33
33
  task = find_dynflow_task
34
- flash[:info] = _('Trying to cancel step %s') % params[:step_id]
35
- ForemanTasks.dynflow.world.event(task.external_id, params[:step_id].to_i, ::Dynflow::Action::Cancellable::Cancel).wait
36
- redirect_to foreman_tasks_task_path(task)
34
+ result = ForemanTasks.dynflow.world.event(task.external_id, params[:step_id].to_i, ::Dynflow::Action::Cancellable::Cancel).wait
35
+ if result.rejected?
36
+ render json: { error: result.reason }, status: :bad_request
37
+ else
38
+ render json: { statusText: 'OK' }
39
+ end
37
40
  end
38
41
 
39
42
  def cancel
@@ -82,7 +82,7 @@ module ForemanTasks
82
82
  ' — ',
83
83
  content_tag(:span, nil, :class => 'time', :style => 'white-space: nowrap;') do
84
84
  fields.time_select(attr, datetime_options.merge(:ignore_date => true), html_options)
85
- end
85
+ end,
86
86
  ].join
87
87
  end
88
88
  end
@@ -139,7 +139,7 @@ module ForemanTasks
139
139
  cronline_fieldset(f, triggering),
140
140
  monthly_fieldset(f, triggering),
141
141
  weekly_fieldset(f, triggering),
142
- time_picker_fieldset(f, triggering)
142
+ time_picker_fieldset(f, triggering),
143
143
  ]
144
144
 
145
145
  content_tag(:fieldset, nil, :id => 'trigger_mode_recurring', :class => "trigger_mode_form #{'hidden' unless triggering.recurring?}") do
@@ -158,7 +158,7 @@ module ForemanTasks
158
158
  # TRANSLATORS: this translation is referring to an option which is a time interval
159
159
  _('is month (range: 1-12)'),
160
160
  # TRANSLATORS: this translation is referring to an option which is a time interval
161
- _('is day of week (range: 0-6)')
161
+ _('is day of week (range: 0-6)'),
162
162
  ].map { |opt| content_tag(:li, opt) }.join
163
163
 
164
164
  help = _("Cron line format 'a b c d e', where: %s") % "<br><ol type=\"a\">#{options}</ol>".html_safe
@@ -257,7 +257,7 @@ module Actions
257
257
  if failed_proxy_tasks.count < options[:retry_count]
258
258
  suspend do |suspended_action|
259
259
  @world.clock.ping suspended_action,
260
- Time.zone.now + options[:retry_interval],
260
+ Time.now.getlocal + options[:retry_interval],
261
261
  event
262
262
  end
263
263
  else
@@ -95,7 +95,7 @@ module ForemanTasks
95
95
  :start_at => next_occurrence_time(time),
96
96
  :start_before => options['start_before'],
97
97
  :recurring_logic_id => id,
98
- :frozen => disabled?
98
+ :frozen => disabled?,
99
99
  }
100
100
  end
101
101
 
@@ -70,6 +70,17 @@ module ForemanTasks
70
70
  end)
71
71
  scope :for_action_types, (->(action_types) { where('foreman_tasks_tasks.label IN (?)', Array(action_types)) })
72
72
 
73
+ apipie :class, "A class representing #{model_name.human} object" do
74
+ name 'Task'
75
+ refs 'Task'
76
+ sections only: %w[all additional]
77
+ property :main_action, object_of: 'Dynflow::Action', desc: 'Returns the main action of the task, e.g. Actions::RemoteExecution::RunHostJob'
78
+ property :label, String, desc: 'Returns the label of the task'
79
+ property :state, String, desc: 'Returns state of the task execution, e.g. "stopped"'
80
+ property :result, String, desc: 'Returns result of the task execution, e.g. "success"'
81
+ property :started_at, ActiveSupport::TimeWithZone, desc: 'Returns date with time the task started at'
82
+ property :ended_at, ActiveSupport::TimeWithZone, desc: 'Returns date with time the task ended at'
83
+ end
73
84
  class Jail < Safemode::Jail
74
85
  allow :started_at, :ended_at, :result, :state, :label, :main_action
75
86
  end
@@ -46,7 +46,8 @@ module ForemanTasks
46
46
  end
47
47
 
48
48
  def progress
49
- execution_plan.try(:progress) || 0
49
+ progress_raw = execution_plan.try(:progress) || 0
50
+ progress_raw.round(2)
50
51
  end
51
52
 
52
53
  def execution_plan(silence_exception = true)
@@ -101,31 +102,28 @@ module ForemanTasks
101
102
 
102
103
  def input_output_failed_steps
103
104
  failed_steps.map do |f|
104
- begin
105
- f_action = f.action(execution_plan)
106
- {
107
- error: ({ exception_class: f.error.exception_class, message: f.error.message, backtrace: f.error.backtrace } if f.error),
108
- action_class: f.action_class.name,
109
- state: f.state,
110
- input: f_action.input.pretty_inspect,
111
- output: f_action.output.pretty_inspect
112
- }
113
- end
105
+ f_action = f.action(execution_plan)
106
+ {
107
+ error: ({ exception_class: f.error.exception_class, message: f.error.message, backtrace: f.error.backtrace } if f.error),
108
+ action_class: f.action_class.name,
109
+ state: f.state,
110
+ input: f_action.input.pretty_inspect,
111
+ output: f_action.output.pretty_inspect,
112
+ }
114
113
  end
115
114
  end
116
115
 
117
116
  def input_output_running_steps
118
117
  running_steps.map do |f|
119
- begin
120
- f_action = f.action(execution_plan)
121
- {
122
- action_class: f.action_class.name,
123
- state: f.state,
124
- input: f_action.input.pretty_inspect,
125
- output: f_action.output.pretty_inspect,
126
- cancellable: cancellable_action?(f_action)
127
- }
128
- end
118
+ f_action = f.action(execution_plan)
119
+ {
120
+ id: f_action.id,
121
+ action_class: f.action_class.name,
122
+ state: f.state,
123
+ input: f_action.input.pretty_inspect,
124
+ output: f_action.output.pretty_inspect,
125
+ cancellable: cancellable_action?(f_action),
126
+ }
129
127
  end
130
128
  end
131
129
 
@@ -218,19 +216,17 @@ module ForemanTasks
218
216
  fixed_count = 0
219
217
  logger = Foreman::Logging.logger('foreman-tasks')
220
218
  running.each do |task|
221
- begin
222
- changes = task.update_from_dynflow(task.execution_plan.to_hash)
223
- unless changes.empty?
224
- fixed_count += 1
225
- logger.warn('Task %s updated at consistency check: %s' % [task.id, changes.inspect])
226
- end
227
- rescue => e
228
- # if we fail updating the data from dynflow, it usually means there is something
229
- # odd with the data consistency and at this point it is not possible to resume, switching
230
- # the task to stopped/error
231
- task.update(:state => 'stopped', :result => 'error')
232
- Foreman::Logging.exception("Failed at consistency check for task #{task.id}", e, :logger => 'foreman-tasks')
219
+ changes = task.update_from_dynflow(task.execution_plan.to_hash)
220
+ unless changes.empty?
221
+ fixed_count += 1
222
+ logger.warn('Task %s updated at consistency check: %s' % [task.id, changes.inspect])
233
223
  end
224
+ rescue => e
225
+ # if we fail updating the data from dynflow, it usually means there is something
226
+ # odd with the data consistency and at this point it is not possible to resume, switching
227
+ # the task to stopped/error
228
+ task.update(:state => 'stopped', :result => 'error')
229
+ Foreman::Logging.exception("Failed at consistency check for task #{task.id}", e, :logger => 'foreman-tasks')
234
230
  end
235
231
  fixed_count
236
232
  end
@@ -4,7 +4,7 @@ module ForemanTasks
4
4
  ERRONEOUS_STATUSES = [
5
5
  { :state => 'paused', :result => ANY },
6
6
  { :state => ANY, :result => 'error' },
7
- { :state => ANY, :result => 'warning' }
7
+ { :state => ANY, :result => 'warning' },
8
8
  ].freeze
9
9
  def is_erroneous(task)
10
10
  remainder = ERRONEOUS_STATUSES.select do |status|
@@ -75,7 +75,7 @@ module ForemanTasks
75
75
  def delay_options
76
76
  {
77
77
  :start_at => start_at.utc,
78
- :start_before => start_before.try(:utc)
78
+ :start_before => start_before.try(:utc),
79
79
  }
80
80
  end
81
81
 
@@ -1,23 +1,23 @@
1
1
  class Setting::ForemanTasks < Setting
2
2
  def self.default_settings
3
3
  [
4
- set('foreman_tasks_sync_task_timeout', N_('Number of seconds to wait for synchronous task to finish.'), 120),
5
- set('dynflow_enable_console', N_('Enable the dynflow console (/foreman_tasks/dynflow) for debugging'), true),
6
- set('dynflow_console_require_auth', N_('Require user to be authenticated as user with admin rights when accessing dynflow console'), true),
7
- set('foreman_tasks_proxy_action_retry_count', N_('Number of attempts to start a task on the smart proxy before failing'), 4),
8
- set('foreman_tasks_proxy_action_retry_interval', N_('Time in seconds between retries'), 15),
9
- set('foreman_tasks_proxy_batch_trigger', N_('Allow triggering tasks on the smart proxy in batches'), true),
10
- set('foreman_tasks_proxy_batch_size', N_('Number of tasks which should be sent to the smart proxy in one request, if foreman_tasks_proxy_batch_trigger is enabled'), 100),
4
+ set('foreman_tasks_sync_task_timeout', N_('Number of seconds to wait for synchronous task to finish.'), 120, N_('Sync task timeout')),
5
+ set('dynflow_enable_console', N_('Enable the dynflow console (/foreman_tasks/dynflow) for debugging'), true, N_('Enable dynflow console')),
6
+ set('dynflow_console_require_auth', N_('Require user to be authenticated as user with admin rights when accessing dynflow console'), true, N_('Require auth for dynflow console')),
7
+ set('foreman_tasks_proxy_action_retry_count', N_('Number of attempts to start a task on the smart proxy before failing'), 4, N_('Proxy action retry count')),
8
+ set('foreman_tasks_proxy_action_retry_interval', N_('Time in seconds between retries'), 15, N_('Proxy action retry interval')),
9
+ set('foreman_tasks_proxy_batch_trigger', N_('Allow triggering tasks on the smart proxy in batches'), true, N_('Allow proxy batch tasks')),
10
+ set('foreman_tasks_proxy_batch_size', N_('Number of tasks which should be sent to the smart proxy in one request, if foreman_tasks_proxy_batch_trigger is enabled'), 100, N_('Proxy tasks batch size')),
11
11
  set('foreman_tasks_troubleshooting_url',
12
12
  N_('Url pointing to the task troubleshooting documentation. '\
13
13
  'It should contain %{label} placeholder, that will be replaced with normalized task label '\
14
14
  '(restricted to only alphanumeric characters)). %{version} placeholder is also available.'),
15
- nil),
15
+ nil, N_('Tasks troubleshooting URL')),
16
16
  set('foreman_tasks_polling_multiplier',
17
17
  N_('Polling multiplier which is used to multiply the default polling intervals. '\
18
18
  'This can be used to prevent polling too frequently for long running tasks.'),
19
19
  1,
20
- N_("Polling intervals multiplier"))
20
+ N_("Polling intervals multiplier")),
21
21
  ]
22
22
  end
23
23
 
@@ -24,7 +24,11 @@ module ForemanTasks
24
24
  private
25
25
 
26
26
  def scope_by(field)
27
- @new_scope = @new_scope.where(field => @params[field]) if @params[field].present?
27
+ if (field == :result) && (@params[field] == 'other')
28
+ @new_scope = @new_scope.where(:result => ['cancelled', 'pending'])
29
+ elsif @params[field].present?
30
+ @new_scope = @new_scope.where(field => @params[field])
31
+ end
28
32
  end
29
33
 
30
34
  def scope_by_time
@@ -0,0 +1,2 @@
1
+ collection @tasks
2
+ extends "foreman_tasks/api/tasks/show"
@@ -1,5 +1,7 @@
1
1
  object @task if @task
2
2
 
3
+ extends 'api/v2/layouts/permissions'
4
+
3
5
  attributes :id, :label, :pending, :action
4
6
  attributes :username, :started_at, :ended_at, :state, :result, :progress
5
7
  attributes :input, :output, :humanized, :cli_example, :start_at
@@ -37,6 +37,7 @@
37
37
 
38
38
  <table class="<%= table_css_classes('table-condensed table-fixed') %>">
39
39
  <thead>
40
+ <th class="col-md-1"><%= N_("ID") %></th>
40
41
  <th><%= N_("Cron line") %></th>
41
42
  <th><%= N_("Task count") %></th>
42
43
  <th><%= N_("Action") %></th>
@@ -50,7 +51,8 @@
50
51
  </thead>
51
52
  <% @recurring_logics.each do |recurring_logic| %>
52
53
  <tr>
53
- <td><%= link_to(recurring_logic.cron_line, foreman_tasks_recurring_logic_path(recurring_logic)) %></td>
54
+ <td><%= link_to(recurring_logic.id, foreman_tasks_recurring_logic_path(recurring_logic)) %></td>
55
+ <td><%= recurring_logic.cron_line %></td>
54
56
  <td><%= link_to(recurring_logic.tasks.count, foreman_tasks_tasks_url(:search => "task_group.id = #{recurring_logic.task_group.id}")) %></td>
55
57
  <td><%= format_task_input(recurring_logic.tasks.first) %></td>
56
58
  <td><%= recurring_logic.tasks.order(:started_at).where('started_at IS NOT NULL').last.try(:started_at) || "-" %></td>
@@ -7,6 +7,7 @@ Foreman::Application.routes.draw do
7
7
  put :disable
8
8
  end
9
9
  collection do
10
+ get 'auto_complete_search'
10
11
  post :clear_cancelled
11
12
  end
12
13
  end
@@ -50,7 +51,6 @@ Foreman::Application.routes.draw do
50
51
  resources :tasks, :only => [:show, :index] do
51
52
  member do
52
53
  get :details
53
- get :sub_tasks
54
54
  end
55
55
  collection do
56
56
  post :bulk_search
@@ -58,6 +58,7 @@ Foreman::Application.routes.draw do
58
58
  post :bulk_cancel
59
59
  post :bulk_stop
60
60
  get :summary
61
+ get '/:parent_task_id/sub_tasks', action: 'index'
61
62
  get '/summary/:id/sub_tasks/', action: 'summary_sub_tasks'
62
63
  post :callback
63
64
  end
@@ -3,7 +3,7 @@ class RenameBookmarksController < ActiveRecord::Migration[5.2]
3
3
  original_controller = 'foreman_tasks_tasks'
4
4
  original_bookmarks = Bookmark.where(controller: original_controller)
5
5
  original_bookmarks_names = Hash[original_bookmarks.pluck(:name, :id)]
6
-
6
+
7
7
  new_controller = 'foreman_tasks/tasks'
8
8
  new_bookmarks = Bookmark.where(controller: new_controller)
9
9
  new_bookmarks.find_each do |new_bookmark|
@@ -18,7 +18,7 @@ class RenameBookmarksController < ActiveRecord::Migration[5.2]
18
18
  original_bookmark.public == new_bookmark.public
19
19
 
20
20
  if is_duplicated
21
- original_bookmark.destroy
21
+ original_bookmark.destroy
22
22
  else
23
23
  modified_name = "#{name}_#{generate_token}"
24
24
  original_bookmark.update(name: modified_name)
@@ -0,0 +1,9 @@
1
+ class AddTaskLockIndexOnResourceTypeAndTaskId < ActiveRecord::Migration[6.0]
2
+ def change
3
+ add_index :foreman_tasks_locks, [:task_id, :resource_type, :resource_id], name: 'index_tasks_locks_on_task_id_resource_type_and_resource_id'
4
+ # These indexes are not needed as they can be gained from partial index lookups
5
+ [:task_id, :name, :resource_type].each do |index|
6
+ remove_index :foreman_tasks_locks, index if index_exists?(:foreman_tasks_locks, index)
7
+ end
8
+ end
9
+ end
@@ -9,9 +9,9 @@ blueprints = [
9
9
  links:
10
10
  [
11
11
  href: "/foreman_tasks/tasks?search=#{CGI.escape('state=paused')}",
12
- title: N_('List of tasks')
13
- ]
14
- }
12
+ title: N_('List of tasks'),
13
+ ],
14
+ },
15
15
  },
16
16
 
17
17
  {
@@ -24,9 +24,9 @@ blueprints = [
24
24
  links:
25
25
  [
26
26
  path_method: :foreman_tasks_task_path,
27
- title: N_('Task Details')
28
- ]
29
- }
27
+ title: N_('Task Details'),
28
+ ],
29
+ },
30
30
  },
31
31
 
32
32
  {
@@ -48,7 +48,7 @@ blueprints = [
48
48
  name: 'tasks_bulk_stop',
49
49
  level: 'info',
50
50
  message: "DYNAMIC",
51
- }
51
+ },
52
52
  ]
53
53
 
54
54
  blueprints.each { |blueprint| UINotifications::Seed.new(blueprint).configure }
@@ -1,7 +1,7 @@
1
1
  Bookmark.without_auditing do
2
2
  [
3
3
  { :name => 'running', :query => 'state = running' },
4
- { :name => 'failed', :query => 'state = paused or result = error or result = warning' }
4
+ { :name => 'failed', :query => 'state = paused or result = error or result = warning' },
5
5
 
6
6
  ].each do |item|
7
7
  next if Bookmark.where(:name => item[:name]).first
@@ -30,12 +30,10 @@ module ForemanTasks
30
30
  actions_with_periods = {}
31
31
  if cleanup_settings[:actions]
32
32
  cleanup_settings[:actions].each do |action|
33
- begin
34
- action_class = action[:name].constantize
35
- actions_with_periods[action_class] = action[:after]
36
- rescue => e
37
- Foreman::Logging.exception("Error handling #{action} cleanup settings", e)
38
- end
33
+ action_class = action[:name].constantize
34
+ actions_with_periods[action_class] = action[:after]
35
+ rescue => e
36
+ Foreman::Logging.exception("Error handling #{action} cleanup settings", e)
39
37
  end
40
38
  end
41
39
  (ForemanTasks.dynflow.world.action_classes - actions_with_periods.keys).each do |action_class|
@@ -15,7 +15,7 @@ module ForemanTasks
15
15
  return @backup_settings if @backup_settings
16
16
  backup_options = {
17
17
  :backup_deleted_plans => true,
18
- :backup_dir => default_backup_dir
18
+ :backup_dir => default_backup_dir,
19
19
  }
20
20
  settings = SETTINGS[:'foreman-tasks'] && SETTINGS[:'foreman-tasks'][:backup]
21
21
  backup_options.merge!(settings) if settings
@@ -8,12 +8,10 @@ module ForemanTasks
8
8
  # clear connection only if not running in some active record transaction already
9
9
  clear_connections = ActiveRecord::Base.connection.open_transactions.zero?
10
10
  super.tap do
11
- begin
12
- on_execution_plan_save(execution_plan_id, value)
13
- rescue => e
14
- Foreman::Logging.exception('Error on on_execution_plan_save event', e,
15
- :logger => 'dynflow')
16
- end
11
+ on_execution_plan_save(execution_plan_id, value)
12
+ rescue => e
13
+ Foreman::Logging.exception('Error on on_execution_plan_save event', e,
14
+ :logger => 'dynflow')
17
15
  end
18
16
  ensure
19
17
  ::ActiveRecord::Base.clear_active_connections! if clear_connections
@@ -34,7 +34,7 @@ module ForemanTasks
34
34
 
35
35
  initializer 'foreman_tasks.register_plugin', :before => :finisher_hook do |_app|
36
36
  Foreman::Plugin.register :"foreman-tasks" do
37
- requires_foreman '>= 2.0.0'
37
+ requires_foreman '>= 2.2.0'
38
38
  divider :top_menu, :parent => :monitor_menu, :last => true, :caption => N_('Foreman Tasks')
39
39
  menu :top_menu, :tasks,
40
40
  :url_hash => { :controller => 'foreman_tasks/tasks', :action => :index },
@@ -57,7 +57,7 @@ module ForemanTasks
57
57
 
58
58
  permission :create_recurring_logics, {}, :resource_type => ForemanTasks::RecurringLogic.name
59
59
 
60
- permission :view_recurring_logics, { :'foreman_tasks/recurring_logics' => [:index, :show],
60
+ permission :view_recurring_logics, { :'foreman_tasks/recurring_logics' => [:auto_complete_search, :index, :show],
61
61
  :'foreman_tasks/api/recurring_logics' => [:index, :show] }, :resource_type => ForemanTasks::RecurringLogic.name
62
62
 
63
63
  permission :edit_recurring_logics, { :'foreman_tasks/recurring_logics' => [:cancel, :enable, :disable, :clear_cancelled],
@@ -79,11 +79,6 @@ module ForemanTasks
79
79
  end
80
80
  end
81
81
 
82
- initializer 'foreman_tasks.ignore_dynflow_tables' do |_app|
83
- # Ignore Dynflow tables when schema-dumping. Dynflow tables are handled automatically by Dynflow.
84
- ActiveRecord::SchemaDumper.ignore_tables << /^dynflow_.*$/
85
- end
86
-
87
82
  initializer 'foreman_tasks.apipie' do
88
83
  # this condition is here for compatibility reason to work with Foreman 1.4.x
89
84
  if Apipie.configuration.api_controllers_matcher.is_a?(Array) &&
@@ -14,7 +14,7 @@ namespace :foreman_tasks do
14
14
  If TASK_SEARCH is set then AFTER, STATES can be set and it's used for cleanup. If TASK_SEARCH is not set then
15
15
  the cleanup respects the configuration file and setting AFTER or STATES will throw exception.
16
16
  DESC
17
- task :run => 'environment' do
17
+ task :run => ['environment', 'dynflow:client'] do
18
18
  options = {}
19
19
 
20
20
  options[:filter] = ENV['TASK_SEARCH'] if ENV['TASK_SEARCH']
@@ -38,7 +38,7 @@ namespace :foreman_tasks do
38
38
  end
39
39
 
40
40
  desc 'Show the current configuration for auto-cleanup'
41
- task :config => 'environment' do
41
+ task :config => ['environment', 'dynflow:client'] do
42
42
  if ForemanTasks::Cleaner.cleanup_settings[:after]
43
43
  puts _('The tasks will be deleted after %{after}') % { :after => ForemanTasks::Cleaner.cleanup_settings[:after] }
44
44
  else