foreman_remote_execution 0.2.3 → 0.3.0

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.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +7 -0
  4. data/.rubocop_todo.yml +16 -5
  5. data/.tx/config +1 -1
  6. data/app/assets/javascripts/template_invocation.js +14 -1
  7. data/app/assets/stylesheets/job_invocations.css.scss +0 -13
  8. data/app/assets/stylesheets/template_invocation.css.scss +7 -13
  9. data/app/controllers/api/v2/foreign_input_sets_controller.rb +1 -1
  10. data/app/controllers/api/v2/job_invocations_controller.rb +12 -18
  11. data/app/controllers/api/v2/remote_execution_features_controller.rb +38 -0
  12. data/app/controllers/api/v2/template_inputs_controller.rb +1 -0
  13. data/app/controllers/job_invocations_controller.rb +3 -13
  14. data/app/controllers/job_templates_controller.rb +1 -1
  15. data/app/controllers/remote_execution_features_controller.rb +19 -0
  16. data/app/helpers/concerns/foreman_remote_execution/hosts_helper_extensions.rb +1 -22
  17. data/app/helpers/remote_execution_helper.rb +30 -12
  18. data/app/lib/actions/remote_execution/helpers/live_output.rb +2 -2
  19. data/app/lib/actions/remote_execution/run_host_job.rb +7 -4
  20. data/app/lib/actions/remote_execution/run_hosts_job.rb +14 -0
  21. data/app/lib/actions/remote_execution/run_proxy_command.rb +2 -2
  22. data/app/models/concerns/foreman_remote_execution/host_extensions.rb +5 -4
  23. data/app/models/concerns/foreman_remote_execution/subnet_extensions.rb +1 -0
  24. data/app/models/input_template_renderer.rb +14 -3
  25. data/app/models/job_invocation.rb +6 -15
  26. data/app/models/job_invocation_composer.rb +131 -21
  27. data/app/models/job_template.rb +77 -22
  28. data/app/models/job_template_effective_user.rb +0 -2
  29. data/app/models/remote_execution_feature.rb +34 -0
  30. data/app/models/setting/remote_execution.rb +4 -1
  31. data/app/models/targeting.rb +2 -2
  32. data/app/models/template_input.rb +17 -13
  33. data/app/views/api/v2/remote_execution_features/base.json.rabl +3 -0
  34. data/app/views/api/v2/remote_execution_features/index.json.rabl +3 -0
  35. data/app/views/api/v2/remote_execution_features/main.json.rabl +3 -0
  36. data/app/views/api/v2/remote_execution_features/show.json.rabl +3 -0
  37. data/app/views/job_invocations/_form.html.erb +51 -40
  38. data/app/views/job_invocations/_preview_hosts_list.html.erb +1 -1
  39. data/app/views/job_invocations/_tab_hosts.html.erb +6 -3
  40. data/app/views/job_invocations/index.html.erb +11 -11
  41. data/app/views/job_templates/_custom_tabs.html.erb +4 -4
  42. data/app/views/job_templates/index.html.erb +5 -5
  43. data/app/views/overrides/nics/_execution_interface.html.erb +9 -1
  44. data/app/views/remote_execution_features/_form.html.erb +24 -0
  45. data/app/views/remote_execution_features/index.html.erb +21 -0
  46. data/app/views/remote_execution_features/show.html.erb +3 -0
  47. data/app/views/template_inputs/_form.html.erb +1 -0
  48. data/app/views/template_inputs/_invocation_form.html.erb +7 -0
  49. data/app/views/templates/package_action.erb +17 -5
  50. data/app/views/templates/power_action.erb +22 -0
  51. data/app/views/templates/puppet_run_once.erb +1 -1
  52. data/config/routes.rb +4 -0
  53. data/db/migrate/20160113162007_expand_all_template_invocations.rb +1 -1
  54. data/db/migrate/20160118124600_create_remote_execution_features.rb +14 -0
  55. data/db/migrate/20160125155108_make_job_template_name_unique.rb +12 -0
  56. data/db/migrate/20160127134031_add_advanced_to_template_input.rb +11 -0
  57. data/db/migrate/20160127162711_reword_puppet_template_description.rb +9 -0
  58. data/db/migrate/20160203104056_add_concurrency_options_to_job_invocation.rb +6 -0
  59. data/db/seeds.d/70-job_templates.rb +2 -1
  60. data/doc/plugins/div_tag.rb +1 -1
  61. data/doc/plugins/plantuml.rb +1 -1
  62. data/doc/plugins/tags.rb +7 -8
  63. data/doc/plugins/toc.rb +0 -1
  64. data/foreman_remote_execution.gemspec +1 -1
  65. data/lib/foreman_remote_execution/engine.rb +10 -2
  66. data/lib/foreman_remote_execution/version.rb +1 -1
  67. data/locale/action_names.rb +8 -0
  68. data/locale/en/foreman_remote_execution.po +767 -11
  69. data/locale/foreman_remote_execution.pot +1026 -8
  70. data/test/functional/api/v2/foreign_input_sets_controller_test.rb +1 -1
  71. data/test/functional/api/v2/job_invocations_controller_test.rb +0 -9
  72. data/test/functional/api/v2/job_templates_controller_test.rb +11 -11
  73. data/test/functional/api/v2/remote_execution_features_controller_test.rb +35 -0
  74. data/test/functional/api/v2/template_inputs_controller_test.rb +1 -1
  75. data/test/unit/actions/run_hosts_job_test.rb +48 -7
  76. data/test/unit/actions/run_proxy_command_test.rb +1 -1
  77. data/test/unit/concerns/host_extensions_test.rb +11 -0
  78. data/test/unit/input_template_renderer_test.rb +4 -4
  79. data/test/unit/job_invocation_composer_test.rb +52 -2
  80. data/test/unit/job_invocation_test.rb +1 -1
  81. data/test/unit/job_template_test.rb +126 -3
  82. data/test/unit/remote_execution_feature_test.rb +42 -0
  83. data/test/unit/targeting_test.rb +4 -4
  84. metadata +26 -7
  85. data/app/views/job_invocation_task_groups/_job_invocation_task_group.html.erb +0 -31
  86. data/app/views/unattended/snippets/_remote_execution_ssh_keys.erb +0 -18
  87. data/db/seeds.d/80-provision_templates.rb +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 85fa812b15aa151cf2a16622d6f8a948fa112042
