foreman_remote_execution 1.3.1 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +16 -0
  3. data/.rubocop_todo.yml +0 -6
  4. data/Rakefile +0 -1
  5. data/app/controllers/api/v2/job_invocations_controller.rb +1 -0
  6. data/app/controllers/concerns/foreman/controller/parameters/job_template.rb +1 -1
  7. data/app/controllers/job_templates_controller.rb +1 -1
  8. data/app/lib/actions/remote_execution/run_host_job.rb +3 -1
  9. data/app/models/concerns/foreman_remote_execution/foreman_tasks_cleaner_extensions.rb +37 -0
  10. data/app/models/concerns/foreman_remote_execution/foreman_tasks_task_extensions.rb +1 -1
  11. data/app/models/concerns/foreman_remote_execution/host_extensions.rb +1 -1
  12. data/app/models/host_status/execution_status.rb +1 -1
  13. data/app/models/job_invocation_composer.rb +15 -3
  14. data/app/models/job_template.rb +1 -1
  15. data/app/models/setting/remote_execution.rb +1 -1
  16. data/app/models/targeting.rb +3 -2
  17. data/app/models/template_input.rb +5 -1
  18. data/app/views/api/v2/foreign_input_sets/create.json.rabl +1 -1
  19. data/app/views/api/v2/foreign_input_sets/index.json.rabl +1 -1
  20. data/app/views/api/v2/foreign_input_sets/main.json.rabl +1 -1
  21. data/app/views/api/v2/foreign_input_sets/show.json.rabl +1 -1
  22. data/app/views/api/v2/job_invocations/create.json.rabl +1 -1
  23. data/app/views/api/v2/job_invocations/index.json.rabl +1 -1
  24. data/app/views/api/v2/job_invocations/main.json.rabl +2 -2
  25. data/app/views/api/v2/job_invocations/show.json.rabl +1 -1
  26. data/app/views/api/v2/job_templates/create.json.rabl +1 -1
  27. data/app/views/api/v2/job_templates/index.json.rabl +1 -1
  28. data/app/views/api/v2/job_templates/main.json.rabl +3 -3
  29. data/app/views/api/v2/job_templates/show.json.rabl +1 -1
  30. data/app/views/api/v2/job_templates/update.json.rabl +1 -1
  31. data/app/views/api/v2/remote_execution_features/index.json.rabl +1 -1
  32. data/app/views/api/v2/remote_execution_features/main.json.rabl +1 -1
  33. data/app/views/api/v2/remote_execution_features/show.json.rabl +1 -1
  34. data/app/views/api/v2/template_inputs/create.json.rabl +1 -1
  35. data/app/views/api/v2/template_inputs/index.json.rabl +1 -1
  36. data/app/views/api/v2/template_inputs/main.json.rabl +2 -2
  37. data/app/views/api/v2/template_inputs/show.json.rabl +1 -1
  38. data/app/views/job_invocations/_form.html.erb +4 -0
  39. data/app/views/job_invocations/_tab_overview.html.erb +4 -1
  40. data/app/views/job_templates/_custom_tabs.html.erb +2 -0
  41. data/db/migrate/20170613101039_add_timeout_to_job_templates_and_job_invocations.rb +6 -0
  42. data/foreman_remote_execution.gemspec +1 -1
  43. data/lib/foreman_remote_execution/engine.rb +1 -0
  44. data/lib/foreman_remote_execution/version.rb +1 -1
  45. data/locale/de/foreman_remote_execution.po +21 -0
  46. data/locale/en/foreman_remote_execution.po +21 -0
  47. data/locale/en_GB/foreman_remote_execution.po +21 -0
  48. data/locale/es/foreman_remote_execution.po +21 -0
  49. data/locale/foreman_remote_execution.pot +86 -56
  50. data/locale/fr/foreman_remote_execution.po +21 -0
  51. data/locale/ja/foreman_remote_execution.po +21 -0
  52. data/locale/ko/foreman_remote_execution.po +21 -0
  53. data/locale/pt_BR/foreman_remote_execution.po +21 -0
  54. data/locale/ru/foreman_remote_execution.po +21 -0
  55. data/locale/zh_CN/foreman_remote_execution.po +21 -0
  56. data/locale/zh_TW/foreman_remote_execution.po +21 -0
  57. data/test/unit/actions/run_hosts_job_test.rb +1 -1
  58. data/test/unit/concerns/foreman_tasks_cleaner_extensions_test.rb +20 -0
  59. data/test/unit/input_template_renderer_test.rb +5 -7
  60. data/test/unit/job_template_importer_test.rb +6 -6
  61. metadata +10 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e4de9b6ef4385fb25d736b6e2a3c79ad3d6240e6
