foreman_remote_execution 1.6.6 → 1.6.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/api/v2/job_invocations_controller.rb +31 -11
- data/app/helpers/remote_execution_helper.rb +1 -1
- data/app/views/job_invocations/show.html.erb +1 -1
- data/config/routes.rb +1 -0
- data/lib/foreman_remote_execution/engine.rb +1 -1
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/test/functional/api/v2/job_invocations_controller_test.rb +74 -25
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8984a2dd913e555a9c90380466a664e33a43b07281623ea730737919fe281419
|
4
|
+
data.tar.gz: 2db7e60c25e0cddcabb57f4541850be79fb2cceb65e3a721a81f5e46a06d0bda
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c63109a7327c158919bd835707556ca487c9840e901a1a2fa43bb2e9ea8d30c08f3c2d73b33c53f2d1f6dc1214b287fbbec35291e2bdc4573c8f744d29e2458
|
7
|
+
data.tar.gz: fc2ca8b0cd9bb7da6aa789dda541eaead960780e757d085b52fa393918bbfbf9bd4437df07e91c24af7f886178df66baad31afa31e621aa26881672c794b644f
|
@@ -4,8 +4,8 @@ module Api
|
|
4
4
|
include ::Api::Version2
|
5
5
|
include ::Foreman::Renderer
|
6
6
|
|
7
|
-
before_action :find_optional_nested_object, :only => %w{output}
|
8
|
-
before_action :find_host, :only => %w{output}
|
7
|
+
before_action :find_optional_nested_object, :only => %w{output raw_output}
|
8
|
+
before_action :find_host, :only => %w{output raw_output}
|
9
9
|
before_action :find_resource, :only => %w{show update destroy clone cancel rerun}
|
10
10
|
|
11
11
|
wrap_parameters JobInvocation, :include => (JobInvocation.attribute_names + [:ssh])
|
@@ -78,19 +78,23 @@ module Api
|
|
78
78
|
param :since, String, :required => false
|
79
79
|
def output
|
80
80
|
if @nested_obj.task.scheduled?
|
81
|
-
render :json =>
|
81
|
+
render :json => delayed_task_output(@nested_obj.task, :default => [])
|
82
82
|
return
|
83
83
|
end
|
84
|
-
task = @nested_obj.sub_task_for_host(@host)
|
85
|
-
refresh = true
|
86
|
-
line_sets = []
|
87
84
|
|
88
|
-
|
89
|
-
|
90
|
-
|
85
|
+
render :json => host_output(@nested_obj, @host, :default => [], :since => params[:since])
|
86
|
+
end
|
87
|
+
|
88
|
+
api :GET, '/job_invocations/:id/hosts/:host_id/raw', N_('Get raw output for a host')
|
89
|
+
param :id, :identifier, :required => true
|
90
|
+
param :host_id, :identifier, :required => true
|
91
|
+
def raw_output
|
92
|
+
if @nested_obj.task.scheduled?
|
93
|
+
render :json => delayed_task_output(@nested_obj.task)
|
94
|
+
return
|
91
95
|
end
|
92
96
|
|
93
|
-
render :json =>
|
97
|
+
render :json => host_output(@nested_obj, @host, :raw => true)
|
94
98
|
end
|
95
99
|
|
96
100
|
api :POST, '/job_invocations/:id/cancel', N_('Cancel job invocation')
|
@@ -129,7 +133,7 @@ module Api
|
|
129
133
|
|
130
134
|
def action_permission
|
131
135
|
case params[:action]
|
132
|
-
when 'output'
|
136
|
+
when 'output', 'raw_output'
|
133
137
|
:view
|
134
138
|
when 'cancel'
|
135
139
|
:cancel
|
@@ -177,6 +181,22 @@ module Api
|
|
177
181
|
line_sets = line_sets.drop_while { |o| o['timestamp'].to_f <= since } if since
|
178
182
|
line_sets
|
179
183
|
end
|
184
|
+
|
185
|
+
def host_output(job_invocation, host, default: nil, since: nil, raw: false)
|
186
|
+
refresh = true
|
187
|
+
|
188
|
+
if (task = job_invocation.sub_task_for_host(host))
|
189
|
+
refresh = task.pending?
|
190
|
+
output = output_lines_since(task, since)
|
191
|
+
output = output.map { |set| set['output'] }.join if raw
|
192
|
+
end
|
193
|
+
|
194
|
+
{ :complete => !refresh, :refresh => refresh, :output => output || default }
|
195
|
+
end
|
196
|
+
|
197
|
+
def delayed_task_output(task, default: nil)
|
198
|
+
{ :complete => false, :refresh => true, :output => default, :delayed => true, :start_at => task.start_at }
|
199
|
+
end
|
180
200
|
end
|
181
201
|
end
|
182
202
|
end
|
@@ -234,6 +234,6 @@ module RemoteExecutionHelper
|
|
234
234
|
def load_template_from_task(template_invocation, target)
|
235
235
|
task = template_invocation.job_invocation.sub_task_for_host(target)
|
236
236
|
return if task.nil?
|
237
|
-
task.execution_plan.actions[1].try(:input)
|
237
|
+
task.execution_plan.actions[1].try(:input).try(:[], 'script')
|
238
238
|
end
|
239
239
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<% title @job_invocation.description
|
1
|
+
<% title @job_invocation.description %>
|
2
2
|
<% stylesheet 'foreman_remote_execution/job_invocations' %>
|
3
3
|
<% javascript 'charts', 'foreman_remote_execution/template_invocation' %>
|
4
4
|
<%= javascript_include_tag *webpack_asset_paths('foreman_remote_execution', :extension => 'js'), "data-turbolinks-track" => true, 'defer' => 'defer' %>
|
data/config/routes.rb
CHANGED
@@ -43,6 +43,7 @@ Rails.application.routes.draw do
|
|
43
43
|
resources :job_invocations, :except => [:new, :edit, :update, :destroy] do
|
44
44
|
resources :hosts, :only => :none do
|
45
45
|
get '/', :to => 'job_invocations#output'
|
46
|
+
get '/raw', :to => 'job_invocations#raw_output'
|
46
47
|
end
|
47
48
|
member do
|
48
49
|
post 'cancel'
|
@@ -58,7 +58,7 @@ module ForemanRemoteExecution
|
|
58
58
|
permission :create_job_invocations, { :job_invocations => [:new, :create, :refresh, :rerun, :preview_hosts],
|
59
59
|
'api/v2/job_invocations' => [:create, :rerun] }, :resource_type => 'JobInvocation'
|
60
60
|
permission :view_job_invocations, { :job_invocations => [:index, :chart, :show, :auto_complete_search], :template_invocations => [:show],
|
61
|
-
'api/v2/job_invocations' => [:index, :show, :output] }, :resource_type => 'JobInvocation'
|
61
|
+
'api/v2/job_invocations' => [:index, :show, :output, :raw_output] }, :resource_type => 'JobInvocation'
|
62
62
|
permission :view_template_invocations, { :template_invocations => [:show],
|
63
63
|
'api/v2/template_invocations' => [:template_invocations] }, :resource_type => 'TemplateInvocation'
|
64
64
|
permission :create_template_invocations, {}, :resource_type => 'TemplateInvocation'
|
@@ -101,34 +101,83 @@ module Api
|
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
104
|
-
|
105
|
-
host
|
106
|
-
ForemanTasks::Task.any_instance.expects(:scheduled?).returns(true)
|
107
|
-
get :output, params: { :job_invocation_id => @invocation.id, :host_id => host.id }
|
108
|
-
result = ActiveSupport::JSON.decode(@response.body)
|
109
|
-
assert_equal result['delayed'], true
|
110
|
-
assert_equal result['refresh'], true
|
111
|
-
assert_equal result['output'], []
|
112
|
-
assert_response :success
|
113
|
-
end
|
104
|
+
describe '#output' do
|
105
|
+
let(:host) { @invocation.template_invocations_hosts.first }
|
114
106
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
107
|
+
test 'should provide output for delayed task' do
|
108
|
+
ForemanTasks::Task.any_instance.expects(:scheduled?).returns(true)
|
109
|
+
get :output, params: { :job_invocation_id => @invocation.id, :host_id => host.id }
|
110
|
+
result = ActiveSupport::JSON.decode(@response.body)
|
111
|
+
assert_equal result['delayed'], true
|
112
|
+
assert_equal result['refresh'], true
|
113
|
+
assert_equal result['output'], []
|
114
|
+
assert_response :success
|
115
|
+
end
|
116
|
+
|
117
|
+
test 'should provide empty output for host which does not have a task yet' do
|
118
|
+
JobInvocation.any_instance.expects(:sub_task_for_host).returns(nil)
|
119
|
+
get :output, params: { :job_invocation_id => @invocation.id, :host_id => host.id }
|
120
|
+
result = ActiveSupport::JSON.decode(@response.body)
|
121
|
+
assert_equal result['refresh'], true
|
122
|
+
assert_equal result['output'], []
|
123
|
+
assert_response :success
|
124
|
+
end
|
125
|
+
|
126
|
+
test 'should fail with 404 for non-existing job invocation' do
|
127
|
+
invocation_id = @invocation.id + 1
|
128
|
+
assert_empty JobInvocation.where(:id => invocation_id)
|
129
|
+
get :output, params: { :job_invocation_id => invocation_id, :host_id => 1234 }
|
130
|
+
result = ActiveSupport::JSON.decode(@response.body)
|
131
|
+
assert_equal result['message'], "Job invocation not found by id '#{invocation_id}'"
|
132
|
+
assert_response :missing
|
133
|
+
end
|
123
134
|
end
|
124
135
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
136
|
+
describe 'raw output' do
|
137
|
+
let(:fake_output) do
|
138
|
+
(1..5).map do |i|
|
139
|
+
{ 'timestamp' => (Time.now - (5 - i)).to_f, 'output' => "#{i}\n" }
|
140
|
+
end
|
141
|
+
end
|
142
|
+
let(:fake_task) do
|
143
|
+
OpenStruct.new :pending? => false, :main_action => OpenStruct.new(:live_output => fake_output)
|
144
|
+
end
|
145
|
+
let(:host) { @invocation.template_invocations_hosts.first }
|
146
|
+
|
147
|
+
test 'should provide raw output for a host' do
|
148
|
+
JobInvocation.any_instance.expects(:task).returns(OpenStruct.new(:scheduled? => false))
|
149
|
+
JobInvocation.any_instance.expects(:sub_task_for_host).returns(fake_task)
|
150
|
+
get :raw_output, params: { :job_invocation_id => @invocation.id, :host_id => host.id }
|
151
|
+
result = ActiveSupport::JSON.decode(@response.body)
|
152
|
+
assert_equal result['complete'], true
|
153
|
+
assert_equal result['output'], (1..5).map(&:to_s).join("\n") + "\n"
|
154
|
+
assert_response :success
|
155
|
+
end
|
156
|
+
|
157
|
+
test 'should provide raw output for delayed task' do
|
158
|
+
start_time = Time.now
|
159
|
+
JobInvocation.any_instance
|
160
|
+
.expects(:task).twice
|
161
|
+
.returns(OpenStruct.new(:scheduled? => true, :start_at => start_time))
|
162
|
+
JobInvocation.any_instance.expects(:sub_task_for_host).never
|
163
|
+
get :raw_output, params: { :job_invocation_id => @invocation.id, :host_id => host.id }
|
164
|
+
result = ActiveSupport::JSON.decode(@response.body)
|
165
|
+
assert_equal result['complete'], false
|
166
|
+
assert_equal result['delayed'], true
|
167
|
+
assert_nil result['output']
|
168
|
+
Time.parse(result['start_at']).to_f.must_be_close_to start_time.to_f
|
169
|
+
assert_response :success
|
170
|
+
end
|
171
|
+
|
172
|
+
test 'should provide raw output for host without task' do
|
173
|
+
JobInvocation.any_instance.expects(:task).returns(OpenStruct.new(:scheduled? => false))
|
174
|
+
JobInvocation.any_instance.expects(:sub_task_for_host)
|
175
|
+
get :raw_output, params: { :job_invocation_id => @invocation.id, :host_id => host.id }
|
176
|
+
result = ActiveSupport::JSON.decode(@response.body)
|
177
|
+
assert_equal result['complete'], false
|
178
|
+
assert_nil result['output']
|
179
|
+
assert_response :success
|
180
|
+
end
|
132
181
|
end
|
133
182
|
|
134
183
|
test 'should cancel a job' do
|
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.7
|
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-12-
|
11
|
+
date: 2018-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deface
|