4
- data.tar.gz: 530bbbd4c60e53d39fa6d6610f613e95a4d6f84c
3
+ metadata.gz: 42b3d239b3161263e650d3d6d6dba548e732145b
4
+ data.tar.gz: aeadb8c264c040867f45d224fc87724f056976db
5
5
  SHA512:
6
- metadata.gz: fe774b17034cecef1ccb880aaa46f1874ac81b0fca7c955a5f6c3e0ecf80782d56e2b5583a67d7df873f3420e679af6a3577243e9aa28d8868efcb8a9f57b0a3
7
- data.tar.gz: d9cdabe2fe9e1ab6c8780b80131b3eed503fcc80994c0c8b1a40e2a342587af9542942718ac892d7c88d881495a2759e1933b7394df7845f3b4b4ea83a46db6d
6
+ metadata.gz: 4b507b186ef9ba52d7612e2843fed86c268bb9dda737e6c8e029a7c9a1046b45caf5495d7e65ed35ce4f9e4a1b8fc2fc9c33ae9763684b5a77e60b61fb69a9ae
7
+ data.tar.gz: 0b7dbd1acb92629cf67f3a4a80f87ba7280f832196efaf471f60d50b278d9823e6da9907991b25552304bf78608305c84c048162d9ae56df8bbb68da9caa2078
data/.gitignore CHANGED
@@ -9,4 +9,6 @@ test/dummy/tmp/
9
9
  test/dummy/.sass-cache
10
10
  locale/*.mo
11
11
  locale/*/*.pox
12
+ locale/*/*.edit.po
13
+ locale/*/*.po.time_stamp
12
14
  Gemfile.lock
@@ -3,6 +3,13 @@ inherit_from:
3
3
 
4
4
  AllCops:
5
5
  RunRailsCops: true # always run the rails cops
6
+ Exclude:
7
+ - 'doc/plugins/**'
8
+
9
+ # TODO: uncomment when on rubocop 0.35.1
10
+ #Rails/Date:
11
+ #Exclude:
12
+ #- foreman_remote_execution.gemspec
6
13
 
7
14
  # Don't enforce documentation
