foreman_remote_execution 1.6.0 → 1.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/app/controllers/api/v2/job_invocations_controller.rb +8 -3
- data/app/helpers/remote_execution_helper.rb +7 -1
- data/app/models/job_invocation_composer.rb +10 -1
- data/app/models/job_template.rb +1 -1
- data/app/views/job_invocations/_form.html.erb +10 -2
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/test/factories/foreman_remote_execution_factories.rb +1 -1
- data/test/functional/api/v2/job_invocations_controller_test.rb +14 -0
- data/test/unit/job_invocation_composer_test.rb +18 -0
- data/test/unit/job_template_test.rb +3 -3
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7e884723b111f87af0bb02b6eb789e3d246edd949afb503c6abda18a3e6a6106
|
4
|
+
data.tar.gz: 9b33580cc044c35b9a44321d9889364f6e8871cbb1d5a20a14fc03e652965dbc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '096f0427feb1f59bcb7eb2759050a6bc420cf7961235b8345791e59a55890da359e78e8d4543a9bd1eab20bfb077450efbb6ad62fcad2149ddfa95b48e6761e9'
|
7
|
+
data.tar.gz: 2c2029fe3abe58f9763609ce6829f8c81afa6755a179cd73408dc4ff790e14166aeaa8d890c872301623218b9773ca44bc0499236134e82942fe58bc37b6ba1b
|
@@ -111,9 +111,14 @@ module Api
|
|
111
111
|
param :failed_only, :bool
|
112
112
|
def rerun
|
113
113
|
composer = JobInvocationComposer.from_job_invocation(@job_invocation, params)
|
114
|
-
composer.
|
115
|
-
|
116
|
-
|
114
|
+
if composer.rerun_possible?
|
115
|
+
composer.trigger!
|
116
|
+
@job_invocation = composer.job_invocation
|
117
|
+
process_response @job_invocation
|
118
|
+
else
|
119
|
+
render :json => { :error => _('Could not rerun job %{id} because its template could not be found') % { :id => composer.reruns } },
|
120
|
+
:status => 404
|
121
|
+
end
|
117
122
|
end
|
118
123
|
|
119
124
|
private
|
@@ -161,7 +161,7 @@ module RemoteExecutionHelper
|
|
161
161
|
|
162
162
|
def preview_box(template_invocation, target)
|
163
163
|
renderer = InputTemplateRenderer.new(template_invocation.template, target, template_invocation)
|
164
|
-
if (preview = renderer.preview)
|
164
|
+
if (preview = (load_template_from_task(template_invocation, target) || renderer.preview))
|
165
165
|
content_tag :pre, preview
|
166
166
|
elsif target.nil?
|
167
167
|
alert :text => _('Could not render the preview because no host matches the search query.'),
|
@@ -234,4 +234,10 @@ module RemoteExecutionHelper
|
|
234
234
|
end
|
235
235
|
end
|
236
236
|
end
|
237
|
+
|
238
|
+
def load_template_from_task(template_invocation, target)
|
239
|
+
task = template_invocation.job_invocation.sub_task_for_host(target)
|
240
|
+
return if task.nil?
|
241
|
+
task.execution_plan.actions[1].try(:input) { |input| input['script'] }
|
242
|
+
end
|
237
243
|
end
|
@@ -186,7 +186,8 @@ class JobInvocationComposer
|
|
186
186
|
:concurrency_control => concurrency_control_params,
|
187
187
|
:execution_timeout_interval => job_invocation.execution_timeout_interval,
|
188
188
|
:remote_execution_feature_id => job_invocation.remote_execution_feature_id,
|
189
|
-
:template_invocations => template_invocations_params
|
189
|
+
:template_invocations => template_invocations_params,
|
190
|
+
:reruns => job_invocation.id }.with_indifferent_access
|
190
191
|
end
|
191
192
|
|
192
193
|
private
|
@@ -297,6 +298,7 @@ class JobInvocationComposer
|
|
297
298
|
end
|
298
299
|
|
299
300
|
attr_accessor :params, :job_invocation, :host_ids, :search_query
|
301
|
+
attr_reader :reruns
|
300
302
|
delegate :job_category, :remote_execution_feature_id, :pattern_template_invocations, :template_invocations, :targeting, :triggering, :to => :job_invocation
|
301
303
|
|
302
304
|
def initialize(params, set_defaults = false)
|
@@ -304,6 +306,7 @@ class JobInvocationComposer
|
|
304
306
|
@set_defaults = set_defaults
|
305
307
|
@job_invocation = JobInvocation.new
|
306
308
|
@job_invocation.task_group = JobInvocationTaskGroup.new
|
309
|
+
@reruns = params[:reruns]
|
307
310
|
compose
|
308
311
|
|
309
312
|
@host_ids = validate_host_ids(params[:host_ids])
|
@@ -342,6 +345,8 @@ class JobInvocationComposer
|
|
342
345
|
job_invocation.key_passphrase = params[:key_passphrase]
|
343
346
|
job_invocation.sudo_password = params[:sudo_password]
|
344
347
|
|
348
|
+
job_invocation.job_category = nil unless rerun_possible?
|
349
|
+
|
345
350
|
self
|
346
351
|
end
|
347
352
|
# rubocop:enable Metrics/AbcSize
|
@@ -470,6 +475,10 @@ class JobInvocationComposer
|
|
470
475
|
job_invocation.pattern_template_invocations.map(&:template_id)
|
471
476
|
end
|
472
477
|
|
478
|
+
def rerun_possible?
|
479
|
+
!(reruns && job_invocation.pattern_template_invocations.empty?)
|
480
|
+
end
|
481
|
+
|
473
482
|
private
|
474
483
|
|
475
484
|
# builds input values for a given templates id based on params
|
data/app/models/job_template.rb
CHANGED
@@ -136,7 +136,7 @@ class JobTemplate < ::Template
|
|
136
136
|
|
137
137
|
def generate_description_format
|
138
138
|
if description_format.blank?
|
139
|
-
generated_description = '%{
|
139
|
+
generated_description = '%{template_name}'
|
140
140
|
unless template_inputs_with_foreign.empty?
|
141
141
|
inputs = template_inputs_with_foreign.map(&:name).map { |name| %{#{name}="%{#{name}}"} }.join(' ')
|
142
142
|
generated_description << " with inputs #{inputs}"
|
@@ -6,7 +6,15 @@
|
|
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
|
-
|
9
|
+
<% unless @composer.rerun_possible? %>
|
10
|
+
<%= alert :text => _('Could not rerun job %{id} because its template could not be found') % { :id => @composer.reruns },
|
11
|
+
:class => 'alert alert-block alert-danger has-error',
|
12
|
+
:close => false %>
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
<%= selectable_f f, :job_category, @composer.available_job_categories,
|
16
|
+
{ :selected => @composer.job_invocation.job_category, :include_blank => @composer.job_invocation.job_category.nil? },
|
17
|
+
:label => _('Job category') %>
|
10
18
|
<%= f.hidden_field(:remote_execution_feature_id, :value => @composer.remote_execution_feature_id) %>
|
11
19
|
|
12
20
|
<% selected_templates_per_provider = {} %>
|
@@ -116,5 +124,5 @@
|
|
116
124
|
|
117
125
|
<%= render :partial => 'preview_hosts_modal' %>
|
118
126
|
|
119
|
-
<%= submit_or_cancel f, false, :cancel_path => job_invocations_path %>
|
127
|
+
<%= submit_or_cancel f, false, :cancel_path => job_invocations_path, :disabled => !@composer.rerun_possible? %>
|
120
128
|
<% end %>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
FactoryBot.define do
|
2
2
|
factory :job_template do
|
3
3
|
sequence(:name) { |n| "Job template #{n}" }
|
4
|
-
sequence(:job_category) { |n| "
|
4
|
+
sequence(:job_category) { |n| "Job name #{n}" }
|
5
5
|
template 'id'
|
6
6
|
provider_type 'SSH'
|
7
7
|
organizations { [Organization.find_by(name: 'Organization 1')] } if SETTINGS[:organizations_enabled]
|
@@ -6,6 +6,11 @@ module Api
|
|
6
6
|
setup do
|
7
7
|
@invocation = FactoryBot.create(:job_invocation, :with_template, :with_task)
|
8
8
|
@template = FactoryBot.create(:job_template, :with_input)
|
9
|
+
|
10
|
+
# Without this the template in template_invocations and in pattern_template_invocations
|
11
|
+
# would belong to different job_categories, causing trouble when trying to rerun
|
12
|
+
@invocation.job_category = @invocation.pattern_template_invocations.first.template.job_category
|
13
|
+
@invocation.save!
|
9
14
|
end
|
10
15
|
|
11
16
|
test 'should get index' do
|
@@ -178,6 +183,8 @@ module Api
|
|
178
183
|
|
179
184
|
test 'should rerun failed only' do
|
180
185
|
@invocation = FactoryBot.create(:job_invocation, :with_template, :with_failed_task)
|
186
|
+
@invocation.job_category = @invocation.pattern_template_invocations.first.template.job_category
|
187
|
+
@invocation.save!
|
181
188
|
JobInvocation.any_instance.expects(:generate_description)
|
182
189
|
JobInvocationComposer.any_instance
|
183
190
|
.expects(:validate_job_category)
|
@@ -191,6 +198,13 @@ module Api
|
|
191
198
|
targeting.user_id.must_equal users(:admin).id
|
192
199
|
targeting.search_query.must_equal "name ^ (#{hostnames.join(',')})"
|
193
200
|
end
|
201
|
+
|
202
|
+
test 'should return 404 if template is not found' do
|
203
|
+
@invocation.job_category = 'Missing category'
|
204
|
+
@invocation.save!
|
205
|
+
post :rerun, params: { :id => @invocation.id }
|
206
|
+
assert_response 404
|
207
|
+
end
|
194
208
|
end
|
195
209
|
end
|
196
210
|
end
|
@@ -156,6 +156,24 @@ class JobInvocationComposerTest < ActiveSupport::TestCase
|
|
156
156
|
end
|
157
157
|
end
|
158
158
|
|
159
|
+
describe '#rerun_possible?' do
|
160
|
+
it 'is true when not rerunning' do
|
161
|
+
composer.must_be :rerun_possible?
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'is true when rerunning with pattern tempalte invocations' do
|
165
|
+
composer.expects(:reruns).returns(1)
|
166
|
+
composer.job_invocation.expects(:pattern_template_invocations).returns([1])
|
167
|
+
composer.must_be :rerun_possible?
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'is false when rerunning without pattern template invocations' do
|
171
|
+
composer.expects(:reruns).returns(1)
|
172
|
+
composer.job_invocation.expects(:pattern_template_invocations).returns([])
|
173
|
+
composer.wont_be :rerun_possible?
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
159
177
|
describe '#selected_job_templates' do
|
160
178
|
it 'returns no template if none was selected through params' do
|
161
179
|
composer.selected_job_templates.must_be_empty
|
@@ -44,14 +44,14 @@ class JobTemplateTest < ActiveSupport::TestCase
|
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'uses the job name as description_format if not set or blank and has no inputs' do
|
47
|
-
minimal_template.generate_description_format.must_equal '%{
|
47
|
+
minimal_template.generate_description_format.must_equal '%{template_name}'
|
48
48
|
minimal_template.description_format = ''
|
49
|
-
minimal_template.generate_description_format.must_equal '%{
|
49
|
+
minimal_template.generate_description_format.must_equal '%{template_name}'
|
50
50
|
end
|
51
51
|
|
52
52
|
it 'generates the description_format if not set or blank and has inputs' do
|
53
53
|
input_name = template.template_inputs.first.name
|
54
|
-
expected_result = %(%{
|
54
|
+
expected_result = %(%{template_name} with inputs #{input_name}="%{#{input_name}}")
|
55
55
|
template.generate_description_format.must_equal expected_result
|
56
56
|
template.description_format = ''
|
57
57
|
template.generate_description_format.must_equal expected_result
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_remote_execution
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.6.
|
4
|
+
version: 1.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Foreman Remote Execution team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deface
|
@@ -418,7 +418,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
418
418
|
version: '0'
|
419
419
|
requirements: []
|
420
420
|
rubyforge_project:
|
421
|
-
rubygems_version: 2.
|
421
|
+
rubygems_version: 2.7.3
|
422
422
|
signing_key:
|
423
423
|
specification_version: 4
|
424
424
|
summary: A plugin bringing remote execution to the Foreman, completing the config
|