foreman_remote_execution 16.1.0 → 16.2.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 +4 -4
- data/app/assets/javascripts/foreman_remote_execution/locale/de/foreman_remote_execution.js +57 -30
- data/app/assets/javascripts/foreman_remote_execution/locale/en_GB/foreman_remote_execution.js +55 -28
- data/app/assets/javascripts/foreman_remote_execution/locale/es/foreman_remote_execution.js +58 -31
- data/app/assets/javascripts/foreman_remote_execution/locale/fr/foreman_remote_execution.js +64 -37
- data/app/assets/javascripts/foreman_remote_execution/locale/ja/foreman_remote_execution.js +65 -38
- data/app/assets/javascripts/foreman_remote_execution/locale/ka/foreman_remote_execution.js +56 -29
- data/app/assets/javascripts/foreman_remote_execution/locale/ko/foreman_remote_execution.js +64 -37
- data/app/assets/javascripts/foreman_remote_execution/locale/pt_BR/foreman_remote_execution.js +58 -31
- data/app/assets/javascripts/foreman_remote_execution/locale/ru/foreman_remote_execution.js +55 -28
- data/app/assets/javascripts/foreman_remote_execution/locale/zh_CN/foreman_remote_execution.js +64 -37
- data/app/assets/javascripts/foreman_remote_execution/locale/zh_TW/foreman_remote_execution.js +55 -28
- data/app/views/api/v2/job_templates/main.json.rabl +1 -1
- data/config/routes.rb +2 -1
- data/extra/cockpit/foreman-cockpit-session +3 -2
- data/lib/foreman_remote_execution/plugin.rb +1 -1
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/locale/de/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/de/foreman_remote_execution.po +57 -30
- data/locale/en_GB/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/en_GB/foreman_remote_execution.po +55 -28
- data/locale/es/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/es/foreman_remote_execution.po +58 -31
- data/locale/foreman_remote_execution.pot +202 -161
- data/locale/fr/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/fr/foreman_remote_execution.po +64 -37
- data/locale/ja/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ja/foreman_remote_execution.po +65 -38
- data/locale/ka/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ka/foreman_remote_execution.po +56 -29
- data/locale/ko/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ko/foreman_remote_execution.po +64 -37
- data/locale/pt_BR/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/pt_BR/foreman_remote_execution.po +58 -31
- data/locale/ru/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ru/foreman_remote_execution.po +55 -28
- data/locale/zh_CN/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/zh_CN/foreman_remote_execution.po +64 -37
- data/locale/zh_TW/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/zh_TW/foreman_remote_execution.po +55 -28
- data/webpack/JobInvocationDetail/CheckboxesActions.js +1 -2
- data/webpack/JobInvocationDetail/JobInvocationHostTable.js +14 -1
- data/webpack/JobInvocationDetail/TemplateInvocation.js +63 -50
- data/webpack/JobInvocationDetail/TemplateInvocationPage.js +1 -0
- data/webpack/JobInvocationDetail/__tests__/TableToolbarActions.test.js +1 -1
- data/webpack/JobInvocationDetail/__tests__/TemplateInvocation.test.js +4 -0
- data/webpack/JobInvocationDetail/index.js +1 -1
- data/webpack/JobWizard/Footer.js +7 -1
- data/webpack/JobWizard/steps/HostsAndInputs/buildHostQuery.js +1 -1
- data/webpack/react_app/components/HostKebab/KebabItems.js +2 -3
- data/webpack/react_app/components/RecentJobsCard/RecentJobsCard.js +5 -6
- metadata +2 -2
@@ -57,9 +57,9 @@ export const TemplateInvocation = ({
|
|
57
57
|
hostID,
|
58
58
|
jobID,
|
59
59
|
isInTableView,
|
60
|
+
isExpanded,
|
60
61
|
hostName,
|
61
62
|
hostProxy,
|
62
|
-
isExpanded,
|
63
63
|
}) => {
|
64
64
|
const intervalRef = useRef(null);
|
65
65
|
const templateURL = showTemplateInvocationUrl(hostID, jobID);
|
@@ -67,72 +67,76 @@ export const TemplateInvocation = ({
|
|
67
67
|
|
68
68
|
const status = useSelector(selectTemplateInvocationStatus(hostID));
|
69
69
|
const response = useSelector(selectTemplateInvocation(hostID));
|
70
|
-
const finished = response.finished ?? true;
|
71
|
-
const autoRefresh = response.auto_refresh || false;
|
72
70
|
const dispatch = useDispatch();
|
73
71
|
|
72
|
+
const responseRef = useRef(response);
|
74
73
|
useEffect(() => {
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
74
|
+
responseRef.current = response;
|
75
|
+
}, [response]);
|
76
|
+
|
77
|
+
const [showOutputType, setShowOutputType] = useState({
|
78
|
+
stderr: true,
|
79
|
+
stdout: true,
|
80
|
+
debug: true,
|
81
|
+
});
|
82
|
+
const [showTemplatePreview, setShowTemplatePreview] = useState(false);
|
83
|
+
const [showCommand, setShowCommand] = useState(false);
|
84
|
+
|
85
|
+
useEffect(() => {
|
86
|
+
const dispatchFetch = () => {
|
87
|
+
dispatch(
|
88
|
+
APIActions.get({
|
89
|
+
url: templateURL,
|
90
|
+
key: `${GET_TEMPLATE_INVOCATION}_${hostID}`,
|
91
|
+
})
|
92
|
+
);
|
90
93
|
};
|
91
|
-
|
92
|
-
if (
|
94
|
+
|
95
|
+
if (intervalRef.current) {
|
96
|
+
clearInterval(intervalRef.current);
|
97
|
+
intervalRef.current = null;
|
98
|
+
}
|
99
|
+
|
100
|
+
if (isExpanded) {
|
101
|
+
if (isEmpty(responseRef.current)) {
|
102
|
+
dispatchFetch();
|
103
|
+
}
|
104
|
+
|
93
105
|
intervalRef.current = setInterval(() => {
|
94
|
-
|
106
|
+
const latestResponse = responseRef.current;
|
107
|
+
const finished = latestResponse?.finished ?? true;
|
108
|
+
// eslint-disable-next-line camelcase
|
109
|
+
const autoRefresh = latestResponse?.auto_refresh || false;
|
110
|
+
|
111
|
+
if (!finished && autoRefresh) {
|
112
|
+
dispatchFetch();
|
113
|
+
} else if (intervalRef.current) {
|
114
|
+
clearInterval(intervalRef.current);
|
115
|
+
}
|
95
116
|
}, 5000);
|
96
117
|
}
|
97
118
|
|
98
119
|
return () => {
|
99
120
|
if (intervalRef.current) {
|
100
121
|
clearInterval(intervalRef.current);
|
101
|
-
intervalRef.current = null;
|
102
122
|
}
|
103
123
|
};
|
104
|
-
}, [
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
124
|
+
}, [isExpanded, dispatch, templateURL, hostID]);
|
125
|
+
|
126
|
+
if (!isExpanded) {
|
127
|
+
return null;
|
128
|
+
}
|
129
|
+
|
130
|
+
if ((status === STATUS.PENDING && isEmpty(response)) || !response) {
|
131
|
+
return <Skeleton />;
|
132
|
+
}
|
113
133
|
|
114
134
|
const errorMessage =
|
115
135
|
response?.response?.data?.error?.message ||
|
116
136
|
response?.response?.data?.error ||
|
117
137
|
JSON.stringify(response);
|
118
|
-
|
119
|
-
|
120
|
-
output,
|
121
|
-
input_values: inputValues,
|
122
|
-
task,
|
123
|
-
permissions,
|
124
|
-
} = response;
|
125
|
-
const { id: taskID, cancellable: taskCancellable } = task || {};
|
126
|
-
const [showOutputType, setShowOutputType] = useState({
|
127
|
-
stderr: true,
|
128
|
-
stdout: true,
|
129
|
-
debug: true,
|
130
|
-
});
|
131
|
-
const [showTemplatePreview, setShowTemplatePreview] = useState(false);
|
132
|
-
const [showCommand, setCommand] = useState(false);
|
133
|
-
if (status === STATUS.PENDING && isEmpty(response)) {
|
134
|
-
return <Skeleton />;
|
135
|
-
} else if (status === STATUS.ERROR) {
|
138
|
+
|
139
|
+
if (status === STATUS.ERROR) {
|
136
140
|
return (
|
137
141
|
<Alert
|
138
142
|
ouiaId="template-invocation-error-alert"
|
@@ -146,6 +150,15 @@ export const TemplateInvocation = ({
|
|
146
150
|
);
|
147
151
|
}
|
148
152
|
|
153
|
+
const {
|
154
|
+
preview,
|
155
|
+
output,
|
156
|
+
input_values: inputValues,
|
157
|
+
task,
|
158
|
+
permissions,
|
159
|
+
} = response;
|
160
|
+
const { id: taskID, cancellable: taskCancellable } = task || {};
|
161
|
+
|
149
162
|
return (
|
150
163
|
<div
|
151
164
|
id={`template-invocation-${hostID}`}
|
@@ -159,7 +172,7 @@ export const TemplateInvocation = ({
|
|
159
172
|
setShowTemplatePreview={setShowTemplatePreview}
|
160
173
|
showTemplatePreview={showTemplatePreview}
|
161
174
|
showCommand={showCommand}
|
162
|
-
setShowCommand={
|
175
|
+
setShowCommand={setShowCommand}
|
163
176
|
newTabUrl={templateInvocationPageUrl(hostID, jobID)}
|
164
177
|
isInTableView={isInTableView}
|
165
178
|
copyToClipboard={
|
@@ -196,7 +196,7 @@ describe('TableToolbarActions', () => {
|
|
196
196
|
const rerunLink = screen.getByRole('link', { name: /rerun/i });
|
197
197
|
expect(rerunLink).toBeEnabled();
|
198
198
|
const expectedHref = foremanUrl(
|
199
|
-
`/job_invocations/42/rerun?search=(
|
199
|
+
`/job_invocations/42/rerun?search=(job_invocation.id = 42) AND ((id ^ (101, 102, 103)))`
|
200
200
|
);
|
201
201
|
expect(rerunLink).toHaveAttribute('href', expectedHref);
|
202
202
|
});
|
@@ -32,6 +32,7 @@ describe('TemplateInvocation', () => {
|
|
32
32
|
hostID="1"
|
33
33
|
jobID="1"
|
34
34
|
isInTableView={false}
|
35
|
+
isExpanded
|
35
36
|
hostName="example-host"
|
36
37
|
hostProxy={{ name: 'example-proxy', href: '#' }}
|
37
38
|
/>
|
@@ -54,6 +55,7 @@ describe('TemplateInvocation', () => {
|
|
54
55
|
hostID="1"
|
55
56
|
jobID="1"
|
56
57
|
isInTableView={false}
|
58
|
+
isExpanded
|
57
59
|
hostName="example-host"
|
58
60
|
hostProxy={{ name: 'example-proxy', href: '#' }}
|
59
61
|
/>
|
@@ -108,6 +110,7 @@ describe('TemplateInvocation', () => {
|
|
108
110
|
hostID="1"
|
109
111
|
jobID="1"
|
110
112
|
isInTableView={false}
|
113
|
+
isExpanded
|
111
114
|
hostName="example-host"
|
112
115
|
hostProxy={{ name: 'example-proxy', href: '#' }}
|
113
116
|
/>
|
@@ -133,6 +136,7 @@ describe('TemplateInvocation', () => {
|
|
133
136
|
hostID="1"
|
134
137
|
jobID="1"
|
135
138
|
isInTableView={false}
|
139
|
+
isExpanded
|
136
140
|
hostName="example-host"
|
137
141
|
/>
|
138
142
|
</Provider>
|
@@ -183,9 +183,9 @@ const JobInvocationDetailPage = ({
|
|
183
183
|
id={id}
|
184
184
|
targeting={targeting}
|
185
185
|
failedCount={failed}
|
186
|
-
finished={finished}
|
187
186
|
autoRefresh={autoRefresh}
|
188
187
|
initialFilter={selectedFilter}
|
188
|
+
statusLabel={statusLabel}
|
189
189
|
onFilterUpdate={handleFilterChange}
|
190
190
|
/>
|
191
191
|
</SkeletonLoader>
|
data/webpack/JobWizard/Footer.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import React from 'react';
|
1
|
+
import React, { useRef } from 'react';
|
2
2
|
import { useSelector } from 'react-redux';
|
3
3
|
import PropTypes from 'prop-types';
|
4
4
|
import { Button, Tooltip, Spinner } from '@patternfly/react-core';
|
@@ -12,6 +12,8 @@ import { selectIsSubmitting } from './JobWizardSelectors';
|
|
12
12
|
|
13
13
|
export const Footer = ({ canSubmit, onSave }) => {
|
14
14
|
const isSubmitting = useSelector(selectIsSubmitting);
|
15
|
+
const tooltipRunOn = useRef(null);
|
16
|
+
const tooltipSkipTo = useRef(null);
|
15
17
|
return (
|
16
18
|
<WizardFooter>
|
17
19
|
<WizardContextConsumer>
|
@@ -52,6 +54,7 @@ export const Footer = ({ canSubmit, onSave }) => {
|
|
52
54
|
: __('Fill all required fields in all the steps')}
|
53
55
|
</div>
|
54
56
|
}
|
57
|
+
triggerRef={tooltipRunOn}
|
55
58
|
>
|
56
59
|
<Button
|
57
60
|
ouiaId="run-on-selected-hosts-footer"
|
@@ -59,6 +62,7 @@ export const Footer = ({ canSubmit, onSave }) => {
|
|
59
62
|
onClick={onSave}
|
60
63
|
isAriaDisabled={!canSubmit}
|
61
64
|
isDisabled={isSubmitting}
|
65
|
+
ref={tooltipRunOn}
|
62
66
|
>
|
63
67
|
{__('Run on selected hosts')}
|
64
68
|
</Button>
|
@@ -73,6 +77,7 @@ export const Footer = ({ canSubmit, onSave }) => {
|
|
73
77
|
)}
|
74
78
|
</div>
|
75
79
|
}
|
80
|
+
triggerRef={tooltipSkipTo}
|
76
81
|
>
|
77
82
|
<Button
|
78
83
|
ouiaId="skip-to-review-footer"
|
@@ -80,6 +85,7 @@ export const Footer = ({ canSubmit, onSave }) => {
|
|
80
85
|
onClick={() => goToStepByName(WIZARD_TITLES.review)}
|
81
86
|
isAriaDisabled={!canSubmit}
|
82
87
|
isDisabled={isSubmitting}
|
88
|
+
ref={tooltipSkipTo}
|
83
89
|
>
|
84
90
|
{__('Skip to review')}
|
85
91
|
</Button>
|
@@ -18,7 +18,7 @@ export const buildHostQuery = (selected, search) => {
|
|
18
18
|
.join(',')})`;
|
19
19
|
|
20
20
|
let hostGroupsSearch;
|
21
|
-
if (
|
21
|
+
if (hostGroups.length < MAX_NAME_ITEMS)
|
22
22
|
hostGroupsSearch = `hostgroup_fullname ^ (${hostGroups
|
23
23
|
.map(({ name }) => nameEscape(name))
|
24
24
|
.join(',')})`;
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import { useSelector } from 'react-redux';
|
3
|
-
import { DropdownItem } from '@patternfly/react-core
|
3
|
+
import { DropdownItem } from '@patternfly/react-core';
|
4
4
|
import { CodeIcon } from '@patternfly/react-icons';
|
5
5
|
import { selectAPIResponse } from 'foremanReact/redux/API/APISelectors';
|
6
6
|
import { translate as __ } from 'foremanReact/common/I18n';
|
@@ -16,9 +16,8 @@ const HostKebabItems = () => {
|
|
16
16
|
<DropdownItem
|
17
17
|
ouiaId="web-console-dropdown-item"
|
18
18
|
icon={<CodeIcon />}
|
19
|
-
|
19
|
+
to={consoleUrl}
|
20
20
|
target="_blank"
|
21
|
-
rel="noreferrer"
|
22
21
|
>
|
23
22
|
{__('Web Console')}
|
24
23
|
</DropdownItem>
|
@@ -1,8 +1,7 @@
|
|
1
1
|
import PropTypes from 'prop-types';
|
2
2
|
import React, { useState } from 'react';
|
3
3
|
|
4
|
-
import { Tabs, Tab, TabTitleText } from '@patternfly/react-core';
|
5
|
-
import { DropdownItem } from '@patternfly/react-core/deprecated';
|
4
|
+
import { DropdownItem, Tabs, Tab, TabTitleText } from '@patternfly/react-core';
|
6
5
|
import CardTemplate from 'foremanReact/components/HostDetails/Templates/CardItem/CardTemplate';
|
7
6
|
import { translate as __ } from 'foremanReact/common/I18n';
|
8
7
|
import { foremanUrl } from 'foremanReact/common/helpers';
|
@@ -26,14 +25,14 @@ const RecentJobsCard = ({ hostDetails: { name, id } }) => {
|
|
26
25
|
header={__('Recent jobs')}
|
27
26
|
dropdownItems={[
|
28
27
|
<DropdownItem
|
29
|
-
|
28
|
+
to={foremanUrl(`${JOB_BASE_URL}${id}`)}
|
30
29
|
key="link-to-all"
|
31
30
|
ouiaId="link-to-all-dropdown-item"
|
32
31
|
>
|
33
32
|
{__('View all jobs')}
|
34
33
|
</DropdownItem>,
|
35
34
|
<DropdownItem
|
36
|
-
|
35
|
+
to={foremanUrl(
|
37
36
|
`${JOB_BASE_URL}${id}+and+status+%3D+failed+or+status%3D+succeeded`
|
38
37
|
)}
|
39
38
|
key="link-to-finished"
|
@@ -42,14 +41,14 @@ const RecentJobsCard = ({ hostDetails: { name, id } }) => {
|
|
42
41
|
{__('View finished jobs')}
|
43
42
|
</DropdownItem>,
|
44
43
|
<DropdownItem
|
45
|
-
|
44
|
+
to={foremanUrl(`${JOB_BASE_URL}${id}+and+status+%3D+running`)}
|
46
45
|
key="link-to-running"
|
47
46
|
ouiaId="link-to-running-dropdown-item"
|
48
47
|
>
|
49
48
|
{__('View running jobs')}
|
50
49
|
</DropdownItem>,
|
51
50
|
<DropdownItem
|
52
|
-
|
51
|
+
to={foremanUrl(`${JOB_BASE_URL}${id}+and+status+%3D+queued`)}
|
53
52
|
key="link-to-scheduled"
|
54
53
|
ouiaId="link-to-scheduled-dropdown-item"
|
55
54
|
>
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_remote_execution
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 16.1
|
4
|
+
version: 16.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Foreman Remote Execution team
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-09-16 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: deface
|