8
15
  Style/Documentation:
@@ -54,11 +54,6 @@ Style/AndOr:
54
54
  Style/BarePercentLiterals:
55
55
  Enabled: false
56
56
 
57
- # Offense count: 3
58
- # Cop supports --auto-correct.
59
- Style/Blocks:
60
- Enabled: false
61
-
62
57
  # Offense count: 1
63
58
  # Configuration parameters: IndentWhenRelativeTo, SupportedStyles, IndentOneStep.
64
59
  Style/CaseIndentation:
@@ -200,3 +195,19 @@ Style/SpaceInsideHashLiteralBraces:
200
195
  # Configuration parameters: IgnoredMethods.
201
196
  Style/SymbolProc:
202
197
  Enabled: false
198
+
199
+ # TODO: uncomment when on rubocop 0.35.1
200
+ #Rails/FindBy:
201
+ #Enabled: false # rails 4
202
+
203
+ # TODO: uncomment when on rubocop 0.35.1
204
+ #Style/UnneededPercentQ:
205
+ #Enabled: false
206
+
207
+ # TODO: uncomment when on rubocop 0.35.1
208
+ #Lint/EndAlignment:
209
+ #Enabled: false
210
+
211
+ # TODO: uncomment when on rubocop 0.35.1
212
+ #Metrics/ModuleLength:
213
+ #Enabled: false
data/.tx/config CHANGED
@@ -2,7 +2,7 @@
2
2
  host = https://www.transifex.com
3
3
 
4
4
  [foreman.foreman_remote_execution]
5
- file_filter = locale/<lang>/foreman_remote_execution.po
5
+ file_filter = locale/<lang>/foreman_remote_execution.edit.po
6
6
  source_file = locale/foreman_remote_execution.pot
7
7
  source_lang = en
8
8
  type = PO
@@ -74,6 +74,19 @@ function job_invocation_form_binds() {
74
74
  $('textarea#targeting_search_query').on('change', refresh_execution_form);
75
75
 
76
76
  $('select#targeting_bookmark_id').on('change', refresh_search_query);
77
+
78
+ $('a.advanced_fields_switch').on('click', toggle_advanced_fields )
79
+ }
80
+
81
+ function toggle_advanced_fields() {
82
+ switcher = $('a.advanced_fields_switch');
83
+ original = switcher.html();
84
+ switcher.html(switcher.data('alternativeLabel'));
85
+ switcher.data('alternativeLabel', original);
86
+
87
+ switcher.siblings('i').toggleClass('fa-angle-right').toggleClass('fa-angle-down');
88
+
89
+ $('div.advanced').toggle()
77
90
  }
78
91
 
79
92
  function delayed_refresh(url, data){
@@ -83,7 +96,7 @@ function delayed_refresh(url, data){
83
96
  url: url,
84
97
  data: data,
85
98
  dataType: "script",
86
- error: function() { $("div.terminal div.printable").append(__('<div class="line error">There was an error while updating the status, try <a href="javascript:window.location.href=window.location.href">refreshing</a> the page</div>')) }
99
+ error: function() { $("div.terminal div.printable").append('<div class="line error">' + __('There was an error while updating the status, try refreshing the page.') + '</div>'); }
87
100
  }
88
101
  )
89
102
  }, 1000);
@@ -20,16 +20,3 @@ div.infoblock {
20
20
  }
21
21
  }
22
22
  }