4
- data.tar.gz: de38d2967d75a10fa0d759d1927eb5a637c9a73a
3
+ metadata.gz: ba7dfa6dd3c06e3240541005c42afc45c5d2c61f
4
+ data.tar.gz: b6985d294864cc4e69919ccf6ec6d7a29478e674
5
5
  SHA512:
6
- metadata.gz: 91604a14604487b8d821e4e81991402c281c0cc342105de1b124bc4c4be18809414f54b9da28c92774c5bb5663c190c7775ed1d76341f5b2ce36e41388d5f7e4
7
- data.tar.gz: 67cfafed4dc9d8a204d478781c227937a657a0134630739bb4670744c3c505f26b1d97e9777e9b9ed7e046729faa9ef8ce4f7f1a5e1dba3224be110876babbdf
6
+ metadata.gz: e3cb2b3678b4127b56ac9b37a7983e42d283a0728204f22c47c319d17878c5eff268cb327311b7d64e74cbef7a750217f2b98b7ef81ce4be1a87dd7695253b85
7
+ data.tar.gz: 5a8f1dc7ff728d443decf1047246e1f11bb87bed37df736b6baa3a19da3ea28797740533d8cb199ed3c93325bdcccaf6a02cd109b7c557f60234cb4654ef2e1e
data/.rubocop.yml CHANGED
@@ -79,3 +79,19 @@ Style/VariableNumber:
79
79
  # a == 0 is not the same as a.zero?, when a is not a number
80
80
  Style/NumericPredicate:
81
81
  Enabled: false
82
+
83
+ Style/FormatStringToken:
84
+ EnforcedStyle: template
85
+
86
+ Rails/SkipsModelValidations:
87
+ Enabled: false
88
+
89
+ Style/SymbolArray:
90
+ Enabled: false
91
+
92
+ # for compatibility with Foreman 1.15
93
+ Rails/ApplicationRecord:
94
+ Enabled: false
95
+
96
+ Style/FormatString:
97
+ Enabled: false
data/.rubocop_todo.yml CHANGED
@@ -122,12 +122,6 @@ Style/IndentationWidth:
122
122
  Style/LineEndConcatenation:
123
123
  Enabled: false
124
124
 
125
- # Offense count: 1
126
- # Cop supports --auto-correct.
127
- Style/MethodCallParentheses:
128
- Exclude:
129
- - 'test/unit/actions/run_hosts_job_test.rb'
130
-
131
125
  # Offense count: 6
132
126
  # Cop supports --auto-correct.
133
127
  # Configuration parameters: EnforcedStyle, SupportedStyles.
data/Rakefile CHANGED
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env rake
2
1
  begin
3
2
  require 'bundler/setup'
4
3
  rescue LoadError
@@ -53,6 +53,7 @@ module Api
53
53
  param :bookmark_id, Integer, :required => false
54
54
  param :search_query, Integer, :required => false
55
55
  param :description_format, String, :required => false, :desc => N_('Override the description format from the template for this invocation only')
56
+ param :execution_timeout_interval, Integer, :required => false, :desc => N_('Override the timeout interval from the template for this invocation only')
56
57
  end
57
58
  end
58
59
 
@@ -15,7 +15,7 @@ module Foreman::Controller::Parameters::JobTemplate
15
15
 
16
16
  def job_template_params_filter
17
17
  Foreman::ParameterFilter.new(::TemplateInput).tap do |filter|
