foreman_remote_execution 0.1.2 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/.rubocop_todo.yml +0 -6
- data/app/assets/javascripts/template_input.js +5 -0
- data/app/assets/javascripts/template_invocation.js +44 -12
- data/app/controllers/api/v2/foreign_input_sets_controller.rb +80 -0
- data/app/controllers/api/v2/job_invocations_controller.rb +28 -14
- data/app/controllers/api/v2/job_templates_controller.rb +24 -20
- data/app/controllers/api/v2/template_inputs_controller.rb +10 -7
- data/app/controllers/job_invocations_controller.rb +18 -6
- data/app/controllers/job_templates_controller.rb +14 -4
- data/app/controllers/template_invocations_controller.rb +5 -3
- data/app/helpers/concerns/foreman_remote_execution/hosts_helper_extensions.rb +1 -1
- data/app/helpers/concerns/foreman_remote_execution/job_templates_extensions.rb +19 -0
- data/app/helpers/remote_execution_helper.rb +88 -39
- data/app/lib/actions/remote_execution/run_host_job.rb +11 -8
- data/app/lib/actions/remote_execution/run_hosts_job.rb +5 -2
- data/app/lib/actions/remote_execution/run_proxy_command.rb +9 -4
- data/app/models/concerns/foreman_remote_execution/errors_flattener.rb +2 -2
- data/app/models/concerns/foreman_remote_execution/host_extensions.rb +2 -2
- data/app/models/concerns/foreman_remote_execution/smart_proxy_extensions.rb +1 -1
- data/app/models/concerns/foreman_remote_execution/template_extensions.rb +9 -1
- data/app/models/foreign_input_set.rb +49 -0
- data/app/models/host_status/execution_status.rb +50 -5
- data/app/models/input_template_renderer.rb +52 -7
- data/app/models/job_invocation.rb +89 -32
- data/app/models/job_invocation_composer.rb +71 -55
- data/app/models/job_template.rb +43 -7
- data/app/models/remote_execution_provider.rb +1 -1
- data/app/models/setting/remote_execution.rb +7 -7
- data/app/models/ssh_execution_provider.rb +1 -1
- data/app/models/targeting.rb +1 -1
- data/app/models/template_invocation.rb +9 -4
- data/app/views/api/v2/foreign_input_sets/base.json.rabl +3 -0
- data/app/views/api/v2/foreign_input_sets/create.json.rabl +3 -0
- data/app/views/api/v2/foreign_input_sets/index.json.rabl +3 -0
- data/app/views/api/v2/foreign_input_sets/main.json.rabl +5 -0
- data/app/views/api/v2/foreign_input_sets/show.json.rabl +3 -0
- data/app/views/api/v2/job_invocations/base.json.rabl +10 -1
- data/app/views/api/v2/job_invocations/main.json.rabl +14 -1
- data/app/views/api/v2/job_templates/base.json.rabl +1 -1
- data/app/views/api/v2/job_templates/main.json.rabl +9 -1
- data/app/views/api/v2/job_templates/show.json.rabl +0 -10
- data/app/views/api/v2/template_inputs/main.json.rabl +2 -1
- data/app/views/job_invocation_task_groups/_job_invocation_task_group.html.erb +1 -1
- data/app/views/job_invocations/_description_fields.html.erb +4 -0
- data/app/views/job_invocations/_form.html.erb +73 -91
- data/app/views/job_invocations/_host_actions_td.html.erb +2 -2
- data/app/views/job_invocations/_host_name_td.html.erb +7 -0
- data/app/views/job_invocations/_tab_hosts.html.erb +6 -6
- data/app/views/job_invocations/_tab_overview.html.erb +3 -3
- data/app/views/job_invocations/index.html.erb +6 -4
- data/app/views/job_invocations/refresh.js.erb +1 -0
- data/app/views/job_invocations/show.html.erb +1 -1
- data/app/views/job_invocations/show.js.erb +6 -3
- data/app/views/job_templates/_custom_tabs.html.erb +24 -14
- data/app/views/job_templates/index.html.erb +3 -1
- data/app/views/template_inputs/_foreign_input_set_form.html.erb +12 -0
- data/app/views/template_inputs/_form.html.erb +11 -12
- data/app/views/template_invocations/show.html.erb +2 -2
- data/app/views/templates/package_action.erb +2 -2
- data/app/views/templates/puppet_run_once.erb +3 -3
- data/app/views/templates/run_command.erb +3 -3
- data/app/views/templates/service_action.erb +2 -2
- data/app/views/unattended/snippets/_remote_execution_ssh_keys.erb +1 -1
- data/config/routes.rb +5 -3
- data/db/migrate/20150616080015_create_template_input.rb +1 -1
- data/db/migrate/20150708133241_add_targeting.rb +7 -7
- data/db/migrate/20150708133242_add_invocation.rb +2 -2
- data/db/migrate/20150708133305_add_template_invocation.rb +6 -6
- data/db/migrate/20151215114631_add_host_id_to_template_invocation.rb +3 -3
- data/db/migrate/20151217092555_migrate_to_task_groups.rb +1 -1
- data/db/migrate/20160108134600_create_template_input_sets.rb +16 -0
- data/db/migrate/20160108141144_make_job_name_default_to_something.rb +9 -0
- data/db/migrate/20160111113032_upcase_ssh_feature.rb +19 -0
- data/db/migrate/20160113161916_add_run_host_job_task_id_to_template_invocation.rb +6 -0
- data/db/migrate/20160113162007_expand_all_template_invocations.rb +45 -0
- data/db/migrate/20160114120200_rename_job_categories.rb +20 -0
- data/db/migrate/20160114125628_rename_job_name_to_job_category.rb +19 -0
- data/db/seeds.d/60-ssh_proxy_feature.rb +1 -1
- data/db/seeds.d/80-provision_templates.rb +2 -2
- data/db/seeds.d/90-bookmarks.rb +19 -0
- data/doc/plugins/graphviz.rb +5 -5
- data/doc/plugins/plantuml.rb +6 -6
- data/doc/plugins/tags.rb +4 -4
- data/foreman_remote_execution.gemspec +3 -4
- data/lib/foreman_remote_execution/engine.rb +12 -9
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/test/factories/foreman_remote_execution_factories.rb +11 -9
- data/test/functional/api/v2/foreign_input_sets_controller_test.rb +63 -0
- data/test/functional/api/v2/job_invocations_controller_test.rb +45 -13
- data/test/functional/api/v2/job_templates_controller_test.rb +6 -6
- data/test/functional/api/v2/template_inputs_controller_test.rb +3 -3
- data/test/unit/actions/run_hosts_job_test.rb +3 -4
- data/test/unit/actions/run_proxy_command_test.rb +7 -7
- data/test/unit/concerns/host_extensions_test.rb +1 -1
- data/test/unit/execution_task_status_mapper_test.rb +93 -0
- data/test/unit/input_template_renderer_test.rb +182 -9
- data/test/unit/job_invocation_composer_test.rb +144 -168
- data/test/unit/job_invocation_test.rb +67 -15
- data/test/unit/job_template_effective_user_test.rb +2 -2
- data/test/unit/job_template_test.rb +36 -12
- data/test/unit/remote_execution_provider_test.rb +6 -6
- data/test/unit/targeting_test.rb +2 -2
- metadata +27 -21
- data/app/models/concerns/foreman_remote_execution/template_relations.rb +0 -10
- data/app/views/job_invocations/_host_provider_td.html.erb +0 -3
- data/app/views/job_templates/auto_complete_job_name.json.erb +0 -3
@@ -1,6 +1,15 @@
|
|
1
1
|
object @job_invocation
|
2
2
|
|
3
|
-
attributes :id, :
|
3
|
+
attributes :id, :description, :job_category, :targeting_id, :status, :start_at, :status_label
|
4
|
+
|
5
|
+
node do |invocation|
|
6
|
+
{
|
7
|
+
:succeeded => invocation_count(invocation, :output_key => :success_count),
|
8
|
+
:failed => invocation_count(invocation, :output_key => :failed_count),
|
9
|
+
:pending => invocation_count(invocation, :output_key => :pending_count),
|
10
|
+
:total => invocation_count(invocation, :output_key => :total_count)
|
11
|
+
}
|
12
|
+
end
|
4
13
|
|
5
14
|
child :task do
|
6
15
|
attributes :id, :state
|
@@ -2,8 +2,21 @@ object @job_invocation
|
|
2
2
|
|
3
3
|
extends "api/v2/job_invocations/base"
|
4
4
|
|
5
|
+
node do |invocation|
|
6
|
+
if invocation.triggering
|
7
|
+
case invocation.triggering.mode
|
8
|
+
when :recurring
|
9
|
+
{:mode => :recurring, :recurrence => partial('foreman_tasks/api/recurring_logics/base', :object => invocation.triggering.recurring_logic)}
|
10
|
+
when :future
|
11
|
+
{:mode => :future, :scheduling => {:start_at => invocation.triggering.start_at, :start_before => invocation.triggering.start_before }}
|
12
|
+
end
|
13
|
+
else
|
14
|
+
{:mode => :immediate}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
5
18
|
child :targeting do
|
6
|
-
attributes :bookmark_id, :search_query, :targeting_type, :user_id
|
19
|
+
attributes :bookmark_id, :search_query, :targeting_type, :user_id, :status, :status_label
|
7
20
|
|
8
21
|
child :hosts do
|
9
22
|
extends "api/v2/hosts/base"
|
@@ -2,8 +2,16 @@ object @job_template
|
|
2
2
|
|
3
3
|
extends "api/v2/job_templates/base"
|
4
4
|
|
5
|
-
attributes :audit_comment, :created_at, :updated_at
|
5
|
+
attributes :audit_comment, :description_format, :created_at, :updated_at, :template, :locked
|
6
6
|
|
7
7
|
child :template_inputs do
|
8
8
|
extends "api/v2/template_inputs/base"
|
9
9
|
end
|
10
|
+
|
11
|
+
child :effective_user => :effective_user do
|
12
|
+
attributes :value, :current_user, :overridable
|
13
|
+
end
|
14
|
+
|
15
|
+
node do |job_template|
|
16
|
+
partial("api/v2/taxonomies/children_nodes", :object => job_template)
|
17
|
+
end
|
@@ -1,13 +1,3 @@
|
|
1
1
|
object @job_template
|
2
2
|
|
3
3
|
extends "api/v2/job_templates/main"
|
4
|
-
|
5
|
-
attributes :template, :locked
|
6
|
-
|
7
|
-
child :effective_user => :effective_user do
|
8
|
-
attributes :value, :current_user, :overridable
|
9
|
-
end
|
10
|
-
|
11
|
-
node do |job_template|
|
12
|
-
partial("api/v2/taxonomies/children_nodes", :object => job_template)
|
13
|
-
end
|
@@ -2,7 +2,8 @@ object @template_input
|
|
2
2
|
|
3
3
|
extends "api/v2/template_inputs/base"
|
4
4
|
|
5
|
-
attributes :template_id, :fact_name, :variable_name, :puppet_parameter_name
|
5
|
+
attributes :template_id, :fact_name, :variable_name, :puppet_parameter_name, :puppet_class_name,
|
6
|
+
:description, :required
|
6
7
|
|
7
8
|
node :options do |input|
|
8
9
|
input.options.split(/\r?\n/) if input.options.present?
|
@@ -0,0 +1,4 @@
|
|
1
|
+
<%= textarea_f(f, :description, :label => _('Description'), :readonly => 'true', :disabled => disabled, :class => 'description', :rows => 2, :help_inline => description_checkbox_f(f, job_template, disabled)) %>
|
2
|
+
<div class="description_format_container <%= 'hidden' if f.object.description_format.nil? %>">
|
3
|
+
<%= description_format_textarea_f(f, job_template, disabled) %>
|
4
|
+
</div>
|
@@ -1,119 +1,101 @@
|
|
1
1
|
<script type="text/javascript">
|
2
2
|
$(function () {
|
3
|
-
regenerate_description($('
|
3
|
+
regenerate_description($('.description'))
|
4
4
|
});
|
5
5
|
</script>
|
6
6
|
|
7
7
|
<%= form_for @composer.job_invocation, :html => {'data-refresh-url' => refresh_job_invocations_path, :id => 'job_invocation_form'} do |f| %>
|
8
8
|
|
9
|
-
|
10
|
-
<li class="active"><a href="#primary" data-toggle="tab"><%= _('Job') %></a></li>
|
11
|
-
<li><a href="#scheduling" data-toggle="tab">Scheduling</a></li>
|
12
|
-
</ul>
|
9
|
+
<%= selectable_f f, :job_category, @composer.available_job_categories, {}, :label => _('Job category') %>
|
13
10
|
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
<% selected_templates_per_provider = {} %>
|
12
|
+
<% @composer.displayed_provider_types.each do |provider_type| %>
|
13
|
+
<%= f.fields_for 'providers' do |providers_fields| %>
|
14
|
+
<%= providers_fields.fields_for provider_type do |provider_type_fields| %>
|
15
|
+
<% templates_for_provider = @composer.templates_for_provider(provider_type) %>
|
16
|
+
<% selected_templates_per_provider[provider_type] = @composer.preselected_template_for_provider(provider_type) || templates_for_provider.first %>
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
<%= textarea_f targeting_fields, :search_query, :value => @composer.displayed_search_query, :rows => 5 %>
|
18
|
+
<%= selectable_f provider_type_fields, 'job_template_id', templates_for_provider.map { |t| [t.name, t.id] },
|
19
|
+
{ :selected => selected_templates_per_provider[provider_type].try(:id) },
|
20
|
+
{ :class => 'job_template_selector', :label => _('Job template'),
|
21
|
+
:data => { :provider_type => provider_type }, :required => true, :onchange => "template_change(this);" }%>
|
22
|
+
<% end %>
|
23
|
+
<% end %>
|
24
|
+
<% end %>
|
26
25
|
|
27
|
-
|
28
|
-
|
26
|
+
<%= fields_for @composer.targeting do |targeting_fields| %>
|
27
|
+
<span id="bookmark_query_map">
|
28
|
+
<% @composer.available_bookmarks.each do |bookmark| %>
|
29
|
+
<span id="bookmark-<%= bookmark.id %>" data-query="<%= bookmark.query %>"></span>
|
30
|
+
<% end %>
|
31
|
+
</span>
|
32
|
+
<%= selectable_f targeting_fields, :bookmark_id, @composer.available_bookmarks.map { |b| [b.name, b.id] }, :selected => @composer.targeting.bookmark_id, :include_blank => true %>
|
33
|
+
<%= textarea_f targeting_fields, :search_query, :value => @composer.displayed_search_query, :rows => 5 %>
|
29
34
|
|
30
|
-
|
31
|
-
|
32
|
-
<%= button_tag(:type => 'button', :class => 'btn btn-default btn-sm', :title => _("Refresh"), :id => 'refresh_execution_form') do %>
|
33
|
-
<%= icon_text('refresh') %>
|
34
|
-
<% end %>
|
35
|
-
<%= button_tag(:type => 'button', :class => 'btn btn-default btn-sm', :title => _("Preview"), :id => 'preview_hosts') do %>
|
36
|
-
<%= icon_text('eye-open') %>
|
37
|
-
<% end %>
|
38
|
-
</div>
|
39
|
-
</div>
|
35
|
+
<div class="form-group ">
|
36
|
+
<label class="col-md-2 control-label"><%= _('Resolves to') %></label>
|
40
37
|
|
41
|
-
|
42
|
-
|
38
|
+
<div class="col-md-4">
|
39
|
+
<%= @composer.targeted_hosts_count %> <%= _('hosts') %>
|
40
|
+
<%= button_tag(:type => 'button', :class => 'btn btn-default btn-sm', :title => _("Refresh"), :id => 'refresh_execution_form') do %>
|
41
|
+
<%= icon_text('refresh') %>
|
42
|
+
<% end %>
|
43
|
+
<%= button_tag(:type => 'button', :class => 'btn btn-default btn-sm', :title => _("Preview"), :id => 'preview_hosts') do %>
|
44
|
+
<%= icon_text('eye-open') %>
|
45
|
+
<% end %>
|
46
|
+
</div>
|
47
|
+
</div>
|
43
48
|
|
44
|
-
|
45
|
-
|
46
|
-
<%= radio_button_f targeting_fields, :targeting_type, :value => Targeting::DYNAMIC_TYPE, :text => _(Targeting::TYPES[Targeting::DYNAMIC_TYPE]) %>
|
47
|
-
</div>
|
48
|
-
<span class="help-inline"><%= popover(_('Explanation'),
|
49
|
-
_("Type has impact on when is the query evaulated to hosts.<br><ul><li><b>Static</b> - evaluates just after you submit this form</li><li><b>Dynamic</b> - evaluates just before the execution is started, so if it's planed in future, targeted hosts set may change before it</li></ul>")) %></span>
|
50
|
-
</div>
|
51
|
-
<% end %>
|
49
|
+
<div class="form-group ">
|
50
|
+
<label class="col-md-2 control-label"><%= _('Type of query') %></label>
|
52
51
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
<% end %>
|
64
|
-
<% @composer.templates_for_provider(provider_type).each do |job_template| %>
|
65
|
-
<%= radio_button_f provider_type_fields, 'job_template_id',
|
66
|
-
:value => job_template.id,
|
67
|
-
:text => job_template.name,
|
68
|
-
:onchange => "regenerate_description($(this).parent().next('fieldset'));",
|
69
|
-
:class => 'job_template_selector',
|
70
|
-
:checked => @composer.job_template_ids.include?(job_template.id) || @composer.only_one_template_available? %>
|
52
|
+
<div class="col-md-4">
|
53
|
+
<%= radio_button_f targeting_fields, :targeting_type, :value => Targeting::STATIC_TYPE, :text => _(Targeting::TYPES[Targeting::STATIC_TYPE]) %>
|
54
|
+
<%= radio_button_f targeting_fields, :targeting_type, :value => Targeting::DYNAMIC_TYPE, :text => _(Targeting::TYPES[Targeting::DYNAMIC_TYPE]) %>
|
55
|
+
</div>
|
56
|
+
|
57
|
+
<span class="help-inline"><%= popover(_('Explanation'),
|
58
|
+
_("Type has impact on when is the query evaulated to hosts.<br><ul><li><b>Static</b> - evaluates just after you submit this form</li><li><b>Dynamic</b> - evaluates just before the execution is started, so if it's planed in future, targeted hosts set may change before it</li></ul>")) %>
|
59
|
+
</span>
|
60
|
+
</div>
|
61
|
+
<% end %>
|
71
62
|
|
72
|
-
|
73
|
-
|
63
|
+
<% @composer.displayed_provider_types.each do |provider_type| %>
|
64
|
+
<fieldset id="provider_<%= provider_type %>" class="provider_form">
|
65
|
+
<%= f.fields_for 'providers' do |providers_fields| %>
|
66
|
+
<%= providers_fields.fields_for provider_type do |provider_type_fields| %>
|
67
|
+
<%= provider_type_fields.fields_for :job_templates do |job_templates_fields| %>
|
68
|
+
<% @composer.templates_for_provider(provider_type).each do |job_template| %>
|
69
|
+
<fieldset id="job_template_<%= job_template.id %>" class="job_template_form <%= 'hidden' if job_template != selected_templates_per_provider[provider_type] %>">
|
70
|
+
<%= job_templates_fields.fields_for job_template.id.to_s do |job_template_fields| %>
|
74
71
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
<% end %>
|
83
|
-
<% end %>
|
72
|
+
<%= job_template_fields.fields_for :input_values do |input_values_fields| %>
|
73
|
+
<% job_template.template_inputs_with_foreign.select { |input| input.input_type == 'user' }.each do |input| %>
|
74
|
+
<%= input_values_fields.fields_for input.id.to_s, @composer.template_invocation_input_value_for(job_template, input) do |input_fields| %>
|
75
|
+
<% unless input.options.blank? %>
|
76
|
+
<%= selectable_f input_fields, :value, input.options_array, {:include_blank => !input.required}, :require => input.required, :label => input.name, :help_inline => input.description, :id => input.name, :onchange => "regenerate_description(this);" %>
|
77
|
+
<% else %>
|
78
|
+
<%= textarea_f input_fields, :value, :label => input.name, :help_inline => input.description, :required => input.required, :rows => 2, :onchange => "regenerate_description(this);", :id => input.name %>
|
84
79
|
<% end %>
|
85
80
|
<% end %>
|
86
|
-
<% if job_template.effective_user.overridable? %>
|
87
|
-
<%= text_f job_template_fields, :effective_user, :label => _('Effective user'), :help_inline => N_("A user to be used for executing the script. If it differs from the SSH user, su or sudo is used to switch the accounts.") %>
|
88
|
-
<% end %>
|
89
|
-
|
90
81
|
<% end %>
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
:rows => 2,
|
97
|
-
:onchange => "regenerate_description(this);",
|
98
|
-
:id => "description_format",
|
99
|
-
:help_inline => popover(_('Explanation'), _('Description template determines the job name once it is submitted. Input values can become part of the name
|
100
|
-
if they are specified using interpolation syntax, e.g. %{fqdn} where fqdn is the name of interpolated input.')) %>
|
101
|
-
</div>
|
102
|
-
</fieldset>
|
82
|
+
<% end %>
|
83
|
+
<% if job_template.effective_user.overridable? %>
|
84
|
+
<%= text_f job_template_fields, :effective_user, :label => _('Effective user'), :help_inline => N_("A user to be used for executing the script. If it differs from the SSH user, su or sudo is used to switch the accounts.") %>
|
85
|
+
<% end %>
|
86
|
+
<%= render :partial => 'description_fields', :locals => { :f => f, :job_template => job_template, :disabled => job_template != selected_templates_per_provider[provider_type] } %>
|
103
87
|
<% end %>
|
104
|
-
|
88
|
+
</fieldset>
|
105
89
|
<% end %>
|
106
90
|
<% end %>
|
107
|
-
|
91
|
+
<% end %>
|
108
92
|
<% end %>
|
93
|
+
</fieldset>
|
94
|
+
<% end %>
|
109
95
|
|
110
|
-
|
111
|
-
|
96
|
+
<%= trigger_selector f, @composer.triggering %>
|
97
|
+
<%= render :partial => 'preview_hosts_modal' %>
|
112
98
|
|
113
|
-
<div class="tab-pane" id="scheduling">
|
114
|
-
<%= trigger_selector f, @composer.triggering %>
|
115
|
-
</div>
|
116
|
-
</div>
|
117
99
|
|
118
100
|
<%= submit_or_cancel f %>
|
119
101
|
<% end %>
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<td class="host_actions" id="<%= dom_id(host) %>-actions" data-refresh_required="
|
2
|
-
<%= action_buttons(template_invocation_actions(task, host)) %>
|
1
|
+
<td class="host_actions" id="<%= dom_id(host) %>-actions" data-refresh_required="" data-id="<%= host.id %>">
|
2
|
+
<%= action_buttons(template_invocation_actions(task, host, job_invocation, template_invocation)) %>
|
3
3
|
</td>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<td class="host_name" id="<%= dom_id(host) %>-name" data-refresh_required="<%= task.nil? ? 'true' : '' %>" data-id="<%= host.id %>">
|
2
|
+
<% if task %>
|
3
|
+
<%= link_to_if_authorized host.name, hash_for_template_invocation_path(:id => template_invocation).merge(:auth_object => host, :permission => :view_hosts) %>
|
4
|
+
<% else %>
|
5
|
+
<%= host.name %>
|
6
|
+
<% end %>
|
7
|
+
</td>
|
@@ -19,7 +19,6 @@
|
|
19
19
|
<thead>
|
20
20
|
<tr>
|
21
21
|
<th><%= sort :name, :as => _('Host') %></th>
|
22
|
-
<th><%= _('Provider') %></th>
|
23
22
|
<th><%= _('Status') %></th>
|
24
23
|
<th><%= _('Actions') %></th>
|
25
24
|
</tr>
|
@@ -27,12 +26,13 @@
|
|
27
26
|
|
28
27
|
<tbody>
|
29
28
|
<% hosts.each do |host| %>
|
30
|
-
<%
|
29
|
+
<% template_invocation = job_invocation.template_invocations.find { |template_invocation| template_invocation.host_id == host.id } %>
|
30
|
+
<% task = template_invocation.try(:run_host_job_task) %>
|
31
31
|
<tr>
|
32
|
-
|
33
|
-
<%= render
|
34
|
-
<%= render
|
35
|
-
<%= render
|
32
|
+
<% options = { :host => host, :task => task, :job_invocation => job_invocation, :template_invocation => template_invocation } %>
|
33
|
+
<%= render 'host_name_td', options %>
|
34
|
+
<%= render 'host_status_td', options %>
|
35
|
+
<%= render 'host_actions_td', options %>
|
36
36
|
</tr>
|
37
37
|
<% end %>
|
38
38
|
</tbody>
|
@@ -13,8 +13,8 @@
|
|
13
13
|
<pre><%= job_invocation.targeting.search_query %></pre>
|
14
14
|
|
15
15
|
<%= _('Evaluated at:') %> <%= job_invocation.targeting.resolved_at %><br>
|
16
|
-
<% if job_invocation.
|
17
|
-
<% job_invocation.
|
16
|
+
<% if job_invocation.pattern_template_invocations.size > 1 %>
|
17
|
+
<% job_invocation.pattern_template_invocations.each do |template_invocation| %>
|
18
18
|
<%= host_counter template_invocation.template.provider.humanized_name, ForemanTasks::Task::DynflowTask.for_action(Actions::RemoteExecution::RunHostJob).for_resource(template_invocation).uniq.size %>
|
19
19
|
<% end %>
|
20
20
|
<% end %>
|
@@ -23,7 +23,7 @@
|
|
23
23
|
|
24
24
|
<div class="col-md-6 infoblock">
|
25
25
|
<h4><%= _('Providers and templates') %></h4>
|
26
|
-
<% job_invocation.
|
26
|
+
<% job_invocation.pattern_template_invocations.each do |template_invocation| %>
|
27
27
|
<h5>
|
28
28
|
<b><%= template_invocation.template.name %></b> <%= 'through' %> <%= template_invocation.template.provider.humanized_name %>
|
29
29
|
</h5>
|
@@ -1,28 +1,30 @@
|
|
1
1
|
<% title _('Job invocations') %>
|
2
2
|
|
3
|
+
<% title_actions(job_invocations_buttons) %>
|
4
|
+
|
3
5
|
<table class="table table-bordered table-striped table-condensed">
|
4
6
|
<thead>
|
5
7
|
<tr>
|
6
|
-
<th><%= sort :
|
8
|
+
<th><%= sort :description, :as => _('Description') %></th>
|
7
9
|
<th><%= _('Status') %></th>
|
8
10
|
<th><%= _('Succeeded') %></th>
|
9
11
|
<th><%= _('Failed') %></th>
|
10
12
|
<th><%= _('Pending') %></th>
|
11
13
|
<th><%= _('Total hosts') %></th>
|
12
|
-
<th><%= sort :
|
14
|
+
<th><%= sort :start_at, :as => _('Start') %></th>
|
13
15
|
</tr>
|
14
16
|
</thead>
|
15
17
|
|
16
18
|
<tbody>
|
17
19
|
<% @job_invocations.each do |invocation| %>
|
18
20
|
<tr>
|
19
|
-
<td><%= link_to_if_authorized "#{invocation.description.try(:capitalize) || invocation.
|
21
|
+
<td><%= link_to_if_authorized "#{invocation.description.try(:capitalize) || invocation.job_category}", hash_for_job_invocation_path(invocation).merge(:auth_object => invocation, :permission => :view_job_invocations) %></td>
|
20
22
|
<td><%= link_to_invocation_task_if_authorized(invocation) %></td>
|
21
23
|
<td><%= invocation_count(invocation, :output_key => :success_count) %></td>
|
22
24
|
<td><%= invocation_count(invocation, :output_key => :failed_count) %></td>
|
23
25
|
<td><%= invocation_count(invocation, :output_key => :pending_count) %></td>
|
24
26
|
<td><%= invocation_count(invocation, :output_key => :total_count) %></td>
|
25
|
-
|
27
|
+
<td><%= time_in_words_span(invocation.start_at) %></td>
|
26
28
|
</tr>
|
27
29
|
<% end %>
|
28
30
|
</tbody>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
$('div.btn-group').html('<%= button_group(job_invocation_task_buttons(@job_invocation.task)).html_safe %>');
|
1
|
+
$('div#title_action div.btn-group').html('<%= button_group(job_invocation_task_buttons(@job_invocation.task)).html_safe %>');
|
2
2
|
$('div#status_chart').html('<%=j job_invocation_chart(@job_invocation) %>');
|
3
3
|
$('div#status').flot_pie();
|
4
4
|
|
@@ -8,12 +8,15 @@ $('div#status').flot_pie();
|
|
8
8
|
hosts_tab.data('refresh_required', '');
|
9
9
|
<% end %>
|
10
10
|
|
11
|
-
<% ['status', 'actions', 'provider'].each do |attribute| %>
|
11
|
+
<% ['name', 'status', 'actions', 'provider'].each do |attribute| %>
|
12
12
|
<% if params["host_ids_needing_#{attribute}_update"].present? %>
|
13
13
|
var td_element;
|
14
14
|
<% Host.authorized(:view_hosts, Host).where(:id => params["host_ids_needing_#{attribute}_update"]).each do |host| %>
|
15
|
+
<% template_invocation = @job_invocation.template_invocations.find { |template_invocation| template_invocation.host_id == host.id } %>
|
16
|
+
<% task = template_invocation.try(:run_host_job_task) %>
|
17
|
+
<% options = { :host => host, :task => task, :job_invocation => @job_invocation, :template_invocation => template_invocation } %>
|
15
18
|
td_element= $('#<%= dom_id(host) %>-<%= attribute %>');
|
16
|
-
td_element.replaceWith('<%=j render("host_#{attribute}_td",
|
19
|
+
td_element.replaceWith('<%=j render("host_#{attribute}_td", options) %>');
|
17
20
|
<% end %>
|
18
21
|
<% end %>
|
19
22
|
<% end %>
|