foreman_remote_execution 1.6.0 → 1.6.1
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.
- 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
|