foreman-tasks 0.16.0 → 0.16.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/.babelrc +4 -1
- data/.eslintrc +4 -13
- data/app/assets/stylesheets/foreman_tasks/application.css.scss +0 -37
- data/app/controllers/foreman_tasks/api/tasks_controller.rb +9 -5
- data/app/controllers/foreman_tasks/tasks_controller.rb +23 -19
- data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +28 -29
- data/app/lib/actions/bulk_action.rb +1 -1
- data/app/models/foreman_tasks/task.rb +1 -1
- data/app/models/foreman_tasks/task/dynflow_task.rb +30 -0
- data/app/services/foreman_tasks/troubleshooting_help_generator.rb +4 -0
- data/app/views/foreman_tasks/api/tasks/details.json.rabl +18 -0
- data/app/views/foreman_tasks/layouts/react.html.erb +1 -1
- data/app/views/foreman_tasks/tasks/index.html.erb +3 -0
- data/app/views/foreman_tasks/tasks/show.html.erb +10 -134
- data/config/routes.rb +3 -0
- data/lib/foreman_tasks/engine.rb +1 -1
- data/lib/foreman_tasks/tasks/export_tasks.rake +1 -2
- data/lib/foreman_tasks/version.rb +1 -1
- data/package.json +6 -20
- data/test/controllers/tasks_controller_test.rb +11 -0
- data/test/helpers/foreman_tasks/foreman_tasks_helper_test.rb +39 -0
- data/test/unit/actions/bulk_action_test.rb +2 -0
- data/test/unit/task_test.rb +4 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/Errors.js +60 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/Locks.js +46 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/Raw.js +73 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +55 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +202 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskHelper.js +38 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +238 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Errors.test.js +36 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Locks.test.js +28 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Raw.test.js +27 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +29 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +18 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskHelper.test.js +77 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskInfo.test.js +60 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Errors.test.js.snap +77 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Locks.test.js.snap +108 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Raw.test.js.snap +174 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/RunningSteps.test.js.snap +62 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +282 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskHelper.test.js.snap +37 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +568 -0
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +87 -0
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.scss +63 -0
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.stories.js +5 -0
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +109 -0
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsConstants.js +18 -0
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsReducer.js +44 -0
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +83 -0
- data/webpack/ForemanTasks/Components/TaskDetails/TasksDetailsHelper.js +1 -0
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +12 -0
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +20 -0
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsReducer.test.js +33 -0
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +97 -0
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +43 -0
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsReducer.test.js.snap +26 -0
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/integration.test.js.snap +122 -0
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/integration.test.js +63 -0
- data/webpack/ForemanTasks/Components/TaskDetails/index.js +77 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/PausedTasksCard/PausedTasksCard.js +6 -1
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/PausedTasksCard/__snapshots__/PausedTasksCard.test.js.snap +2 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/RunningTasksCard/RunningTasksCard.js +6 -1
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/RunningTasksCard/__snapshots__/RunningTasksCard.test.js.snap +2 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.js +3 -6
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.scss +0 -3
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/__snapshots__/ScheduledTasksCard.test.js.snap +3 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.js +2 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.scss +0 -4
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCardHelper.js +3 -3
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/StoppedTasksCard.test.js.snap +495 -54
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.js +1 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.scss +6 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/TasksDonutChart.scss +0 -3
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksLabelsRow/TasksLabelsRow.scss +1 -1
- data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboard.scss +2 -2
- data/webpack/ForemanTasks/Components/common/ClickConfirmation/index.js +83 -0
- data/webpack/ForemanTasks/ForemanTasksReducers.js +2 -0
- data/webpack/__mocks__/foremanReact/common/I18n.js +2 -0
- data/webpack/__mocks__/foremanReact/components/Layout/LayoutActions.js +2 -0
- data/webpack/index.js +5 -0
- metadata +46 -9
- data/app/views/foreman_tasks/tasks/_details.html.erb +0 -195
- data/app/views/foreman_tasks/tasks/_errors.html.erb +0 -42
- data/app/views/foreman_tasks/tasks/_locks.html.erb +0 -19
- data/app/views/foreman_tasks/tasks/_raw.html.erb +0 -28
- data/app/views/foreman_tasks/tasks/_running_steps.html.erb +0 -40
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 75231de648b74702c80ca64886f1d6c19caf3a7920d547807f892e130194cedb
|
|
4
|
+
data.tar.gz: bf5f7331818981dbf841c3a696e0e768bec3328b9e349df13532d1757bbe86a9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8699acec8437f71f4fb52fb89a79dc96857cb08cd09375c7d33d9d4e72d67de8e95ee53352b14f1f80f1a62b880943df996d6fca16a666022ca030dcfdb4cd7d
|
|
7
|
+
data.tar.gz: fc3e36ab57cadf68fa033a4224890c2fdc71a76e18d782b0758cac2bef7748a2cc5e3f30b3f7a37641cb2b9f3ff8d1c79f3b2d2e90cfb0e2050381f04e2a7794
|
data/.babelrc
CHANGED
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
"transform-class-properties",
|
|
14
14
|
"transform-object-rest-spread",
|
|
15
15
|
"transform-object-assign",
|
|
16
|
-
"lodash",
|
|
17
16
|
"syntax-dynamic-import"
|
|
18
17
|
],
|
|
19
18
|
"env": {
|
|
20
19
|
"test": {
|
|
20
|
+
"presets": ["@theforeman/vendor-dev/babel.preset.js"],
|
|
21
21
|
"plugins": [
|
|
22
22
|
["module-resolver", {
|
|
23
23
|
"alias": {
|
|
@@ -27,6 +27,9 @@
|
|
|
27
27
|
}],
|
|
28
28
|
"dynamic-import-node"
|
|
29
29
|
]
|
|
30
|
+
},
|
|
31
|
+
"storybook": {
|
|
32
|
+
"presets": ["@theforeman/vendor-dev/babel.preset.js"]
|
|
30
33
|
}
|
|
31
34
|
}
|
|
32
35
|
}
|
data/.eslintrc
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"plugins": ["patternfly-react"],
|
|
3
|
-
"extends": [
|
|
3
|
+
"extends": [
|
|
4
|
+
"plugin:patternfly-react/recommended",
|
|
5
|
+
"./node_modules/@theforeman/vendor-dev/eslint.extends.js"
|
|
6
|
+
],
|
|
4
7
|
"rules": {
|
|
5
8
|
"prettier/prettier": ["error", {
|
|
6
9
|
"singleQuote": true,
|
|
@@ -17,17 +20,5 @@
|
|
|
17
20
|
"import/resolver": {
|
|
18
21
|
"babel-module": {}
|
|
19
22
|
}
|
|
20
|
-
},
|
|
21
|
-
"globals": {
|
|
22
|
-
"document": false,
|
|
23
|
-
"escape": false,
|
|
24
|
-
"navigator": false,
|
|
25
|
-
"unescape": false,
|
|
26
|
-
"window": false,
|
|
27
|
-
"$": true,
|
|
28
|
-
"_": true,
|
|
29
|
-
"__": true,
|
|
30
|
-
"n__": true,
|
|
31
|
-
"d3": true
|
|
32
23
|
}
|
|
33
24
|
}
|
|
@@ -12,43 +12,6 @@
|
|
|
12
12
|
*= require_tree .
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
.spin {
|
|
16
|
-
-webkit-animation: spin 1s infinite linear;
|
|
17
|
-
-moz-animation: spin 1s infinite linear;
|
|
18
|
-
-o-animation: spin 1s infinite linear;
|
|
19
|
-
animation: spin 1s infinite linear;
|
|
20
|
-
-webkit-transform-origin: 50% 50%;
|
|
21
|
-
transform-origin: 50% 50%;
|
|
22
|
-
-ms-transform-origin: 50% 50%; /* IE 9 */
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
@-moz-keyframes spin {
|
|
26
|
-
from {
|
|
27
|
-
-moz-transform: rotate(0deg);
|
|
28
|
-
}
|
|
29
|
-
to {
|
|
30
|
-
-moz-transform: rotate(360deg);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
@-webkit-keyframes spin {
|
|
35
|
-
from {
|
|
36
|
-
-webkit-transform: rotate(0deg);
|
|
37
|
-
}
|
|
38
|
-
to {
|
|
39
|
-
-webkit-transform: rotate(360deg);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
@keyframes spin {
|
|
44
|
-
from {
|
|
45
|
-
transform: rotate(0deg);
|
|
46
|
-
}
|
|
47
|
-
to {
|
|
48
|
-
transform: rotate(360deg);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
15
|
div.form-group div.trigger_fields {
|
|
53
16
|
margin-top: 15px;
|
|
54
17
|
}
|
|
@@ -16,7 +16,7 @@ module ForemanTasks
|
|
|
16
16
|
class BadRequest < Apipie::ParamError
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
before_action :find_task, :only => [:show]
|
|
19
|
+
before_action :find_task, :only => [:show, :details]
|
|
20
20
|
|
|
21
21
|
api :GET, '/tasks/summary', 'Show task summary'
|
|
22
22
|
def summary
|
|
@@ -27,6 +27,10 @@ module ForemanTasks
|
|
|
27
27
|
param :id, :identifier, desc: 'UUID of the task'
|
|
28
28
|
def show; end
|
|
29
29
|
|
|
30
|
+
api :GET, '/tasks/:id/details', 'Show task extended details'
|
|
31
|
+
param :id, :identifier, desc: 'UUID of the task'
|
|
32
|
+
def details; end
|
|
33
|
+
|
|
30
34
|
api :POST, '/tasks/bulk_search', 'List dynflow tasks for uuids'
|
|
31
35
|
param :searches, Array, :desc => 'List of uuids to fetch info about' do
|
|
32
36
|
param :search_id, String, :desc => <<-DESC
|
|
@@ -117,10 +121,10 @@ module ForemanTasks
|
|
|
117
121
|
param :order, String, :desc => N_('How to order the sorted results (e.g. ASC for ascending)')
|
|
118
122
|
end
|
|
119
123
|
def index
|
|
120
|
-
scope = resource_scope.search_for(params[:search]).select('DISTINCT foreman_tasks_tasks.*')
|
|
121
|
-
|
|
122
124
|
total = resource_scope.count
|
|
123
|
-
subtotal =
|
|
125
|
+
subtotal = resource_scope.search_for(params[:search]).select('DISTINCT foreman_tasks_tasks.id').count
|
|
126
|
+
|
|
127
|
+
scope = resource_scope.search_for(params[:search]).select('DISTINCT foreman_tasks_tasks.*')
|
|
124
128
|
|
|
125
129
|
ordering_params = {
|
|
126
130
|
sort_by: params[:sort_by] || 'started_at',
|
|
@@ -276,7 +280,7 @@ module ForemanTasks
|
|
|
276
280
|
|
|
277
281
|
def action_permission
|
|
278
282
|
case params[:action]
|
|
279
|
-
when 'bulk_search', 'summary'
|
|
283
|
+
when 'bulk_search', 'summary', 'details'
|
|
280
284
|
:view
|
|
281
285
|
when 'bulk_resume'
|
|
282
286
|
:edit
|
|
@@ -12,16 +12,7 @@ module ForemanTasks
|
|
|
12
12
|
|
|
13
13
|
def index
|
|
14
14
|
params[:order] ||= 'started_at DESC'
|
|
15
|
-
|
|
16
|
-
format.html do
|
|
17
|
-
@tasks = filter(resource_base)
|
|
18
|
-
render :index, layout: !request.xhr?
|
|
19
|
-
end
|
|
20
|
-
format.csv do
|
|
21
|
-
@tasks = filter(resource_base, paginate: false)
|
|
22
|
-
csv_response(@tasks, [:id, :action, :state, :result, 'started_at.in_time_zone', 'ended_at.in_time_zone', :username], ['Id', 'Action', 'State', 'Result', 'Started At', 'Ended At', 'User'])
|
|
23
|
-
end
|
|
24
|
-
end
|
|
15
|
+
respond_with_tasks resource_base
|
|
25
16
|
end
|
|
26
17
|
|
|
27
18
|
def summary
|
|
@@ -29,14 +20,14 @@ module ForemanTasks
|
|
|
29
20
|
end
|
|
30
21
|
|
|
31
22
|
def sub_tasks
|
|
32
|
-
task
|
|
33
|
-
@
|
|
34
|
-
|
|
23
|
+
# @task is used when rendering breadcrumbs
|
|
24
|
+
@task = resource_base.find(params[:id])
|
|
25
|
+
respond_with_tasks @task.sub_tasks
|
|
35
26
|
end
|
|
36
27
|
|
|
37
28
|
def cancel_step
|
|
38
29
|
task = find_dynflow_task
|
|
39
|
-
flash[:
|
|
30
|
+
flash[:info] = _('Trying to cancel step %s') % params[:step_id]
|
|
40
31
|
ForemanTasks.dynflow.world.event(task.external_id, params[:step_id].to_i, ::Dynflow::Action::Cancellable::Cancel).wait
|
|
41
32
|
redirect_to foreman_tasks_task_path(task)
|
|
42
33
|
end
|
|
@@ -44,7 +35,7 @@ module ForemanTasks
|
|
|
44
35
|
def cancel
|
|
45
36
|
task = find_dynflow_task
|
|
46
37
|
if task.cancel
|
|
47
|
-
flash[:
|
|
38
|
+
flash[:info] = _('Trying to cancel the task')
|
|
48
39
|
else
|
|
49
40
|
flash[:warning] = _('The task cannot be cancelled at the moment.')
|
|
50
41
|
end
|
|
@@ -54,7 +45,7 @@ module ForemanTasks
|
|
|
54
45
|
def abort
|
|
55
46
|
task = find_dynflow_task
|
|
56
47
|
if task.abort
|
|
57
|
-
flash[:
|
|
48
|
+
flash[:info] = _('Trying to abort the task')
|
|
58
49
|
else
|
|
59
50
|
flash[:warning] = _('The task cannot be aborted at the moment.')
|
|
60
51
|
end
|
|
@@ -65,7 +56,7 @@ module ForemanTasks
|
|
|
65
56
|
task = find_dynflow_task
|
|
66
57
|
if task.resumable?
|
|
67
58
|
ForemanTasks.dynflow.world.execute(task.execution_plan.id)
|
|
68
|
-
flash[:
|
|
59
|
+
flash[:info] = _('The execution was resumed.')
|
|
69
60
|
else
|
|
70
61
|
flash[:warning] = _('The execution has to be resumable.')
|
|
71
62
|
end
|
|
@@ -77,7 +68,7 @@ module ForemanTasks
|
|
|
77
68
|
if task.paused?
|
|
78
69
|
task.state = :stopped
|
|
79
70
|
task.save!
|
|
80
|
-
flash[:
|
|
71
|
+
flash[:info] = _('The task resources were unlocked.')
|
|
81
72
|
else
|
|
82
73
|
flash[:warning] = _('The execution has to be paused.')
|
|
83
74
|
end
|
|
@@ -88,7 +79,7 @@ module ForemanTasks
|
|
|
88
79
|
task = find_dynflow_task
|
|
89
80
|
task.state = :stopped
|
|
90
81
|
task.save!
|
|
91
|
-
flash[:
|
|
82
|
+
flash[:info] = _('The task resources were unlocked with force.')
|
|
92
83
|
redirect_back(:fallback_location => foreman_tasks_task_path(task))
|
|
93
84
|
end
|
|
94
85
|
|
|
@@ -103,6 +94,19 @@ module ForemanTasks
|
|
|
103
94
|
|
|
104
95
|
private
|
|
105
96
|
|
|
97
|
+
def respond_with_tasks(scope)
|
|
98
|
+
respond_to do |format|
|
|
99
|
+
format.html do
|
|
100
|
+
@tasks = filter(scope)
|
|
101
|
+
render :index, layout: !request.xhr?
|
|
102
|
+
end
|
|
103
|
+
format.csv do
|
|
104
|
+
@tasks = filter(scope, paginate: false)
|
|
105
|
+
csv_response(@tasks, [:id, :action, :state, :result, 'started_at.in_time_zone', 'ended_at.in_time_zone', :username], ['Id', 'Action', 'State', 'Result', 'Started At', 'Ended At', 'User'])
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
106
110
|
def restrict_dangerous_actions
|
|
107
111
|
render_403 unless Setting['dynflow_allow_dangerous_actions']
|
|
108
112
|
end
|
|
@@ -25,38 +25,17 @@ module ForemanTasks
|
|
|
25
25
|
ret.html_safe
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
def
|
|
29
|
-
return
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
when 'success'
|
|
33
|
-
'pficon-ok'
|
|
34
|
-
when 'error'
|
|
35
|
-
'pficon-error-circle-o'
|
|
36
|
-
when 'warning'
|
|
37
|
-
'pficon-ok status-warn'
|
|
38
|
-
else
|
|
39
|
-
'pficon-help'
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
"task-status #{icon_class}"
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def time_in_words_span(time)
|
|
46
|
-
if time.nil?
|
|
47
|
-
_('N/A')
|
|
48
|
-
else
|
|
49
|
-
content_tag :span, (time > Time.now.utc ? _('in %s') : _('%s ago')) % time_ago_in_words(time),
|
|
50
|
-
:'data-original-title' => time.try(:in_time_zone), :rel => 'twipsy'
|
|
51
|
-
end
|
|
28
|
+
def troubleshooting_info_text
|
|
29
|
+
return if @task.state != 'paused' || @task.main_action.nil?
|
|
30
|
+
helper = TroubleshootingHelpGenerator.new(@task.main_action)
|
|
31
|
+
helper.generate_text
|
|
52
32
|
end
|
|
53
33
|
|
|
54
|
-
def
|
|
55
|
-
if
|
|
56
|
-
|
|
34
|
+
def username_link_task(owner, username)
|
|
35
|
+
if owner.present? && username != User::ANONYMOUS_API_ADMIN && username != User::ANONYMOUS_ADMIN
|
|
36
|
+
link_to_if_authorized(username, hash_for_edit_user_path(owner))
|
|
57
37
|
else
|
|
58
|
-
|
|
59
|
-
:'data-original-title' => number_with_delimiter((finish - start).to_i) + _(' seconds'), :rel => 'twipsy'
|
|
38
|
+
username
|
|
60
39
|
end
|
|
61
40
|
end
|
|
62
41
|
|
|
@@ -122,6 +101,26 @@ module ForemanTasks
|
|
|
122
101
|
render :partial => 'common/trigger_form', :locals => { :f => f, :triggering => triggering }
|
|
123
102
|
end
|
|
124
103
|
|
|
104
|
+
def task_breadcrumb_item(task, active = false)
|
|
105
|
+
item = { :caption => format_task_input(task) }
|
|
106
|
+
item[:url] = url_for(foreman_tasks_task_path(task.id)) unless active
|
|
107
|
+
item
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def index_breadcrumb_item
|
|
111
|
+
item = { :caption => _('Tasks') }
|
|
112
|
+
item[:url] = foreman_tasks_tasks_url if action_name != 'index'
|
|
113
|
+
item
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def breadcrumb_items
|
|
117
|
+
items = [index_breadcrumb_item]
|
|
118
|
+
return items if action_name == 'index'
|
|
119
|
+
items << task_breadcrumb_item(@task, action_name == 'show')
|
|
120
|
+
items << { :caption => _('Sub tasks') } if action_name == 'sub_tasks'
|
|
121
|
+
items
|
|
122
|
+
end
|
|
123
|
+
|
|
125
124
|
private
|
|
126
125
|
|
|
127
126
|
def future_mode_fieldset(f, triggering)
|
|
@@ -46,7 +46,7 @@ module Actions
|
|
|
46
46
|
def create_sub_plans
|
|
47
47
|
action_class = input[:action_class].constantize
|
|
48
48
|
target_class = input[:target_class].constantize
|
|
49
|
-
targets = target_class.where(:id => current_batch)
|
|
49
|
+
targets = target_class.unscoped.where(:id => current_batch)
|
|
50
50
|
|
|
51
51
|
missing = Array.new((current_batch - targets.map(&:id)).count) { nil }
|
|
52
52
|
|
|
@@ -99,6 +99,36 @@ module ForemanTasks
|
|
|
99
99
|
execution_plan.try(:steps_in_state, :running, :suspended) || []
|
|
100
100
|
end
|
|
101
101
|
|
|
102
|
+
def input_output_failed_steps
|
|
103
|
+
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
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def input_output_running_steps
|
|
118
|
+
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
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
102
132
|
def humanized
|
|
103
133
|
{ action: get_humanized(:humanized_name),
|
|
104
134
|
input: get_humanized(:humanized_input),
|
|
@@ -44,6 +44,10 @@ module ForemanTasks
|
|
|
44
44
|
# rubocop:enable Rails/OutputSafety
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
+
def generate_text
|
|
48
|
+
(description + link_descriptions_html).join("\n")
|
|
49
|
+
end
|
|
50
|
+
|
|
47
51
|
def link_descriptions_html
|
|
48
52
|
links.map do |link|
|
|
49
53
|
link.description % { link: %(<a href="%{href}">%{title}</a>) % link.to_h }
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
object @task if @task
|
|
2
|
+
|
|
3
|
+
extends 'foreman_tasks/api/tasks/show'
|
|
4
|
+
|
|
5
|
+
attributes :parent_task_id, :start_at, :start_before, :external_id
|
|
6
|
+
node(:action) { @task.action }
|
|
7
|
+
node(:execution_plan) { { state: @task.execution_plan.state, cancellable: @task.execution_plan.cancellable? } }
|
|
8
|
+
node(:failed_steps) { @task.input_output_failed_steps }
|
|
9
|
+
node(:running_steps) { @task.input_output_running_steps }
|
|
10
|
+
node(:help) { troubleshooting_info_text }
|
|
11
|
+
node(:has_sub_tasks) { @task.sub_tasks.any? }
|
|
12
|
+
node(:allowDangerousActions) { Setting['dynflow_allow_dangerous_actions'] }
|
|
13
|
+
node(:locks) do
|
|
14
|
+
@task.locks.map do |lock|
|
|
15
|
+
{ name: lock.name, exclusive: lock.exclusive, resource_type: lock.resource_type, resource_id: lock.resource_id }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
node(:username_path) { username_link_task(@task.owner, @task.username) }
|
|
@@ -1,144 +1,20 @@
|
|
|
1
1
|
<% stylesheet 'foreman_tasks/tasks' %>
|
|
2
|
-
|
|
2
|
+
<% content_for(:javascripts) do %>
|
|
3
|
+
<%= webpacked_plugins_js_for :'foreman-tasks' %>
|
|
4
|
+
<% end %>
|
|
5
|
+
<% content_for(:stylesheets) do %>
|
|
6
|
+
<%= webpacked_plugins_css_for :'foreman-tasks' %>
|
|
7
|
+
<% end %>
|
|
3
8
|
<%= breadcrumbs(
|
|
4
|
-
items:
|
|
5
|
-
{
|
|
6
|
-
caption: _('Tasks'),
|
|
7
|
-
url: url_for(foreman_tasks_tasks_path)
|
|
8
|
-
},
|
|
9
|
-
{
|
|
10
|
-
caption: format_task_input(@task)
|
|
11
|
-
}
|
|
12
|
-
],
|
|
9
|
+
items: breadcrumb_items,
|
|
13
10
|
name_field: 'action',
|
|
14
11
|
resource_url: foreman_tasks_api_tasks_path,
|
|
15
12
|
switcher_item_url: foreman_tasks_task_path(:id => ':id')
|
|
16
13
|
) %>
|
|
17
14
|
|
|
18
15
|
|
|
19
|
-
<div class="task-details">
|
|
20
|
-
|
|
21
|
-
if (typeof taskProgressReloader === 'undefined') {
|
|
22
|
-
var taskProgressReloader = {
|
|
23
|
-
timeoutId: null,
|
|
24
|
-
formId: null,
|
|
25
|
-
reload: function () {
|
|
26
|
-
tfm.tools.showSpinner();
|
|
27
|
-
taskProgressReloader.timeoutId = null;
|
|
28
|
-
taskProgressReloader.formId = null;
|
|
29
|
-
|
|
30
|
-
$.ajax({
|
|
31
|
-
type:'GET',
|
|
32
|
-
url: document.location.href,
|
|
33
|
-
headers: {"X-Foreman-Layout": "two-pane"},
|
|
34
|
-
success: function(response){
|
|
35
|
-
$('#content .task-details').replaceWith($(response));
|
|
36
|
-
},
|
|
37
|
-
error: function(response){
|
|
38
|
-
document.location.reload();
|
|
39
|
-
},
|
|
40
|
-
complete: function(){
|
|
41
|
-
tfm.tools.hideSpinner();
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
start: function () {
|
|
47
|
-
var button = $('.reload-button');
|
|
48
|
-
if (!taskProgressReloader.timeoutId) {
|
|
49
|
-
taskProgressReloader.timeoutId = setTimeout(this.reload, 5000);
|
|
50
|
-
taskProgressReloader.formId = $(button).closest('form')[0].id;
|
|
51
|
-
}
|
|
52
|
-
button.html('<span class="glyphicon glyphicon-refresh spin"></span> <%= _('Stop auto-reloading') %>');
|
|
53
|
-
button.show();
|
|
54
|
-
},
|
|
55
|
-
|
|
56
|
-
stop: function () {
|
|
57
|
-
if (taskProgressReloader.timeoutId) {
|
|
58
|
-
clearTimeout(taskProgressReloader.timeoutId);
|
|
59
|
-
}
|
|
60
|
-
taskProgressReloader.timeoutId = null;
|
|
61
|
-
taskProgressReloader.formId = null;
|
|
62
|
-
var button = $('.reload-button');
|
|
63
|
-
button.html('<span class="glyphicon glyphicon-refresh"></span> <%= _('Start auto-reloading') %>');
|
|
64
|
-
button.show();
|
|
65
|
-
},
|
|
66
|
-
|
|
67
|
-
toggle: function () {
|
|
68
|
-
if (taskProgressReloader.timeoutId) {
|
|
69
|
-
this.stop();
|
|
70
|
-
} else {
|
|
71
|
-
this.start();
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
$(document).ready(function () {
|
|
78
|
-
$('.modal-submit').click(function(e){
|
|
79
|
-
if($(this).hasClass('disabled')){
|
|
80
|
-
e.preventDefault();
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
$('.disable-unlock').click(function() {
|
|
84
|
-
var button = $(this).parents('.modal').find('.modal-submit');
|
|
85
|
-
|
|
86
|
-
if($(this).is(':checked')){
|
|
87
|
-
button.removeClass('disabled')
|
|
88
|
-
}
|
|
89
|
-
else{
|
|
90
|
-
button.addClass('disabled')
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
$('.reload-button').click(function (event) {
|
|
95
|
-
taskProgressReloader.toggle();
|
|
96
|
-
event.preventDefault();
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
$('.reload-button-stop').click(function (event) {
|
|
100
|
-
taskProgressReloader.stop();
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
$('ul.nav-tabs a' ).click(function (event) {
|
|
104
|
-
taskProgressReloader.stop();
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
<% if @task.state != 'stopped' %>
|
|
108
|
-
taskProgressReloader.start();
|
|
109
|
-
<% else %>
|
|
110
|
-
taskProgressReloader.stop();
|
|
111
|
-
<% end %>
|
|
112
|
-
});
|
|
113
|
-
</script>
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
<%= form_for @task, :url => "#" do %>
|
|
117
|
-
|
|
118
|
-
<ul class="nav nav-tabs" data-tabs="tabs">
|
|
119
|
-
<li class="active"><a href="#primary" data-toggle="tab"><%= _("Task") %></a></li>
|
|
120
|
-
<li><a href="#running-steps" data-toggle="tab"><%= _("Running Steps") %></a></li>
|
|
121
|
-
<li><a href="#errors" data-toggle="tab"><%= _("Errors") %></a></li>
|
|
122
|
-
<li><a href="#locks" data-toggle="tab"><%= _("Locks") %></a></li>
|
|
123
|
-
<li><a href="#raw" data-toggle="tab"><%= _("Raw") %></a></li>
|
|
124
|
-
</ul>
|
|
16
|
+
<div class="task-details" id="foremanTaskDetails">
|
|
17
|
+
</div>
|
|
125
18
|
|
|
126
|
-
<div class="tab-content">
|
|
127
|
-
<div class="tab-pane active" id="primary">
|
|
128
|
-
<%= render :partial => 'details' %>
|
|
129
|
-
</div>
|
|
130
|
-
<div class="tab-pane" id="running-steps">
|
|
131
|
-
<%= render :partial => 'running_steps' %>
|
|
132
|
-
</div>
|
|
133
|
-
<div class="tab-pane" id="errors">
|
|
134
|
-
<%= render :partial => 'errors' %>
|
|
135
|
-
</div>
|
|
136
|
-
<div class="tab-pane" id="raw">
|
|
137
|
-
<%= render :partial => 'raw' %>
|
|
138
|
-
</div>
|
|
139
|
-
<div class="tab-pane" id="locks">
|
|
140
|
-
<%= render :partial => 'locks' %>
|
|
141
|
-
</div>
|
|
142
19
|
|
|
143
|
-
|
|
144
|
-
</div>
|
|
20
|
+
<%= mount_react_component('TaskDetails', '#foremanTaskDetails') %>
|