18
- filter.permit :job_category, :provider_type, :description_format,
18
+ filter.permit :job_category, :provider_type, :description_format, :execution_timeout_interval,
19
19
  :effective_user_attributes => [job_template_effective_user_filter],
20
20
  :template_inputs_attributes => [template_input_params_filter],
21
21
  :foreign_input_sets_attributes => [foreign_input_set_params_filter]
@@ -14,7 +14,7 @@ class JobTemplatesController < ::TemplatesController
14
14
  end
15
15
 
16
16
  def preview
17
- find_resource unless @template.present?
17
+ find_resource if @template.blank?
18
18
  base = Host.authorized(:view_hosts, Host)
19
19
  host = params[:preview_host_id].present? ? base.find(params[:preview_host_id]) : base.first
20
20
  @template.template = params[:template]
@@ -48,7 +48,9 @@ module Actions
48
48
 
49
49
  provider = template_invocation.template.provider
50
50
  hostname = provider.find_ip_or_hostname(host)
51
- action_options = provider.proxy_command_options(template_invocation, host).merge(:hostname => hostname, :script => script)
51
+ action_options = provider.proxy_command_options(template_invocation, host)
52
+ .merge(:hostname => hostname, :script => script,
53
+ :execution_timeout_interval => job_invocation.execution_timeout_interval)
52
54
  plan_delegated_action(proxy, ForemanRemoteExecutionCore::Actions::RunScript, action_options)
53
55
  plan_self
54
56
  end
@@ -0,0 +1,37 @@
1
+ module ForemanRemoteExecution
2
+ module ForemanTasksCleanerExtensions
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ prepend ForemanRemoteExecution::JobInvocationCleaner
7
+ end
8
+ end
9
+
10
+ module JobInvocationCleaner
11
+ def delete
12
+ super
13
+ if noop
14
+ say '[noop] deleting orphaned job invocations'
15
+ say "[noop] #{orphaned_job_invocations.count} job invocations would be deleted"
16
+ else
17
+ count = orphaned_job_invocations.count
18
+ orphaned_job_invocations.find_each(&:destroy)
19
+ say "deleted #{count} orphaned job_invocations", false if verbose
20
+ end
21
+ end
22
+
23
+ def delete_tasks(chunk)
24
+ super(chunk)
25
+ delete_job_invocations(chunk)
26
+ end
27
+
28
+ def delete_job_invocations(chunk)
29
+ JobInvocation.where(:task_id => chunk.map(&:id)).find_each(&:destroy)
30
+ end
31
+
32
+ def orphaned_job_invocations
33
+ JobInvocation.joins('LEFT JOIN foreman_tasks_tasks ON task_id = foreman_tasks_tasks.id')
34
+ .where('task_id IS NOT NULL and foreman_tasks_tasks.id IS NULL')
35
+ end
36
+ end
37
+ end
@@ -3,7 +3,7 @@ module ForemanRemoteExecution
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
- has_many :job_invocations, :dependent => :nullify, :foreign_key => 'task_id'
6
+ has_many :job_invocations, :dependent => :destroy, :foreign_key => 'task_id'
7
7
  end
8
8
  end
9
9
  end
@@ -54,7 +54,7 @@ module ForemanRemoteExecution
54
54
  def host_params_with_remote_execution
55
55
  params = host_params_without_remote_execution
56
56
  keys = remote_execution_ssh_keys
57
- params['remote_execution_ssh_keys'] = keys unless keys.blank?
57
+ params['remote_execution_ssh_keys'] = keys if keys.present?
58
58
  [:remote_execution_ssh_user, :remote_execution_effective_user_method,
59
59
  :remote_execution_connect_by_ip].each do |key|
60
60
  params[key.to_s] = Setting[key] unless params.key?(key.to_s)
@@ -68,7 +68,7 @@ class HostStatus::ExecutionStatus < HostStatus::Status
68
68
  def status
69
69
  if task.nil? || task.state == 'scheduled'
70
70
  QUEUED
