foreman_remote_execution 3.2.2 → 3.3.4
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 +4 -4
- data/.eslintrc +5 -30
- data/.github/workflows/ci.yml +101 -0
- data/.gitignore +1 -0
- data/.rubocop_todo.yml +3 -0
- data/Gemfile +1 -0
- data/app/assets/stylesheets/foreman_remote_execution/job_invocations.scss +6 -5
- data/app/controllers/api/v2/job_invocations_controller.rb +17 -0
- data/app/helpers/remote_execution_helper.rb +38 -33
- data/app/lib/actions/remote_execution/run_host_job.rb +3 -2
- data/app/models/remote_execution_provider.rb +5 -0
- data/app/services/default_proxy_proxy_selector.rb +20 -0
- data/app/views/api/v2/job_invocations/main.json.rabl +6 -0
- data/app/views/job_invocations/_card_target_hosts.html.erb +1 -1
- data/app/views/job_invocations/_tab_hosts.html.erb +3 -23
- data/app/views/job_invocations/index.html.erb +2 -1
- data/app/views/job_invocations/show.html.erb +0 -6
- data/app/views/job_invocations/show.json.erb +4 -0
- data/app/views/templates/ssh/package_action.erb +1 -0
- data/app/views/templates/ssh/puppet_agent_disable.erb +3 -0
- data/app/views/templates/ssh/puppet_agent_enable.erb +3 -0
- data/app/views/templates/ssh/puppet_install_modules_from_forge.erb +3 -0
- data/app/views/templates/ssh/puppet_run_once.erb +3 -0
- data/db/seeds.d/70-job_templates.rb +1 -1
- data/foreman_remote_execution.gemspec +4 -5
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/locale/action_names.rb +0 -1
- data/package.json +16 -33
- data/webpack/__mocks__/foremanReact/common/I18n.js +1 -0
- data/webpack/__mocks__/foremanReact/components/common/ActionButtons/ActionButtons.js +3 -0
- data/webpack/__mocks__/foremanReact/constants.js +3 -0
- data/webpack/index.js +9 -7
- data/webpack/react_app/components/TargetingHosts/TargetingHosts.js +52 -0
- data/webpack/react_app/components/TargetingHosts/TargetingHostsActions.js +8 -0
- data/webpack/react_app/components/TargetingHosts/TargetingHostsConsts.js +1 -0
- data/webpack/react_app/components/TargetingHosts/TargetingHostsSelectors.js +12 -0
- data/webpack/react_app/components/TargetingHosts/__tests__/HostItem.test.js +6 -0
- data/webpack/react_app/components/TargetingHosts/__tests__/HostStatus.test.js +6 -0
- data/webpack/react_app/components/TargetingHosts/__tests__/TargetingHosts.test.js +6 -0
- data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/HostItem.test.js.snap +31 -0
- data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/HostStatus.test.js.snap +12 -0
- data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/TargetingHosts.test.js.snap +81 -0
- data/webpack/react_app/components/TargetingHosts/__tests__/fixtures.js +43 -0
- data/webpack/react_app/components/TargetingHosts/components/HostItem.js +39 -0
- data/webpack/react_app/components/TargetingHosts/components/HostStatus.js +54 -0
- data/webpack/react_app/components/TargetingHosts/index.js +37 -0
- data/webpack/react_app/components/jobInvocations/AggregateStatus/index.js +10 -0
- data/webpack/react_app/components/jobInvocations/AggregateStatus/index.test.js +6 -3
- data/webpack/react_app/components/jobInvocations/index.js +19 -7
- data/webpack/react_app/redux/actions/jobInvocations/index.js +12 -8
- data/webpack/react_app/redux/consts.js +1 -2
- data/webpack/react_app/redux/reducers/jobInvocations/index.fixtures.js +8 -40
- data/webpack/react_app/redux/reducers/jobInvocations/index.test.js +17 -11
- data/webpack/test_setup.js +2 -1
- metadata +26 -12
- data/.hound.yml +0 -19
- data/.travis.yml +0 -6
- data/app/views/job_invocations/_host_actions_td.html.erb +0 -3
- data/app/views/job_invocations/_host_name_td.html.erb +0 -8
- data/app/views/job_invocations/_host_status_td.html.erb +0 -1
- data/app/views/job_invocations/show.js.erb +0 -23
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: af3cd3861fdf9ca798dff28f5da9441110f6442b9cb156604325c0c535dd7d27
|
|
4
|
+
data.tar.gz: 24188a80f5231e8d15826d85322ff410a23bb62cded5a6ab5d30a87063eb8b85
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bdb4f63c31a63b4a54268f7fa36174cdf11ba90393159862370b29679d90a46ea5e0b8f86a0d98708166fa89fc0af0223dd4f93990fd0bc6e12c9dac473ab6e2
|
|
7
|
+
data.tar.gz: 4c03fa3ead970d7817e00e884a32857a5a17ae1e41462e40db4057a57f4def05f04d6ad1a16829807a883482d3a684fe344b06e367c72a99cc13c1faacb7b673
|
data/.eslintrc
CHANGED
|
@@ -1,32 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"extends": [
|
|
4
|
-
|
|
5
|
-
"
|
|
6
|
-
]
|
|
7
|
-
"env": {
|
|
8
|
-
"browser": true,
|
|
9
|
-
"es6": true,
|
|
10
|
-
"node": true,
|
|
11
|
-
"jasmine": true,
|
|
12
|
-
"jest": true
|
|
13
|
-
},
|
|
14
|
-
"parser": "babel-eslint",
|
|
15
|
-
"rules": {
|
|
16
|
-
"react/jsx-uses-vars": "error",
|
|
17
|
-
"react/jsx-uses-react": "error",
|
|
18
|
-
"no-unused-vars": [
|
|
19
|
-
"error",
|
|
20
|
-
{
|
|
21
|
-
"vars": "all",
|
|
22
|
-
"args": "none"
|
|
23
|
-
}
|
|
24
|
-
],
|
|
25
|
-
"no-underscore-dangle": "off",
|
|
26
|
-
"no-use-before-define": "off",
|
|
27
|
-
"import/prefer-default-export": "off",
|
|
28
|
-
// Import rules off for now due to HoundCI issue
|
|
29
|
-
"import/no-unresolved": "off",
|
|
30
|
-
"import/extensions": "off"
|
|
31
|
-
}
|
|
2
|
+
"plugins": ["@theforeman/foreman"],
|
|
3
|
+
"extends": [
|
|
4
|
+
"plugin:@theforeman/foreman/core",
|
|
5
|
+
"plugin:@theforeman/foreman/plugins"
|
|
6
|
+
]
|
|
32
7
|
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on: [pull_request]
|
|
3
|
+
env:
|
|
4
|
+
RAILS_ENV: test
|
|
5
|
+
DATABASE_URL: postgresql://postgres:@localhost/test
|
|
6
|
+
DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL: true
|
|
7
|
+
jobs:
|
|
8
|
+
rubocop:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v2
|
|
12
|
+
- name: Setup Ruby
|
|
13
|
+
uses: ruby/setup-ruby@v1
|
|
14
|
+
with:
|
|
15
|
+
ruby-version: 2.6
|
|
16
|
+
- name: Setup
|
|
17
|
+
run: |
|
|
18
|
+
gem install bundler
|
|
19
|
+
bundle install --jobs=3 --retry=3
|
|
20
|
+
- name: Run rubocop
|
|
21
|
+
run: bundle exec rubocop
|
|
22
|
+
test_ruby:
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
needs: rubocop
|
|
25
|
+
services:
|
|
26
|
+
postgres:
|
|
27
|
+
image: postgres:12.1
|
|
28
|
+
ports: ['5432:5432']
|
|
29
|
+
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
|
|
30
|
+
strategy:
|
|
31
|
+
fail-fast: false
|
|
32
|
+
matrix:
|
|
33
|
+
foreman-core-branch: [2.1-stable, develop]
|
|
34
|
+
ruby-version: [2.5, 2.6]
|
|
35
|
+
node-version: [12]
|
|
36
|
+
steps:
|
|
37
|
+
- run: sudo apt-get update
|
|
38
|
+
- run: sudo apt-get install build-essential libcurl4-openssl-dev zlib1g-dev libpq-dev
|
|
39
|
+
- uses: actions/checkout@v2
|
|
40
|
+
with:
|
|
41
|
+
repository: theforeman/foreman
|
|
42
|
+
ref: ${{ matrix.foreman-core-branch }}
|
|
43
|
+
- uses: actions/checkout@v2
|
|
44
|
+
with:
|
|
45
|
+
path: foreman_remote_execution
|
|
46
|
+
- name: Setup Ruby
|
|
47
|
+
uses: ruby/setup-ruby@v1
|
|
48
|
+
with:
|
|
49
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
50
|
+
- name: Setup Node
|
|
51
|
+
uses: actions/setup-node@v1
|
|
52
|
+
with:
|
|
53
|
+
node-version: ${{ matrix.node-version }}
|
|
54
|
+
- uses: actions/cache@v1
|
|
55
|
+
with:
|
|
56
|
+
path: vendor/bundle
|
|
57
|
+
key: ${{ runner.os }}-fgems-${{ matrix.ruby-version }}-${{ hashFiles('Gemfile.lock') }}
|
|
58
|
+
restore-keys: |
|
|
59
|
+
${{ runner.os }}-fgems-${{ matrix.ruby-version }}-
|
|
60
|
+
- name: Setup Bundler
|
|
61
|
+
run: |
|
|
62
|
+
echo "gem 'foreman_remote_execution', path: './foreman_remote_execution'" > bundler.d/foreman_remote_execution.local.rb
|
|
63
|
+
gem install bundler
|
|
64
|
+
bundle config set without journald development console libvirt
|
|
65
|
+
bundle config set path vendor/bundle
|
|
66
|
+
- name: Prepare test env
|
|
67
|
+
run: |
|
|
68
|
+
bundle install --jobs=3 --retry=3
|
|
69
|
+
bundle exec rake db:create
|
|
70
|
+
bundle exec rake db:migrate
|
|
71
|
+
- name: Run plugin tests
|
|
72
|
+
run: |
|
|
73
|
+
bundle exec rake test:foreman_remote_execution
|
|
74
|
+
bundle exec rake test TEST="test/unit/foreman/access_permissions_test.rb"
|
|
75
|
+
test_js:
|
|
76
|
+
runs-on: ubuntu-latest
|
|
77
|
+
needs: rubocop
|
|
78
|
+
strategy:
|
|
79
|
+
fail-fast: false
|
|
80
|
+
matrix:
|
|
81
|
+
ruby-version: [2.6]
|
|
82
|
+
node-version: [10, 12]
|
|
83
|
+
steps:
|
|
84
|
+
- uses: actions/checkout@v2
|
|
85
|
+
- name: Setup Ruby
|
|
86
|
+
uses: ruby/setup-ruby@v1
|
|
87
|
+
with:
|
|
88
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
89
|
+
- name: Setup Node
|
|
90
|
+
uses: actions/setup-node@v1
|
|
91
|
+
with:
|
|
92
|
+
node-version: ${{ matrix.node-version }}
|
|
93
|
+
- name: Nmp install
|
|
94
|
+
run: |
|
|
95
|
+
npm install
|
|
96
|
+
- name: Run plugin linter
|
|
97
|
+
run: |
|
|
98
|
+
npm run lint
|
|
99
|
+
- name: Run plugin tests
|
|
100
|
+
run: |
|
|
101
|
+
npm run test
|
data/.gitignore
CHANGED
data/.rubocop_todo.yml
CHANGED
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
|
8
8
|
|
|
9
|
+
Minitest/GlobalExpectations:
|
|
10
|
+
Enabled: false
|
|
11
|
+
|
|
9
12
|
# Offense count: 2
|
|
10
13
|
# Cop supports --auto-correct.
|
|
11
14
|
# Configuration parameters: TreatCommentsAsGroupSeparators, Include.
|
data/Gemfile
CHANGED
|
@@ -18,11 +18,17 @@ module Api
|
|
|
18
18
|
|
|
19
19
|
api :GET, '/job_invocations/:id', N_('Show job invocation')
|
|
20
20
|
param :id, :identifier, :required => true
|
|
21
|
+
param :host_status, :bool, required: false, desc: N_('Show Job status for the hosts')
|
|
21
22
|
def show
|
|
22
23
|
@hosts = @job_invocation.targeting.hosts.authorized(:view_hosts, Host)
|
|
23
24
|
@template_invocations = @job_invocation.template_invocations
|
|
24
25
|
.where(host: @hosts)
|
|
25
26
|
.includes(:input_values)
|
|
27
|
+
|
|
28
|
+
if params[:host_status] == 'true'
|
|
29
|
+
template_invocations = @template_invocations.includes(:run_host_job_task).to_a
|
|
30
|
+
@host_statuses = Hash[template_invocations.map { |ti| [ti.host_id, template_invocation_status(ti)] }]
|
|
31
|
+
end
|
|
26
32
|
end
|
|
27
33
|
|
|
28
34
|
def_param_group :job_invocation do
|
|
@@ -208,6 +214,17 @@ module Api
|
|
|
208
214
|
def parent_scope
|
|
209
215
|
resource_class.where(nil)
|
|
210
216
|
end
|
|
217
|
+
|
|
218
|
+
def template_invocation_status(template_invocation)
|
|
219
|
+
task = template_invocation.try(:run_host_job_task)
|
|
220
|
+
parent_task = @job_invocation.task
|
|
221
|
+
|
|
222
|
+
return(parent_task.result == 'cancelled' ? 'cancelled' : 'N/A') if task.nil?
|
|
223
|
+
return task.state if task.state == 'running' || task.state == 'planned'
|
|
224
|
+
return 'error' if task.result == 'warning'
|
|
225
|
+
|
|
226
|
+
task.result
|
|
227
|
+
end
|
|
211
228
|
end
|
|
212
229
|
end
|
|
213
230
|
end
|
|
@@ -14,43 +14,35 @@ module RemoteExecutionHelper
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def template_invocation_status(task, parent_task)
|
|
17
|
-
if task.nil?
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
end
|
|
23
|
-
elsif task.state == 'running'
|
|
24
|
-
icon_text('running', _('running'), :kind => 'pficon')
|
|
25
|
-
elsif task.state == 'planned'
|
|
26
|
-
icon_text('build', _('planned'), :kind => 'pficon')
|
|
27
|
-
else
|
|
28
|
-
case task.result
|
|
29
|
-
when 'warning', 'error'
|
|
30
|
-
icon_text('error-circle-o', _('failed'), :kind => 'pficon')
|
|
31
|
-
when 'cancelled'
|
|
32
|
-
icon_text('warning-triangle-o', _('cancelled'), :kind => 'pficon')
|
|
33
|
-
when 'success'
|
|
34
|
-
icon_text('ok', _('success'), :kind => 'pficon')
|
|
35
|
-
else
|
|
36
|
-
task.result
|
|
37
|
-
end
|
|
38
|
-
end
|
|
17
|
+
return(parent_task.result == 'cancelled' ? _('cancelled') : 'N/A') if task.nil?
|
|
18
|
+
return task.state if task.state == 'running' || task.state == 'planned'
|
|
19
|
+
return _('error') if task.result == 'warning'
|
|
20
|
+
|
|
21
|
+
task.result
|
|
39
22
|
end
|
|
40
23
|
|
|
41
24
|
def template_invocation_actions(task, host, job_invocation, template_invocation)
|
|
25
|
+
links = []
|
|
42
26
|
host_task = template_invocation.try(:run_host_job_task)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
27
|
+
|
|
28
|
+
if authorized_for(hash_for_host_path(host).merge(auth_object: host, permission: :view_hosts, authorizer: job_hosts_authorizer))
|
|
29
|
+
links << { title: _('Host detail'),
|
|
30
|
+
action: { href: host_path(host), 'data-method': 'get', id: "#{host.name}-actions-detail" } }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
if authorized_for(hash_for_rerun_job_invocation_path(id: job_invocation, host_ids: [ host.id ], authorizer: job_hosts_authorizer))
|
|
34
|
+
links << { title: (_('Rerun on %s') % host.name),
|
|
35
|
+
action: { href: rerun_job_invocation_path(job_invocation, host_ids: [ host.id ]),
|
|
36
|
+
'data-method': 'get', id: "#{host.name}-actions-rerun" } }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
if host_task.present? && authorized_for(hash_for_foreman_tasks_task_path(host_task).merge(auth_object: host_task, permission: :view_foreman_tasks))
|
|
40
|
+
links << { title: _('Host task'),
|
|
41
|
+
action: { href: foreman_tasks_task_path(host_task),
|
|
42
|
+
'data-method': 'get', id: "#{host.name}-actions-task" } }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
links
|
|
54
46
|
end
|
|
55
47
|
|
|
56
48
|
def remote_execution_provider_for(template_invocation)
|
|
@@ -237,4 +229,17 @@ module RemoteExecutionHelper
|
|
|
237
229
|
|
|
238
230
|
task.execution_plan.actions[1].try(:input).try(:[], 'script')
|
|
239
231
|
end
|
|
232
|
+
|
|
233
|
+
def targeting_hosts(job_invocation, hosts)
|
|
234
|
+
hosts.map do |host|
|
|
235
|
+
template_invocation = job_invocation.template_invocations.find { |template_inv| template_inv.host_id == host.id }
|
|
236
|
+
task = template_invocation.try(:run_host_job_task)
|
|
237
|
+
link_authorized = !task.nil? && authorized_for(hash_for_template_invocation_path(:id => template_invocation).merge(:auth_object => host, :permission => :view_hosts, :authorizer => job_hosts_authorizer))
|
|
238
|
+
|
|
239
|
+
{ name: host.name,
|
|
240
|
+
link: link_authorized ? template_invocation_path(:id => template_invocation) : '',
|
|
241
|
+
status: template_invocation_status(task, job_invocation.task),
|
|
242
|
+
actions: template_invocation_actions(task, host, job_invocation, template_invocation) }
|
|
243
|
+
end
|
|
244
|
+
end
|
|
240
245
|
end
|
|
@@ -29,6 +29,9 @@ module Actions
|
|
|
29
29
|
|
|
30
30
|
raise _('Could not use any template used in the job invocation') if template_invocation.blank?
|
|
31
31
|
|
|
32
|
+
provider = template_invocation.template.provider
|
|
33
|
+
proxy_selector = provider.required_proxy_selector_for(template_invocation.template) || proxy_selector
|
|
34
|
+
|
|
32
35
|
provider_type = template_invocation.template.provider_type.to_s
|
|
33
36
|
proxy = determine_proxy!(proxy_selector, provider_type, host)
|
|
34
37
|
|
|
@@ -36,8 +39,6 @@ module Actions
|
|
|
36
39
|
script = renderer.render
|
|
37
40
|
raise _('Failed rendering template: %s') % renderer.error_message unless script
|
|
38
41
|
|
|
39
|
-
provider = template_invocation.template.provider
|
|
40
|
-
|
|
41
42
|
additional_options = { :hostname => provider.find_ip_or_hostname(host),
|
|
42
43
|
:script => script,
|
|
43
44
|
:execution_timeout_interval => job_invocation.execution_timeout_interval,
|
|
@@ -98,5 +98,10 @@ class RemoteExecutionProvider
|
|
|
98
98
|
def proxy_action_class
|
|
99
99
|
ForemanRemoteExecutionCore::Actions::RunScript
|
|
100
100
|
end
|
|
101
|
+
|
|
102
|
+
# Return a specific proxy selector to use for running a given template
|
|
103
|
+
# Returns either nil to use the default selector or an instance of a (sub)class of ::ForemanTasks::ProxySelector
|
|
104
|
+
def required_proxy_selector_for(_template)
|
|
105
|
+
end
|
|
101
106
|
end
|
|
102
107
|
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class DefaultProxyProxySelector < ::RemoteExecutionProxySelector
|
|
2
|
+
def initialize
|
|
3
|
+
# TODO: Remove this once we have a reliable way of determining the internal proxy without katello
|
|
4
|
+
# Tracked as https://projects.theforeman.org/issues/29840
|
|
5
|
+
raise _('Internal proxy selector can only be used if Katello is enabled') unless defined?(::Katello)
|
|
6
|
+
|
|
7
|
+
super
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def available_proxies(host, provider)
|
|
11
|
+
# TODO: Once we have a internal proxy marker/feature on the proxy, we can
|
|
12
|
+
# swap the implementation
|
|
13
|
+
raise _('default_capsule method missing from SmartProxy') unless ::SmartProxy.respond_to?(:default_capsule)
|
|
14
|
+
|
|
15
|
+
internal_proxy = ::SmartProxy.default_capsule
|
|
16
|
+
super.reduce({}) do |acc, (key, proxies)|
|
|
17
|
+
acc.merge(key => proxies.select { |proxy| proxy == internal_proxy })
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<% template_invocations = job_invocation.pattern_template_invocations %>
|
|
2
|
-
<div class="card-pf card-pf-accented">
|
|
2
|
+
<div class="card-pf card-pf-accented target-hosts-card">
|
|
3
3
|
<div class="card-pf-title">
|
|
4
4
|
<h2 style="height: 18px;" class="card-pf-title">
|
|
5
5
|
<%= _('Target hosts') %>
|
|
@@ -15,29 +15,9 @@
|
|
|
15
15
|
<% end %>
|
|
16
16
|
<br>
|
|
17
17
|
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
<th><%= sort :name, :as => _('Host') %></th>
|
|
22
|
-
<th><%= _('Status') %></th>
|
|
23
|
-
<th><%= _('Actions') %></th>
|
|
24
|
-
</tr>
|
|
25
|
-
</thead>
|
|
26
|
-
|
|
27
|
-
<tbody>
|
|
28
|
-
<% hosts.each do |host| %>
|
|
29
|
-
<% template_invocation = job_invocation.template_invocations.find { |template_invocation| template_invocation.host_id == host.id } %>
|
|
30
|
-
<% task = template_invocation.try(:run_host_job_task) %>
|
|
31
|
-
<tr>
|
|
32
|
-
<% options = { :host => host, :task => task, :job_invocation => job_invocation, :template_invocation => template_invocation } %>
|
|
33
|
-
<%= render 'host_name_td', options %>
|
|
34
|
-
<%= render 'host_status_td', options %>
|
|
35
|
-
<%= render 'host_actions_td', options %>
|
|
36
|
-
</tr>
|
|
37
|
-
<% end %>
|
|
38
|
-
</tbody>
|
|
39
|
-
</table>
|
|
40
|
-
|
|
18
|
+
<div id="targeting_hosts">
|
|
19
|
+
<%= mount_react_component('TargetingHosts', '#targeting_hosts') %>
|
|
20
|
+
</div>
|
|
41
21
|
<%= will_paginate_with_info @hosts, :container => true %>
|
|
42
22
|
<% else %>
|
|
43
23
|
<div class="alert alert-warning">
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
<% stylesheet 'foreman_remote_execution/foreman_remote_execution' %>
|
|
1
2
|
<% title _('Job invocations') %>
|
|
2
3
|
|
|
3
4
|
<% title_actions(job_invocations_buttons) %>
|
|
@@ -19,7 +20,7 @@
|
|
|
19
20
|
<tbody>
|
|
20
21
|
<% @job_invocations.each do |invocation| %>
|
|
21
22
|
<tr>
|
|
22
|
-
<td><%= link_to_if_authorized invocation_description(invocation), hash_for_job_invocation_path(invocation).merge(:auth_object => invocation, :permission => :view_job_invocations, :authorizer => authorizer) %></td>
|
|
23
|
+
<td class="text_warp"><%= link_to_if_authorized invocation_description(invocation), hash_for_job_invocation_path(invocation).merge(:auth_object => invocation, :permission => :view_job_invocations, :authorizer => authorizer) %></td>
|
|
23
24
|
<td><%= trunc_with_tooltip(invocation&.targeting&.search_query, 15) %></td>
|
|
24
25
|
<td><%= link_to_invocation_task_if_authorized(invocation) %></td>
|
|
25
26
|
<td><%= invocation_result(invocation, :success_count) %></td>
|
|
@@ -41,9 +41,3 @@
|
|
|
41
41
|
<% end %>
|
|
42
42
|
<%= render_tab_content_for(:main_tabs, subject: @job_invocation) %>
|
|
43
43
|
</div>
|
|
44
|
-
|
|
45
|
-
<script id="job_invocation_refresh" data-refresh-url="<%= job_invocation_path(@job_invocation) %>">
|
|
46
|
-
<% if @auto_refresh %>
|
|
47
|
-
delayed_refresh($('script#job_invocation_refresh').data('refresh-url'), job_invocation_refresh_data());
|
|
48
|
-
<% end %>
|
|
49
|
-
</script>
|