23
-
24
- // chances are that these will be present in Foreman 1.10
25
- .status-ok {
26
- color: #5CB85C;
27
- }
28
-
29
- .status-error {
30
- color: #D9534F
31
- }
32
-
33
- .status-warn, .status-question {
34
- color: #DB843D;
35
- }
@@ -19,27 +19,21 @@ div.terminal {
19
19
  display: block;
20
20
  padding: 9.5px;
21
21
  margin: 0 0 10px;
22
- font-size: 13px;
23
- line-height: 1.428571429;
22
+ font-size: 12px;
24
23
  word-break: break-all;
25
24
  word-wrap: break-word;
26
- color: #B2B2B2;
27
- background-color: #000000;
25
+ color: rgba(255, 255, 255, 1);
26
+ background-color: rgba(47, 47, 47, 1);
28
27
  border: 1px solid #000000;
29
- border-radius: 4px;
30
- font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
28
+ border-radius: 0px;
29
+ font-family: Menlo, Monaco, Consolas, monospace;
31
30
 
32
31
  div.printable {
33
32
  min-height: 50px;
34
33
  }
35
34
 
36
- div.line.error, div.line.debug {
37
- color: #a9302a;
38
- }
39
-
40
- div.line.stderr {
41
- background-color: rgba(205, 209, 207, 0.21);
42
- color: #FFFFFF;
35
+ div.line.stderr, div.line.error, div.line.debug {
36
+ color: red;
43
37
  }
44
38
 
45
39
  div.line span.counter {
@@ -22,7 +22,7 @@ module Api
22
22
 
23
23
  def_param_group :foreign_input_set do
24
24
  param :foreign_input_set, Hash, :required => true, :action_aware => true do
25
- param :target_template_id, :identifier, :required => true, :desc => N_('Target template id')
25
+ param :target_template_id, :identifier, :required => true, :desc => N_('Target template ID')
26
26
  param :include_all, :bool, :desc => N_('Include all inputs form the foreign template')
27
27
  param :include, String, :desc => N_('A comma separated list of input names to be included from the foreign template.')
28
28
  param :exclude, String, :desc => N_('A comma separated list of input names to be included from the foreign template.')
@@ -8,7 +8,7 @@ module Api
8
8
  before_filter :find_optional_nested_object
9
9
  before_filter :find_host, :only => %w{output}
10
10
  before_filter :find_resource, :only => %w{show update destroy clone}
11
- before_filter :validate_templates, :only => :create
11
+ before_filter :validate_template, :only => :create
12
12
 
13
13
  wrap_parameters JobInvocation, :include => (JobInvocation.attribute_names + [:ssh])
14
14
 
@@ -25,8 +25,7 @@ module Api
25
25
 
26
26
  def_param_group :job_invocation do
27
27
  param :job_invocation, Hash, :required => true, :action_aware => true do
28
- param :job_category, String, :required => true, :desc => N_('Job category')
29
- param :job_template_id, String, :required => false, :desc => N_('If using a specific template, the id of that template.')
28
+ param :job_template_id, String, :required => true, :desc => N_('The job template to use')
30
29
  param :targeting_type, String, :required => true, :desc => N_('Invocation type, one of %s') % Targeting::TYPES
31
30
  param :inputs, Hash, :required => false, :desc => N_('Inputs to use')
32
31
  param :ssh, Hash, :desc => N_('SSH provider specific options') do
@@ -46,6 +45,11 @@ module Api
46
45
  param :start_before, DateTime, :required => false, :desc => N_('Indicates that the action should be cancelled if it cannot be started before this time.')
47
46
  end
48
47
 
48
+ param :concurrency_control, Hash, :desc => N_('Control concurrency level and distribution over time') do
49
+ param :time_span, Integer, :desc => N_('Distribute tasks over N seconds')
50
+ param :concurrency_level, Integer, :desc => N_('Run at most N tasks at a time')
51
+ end
52
+
49
53
  param :bookmark_id, Integer, :required => false
50
54
  param :search_query, Integer, :required => false
51
55
  param :description_format, String, :required => false, :desc => N_('Override the description format from the template for this invocation only')
@@ -56,10 +60,8 @@ module Api
56
60
  param_group :job_invocation, :as => :create
57
61
  def create
58
62
  composer = JobInvocationComposer.from_api_params(job_invocation_params)
59
- composer.save!
63
+ composer.trigger!
60
64
  @job_invocation = composer.job_invocation
61
- @job_invocation.generate_description! if @job_invocation.description.blank?
62
- composer.triggering.trigger(::Actions::RemoteExecution::RunHostsJob, @job_invocation)
63
65
  process_response @job_invocation
64
66
  end
65
67
 
@@ -99,18 +101,10 @@ module Api
99
101
  not_found({ :error => { :message => (_("Host with id '%{id}' was not found") % { :id => params['host_id'] }) } })
100
102
  end
101
103
 
102
- def validate_templates
103
- templates = []
104
- if job_invocation_params[:job_template_id]
105
- templates << JobTemplate.find(job_invocation_params[:job_template_id])
106
- else
107
- templates = JobTemplate.where(:job_category => job_invocation_params[:job_category])
108
- if templates.pluck(:provider_type).uniq.length != templates.length
109
- raise Foreman::Exception, _('Duplicate remote execution providers found for specified Job, please specify a single job_template_id.')
110
- end
111
- end
112
-
113
- raise Foreman::Exception, _('No templates associated with specified Job Name') if templates.empty?
104
+ def validate_template
105
+ JobTemplate.authorized(:view_job_templates).find(job_invocation_params['job_template_id'])
106
+ rescue ActiveRecord::RecordNotFound
107
+ not_found({ :error => { :message => (_("Template with id '%{id}' was not found") % { :id => job_invocation_params['job_template_id'] }) } })
114
108
  end
115
109
 
116
110
  def job_invocation_params
@@ -0,0 +1,38 @@
1
+ module Api
2
+ module V2
3
+ class RemoteExecutionFeaturesController < ::Api::V2::BaseController
4
+ include ::Api::Version2
5
+
6
+ before_filter :find_resource, :only => %w{show update}
7
+
8
+ api :GET, '/remote_execution_features/', N_('List remote execution features')
9
+ def index
10
+ @remote_execution_features = resource_scope
11
+ end
12
+
13
+ api :GET, '/remote_execution_features/:id', N_('Show remote execution feature')
14
+ param :id, :identifier, :required => true
15
+ def show
16
+ end
17
+
18
+ def_param_group :remote_execution_feature do
19
+ param :remote_execution_feature, Hash, :required => true, :action_aware => true do
20
+ param :job_template_id, :identifier, :required => true, :desc => N_('Job template ID to be used for the feature')
21
+ end
22
+ end
23
+
24
+ api :PUT, '/remote_execution_features/:id', N_('Update a job template')
25
+ param :id, :identifier, :required => true
26
+ param_group :remote_execution_feature
27
+ def update
28
+ process_response @remote_execution_feature.update_attributes(params[:remote_execution_feature])
29
+ end
30
+
31
+ private
32
+
33
+ def parent_scope
34
+ resource_class.where(nil)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -26,6 +26,7 @@ module Api
26
26
  param :name, String, :required => true, :desc => N_('Input name')
27
27
  param :description, String, :required => false, :desc => N_('Input description')
28
28
  param :required, :bool, :allow_nil => true, :desc => N_('Input is required')
29
+ param :advanced, :bool, :allow_nil => true, :desc => N_('Input is advanced')
29
30
  param :input_type, TemplateInput::TYPES.keys.map(&:to_s), :required => true, :desc => N_('Input type')
30
31
  param :fact_name, String, :required => false, :desc => N_('Fact name, used when input type is fact')
31
32
  param :variable_name, String, :required => false, :desc => N_('Variable name, used when input type is variable')
@@ -1,8 +1,6 @@
1
1
  class JobInvocationsController < ApplicationController
2
2
  include Foreman::Controller::AutoCompleteSearch
3
3
 
4
- before_filter :find_or_create_triggering, :only => [:create, :refresh]
5
-
6
4
  def new
7
5
  ui_params = {
8
6
  :host_ids => params[:host_ids],
@@ -27,10 +25,9 @@ class JobInvocationsController < ApplicationController
27
25
  def rerun
28
26
  job_invocation = resource_base.find(params[:id])
29
27
  @composer = JobInvocationComposer.from_job_invocation(job_invocation)
30
-
31
28
  if params[:failed_only]
32
29
  host_ids = job_invocation.failed_host_ids
33
- @composer.search_query = @composer.targeting.build_query_from_hosts(host_ids)
30
+ @composer.search_query = Targeting.build_query_from_hosts(host_ids)
34
31
  end
35
32
 
36
33
  render :action => 'new'
@@ -38,11 +35,8 @@ class JobInvocationsController < ApplicationController
38
35
 
39
36
  def create
40
37
  @composer = JobInvocationComposer.from_ui_params(params)
41
- if @composer.save
42
- job_invocation = @composer.job_invocation
43
- job_invocation.generate_description! if job_invocation.description.blank?
44
- @composer.triggering.trigger(::Actions::RemoteExecution::RunHostsJob, job_invocation)
45
- redirect_to job_invocation_path(job_invocation)
38
+ if @composer.trigger
39
+ redirect_to job_invocation_path(@composer.job_invocation)
46
40
  else
47
41
  @composer.job_invocation.description_format = nil if params[:job_invocation].key?(:description_override)
48
42
  render :action => 'new'
@@ -79,10 +73,6 @@ class JobInvocationsController < ApplicationController
79
73
 
80
74
  private
81
75
 
82
- def find_or_create_triggering
83
- @triggering ||= ::ForemanTasks::Triggering.new_from_params(params[:triggering])
84
- end
85
-
86
76
  def action_permission
87
77
  case params[:action]
88
78
  when 'rerun'
@@ -20,7 +20,7 @@ class JobTemplatesController < ::TemplatesController
20
20
  if (output = renderer.preview)
21
21
  render :text => output
22
22
  else
23
- render :status => 406, :text => renderer.error_message + _(', note that you must save template input changes before you try to preview it.')
23
+ render :status => 406, :text => _('Problem with previewing the template: %{error}. Note that you must save template input changes before you try to preview it.' % {:error => renderer.error_message})
24
24
  end
25
25
  end
26
26
 
@@ -0,0 +1,19 @@
1
+ class RemoteExecutionFeaturesController < ::ApplicationController
2
+ before_filter :find_resource, :only => [:show, :update]
3
+
4
+ def index
5
+ @remote_execution_features = resource_base.all
6
+ end
7
+
8
+ def show
9
+ end
10
+
11
+ def update
12
+ if @remote_execution_feature.update_attributes(params[:remote_execution_feature])
13
+ process_success :object => @remote_execution_feature
14
+ else
15
+ process_error :object => @remote_execution_feature
16
+ end
17
+ end
18
+
19
+ end
@@ -5,36 +5,15 @@ module ForemanRemoteExecution
5
5
  included do
6
6
  alias_method_chain(:host_title_actions, :run_button)
7
7
  alias_method_chain :multiple_actions, :remote_execution
8
- alias_method_chain :multiple_actions_select, :remote_execution
9
8
  end
10
9
 
11
10
  def multiple_actions_with_remote_execution
12
- # The modal window loads empty page, we hook the custom function
13
- # to the link later. The ?run_job=true is there just to be able to identify the link
14
- multiple_actions_without_remote_execution + [[_('Run Job'), 'blank.html?run_job=true']]
11
+ multiple_actions_without_remote_execution + [[_('Run Job'), new_job_invocation_path, false]]
15
12
  end
16
13
 
17
14
  def host_title_actions_with_run_button(*args)
18
15
  title_actions(button_group(link_to(_('Run Job'), new_job_invocation_path(:host_ids => [args.first.id]), :id => :run_button)))
19
16
  host_title_actions_without_run_button(*args)
20
17
  end
21
-
22
- def multiple_actions_select_with_remote_execution(*args)
23
- # TODO: awful hack to open the job invocation form as a new
24
- # page rather than using the AJAX inside a modal window.
25
- # Since we want for this plugin to be compatible with 1.9, we
26
- # need to monkey patch/js hack for now, but it should be removed
27
- # after we fix and release http://projects.theforeman.org/issues/11309
28
- multiple_actions_select_without_remote_execution(*args) +
29
- <<-JAVASCRIPT.html_safe
30
- <script>
31
- $(function () {
32
- $("#submit_multiple a[onclick*='blank.html?run_job=true']").click(function (e) {
33
- document.location = "#{new_job_invocation_path}?" + $.param({host_ids: $.foremanSelectedHosts});
34
- })
35
- })
36
- </script>
37
- JAVASCRIPT
38
- end
39
18
  end
40
19
  end
@@ -1,3 +1,4 @@
1
+ # rubocop:disable Metrics/ModuleLength
1
2
  module RemoteExecutionHelper
2
3
  def providers_options
3
4
  RemoteExecutionProvider.providers.map { |key, provider| [ key, _(provider) ] }
@@ -34,7 +35,7 @@ module RemoteExecutionHelper
34
35
  when HostStatus::ExecutionStatus::QUEUED
35
36
  _('queued')
36
37
  when HostStatus::ExecutionStatus::RUNNING
37
- _('running %s%') % invocation.progress
38
+ _('running %{percent}%') % {:percent => invocation.progress}
38
39
  when HostStatus::ExecutionStatus::OK
39
40
  _('succeeded')
40
41
  when HostStatus::ExecutionStatus::ERROR
@@ -60,19 +61,19 @@ module RemoteExecutionHelper
60
61
 
61
62
  def template_invocation_status(task)
62
63
  if task.nil?
63
- content_tag(:i, '&nbsp'.html_safe, :class => 'glyphicon glyphicon-question-sign') + content_tag(:span, _('N/A'))
64
+ icon_text('question', 'N/A', :kind => 'fa')
64
65
  else
65
66
  case task.result
66
67
  when 'warning', 'error'
67
68
  if task_cancelled?(task)
68
- content_tag(:i, '&nbsp'.html_safe, :class => 'glyphicon glyphicon-warning-sign') + content_tag(:span, _('cancelled'), :class => 'status-error')
69
+ icon_text('warning-triangle-o', _('cancelled'), :kind => 'pficon')
69
70
  else
70
- content_tag(:i, '&nbsp'.html_safe, :class => 'glyphicon glyphicon-exclamation-sign') + content_tag(:span, _('failed'), :class => 'status-error')
71
+ icon_text('error-circle-o', _('failed'), :kind => 'pficon')
71
72
  end
72
73
  when 'success'
73
- content_tag(:i, '&nbsp'.html_safe, :class => 'glyphicon glyphicon-ok-sign') + content_tag(:span, _('success'), :class => 'status-ok')
74
+ icon_text('ok', _('success'), :kind => 'pficon')
74
75
  when 'pending'
75
- content_tag(:i, '&nbsp'.html_safe, :class => 'glyphicon glyphicon-question-sign') + content_tag(:span, _('pending'))
76
+ icon_text('question', _('pending'), :kind => 'fa')
76
77
  else
77
78
  task.result
78
79
  end
@@ -164,6 +165,13 @@ module RemoteExecutionHelper
164
165
  end
165
166
  end
166
167
 
168
+ def invocation_result(invocation, key)
169
+ unknown = '&mdash;'
170
+ result = invocation_count(invocation, :output_key => key, :unknown_string => unknown.html_safe)
171
+ label = key == :failed_count ? 'danger' : 'info'
172
+ result == unknown ? result : report_event_column(result, "label-#{label}")
173
+ end
174
+
167
175
  def preview_box(template_invocation, target)
168
176
  renderer = InputTemplateRenderer.new(template_invocation.template, target, template_invocation)
169
177
  if (preview = renderer.preview)
@@ -189,7 +197,7 @@ module RemoteExecutionHelper
189
197
  if time.nil?
190
198
  _('N/A')
191
199
  else
192
- content_tag :span, (time > Time.now ? _('in %s') : _('%s ago')) % time_ago_in_words(time),
200
+ content_tag :span, (time > Time.now.utc ? _('in %s') : _('%s ago')) % time_ago_in_words(time),
193
201
  { :'data-original-title' => time.try(:in_time_zone), :rel => 'twipsy' }
194
202
  end
195
203
  end
@@ -228,12 +236,22 @@ module RemoteExecutionHelper
228
236
  :value => f.object.description_format || job_template.generate_description_format,
229
237
  :rows => 2,
230
238
  :onchange => 'regenerate_description(this);',
231
- :class => 'description_format',
239
+ :class => 'description_format advanced',
232
240
  :disabled => disabled,
233
241
  :help_inline => popover(_('Explanation'),
234
- _('This template is used to generate the description.
235
- Input values can be used using the syntax %{package}.
236
- You may also include the job category and template
237
- name using %{job_category} and %{template_name}.'))
242
+ _('This template is used to generate the description ' +
243
+ 'Input values can be used using the syntax %{package}. ' +
244
+ 'You may also include the job category and template ' +
245
+ 'name using %{job_category} and %{template_name}.'))
246
+ end
247
+
248
+ def advanced_switch_f(default_text, switch_text)
249
+ content_tag :div, :class => 'form-group' do
250
+ content_tag(:div, '', :class => 'col-md-2 control-label') +
251
+ content_tag(:div, :class => 'col-md-4') do
252
+ content_tag(:i, '', :class => 'fa fa-angle-right') + ' ' +
253
+ link_to(default_text, '#', :class => 'advanced_fields_switch', :'data-alternative-label' => switch_text)
254
+ end
255
+ end
238
256
  end
239
257
  end