71
- elsif task.state == 'stopped' && 'success' == task.result
71
+ elsif task.state == 'stopped' && task.result == 'success'
72
72
  OK
73
73
  elsif task.pending?
74
74
  RUNNING
@@ -13,6 +13,7 @@ class JobInvocationComposer
13
13
  :host_ids => ui_params[:host_ids],
14
14
  :description_format => job_invocation_base[:description_format],
15
15
  :concurrency_control => concurrency_control_params,
16
+ :execution_timeout_interval => execution_timeout_interval,
16
17
  :template_invocations => template_invocations_params }.with_indifferent_access
17
18
  end
18
19
 
@@ -24,6 +25,14 @@ class JobInvocationComposer
24
25
  job_invocation_base.fetch(:providers, {})
25
26
  end
26
27
 
28
+ def execution_timeout_interval
29
+ providers_base.values.map do |provider|
30
+ id = provider[:job_template_id]
31
+ provider.fetch(:job_templates, {}).fetch(id, {})[:execution_timeout_interval]
32
+ end.first
33
+ end
34
+
35
+ # TODO: Fix this comment
27
36
  # parses params to get job templates in form of id => attributes for selected job templates, e.g.
28
37
  # {
29
38
  # "459" => {},
@@ -80,6 +89,7 @@ class JobInvocationComposer
80
89
  :triggering => triggering_params,
81
90
  :description_format => api_params[:description_format],
82
91
  :concurrency_control => concurrency_control_params,
92
+ :execution_timeout_interval => api_params[:execution_timeout_interval] || template.execution_timeout_interval,
83
93
  :template_invocations => template_invocations_params }.with_indifferent_access
84
94
  end
85
95
 
@@ -161,6 +171,7 @@ class JobInvocationComposer
161
171
  :triggering => triggering_params,
162
172
  :description_format => job_invocation.description_format,
163
173
  :concurrency_control => concurrency_control_params,
174
+ :execution_timeout_interval => job_invocation.execution_timeout_interval,
164
175
  :template_invocations => template_invocations_params }.with_indifferent_access
165
176
  end
166
177
 
@@ -274,7 +285,7 @@ class JobInvocationComposer
274
285
  compose
275
286
 
276
287
  @host_ids = validate_host_ids(params[:host_ids])
277
- @search_query = job_invocation.targeting.search_query unless job_invocation.targeting.bookmark_id.present?
288
+ @search_query = job_invocation.targeting.search_query if job_invocation.targeting.bookmark_id.blank?
278
289
  end
279
290
 
280
291
  def self.from_job_invocation(job_invocation, params = {})
@@ -300,8 +311,9 @@ class JobInvocationComposer
300
311
  job_invocation.triggering = build_triggering
301
312
  job_invocation.pattern_template_invocations = build_template_invocations
302
313
  job_invocation.description_format = params[:description_format]
303
- job_invocation.time_span = params[:concurrency_control][:time_span].to_i unless params[:concurrency_control][:time_span].blank?
304
- job_invocation.concurrency_level = params[:concurrency_control][:level].to_i unless params[:concurrency_control][:level].blank?
314
+ job_invocation.time_span = params[:concurrency_control][:time_span].to_i if params[:concurrency_control][:time_span].present?
315
+ job_invocation.concurrency_level = params[:concurrency_control][:level].to_i if params[:concurrency_control][:level].present?
316
+ job_invocation.execution_timeout_interval = params[:execution_timeout_interval]
305
317
 
306
318
  self
307
319
  end
@@ -217,7 +217,7 @@ class JobTemplate < ::Template
217
217
 
218
218
  def self.parse_metadata(template)
219
219
  match = template.match(/<%\#(.+?).-?%>/m)
220
- match.nil? ? {} : YAML.load(match[1])
220
+ match.nil? ? {} : YAML.safe_load(match[1])
221
221
  end
222
222
 
223
223
  private
@@ -40,7 +40,7 @@ class Setting::RemoteExecution < Setting
40
40
  self.set('remote_execution_connect_by_ip',
41
41
  N_('Should the ip addresses on host interfaces be preferred over the fqdn? '\
42
42
  'It is useful, when DNS not resolving the fqdns properly. You may override this per host by setting a parameter called remote_execution_connect_by_ip.'),
43
- false),
43
+ false)
44
44
  ].each { |s| self.create! s.update(:category => 'Setting::RemoteExecution') }
