foreman_remote_execution 3.0.3 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.hound.yml +2 -1
- data/.rubocop.yml +80 -50
- data/.rubocop_todo.yml +113 -73
- data/Gemfile +4 -0
- data/app/controllers/api/v2/foreign_input_sets_controller.rb +3 -2
- data/app/controllers/api/v2/job_invocations_controller.rb +7 -6
- data/app/controllers/api/v2/job_templates_controller.rb +3 -2
- data/app/controllers/api/v2/remote_execution_features_controller.rb +3 -2
- data/app/controllers/api/v2/template_invocations_controller.rb +1 -1
- data/app/controllers/cockpit_controller.rb +1 -0
- data/app/controllers/concerns/foreman/controller/parameters/foreign_input_set.rb +1 -1
- data/app/controllers/concerns/foreman/controller/parameters/job_template.rb +4 -4
- data/app/controllers/job_invocations_controller.rb +10 -6
- data/app/controllers/job_templates_controller.rb +1 -1
- data/app/controllers/remote_execution_features_controller.rb +3 -2
- data/app/helpers/concerns/foreman_remote_execution/hosts_helper_extensions.rb +16 -5
- data/app/helpers/job_invocations_chart_helper.rb +11 -10
- data/app/helpers/job_invocations_helper.rb +13 -5
- data/app/helpers/remote_execution_helper.rb +43 -46
- data/app/lib/actions/remote_execution/run_host_job.rb +5 -6
- data/app/lib/actions/remote_execution/run_hosts_job.rb +2 -2
- data/app/lib/foreman_remote_execution/renderer/scope/input.rb +1 -0
- data/app/models/concerns/foreman_remote_execution/errors_flattener.rb +0 -2
- data/app/models/concerns/foreman_remote_execution/host_extensions.rb +3 -5
- data/app/models/concerns/foreman_remote_execution/nic_extensions.rb +1 -0
- data/app/models/concerns/foreman_remote_execution/smart_proxy_extensions.rb +1 -0
- data/app/models/foreign_input_set.rb +3 -2
- data/app/models/input_template_renderer.rb +1 -1
- data/app/models/job_invocation.rb +10 -12
- data/app/models/job_invocation_composer.rb +20 -14
- data/app/models/job_invocation_task_group.rb +1 -1
- data/app/models/job_template.rb +3 -3
- data/app/models/remote_execution_feature.rb +0 -2
- data/app/models/remote_execution_provider.rb +4 -2
- data/app/models/setting/remote_execution.rb +54 -56
- data/app/models/ssh_execution_provider.rb +2 -2
- data/app/models/targeting.rb +1 -0
- data/app/models/template_invocation.rb +2 -3
- data/app/views/api/v2/job_invocations/base.json.rabl +1 -1
- data/app/views/api/v2/job_invocations/main.json.rabl +5 -2
- data/app/views/job_invocations/_card_target_hosts.html.erb +12 -0
- data/app/views/job_invocations/_card_user_input.html.erb +1 -1
- data/app/views/job_invocations/_form.html.erb +3 -2
- data/app/views/job_invocations/_rerun_taxonomies.html.erb +22 -0
- data/app/views/job_invocations/_user_input.html.erb +1 -1
- data/app/views/job_invocations/show.html.erb +2 -0
- data/db/migrate/20151215114631_add_host_id_to_template_invocation.rb +1 -0
- data/db/migrate/20180110104432_rename_template_invocation_permission.rb +1 -0
- data/db/seeds.d/50-notification_blueprints.rb +4 -4
- data/db/seeds.d/90-bookmarks.rb +1 -0
- data/extra/cockpit/foreman-cockpit-session +7 -2
- data/lib/foreman_remote_execution/engine.rb +18 -17
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/test/benchmark/run_hosts_job_benchmark.rb +1 -1
- data/test/factories/foreman_remote_execution_factories.rb +1 -1
- data/test/functional/api/v2/job_invocations_controller_test.rb +9 -9
- data/test/functional/api/v2/job_templates_controller_test.rb +1 -1
- data/test/functional/api/v2/remote_execution_features_controller_test.rb +2 -2
- data/test/functional/api/v2/template_invocations_controller_test.rb +4 -4
- data/test/functional/job_invocations_controller_test.rb +11 -11
- data/test/functional/job_templates_controller_test.rb +1 -1
- data/test/unit/actions/run_hosts_job_test.rb +8 -8
- data/test/unit/concerns/foreman_tasks_cleaner_extensions_test.rb +3 -3
- data/test/unit/concerns/host_extensions_test.rb +19 -19
- data/test/unit/concerns/nic_extensions_test.rb +1 -1
- data/test/unit/execution_task_status_mapper_test.rb +10 -10
- data/test/unit/input_template_renderer_test.rb +77 -77
- data/test/unit/job_invocation_composer_test.rb +100 -96
- data/test/unit/job_invocation_test.rb +29 -29
- data/test/unit/job_template_effective_user_test.rb +3 -3
- data/test/unit/job_template_test.rb +31 -31
- data/test/unit/remote_execution_feature_test.rb +19 -19
- data/test/unit/remote_execution_provider_test.rb +29 -29
- data/test/unit/renderer_scope_input.rb +6 -6
- data/test/unit/targeting_test.rb +6 -6
- data/test/unit/template_invocation_input_value_test.rb +3 -3
- metadata +3 -2
data/Gemfile
CHANGED
@@ -18,7 +18,8 @@ module Api
|
|
18
18
|
api :GET, '/templates/:template_id/foreign_input_sets/:id', N_('Show foreign input set details')
|
19
19
|
param :template_id, :identifier, :required => true
|
20
20
|
param :id, :identifier, :required => true
|
21
|
-
def show
|
21
|
+
def show
|
22
|
+
end
|
22
23
|
|
23
24
|
def_param_group :foreign_input_set do
|
24
25
|
param :foreign_input_set, Hash, :required => true, :action_aware => true do
|
@@ -50,7 +51,7 @@ module Api
|
|
50
51
|
param :id, :identifier, :required => true
|
51
52
|
param_group :foreign_input_set
|
52
53
|
def update
|
53
|
-
process_response @foreign_input_set.
|
54
|
+
process_response @foreign_input_set.update(foreign_input_set_params)
|
54
55
|
end
|
55
56
|
|
56
57
|
def resource_name(nested_resource = nil)
|
@@ -18,9 +18,9 @@ module Api
|
|
18
18
|
|
19
19
|
api :GET, '/job_invocations/:id', N_('Show job invocation')
|
20
20
|
param :id, :identifier, :required => true
|
21
|
-
def show
|
21
|
+
def show
|
22
|
+
end
|
22
23
|
|
23
|
-
# rubocop:disable Metrics/BlockLength
|
24
24
|
def_param_group :job_invocation do
|
25
25
|
param :job_invocation, Hash, :required => true, :action_aware => true do
|
26
26
|
param :job_template_id, String, :required => false, :desc => N_('The job template to use, parameter is required unless feature was specified')
|
@@ -29,8 +29,8 @@ module Api
|
|
29
29
|
param :inputs, Hash, :required => false, :desc => N_('Inputs to use')
|
30
30
|
param :ssh, Hash, :desc => N_('SSH provider specific options') do
|
31
31
|
param :effective_user, String,
|
32
|
-
|
33
|
-
|
32
|
+
:required => false,
|
33
|
+
:desc => N_('What user should be used to run the script (using sudo-like mechanisms). Defaults to a template parameter or global setting.')
|
34
34
|
end
|
35
35
|
|
36
36
|
param :recurrence, Hash, :desc => N_('Create a recurring job') do
|
@@ -107,7 +107,7 @@ module Api
|
|
107
107
|
render :json => { :cancelled => result, :id => @job_invocation.id }
|
108
108
|
else
|
109
109
|
render :json => { :message => _('The job could not be cancelled.') },
|
110
|
-
:status =>
|
110
|
+
:status => :unprocessable_entity
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
@@ -122,7 +122,7 @@ module Api
|
|
122
122
|
process_response @job_invocation
|
123
123
|
else
|
124
124
|
render :json => { :error => _('Could not rerun job %{id} because its template could not be found') % { :id => composer.reruns } },
|
125
|
-
:status =>
|
125
|
+
:status => :not_found
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
@@ -159,6 +159,7 @@ module Api
|
|
159
159
|
|
160
160
|
def job_invocation_params
|
161
161
|
return @job_invocation_params if @job_invocation_params.present?
|
162
|
+
|
162
163
|
job_invocation_params = params.fetch(:job_invocation, {}).dup
|
163
164
|
if job_invocation_params.key?(:ssh)
|
164
165
|
job_invocation_params.merge!(job_invocation_params.delete(:ssh).permit(:effective_user))
|
@@ -42,7 +42,8 @@ module Api
|
|
42
42
|
|
43
43
|
api :GET, '/job_templates/:id', N_('Show job template details')
|
44
44
|
param :id, :identifier, :required => true
|
45
|
-
def show
|
45
|
+
def show
|
46
|
+
end
|
46
47
|
|
47
48
|
def_param_group :job_template do
|
48
49
|
param :job_template, Hash, :required => true, :action_aware => true do
|
@@ -78,7 +79,7 @@ module Api
|
|
78
79
|
param :id, :identifier, :required => true
|
79
80
|
param_group :job_template
|
80
81
|
def update
|
81
|
-
process_response @job_template.
|
82
|
+
process_response @job_template.update(job_template_params)
|
82
83
|
end
|
83
84
|
|
84
85
|
api :GET, '/job_templates/revision'
|
@@ -13,7 +13,8 @@ module Api
|
|
13
13
|
|
14
14
|
api :GET, '/remote_execution_features/:id', N_('Show remote execution feature')
|
15
15
|
param :id, :identifier, :required => true
|
16
|
-
def show
|
16
|
+
def show
|
17
|
+
end
|
17
18
|
|
18
19
|
def_param_group :remote_execution_feature do
|
19
20
|
param :remote_execution_feature, Hash, :required => true, :action_aware => true do
|
@@ -25,7 +26,7 @@ module Api
|
|
25
26
|
param :id, :identifier, :required => true
|
26
27
|
param_group :remote_execution_feature
|
27
28
|
def update
|
28
|
-
process_response @remote_execution_feature.
|
29
|
+
process_response @remote_execution_feature.update(remote_execution_feature_params)
|
29
30
|
end
|
30
31
|
|
31
32
|
private
|
@@ -7,7 +7,7 @@ module Api
|
|
7
7
|
before_action :find_job_invocation, :only => %w{template_invocations}
|
8
8
|
|
9
9
|
api :GET, '/job_invocations/:job_invocation_id/template_invocations',
|
10
|
-
|
10
|
+
N_('List template invocations belonging to job invocation')
|
11
11
|
param_group :search_and_pagination, ::Api::V2::BaseController
|
12
12
|
param :job_invocation_id, :identifier, :required => true
|
13
13
|
def template_invocations
|
@@ -5,7 +5,7 @@ module ::Foreman::Controller::Parameters::ForeignInputSet
|
|
5
5
|
def foreign_input_set_params_filter
|
6
6
|
Foreman::ParameterFilter.new(::ForeignInputSet).tap do |filter|
|
7
7
|
filter.permit_by_context(:id, :_destroy, :template_id, :target_template_id, :include_all, :include, :exclude,
|
8
|
-
|
8
|
+
:nested => true)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -9,16 +9,16 @@ module Foreman::Controller::Parameters::JobTemplate
|
|
9
9
|
def job_template_effective_user_filter
|
10
10
|
Foreman::ParameterFilter.new(::JobTemplateEffectiveUser).tap do |filter|
|
11
11
|
filter.permit_by_context(:value, :current_user, :overridable,
|
12
|
-
|
12
|
+
:nested => true)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
def job_template_params_filter
|
17
17
|
Foreman::ParameterFilter.new(::TemplateInput).tap do |filter|
|
18
18
|
filter.permit :job_category, :provider_type, :description_format, :execution_timeout_interval,
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
:effective_user_attributes => [job_template_effective_user_filter],
|
20
|
+
:template_inputs_attributes => [template_input_params_filter],
|
21
|
+
:foreign_input_sets_attributes => [foreign_input_set_params_filter]
|
22
22
|
add_template_params_filter(filter)
|
23
23
|
add_taxonomix_params_filter(filter)
|
24
24
|
end
|
@@ -3,15 +3,15 @@ class JobInvocationsController < ApplicationController
|
|
3
3
|
include ::ForemanTasks::Concerns::Parameters::Triggering
|
4
4
|
include ::JobInvocationsChartHelper
|
5
5
|
|
6
|
-
|
7
6
|
def new
|
8
7
|
return @composer = prepare_composer if params[:feature].present?
|
8
|
+
|
9
9
|
ui_params = {
|
10
10
|
:host_ids => params[:host_ids],
|
11
11
|
:targeting => {
|
12
12
|
:targeting_type => Targeting::STATIC_TYPE,
|
13
|
-
:bookmark_id => params[:bookmark_id]
|
14
|
-
}
|
13
|
+
:bookmark_id => params[:bookmark_id],
|
14
|
+
},
|
15
15
|
}
|
16
16
|
# replace an empty string search with a dummy search query to match all hosts
|
17
17
|
# but only if search query was entered (based on presence of :search parameter)
|
@@ -24,8 +24,8 @@ class JobInvocationsController < ApplicationController
|
|
24
24
|
ui_params[:job_invocation] = {
|
25
25
|
:job_category => template.job_category,
|
26
26
|
:providers => {
|
27
|
-
template.provider_type => {:job_template_id => template.id}
|
28
|
-
}
|
27
|
+
template.provider_type => {:job_template_id => template.id},
|
28
|
+
},
|
29
29
|
}
|
30
30
|
end
|
31
31
|
|
@@ -35,6 +35,8 @@ class JobInvocationsController < ApplicationController
|
|
35
35
|
def rerun
|
36
36
|
job_invocation = resource_base.find(params[:id])
|
37
37
|
@composer = JobInvocationComposer.from_job_invocation(job_invocation, params)
|
38
|
+
@job_organization = Taxonomy.find_by(id: job_invocation.task.input[:current_organization_id])
|
39
|
+
@job_location = Taxonomy.find_by(id: job_invocation.task.input[:current_location_id])
|
38
40
|
render :action => 'new'
|
39
41
|
end
|
40
42
|
|
@@ -58,6 +60,8 @@ class JobInvocationsController < ApplicationController
|
|
58
60
|
.where(:template_invocations => { :job_invocation_id => @job_invocation.id})
|
59
61
|
end
|
60
62
|
@hosts = resource_base_search_and_page
|
63
|
+
@job_organization = Taxonomy.find_by(id: @job_invocation.task.input[:current_organization_id])
|
64
|
+
@job_location = Taxonomy.find_by(id: @job_invocation.task.input[:current_location_id])
|
61
65
|
end
|
62
66
|
|
63
67
|
def index
|
@@ -79,7 +83,7 @@ class JobInvocationsController < ApplicationController
|
|
79
83
|
:success => @job_invocation.progress_report[:success],
|
80
84
|
:cancelled => @job_invocation.progress_report[:cancelled],
|
81
85
|
:failed => @job_invocation.progress_report[:error],
|
82
|
-
:pending => @job_invocation.progress_report[:pending]
|
86
|
+
:pending => @job_invocation.progress_report[:pending],
|
83
87
|
},
|
84
88
|
}
|
85
89
|
end
|
@@ -35,7 +35,7 @@ class JobTemplatesController < ::TemplatesController
|
|
35
35
|
contents = params.fetch(:imported_template, {}).fetch(:template, nil).try(:read)
|
36
36
|
|
37
37
|
@template = JobTemplate.import_raw(contents, :update => Foreman::Cast.to_bool(params[:imported_template][:overwrite]))
|
38
|
-
if @template
|
38
|
+
if @template&.save
|
39
39
|
flash[:notice] = _('Job template imported successfully.')
|
40
40
|
redirect_to job_templates_path(:search => "name = \"#{@template.name}\"")
|
41
41
|
else
|
@@ -6,10 +6,11 @@ class RemoteExecutionFeaturesController < ::ApplicationController
|
|
6
6
|
@remote_execution_features = resource_base.all
|
7
7
|
end
|
8
8
|
|
9
|
-
def show
|
9
|
+
def show
|
10
|
+
end
|
10
11
|
|
11
12
|
def update
|
12
|
-
if @remote_execution_feature.
|
13
|
+
if @remote_execution_feature.update(remote_execution_feature_params)
|
13
14
|
process_success :object => @remote_execution_feature
|
14
15
|
else
|
15
16
|
process_error :object => @remote_execution_feature
|
@@ -1,13 +1,17 @@
|
|
1
1
|
module ForemanRemoteExecution
|
2
2
|
module HostsHelperExtensions
|
3
|
+
def host_overview_buttons(host)
|
4
|
+
[
|
5
|
+
{ :button => link_to_if_authorized(_("Jobs"), hash_for_job_invocations_path(search: "host=#{host.name}"), :title => _("Job invocations"), :class => 'btn btn-default'), :priority => 200 },
|
6
|
+
]
|
7
|
+
end
|
8
|
+
|
3
9
|
def multiple_actions
|
4
10
|
super + [ [_('Schedule Remote Job'), new_job_invocation_path, false] ]
|
5
11
|
end
|
6
12
|
|
7
13
|
def schedule_job_multi_button(*args)
|
8
|
-
host_features =
|
9
|
-
link_to(_('%s') % feature.name, job_invocations_path(:host_ids => [args.first.id], :feature => feature.label), :method => :post)
|
10
|
-
end
|
14
|
+
host_features = rex_host_features(*args)
|
11
15
|
|
12
16
|
if host_features.present?
|
13
17
|
action_buttons(schedule_job_button(*args), *host_features)
|
@@ -16,19 +20,26 @@ module ForemanRemoteExecution
|
|
16
20
|
end
|
17
21
|
end
|
18
22
|
|
23
|
+
def rex_host_features(*args)
|
24
|
+
RemoteExecutionFeature.with_host_action_button.order(:label).map do |feature|
|
25
|
+
link_to(_('%s') % feature.name, job_invocations_path(:host_ids => [args.first.id], :feature => feature.label), :method => :post)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
19
29
|
def schedule_job_button(*args)
|
20
30
|
link_to(_('Schedule Remote Job'), new_job_invocation_path(:host_ids => [args.first.id]), :id => :run_button, :class => 'btn btn-default')
|
21
31
|
end
|
22
32
|
|
23
33
|
def web_console_button(host, *args)
|
24
34
|
return unless authorized_for(permission: 'cockpit_hosts', auth_object: host)
|
35
|
+
|
25
36
|
url = SSHExecutionProvider.cockpit_url_for_host(host.name)
|
26
|
-
url ? link_to(_('Web Console'), url, :class => 'btn btn-default', :id => :'web-console-button') : nil
|
37
|
+
url ? link_to(_('Web Console'), url, :class => 'btn btn-default', :id => :'web-console-button', :target => '_new') : nil
|
27
38
|
end
|
28
39
|
|
29
40
|
def host_title_actions(*args)
|
30
41
|
title_actions(button_group(schedule_job_multi_button(*args)),
|
31
|
-
|
42
|
+
button_group(web_console_button(*args)))
|
32
43
|
super(*args)
|
33
44
|
end
|
34
45
|
end
|
@@ -3,12 +3,13 @@
|
|
3
3
|
module JobInvocationsChartHelper
|
4
4
|
def job_invocation_chart(invocation)
|
5
5
|
donut_chart('#status_chart',
|
6
|
-
|
7
|
-
|
6
|
+
job_invocation_data(invocation)[:columns],
|
7
|
+
job_invocation_data(invocation)[:groups])
|
8
8
|
end
|
9
9
|
|
10
10
|
def job_invocation_data(invocation)
|
11
11
|
return @job_invocation_data if @job_invocation_data.present?
|
12
|
+
|
12
13
|
progress_report = invocation.progress_report
|
13
14
|
success = progress_report[:success]
|
14
15
|
cancelled = progress_report[:cancelled]
|
@@ -45,26 +46,26 @@ module JobInvocationsChartHelper
|
|
45
46
|
|
46
47
|
def job_invocation_success_status
|
47
48
|
icon_text('ok',
|
48
|
-
|
49
|
-
|
49
|
+
@job_invocation_data[0][1],
|
50
|
+
:kind => 'pficon')
|
50
51
|
end
|
51
52
|
|
52
53
|
def job_invocation_failed_status
|
53
54
|
icon_text('error-circle-o',
|
54
|
-
|
55
|
-
|
55
|
+
@job_invocation_data[1][1],
|
56
|
+
:kind => 'pficon')
|
56
57
|
end
|
57
58
|
|
58
59
|
def job_invocation_pending_status
|
59
60
|
icon_text('running',
|
60
|
-
|
61
|
-
|
61
|
+
@job_invocation_data[2][1],
|
62
|
+
:kind => 'pficon')
|
62
63
|
end
|
63
64
|
|
64
65
|
def job_invocation_cancelled_status
|
65
66
|
icon_text('close',
|
66
|
-
|
67
|
-
|
67
|
+
@job_invocation_data[3][1],
|
68
|
+
:kind => 'pficon')
|
68
69
|
end
|
69
70
|
|
70
71
|
def task_failed?(task)
|
@@ -15,7 +15,7 @@ module JobInvocationsHelper
|
|
15
15
|
def job_invocations_buttons
|
16
16
|
[
|
17
17
|
documentation_button_rex('3.2ExecutingaJob'),
|
18
|
-
display_link_if_authorized(_('Run Job'), hash_for_new_job_invocation_path)
|
18
|
+
display_link_if_authorized(_('Run Job'), hash_for_new_job_invocation_path),
|
19
19
|
]
|
20
20
|
end
|
21
21
|
|
@@ -25,7 +25,7 @@ module JobInvocationsHelper
|
|
25
25
|
link_content = template_name + ' - ' + provider + ' ' +
|
26
26
|
icon_text('edit', '', :kind => 'pficon')
|
27
27
|
link_to_if_authorized(link_content,
|
28
|
-
|
28
|
+
hash_for_edit_job_template_path(:id => template.id))
|
29
29
|
end
|
30
30
|
|
31
31
|
def preview_hosts(template_invocation)
|
@@ -41,10 +41,18 @@ module JobInvocationsHelper
|
|
41
41
|
def collapsed_preview(target)
|
42
42
|
title = target.try(:name) || 'N/A'
|
43
43
|
content_tag(:h5,
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
:class => "expander collapsed out",
|
45
|
+
:data => { :toggle => 'collapse',
|
46
|
+
:target => "#preview_#{target.id}" }) do
|
47
47
|
content_tag(:span, '', :class => 'caret') + title
|
48
48
|
end
|
49
49
|
end
|
50
|
+
|
51
|
+
def show_job_organization(organization)
|
52
|
+
organization.presence || _('Any Organization')
|
53
|
+
end
|
54
|
+
|
55
|
+
def show_job_location(location)
|
56
|
+
location.presence || _('Any Location')
|
57
|
+
end
|
50
58
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# rubocop:disable Metrics/ModuleLength
|
2
1
|
module RemoteExecutionHelper
|
3
2
|
def providers_options
|
4
3
|
RemoteExecutionProvider.providers.map { |key, provider| [ key, _(provider.humanized_name) ] }
|
@@ -46,7 +45,7 @@ module RemoteExecutionHelper
|
|
46
45
|
hash_for_foreman_tasks_task_path(host_task)
|
47
46
|
.merge(:auth_object => host_task, :permission => :view_foreman_tasks)
|
48
47
|
)
|
49
|
-
end
|
48
|
+
end,
|
50
49
|
]
|
51
50
|
end
|
52
51
|
|
@@ -57,66 +56,63 @@ module RemoteExecutionHelper
|
|
57
56
|
def job_invocations_buttons
|
58
57
|
[
|
59
58
|
documentation_button_rex('3.2ExecutingaJob'),
|
60
|
-
new_link(_('Run Job'))
|
59
|
+
new_link(_('Run Job')),
|
61
60
|
]
|
62
61
|
end
|
63
62
|
|
64
|
-
# rubocop:disable Metrics/AbcSize
|
65
63
|
def job_invocation_task_buttons(task)
|
66
64
|
job_invocation = task.task_groups.find { |group| group.class == JobInvocationTaskGroup }.job_invocation
|
67
65
|
task_authorizer = Authorizer.new(User.current, :collection => [task])
|
68
66
|
buttons = []
|
69
67
|
if authorized_for(hash_for_new_job_invocation_path)
|
70
68
|
buttons << link_to(_('Rerun'), rerun_job_invocation_path(:id => job_invocation.id),
|
71
|
-
|
72
|
-
|
69
|
+
:class => 'btn btn-default',
|
70
|
+
:title => _('Rerun the job'))
|
73
71
|
end
|
74
72
|
if authorized_for(hash_for_new_job_invocation_path)
|
75
73
|
buttons << link_to(_('Rerun failed'), rerun_job_invocation_path(:id => job_invocation.id, :failed_only => 1),
|
76
|
-
|
77
|
-
|
78
|
-
|
74
|
+
:class => 'btn btn-default',
|
75
|
+
:disabled => job_invocation.failed_hosts.none?,
|
76
|
+
:title => _('Rerun on failed hosts'))
|
79
77
|
end
|
80
78
|
if authorized_for(:permission => :view_foreman_tasks, :auth_object => task, :authorizer => task_authorizer)
|
81
79
|
buttons << link_to(_('Job Task'), foreman_tasks_task_path(task),
|
82
|
-
|
83
|
-
|
80
|
+
:class => 'btn btn-default',
|
81
|
+
:title => _('See the last task details'))
|
84
82
|
end
|
85
83
|
if authorized_for(:permission => :cancel_job_invocations, :auth_object => job_invocation)
|
86
84
|
buttons << button_to(_('Cancel Job'), cancel_job_invocation_path(job_invocation),
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
85
|
+
:class => 'btn btn-danger',
|
86
|
+
:title => _('Try to cancel the job'),
|
87
|
+
:disabled => !task.cancellable?,
|
88
|
+
:method => :post)
|
91
89
|
buttons << button_to(_('Abort Job'), cancel_job_invocation_path(job_invocation, :force => true),
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
90
|
+
:class => 'btn btn-danger',
|
91
|
+
:title => _('Try to abort the job without waiting for the results from the remote hosts'),
|
92
|
+
:disabled => !task.cancellable?,
|
93
|
+
:method => :post)
|
96
94
|
end
|
97
95
|
return buttons
|
98
96
|
end
|
99
97
|
|
100
|
-
# rubocop:enable Metrics/AbcSize
|
101
|
-
|
102
98
|
def template_invocation_task_buttons(task, invocation)
|
103
99
|
buttons = []
|
104
100
|
if authorized_for(:permission => :view_foreman_tasks, :auth_object => task)
|
105
101
|
buttons << link_to(_('Task Details'), foreman_tasks_task_path(task),
|
106
|
-
|
107
|
-
|
102
|
+
:class => 'btn btn-default',
|
103
|
+
:title => _('See the task details'))
|
108
104
|
end
|
109
105
|
if authorized_for(:permission => :cancel_job_invocations, :auth_object => invocation)
|
110
106
|
buttons << link_to(_('Cancel Job'), cancel_foreman_tasks_task_path(task),
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
107
|
+
:class => 'btn btn-danger',
|
108
|
+
:title => _('Try to cancel the job on a host'),
|
109
|
+
:disabled => !task.cancellable?,
|
110
|
+
:method => :post)
|
115
111
|
buttons << link_to(_('Abort Job'), abort_foreman_tasks_task_path(task),
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
112
|
+
:class => 'btn btn-danger',
|
113
|
+
:title => _('Try to abort the job on a host without waiting for its result'),
|
114
|
+
:disabled => !task.cancellable?,
|
115
|
+
:method => :post)
|
120
116
|
end
|
121
117
|
buttons
|
122
118
|
end
|
@@ -128,7 +124,7 @@ module RemoteExecutionHelper
|
|
128
124
|
else
|
129
125
|
task_authorizer = Authorizer.new(User.current, :collection => [invocation.task])
|
130
126
|
link_to_if_authorized job_invocation_status(invocation),
|
131
|
-
|
127
|
+
hash_for_foreman_tasks_task_path(invocation.task).merge(:auth_object => invocation.task, :permission => :view_foreman_tasks, :authorizer => task_authorizer)
|
132
128
|
end
|
133
129
|
end
|
134
130
|
|
@@ -193,7 +189,7 @@ module RemoteExecutionHelper
|
|
193
189
|
_('N/A')
|
194
190
|
else
|
195
191
|
content_tag :span, (time > Time.now.utc ? _('in %s') : _('%s ago')) % time_ago_in_words(time),
|
196
|
-
|
192
|
+
{ :'data-original-title' => time.try(:in_time_zone), :rel => 'twipsy' }
|
197
193
|
end
|
198
194
|
end
|
199
195
|
|
@@ -205,23 +201,23 @@ module RemoteExecutionHelper
|
|
205
201
|
|
206
202
|
def description_checkbox_f(f, job_template, disabled)
|
207
203
|
check_box_tag('description_format_override',
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
204
|
+
job_template.generate_description_format,
|
205
|
+
f.object.description_format.nil?,
|
206
|
+
:class => 'description_format_override',
|
207
|
+
:name => f.object_name + '[description_override]',
|
208
|
+
:disabled => disabled,
|
209
|
+
:onchange => 'description_override(this);') + ' ' + _('Use default description template')
|
214
210
|
end
|
215
211
|
|
216
212
|
def description_format_textarea_f(f, job_template, disabled)
|
217
213
|
textarea_f f, 'description_format',
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
214
|
+
:label => _('Description template'),
|
215
|
+
:value => f.object.description_format || job_template.generate_description_format,
|
216
|
+
:rows => 2,
|
217
|
+
:onchange => 'regenerate_description(this);',
|
218
|
+
:class => 'description_format advanced',
|
219
|
+
:disabled => disabled,
|
220
|
+
:label_help => description_format_help
|
225
221
|
end
|
226
222
|
|
227
223
|
def description_format_help
|
@@ -234,6 +230,7 @@ module RemoteExecutionHelper
|
|
234
230
|
def load_template_from_task(template_invocation, target)
|
235
231
|
task = template_invocation.job_invocation.sub_task_for_host(target)
|
236
232
|
return if task.nil?
|
233
|
+
|
237
234
|
task.execution_plan.actions[1].try(:input).try(:[], 'script')
|
238
235
|
end
|
239
236
|
end
|