45
45
  end
46
46
 
@@ -38,8 +38,9 @@ class Targeting < ActiveRecord::Base
38
38
  self.search_query = bookmark.query if dynamic? && bookmark.present?
39
39
  self.resolved_at = Time.zone.now
40
40
  self.validate!
41
- # avoid validation of hosts objects - tey will be loaded for no reason.
42
- host_ids = User.as(user.login) { Host.authorized(RESOLVE_PERMISSION, Host).search_for(search_query).pluck(:id) }
41
+ # avoid validation of hosts objects - they will be loaded for no reason.
42
+ # pluck(:id) returns duplicate results for HostCollections
43
+ host_ids = User.as(user.login) { Host.authorized(RESOLVE_PERMISSION, Host).search_for(search_query).pluck(:id).uniq }
43
44
  # this can be optimized even more, by introducing bulk insert
44
45
  self.targeting_hosts.build(host_ids.map { |id| { :host_id => id } })
45
46
  self.save(:validate => false)
@@ -173,7 +173,11 @@ class TemplateInput < ActiveRecord::Base
173
173
  private
174
174
 
175
175
  def get_enc
176
- @enc ||= Classification::ClassParam.new(:host => @renderer.host).enc
176
+ @enc ||= if SETTINGS[:version].short <= '1.15'
177
+ Classification::ClassParam.new(:host => @renderer.host).enc
178
+ else
179
+ HostInfoProviders::PuppetInfo.new(@renderer.host).puppetclass_parameters
180
+ end
177
181
  end
178
182
  end
179
183
  end
@@ -1,3 +1,3 @@
1
1
  object @foreign_input_set
2
2
 
3
- extends "api/v2/foreign_input_sets/show"
3
+ extends 'api/v2/foreign_input_sets/show'
@@ -1,3 +1,3 @@
1
1
  collection @foreign_input_sets
2
2
 
3
- extends "api/v2/foreign_input_sets/main"
3
+ extends 'api/v2/foreign_input_sets/main'
@@ -1,5 +1,5 @@
1
1
  object @foreign_input_set
2
2
 
3
- extends "api/v2/foreign_input_sets/base"
3
+ extends 'api/v2/foreign_input_sets/base'
4
4
 
5
5
  attributes :template_id, :target_input_id, :target_template_name, :include_all, :include, :exclude
@@ -1,3 +1,3 @@
1
1
  object @foreign_input_set
2
2
 
3
- extends "api/v2/foreign_input_sets/main"
3
+ extends 'api/v2/foreign_input_sets/main'
@@ -1,3 +1,3 @@
1
1
  object @job_invocation
2
2
 
3
- extends "api/v2/job_invocations/show"
3
+ extends 'api/v2/job_invocations/show'
@@ -1,3 +1,3 @@
1
1
  collection @job_invocations
2
2
 
3
- extends "api/v2/job_invocations/base"
3
+ extends 'api/v2/job_invocations/base'
@@ -1,6 +1,6 @@
1
1
  object @job_invocation
2
2
 
3
- extends "api/v2/job_invocations/base"
3
+ extends 'api/v2/job_invocations/base'
4
4
 
5
5
  node do |invocation|
6
6
  if invocation.triggering
@@ -19,7 +19,7 @@ child :targeting do
19
19
  attributes :bookmark_id, :search_query, :targeting_type, :user_id, :status, :status_label
20
20
 
21
21
  child :hosts do
22
- extends "api/v2/hosts/base"
22
+ extends 'api/v2/hosts/base'
23
23
  end
24
24
  end
25
25
 
@@ -1,3 +1,3 @@
1
1
  object @job_invocation
2
2
 
3
- extends "api/v2/job_invocations/main"
3
+ extends 'api/v2/job_invocations/main'
@@ -1,3 +1,3 @@
1
1
  object @job_template
2
2
 
3
- extends "api/v2/job_templates/show"
3
+ extends 'api/v2/job_templates/show'
@@ -1,3 +1,3 @@
1
1
  collection @job_templates
2
2
 
3
- extends "api/v2/job_templates/base"
3
+ extends 'api/v2/job_templates/base'
@@ -1,11 +1,11 @@
1
1
  object @job_template
2
2
 
3
- extends "api/v2/job_templates/base"
3
+ extends 'api/v2/job_templates/base'
4
4
 
5
5
  attributes :audit_comment, :description_format, :created_at, :updated_at, :template, :locked
6
6
 
7
7
  child :template_inputs do
8
- extends "api/v2/template_inputs/base"
8
+ extends 'api/v2/template_inputs/base'
9
9
  end
10
10
 
11
11
  child :effective_user => :effective_user do
@@ -13,5 +13,5 @@ child :effective_user => :effective_user do
13
13
  end
14
14
 
15
15
  node do |job_template|
16
- partial("api/v2/taxonomies/children_nodes", :object => job_template)
16
+ partial('api/v2/taxonomies/children_nodes', :object => job_template)
17
17
  end
@@ -1,3 +1,3 @@
1
1
  object @job_template
2
2
 
3
- extends "api/v2/job_templates/main"
3
+ extends 'api/v2/job_templates/main'
@@ -1,3 +1,3 @@
1
1
  object @job_template
2
2
 
3
- extends "api/v2/job_templates/show"
3
+ extends 'api/v2/job_templates/show'
@@ -1,3 +1,3 @@
1
1
  collection @remote_execution_features
2
2
 
3
- extends "api/v2/remote_execution_features/main"
3
+ extends 'api/v2/remote_execution_features/main'
@@ -1,3 +1,3 @@
1
1
  object @remote_execution_feature
2
2
 
3
- extends "api/v2/remote_execution_features/base"
3
+ extends 'api/v2/remote_execution_features/base'
@@ -1,3 +1,3 @@
1
1
  object @remote_execution_feature
2
2
 
3
- extends "api/v2/remote_execution_features/main"
3
+ extends 'api/v2/remote_execution_features/main'
@@ -1,3 +1,3 @@
1
1
  object @template_input
2
2
 
3
- extends "api/v2/template_inputs/show"
3
+ extends 'api/v2/template_inputs/show'
@@ -1,3 +1,3 @@
1
1
  collection @template_inputs
2
2
 
3
- extends "api/v2/template_inputs/main"
3
+ extends 'api/v2/template_inputs/main'
@@ -1,9 +1,9 @@
1
1
  object @template_input
2
2
 
3
- extends "api/v2/template_inputs/base"
3
+ extends 'api/v2/template_inputs/base'
4
4
 
5
5
  attributes :template_id, :fact_name, :variable_name, :puppet_parameter_name, :puppet_class_name,
6
- :description, :required
6
+ :description, :required
7
7
 
8
8
  node :options do |input|
9
9
  input.options.split(/\r?\n/) if input.options.present?
@@ -1,3 +1,3 @@
1
1
  object @template_input
2
2
 
3
- extends "api/v2/template_inputs/main"
3
+ extends 'api/v2/template_inputs/main'
@@ -76,6 +76,10 @@
76
76
  <% end %>
77
77
  <%= render :partial => 'description_fields', :locals => { :f => f, :job_template => job_template, :disabled => job_template != selected_templates_per_provider[provider_type] } %>
78
78
  </div>
79
+
80
+ <div class="advanced hidden">
81
+ <%= number_f job_template_fields, :execution_timeout_interval, :value => f.object.execution_timeout_interval || job_template.execution_timeout_interval, :label => _('Timeout to kill'), :help_inline => N_('Time in seconds from the start on the remote host after which the job should be killed.') %>
82
+ </div>
79
83
  <% end %>
80
84
  </fieldset>
81
85
  <% end %>