foreman_patch 1.1.1 → 1.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +0 -6
- data/app/controllers/foreman_patch/api/v2/invocations_controller.rb +23 -1
- data/app/lib/actions/foreman_patch/cycle/initiate.rb +6 -1
- data/app/lib/actions/foreman_patch/invocation/patch.rb +6 -2
- data/app/lib/actions/foreman_patch/invocation/wait_for_host.rb +9 -16
- data/app/lib/actions/foreman_patch/window/patch.rb +4 -4
- data/app/models/foreman_patch/invocation.rb +6 -0
- data/app/models/foreman_patch/plan.rb +1 -1
- data/app/models/foreman_patch/round.rb +9 -26
- data/app/models/foreman_patch/window.rb +1 -1
- data/app/views/foreman_patch/api/v2/rounds/base.json.rabl +1 -1
- data/app/views/foreman_patch/api/v2/rounds/status.json.rabl +2 -8
- data/app/views/templates/ensure_services.erb +7 -4
- data/config/api_routes.rb +7 -1
- data/lib/foreman_patch/version.rb +1 -1
- data/lib/foreman_patch.rb +3 -2
- data/webpack/components/Invocations/Invocations.js +48 -16
- data/webpack/components/Invocations/InvocationsPage.js +24 -1
- data/webpack/components/Invocations/InvocationsSelectors.js +1 -1
- data/webpack/components/Invocations/components/{InvocationItem.js → InvocationActions.js} +4 -16
- data/webpack/components/Invocations/index.js +93 -10
- data/webpack/components/RoundProgress/AggregateStatus.js +6 -5
- data/webpack/components/RoundProgress/RoundProgress.js +7 -6
- data/webpack/components/RoundProgress/RoundProgressSelectors.js +3 -2
- data/webpack/index.js +8 -0
- data/webpack/src/ForemanPatch.js +11 -0
- data/webpack/src/Router/index.js +14 -0
- data/webpack/src/Router/routes.js +3 -0
- data/webpack/src/index.js +1 -0
- data/webpack/src/reducers.js +7 -0
- metadata +12 -63
- data/app/lib/actions/foreman_patch/invocation/ensure_services.rb +0 -47
- data/app/lib/actions/foreman_patch/invocation/restart.rb +0 -101
- data/app/lib/actions/foreman_patch/invocation/update_packages.rb +0 -52
- data/app/lib/actions/helpers/failure_notification.rb +0 -20
- data/app/lib/actions/helpers/with_feature_action.rb +0 -102
- data/public/assets/foreman_patch/cycle_plans-e5667e178ba389908f5c815b24ec0ea77c340849d56bc39c5ce72bb626bd446a.scss +0 -6
- data/public/assets/foreman_patch/cycle_plans-e5667e178ba389908f5c815b24ec0ea77c340849d56bc39c5ce72bb626bd446a.scss.gz +0 -0
- data/public/assets/foreman_patch/foreman_patch-ce5805a60c0d5f896f557ff5246e5a09172043004c850b39bea54e618df1c485.css +0 -1
- data/public/assets/foreman_patch/foreman_patch-ce5805a60c0d5f896f557ff5246e5a09172043004c850b39bea54e618df1c485.css.gz +0 -0
- data/public/assets/foreman_patch/foreman_patch.json +0 -1
- data/public/assets/foreman_patch/plan_edit_windows-e656ba411642a7f983b51958ab30ac49c056322d19295a603cff4d5e6c71c8ed.js +0 -1
- data/public/assets/foreman_patch/plan_edit_windows-e656ba411642a7f983b51958ab30ac49c056322d19295a603cff4d5e6c71c8ed.js.gz +0 -0
- data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.css +0 -1
- data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.css.gz +0 -0
- data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.js +0 -6
- data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.js.gz +0 -0
- data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.js.map +0 -1
- data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.js.map.gz +0 -0
- data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.css +0 -1
- data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.css.gz +0 -0
- data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.js +0 -6
- data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.js.gz +0 -0
- data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.js.map +0 -1
- data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.js.map.gz +0 -0
- data/public/webpack/foreman_patch/manifest.json +0 -26
- data/public/webpack/foreman_patch/manifest.json.gz +0 -0
- data/public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js +0 -2
- data/public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js.gz +0 -0
- data/public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js.map +0 -1
- data/public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js.map.gz +0 -0
- /data/webpack/components/Invocations/{InvocationsPage.scss → Invocations.scss} +0 -0
@@ -1,6 +1,7 @@
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
2
2
|
import { useSelector, useDispatch } from 'react-redux';
|
3
3
|
import PropTypes from 'prop-types';
|
4
|
+
import { Grid } from 'patternfly-react';
|
4
5
|
|
5
6
|
import {
|
6
7
|
withInterval,
|
@@ -8,7 +9,13 @@ import {
|
|
8
9
|
} from 'foremanReact/redux/middlewares/IntervalMiddleware';
|
9
10
|
import { get } from 'foremanReact/redux/API';
|
10
11
|
import { useForemanSettings } from 'foremanReact/Root/Context/ForemanContext';
|
12
|
+
import { getControllerSearchProps } from 'foremanReact/constants';
|
13
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
14
|
+
import SearchBar from 'foremanReact/components/SearchBar';
|
15
|
+
import Pagination from 'foremanReact/components/Pagination/PaginationWrapper';
|
16
|
+
import { ActionButtons } from 'foremanReact/components/common/ActionButtons/ActionButtons';
|
11
17
|
|
18
|
+
import Invocations from './Invocations';
|
12
19
|
import {
|
13
20
|
selectItems,
|
14
21
|
selectTotal,
|
@@ -18,7 +25,8 @@ import {
|
|
18
25
|
} from './InvocationsSelectors';
|
19
26
|
import { getUrl } from './InvocationsHelpers';
|
20
27
|
import { INVOCATIONS } from './InvocationsConstants';
|
21
|
-
|
28
|
+
|
29
|
+
import './Invocations.scss';
|
22
30
|
|
23
31
|
const WrappedInvocations = ({ round }) => {
|
24
32
|
const dispatch = useDispatch();
|
@@ -36,6 +44,9 @@ const WrappedInvocations = ({ round }) => {
|
|
36
44
|
});
|
37
45
|
const [url, setUrl] = useState(getUrl(round, searchQuery, pagination));
|
38
46
|
const intervalExists = useSelector(selectIntervalExists);
|
47
|
+
const [selectedItems, setSelectedItems] = useState([]);
|
48
|
+
const [recentSelectedItemIndex, setRecentSelectedRowIndex] = useState(null);
|
49
|
+
const [shifting, setShifting] = useState(false);
|
39
50
|
|
40
51
|
const handleSearch = query => {
|
41
52
|
const defaultPagination = { page: 1, perPage: pagination.perPage };
|
@@ -52,6 +63,32 @@ const WrappedInvocations = ({ round }) => {
|
|
52
63
|
setUrl(getUrl(round, searchQuery, args));
|
53
64
|
};
|
54
65
|
|
66
|
+
const selectAll = (isSelecting) => setSelectedItems(isSelecting ? items.map(item => item.id) : []);
|
67
|
+
|
68
|
+
const areAllSelected = selectedItems.length == items.length;
|
69
|
+
|
70
|
+
const setItemSelected = (item, isSelecting) =>
|
71
|
+
setSelectedItems(prevSelected => {
|
72
|
+
const otherSelectedItems = prevSelected.filter(i => i !== item.id);
|
73
|
+
return isSelecting ? [...otherSelectedItems, item.id] : otherSelectedItems;
|
74
|
+
});
|
75
|
+
|
76
|
+
const onSelect = (item, rowIndex, isSelecting) => {
|
77
|
+
if (shifting && recentSelectedRowIndex !== null) {
|
78
|
+
const numberSelected = rowIndex - recentSelectedRowIndex;
|
79
|
+
const intermediateIndexes =
|
80
|
+
numberSelected > 0
|
81
|
+
? Array.from(new Array(numberSelected + 1), (_x, i) => i + recentSelectedRowIndex)
|
82
|
+
: Array.from(new Array(Math.abs(numberSelected) + 1), (_x, i) => i + rowIndex);
|
83
|
+
intermediateIndexes.forEach(index, setItemSelected(items[index], isSelecting));
|
84
|
+
} else {
|
85
|
+
setItemSelected(item, isSelecting);
|
86
|
+
}
|
87
|
+
setRecentSelectedRowIndex(rowIndex);
|
88
|
+
};
|
89
|
+
|
90
|
+
const isSelected = item => selectedItems.includes(item.id);
|
91
|
+
|
55
92
|
const stopApiInterval = () => {
|
56
93
|
if (intervalExists) {
|
57
94
|
dispatch(stopInterval(INVOCATIONS));
|
@@ -67,27 +104,73 @@ const WrappedInvocations = ({ round }) => {
|
|
67
104
|
}), 5000);
|
68
105
|
|
69
106
|
useEffect(() => {
|
107
|
+
const onKeyDown = (e) => {
|
108
|
+
if (e.key === 'Shift') {
|
109
|
+
setShifting(true);
|
110
|
+
}
|
111
|
+
};
|
112
|
+
const onKeyUp = (e) => {
|
113
|
+
if (e.key === 'Shift') {
|
114
|
+
setShifting(false);
|
115
|
+
}
|
116
|
+
};
|
117
|
+
|
70
118
|
dispatch(getData(url));
|
71
119
|
|
72
120
|
if (!autoRefresh) {
|
73
121
|
dispatch(stopInterval(INVOCATIONS));
|
74
122
|
}
|
75
123
|
|
124
|
+
document.addEventListener('keydown', onKeyDown);
|
125
|
+
document.addEventListener('keyup', onKeyUp);
|
126
|
+
|
76
127
|
return () => {
|
77
128
|
dispatch(stopInterval(INVOCATIONS));
|
129
|
+
document.removeEventListener('keydown', onKeyDown);
|
130
|
+
document.removeEventListener('keyup', onKeyUp);
|
78
131
|
};
|
79
132
|
}, [dispatch, url, autoRefresh]);
|
80
133
|
|
81
134
|
return (
|
82
|
-
<
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
135
|
+
<React.Fragment>
|
136
|
+
<Grid.Row>
|
137
|
+
<Grid.Col md={6} className="title_filter">
|
138
|
+
<SearchBar
|
139
|
+
onSearch={handleSearch}
|
140
|
+
data={{
|
141
|
+
...getControllerSearchProps('foreman_patch/invocations'),
|
142
|
+
autocomplete: {
|
143
|
+
id: 'invocations_search',
|
144
|
+
searchQuery,
|
145
|
+
url: '/foreman_patch/invocations/auto_complete_search',
|
146
|
+
useKeyShortcuts: true,
|
147
|
+
},
|
148
|
+
bookmarks: {},
|
149
|
+
}}
|
150
|
+
/>
|
151
|
+
</Grid.Col>
|
152
|
+
<Grid.Col md={6}>
|
153
|
+
<ActionButtons buttons={actions} />
|
154
|
+
</Grid.Col>
|
155
|
+
</Grid.Row>
|
156
|
+
<br />
|
157
|
+
<Invocations
|
158
|
+
status={status}
|
159
|
+
items={items}
|
160
|
+
selectAll={selectAll}
|
161
|
+
areAllSelected={areAllSelected}
|
162
|
+
isSelected={isSelected}
|
163
|
+
onSelect={onSelect}
|
164
|
+
/>
|
165
|
+
<Pagination
|
166
|
+
viewType="table"
|
167
|
+
itemCount={total}
|
168
|
+
pagination={pagination}
|
169
|
+
onChange={handlePagination}
|
170
|
+
dropdownButtonId="invocations-pagination-dropdown"
|
171
|
+
className="invocations-pagination"
|
172
|
+
/>
|
173
|
+
</React.Fragment>
|
91
174
|
);
|
92
175
|
};
|
93
176
|
|
@@ -19,7 +19,7 @@ const AggregateStatus = ({ progress }) => (
|
|
19
19
|
<span className="card-pf-aggregate-status-notification">
|
20
20
|
<span id="failed_count">
|
21
21
|
<span className="pficon pficon-error-circle-o" />
|
22
|
-
{progress.
|
22
|
+
{progress.error}
|
23
23
|
</span>
|
24
24
|
</span>
|
25
25
|
<span className="card-pf-aggregate-status-notification">
|
@@ -31,7 +31,7 @@ const AggregateStatus = ({ progress }) => (
|
|
31
31
|
<span className="card-pf-aggregate-status-notification">
|
32
32
|
<span id="pending_count">
|
33
33
|
<span className="pficon pficon-pending" />
|
34
|
-
{progress.pending}
|
34
|
+
{progress.pending + progress.planned}
|
35
35
|
</span>
|
36
36
|
</span>
|
37
37
|
<span className="card-pf-aggregate-status-notification">
|
@@ -46,11 +46,12 @@ const AggregateStatus = ({ progress }) => (
|
|
46
46
|
|
47
47
|
AggregateStatus.propTypes = {
|
48
48
|
progress: PropTypes.shape({
|
49
|
+
planned: PropTypes.number,
|
50
|
+
pending: PropTypes.number,
|
51
|
+
running: PropTypes.number,
|
49
52
|
success: PropTypes.number,
|
50
53
|
warning: PropTypes.number,
|
51
|
-
|
52
|
-
running: PropTypes.number,
|
53
|
-
pending: PropTypes.number,
|
54
|
+
error: PropTypes.number,
|
54
55
|
cancelled: PropTypes.number,
|
55
56
|
}).isRequired,
|
56
57
|
};
|
@@ -11,14 +11,14 @@ const RoundProgress = ({ progress }) => {
|
|
11
11
|
const data = [
|
12
12
|
[__('Success'), progress.success, '#5CB85C'],
|
13
13
|
[__('Warning'), progress.warning, '#DB843D'],
|
14
|
-
[__('Failed'), progress.
|
14
|
+
[__('Failed'), progress.error, '#D9534F'],
|
15
15
|
[__('Running'), progress.running, '#3D96AE'],
|
16
|
-
[__('Pending'), progress.pending, '#DEDEDE'],
|
16
|
+
[__('Pending'), progress.pending + progress.planned, '#DEDEDE'],
|
17
17
|
[__('Cancelled'), progress.cancelled, '#B7312D'],
|
18
18
|
];
|
19
19
|
|
20
20
|
const iMax = data.reduce((im, e, i, arr) =>
|
21
|
-
(e[1] > arr[im][
|
21
|
+
(e[1] > arr[im][1] ? i : im), 0);
|
22
22
|
|
23
23
|
return (
|
24
24
|
<div id="round_progress">
|
@@ -36,11 +36,12 @@ const RoundProgress = ({ progress }) => {
|
|
36
36
|
|
37
37
|
RoundProgress.propTypes = {
|
38
38
|
progress: PropTypes.shape({
|
39
|
+
pending: PropTypes.number,
|
40
|
+
planned: PropTypes.number,
|
41
|
+
running: PropTypes.number,
|
39
42
|
success: PropTypes.number,
|
40
43
|
warning: PropTypes.number,
|
41
|
-
|
42
|
-
running: PropTypes.number,
|
43
|
-
pending: PropTypes.number,
|
44
|
+
error: PropTypes.number,
|
44
45
|
cancelled: PropTypes.number,
|
45
46
|
}).isRequired,
|
46
47
|
};
|
@@ -8,9 +8,10 @@ import { ROUND_PROGRESS } from './RoundProgressConstants';
|
|
8
8
|
const defaultProgress = {
|
9
9
|
success: 0,
|
10
10
|
warning: 0,
|
11
|
-
|
11
|
+
error: 0,
|
12
12
|
running: 0,
|
13
13
|
pending: 0,
|
14
|
+
planned: 0,
|
14
15
|
cancelled: 0,
|
15
16
|
};
|
16
17
|
|
@@ -18,7 +19,7 @@ export const selectProgress = state =>
|
|
18
19
|
selectAPIResponse(state, ROUND_PROGRESS).progress || defaultProgress;
|
19
20
|
|
20
21
|
export const selectAutoRefresh = state =>
|
21
|
-
|
22
|
+
selectAPIResponse(state, ROUND_PROGRESS).status != 'complete';
|
22
23
|
|
23
24
|
export const selectStatus = state =>
|
24
25
|
selectAPIStatus(state, ROUND_PROGRESS);
|
data/webpack/index.js
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
/* eslint-disable import/no-extraneous-dependencies */
|
3
3
|
/* eslint-disable import/extensions */
|
4
4
|
import componentRegistry from 'foremanReact/components/componentRegistry';
|
5
|
+
import { registerReducer } from 'foremanReact/common/MountingService';
|
6
|
+
import reducers from './src/reducers';
|
7
|
+
import ForemanPatch from './src/ForemanPatch';
|
5
8
|
|
6
9
|
import Rounds from './components/Rounds';
|
7
10
|
import Plan from './components/Plan';
|
@@ -17,4 +20,9 @@ const components = [
|
|
17
20
|
{ name: 'RoundProgress', type: RoundProgress },
|
18
21
|
];
|
19
22
|
|
23
|
+
Object.entries(reducers).forEach(([key, reducer]) =>
|
24
|
+
registerReducer(key, reducer)
|
25
|
+
);
|
26
|
+
|
20
27
|
components.forEach(component => componentRegistry.register(component));
|
28
|
+
componentRegistry.register({ name: 'ForemanPatch', type: ForemanPatch });
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { Switch, Route } from 'react-router-dom';
|
3
|
+
|
4
|
+
import routes from './routes';
|
5
|
+
|
6
|
+
const Router = () => (
|
7
|
+
<Switch>
|
8
|
+
{Object.entries(routes).map(([key, props]) => (
|
9
|
+
<Route key={key} {...props} />
|
10
|
+
))}
|
11
|
+
</Switch>
|
12
|
+
);
|
13
|
+
|
14
|
+
export default Router;
|
@@ -0,0 +1 @@
|
|
1
|
+
export { default } from './ForemanPuppet';
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_patch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Galens
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: katello
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '4'
|
19
|
+
version: '4.1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '4'
|
26
|
+
version: '4.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: foreman-tasks
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -31,9 +31,6 @@ dependencies:
|
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '4.0'
|
34
|
-
- - "<"
|
35
|
-
- !ruby/object:Gem::Version
|
36
|
-
version: '6.0'
|
37
34
|
type: :runtime
|
38
35
|
prerelease: false
|
39
36
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -41,9 +38,6 @@ dependencies:
|
|
41
38
|
- - ">="
|
42
39
|
- !ruby/object:Gem::Version
|
43
40
|
version: '4.0'
|
44
|
-
- - "<"
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version: '6.0'
|
47
41
|
- !ruby/object:Gem::Dependency
|
48
42
|
name: foreman_remote_execution
|
49
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -51,9 +45,6 @@ dependencies:
|
|
51
45
|
- - ">="
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '4.0'
|
54
|
-
- - "<"
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
version: '6.0'
|
57
48
|
type: :runtime
|
58
49
|
prerelease: false
|
59
50
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -61,23 +52,6 @@ dependencies:
|
|
61
52
|
- - ">="
|
62
53
|
- !ruby/object:Gem::Version
|
63
54
|
version: '4.0'
|
64
|
-
- - "<"
|
65
|
-
- !ruby/object:Gem::Version
|
66
|
-
version: '6.0'
|
67
|
-
- !ruby/object:Gem::Dependency
|
68
|
-
name: rake-version
|
69
|
-
requirement: !ruby/object:Gem::Requirement
|
70
|
-
requirements:
|
71
|
-
- - "~>"
|
72
|
-
- !ruby/object:Gem::Version
|
73
|
-
version: 1.0.1
|
74
|
-
type: :development
|
75
|
-
prerelease: false
|
76
|
-
version_requirements: !ruby/object:Gem::Requirement
|
77
|
-
requirements:
|
78
|
-
- - "~>"
|
79
|
-
- !ruby/object:Gem::Version
|
80
|
-
version: 1.0.1
|
81
55
|
- !ruby/object:Gem::Dependency
|
82
56
|
name: rubocop
|
83
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -141,11 +115,8 @@ files:
|
|
141
115
|
- app/lib/actions/foreman_patch/cycle/prepare_content.rb
|
142
116
|
- app/lib/actions/foreman_patch/host/reschedule.rb
|
143
117
|
- app/lib/actions/foreman_patch/invocation/action.rb
|
144
|
-
- app/lib/actions/foreman_patch/invocation/ensure_services.rb
|
145
118
|
- app/lib/actions/foreman_patch/invocation/patch.rb
|
146
119
|
- app/lib/actions/foreman_patch/invocation/reschedule.rb
|
147
|
-
- app/lib/actions/foreman_patch/invocation/restart.rb
|
148
|
-
- app/lib/actions/foreman_patch/invocation/update_packages.rb
|
149
120
|
- app/lib/actions/foreman_patch/invocation/wait_for_host.rb
|
150
121
|
- app/lib/actions/foreman_patch/round/add_missing_hosts.rb
|
151
122
|
- app/lib/actions/foreman_patch/round/create.rb
|
@@ -157,8 +128,6 @@ files:
|
|
157
128
|
- app/lib/actions/foreman_patch/window/plan.rb
|
158
129
|
- app/lib/actions/foreman_patch/window/publish.rb
|
159
130
|
- app/lib/actions/foreman_patch/window/resolve_hosts.rb
|
160
|
-
- app/lib/actions/helpers/failure_notification.rb
|
161
|
-
- app/lib/actions/helpers/with_feature_action.rb
|
162
131
|
- app/lib/actions/middleware/check_exit_status.rb
|
163
132
|
- app/mailers/foreman_patch/cycle_mailer.rb
|
164
133
|
- app/mailers/foreman_patch/group_mailer.rb
|
@@ -318,31 +287,6 @@ files:
|
|
318
287
|
- locale/foreman_patch.pot
|
319
288
|
- locale/gemspec.rb
|
320
289
|
- package.json
|
321
|
-
- public/assets/foreman_patch/cycle_plans-e5667e178ba389908f5c815b24ec0ea77c340849d56bc39c5ce72bb626bd446a.scss
|
322
|
-
- public/assets/foreman_patch/cycle_plans-e5667e178ba389908f5c815b24ec0ea77c340849d56bc39c5ce72bb626bd446a.scss.gz
|
323
|
-
- public/assets/foreman_patch/foreman_patch-ce5805a60c0d5f896f557ff5246e5a09172043004c850b39bea54e618df1c485.css
|
324
|
-
- public/assets/foreman_patch/foreman_patch-ce5805a60c0d5f896f557ff5246e5a09172043004c850b39bea54e618df1c485.css.gz
|
325
|
-
- public/assets/foreman_patch/foreman_patch.json
|
326
|
-
- public/assets/foreman_patch/plan_edit_windows-e656ba411642a7f983b51958ab30ac49c056322d19295a603cff4d5e6c71c8ed.js
|
327
|
-
- public/assets/foreman_patch/plan_edit_windows-e656ba411642a7f983b51958ab30ac49c056322d19295a603cff4d5e6c71c8ed.js.gz
|
328
|
-
- public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.css
|
329
|
-
- public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.css.gz
|
330
|
-
- public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.js
|
331
|
-
- public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.js.gz
|
332
|
-
- public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.js.map
|
333
|
-
- public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.js.map.gz
|
334
|
-
- public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.css
|
335
|
-
- public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.css.gz
|
336
|
-
- public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.js
|
337
|
-
- public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.js.gz
|
338
|
-
- public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.js.map
|
339
|
-
- public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.js.map.gz
|
340
|
-
- public/webpack/foreman_patch/manifest.json
|
341
|
-
- public/webpack/foreman_patch/manifest.json.gz
|
342
|
-
- public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js
|
343
|
-
- public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js.gz
|
344
|
-
- public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js.map
|
345
|
-
- public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js.map.gz
|
346
290
|
- test/factories/foreman_patch_factories.rb
|
347
291
|
- test/test_plugin_helper.rb
|
348
292
|
- test/unit/foreman_patch_test.rb
|
@@ -363,12 +307,12 @@ files:
|
|
363
307
|
- webpack/components/Invocation/InvocationSelectors.js
|
364
308
|
- webpack/components/Invocation/index.js
|
365
309
|
- webpack/components/Invocations/Invocations.js
|
310
|
+
- webpack/components/Invocations/Invocations.scss
|
366
311
|
- webpack/components/Invocations/InvocationsConstants.js
|
367
312
|
- webpack/components/Invocations/InvocationsHelpers.js
|
368
313
|
- webpack/components/Invocations/InvocationsPage.js
|
369
|
-
- webpack/components/Invocations/InvocationsPage.scss
|
370
314
|
- webpack/components/Invocations/InvocationsSelectors.js
|
371
|
-
- webpack/components/Invocations/components/
|
315
|
+
- webpack/components/Invocations/components/InvocationActions.js
|
372
316
|
- webpack/components/Invocations/components/InvocationStatus.js
|
373
317
|
- webpack/components/Invocations/index.js
|
374
318
|
- webpack/components/Plan/Plan.js
|
@@ -409,6 +353,11 @@ files:
|
|
409
353
|
- webpack/components/common/Terminal/Terminal.js
|
410
354
|
- webpack/components/common/Terminal/Terminal.scss
|
411
355
|
- webpack/index.js
|
356
|
+
- webpack/src/ForemanPatch.js
|
357
|
+
- webpack/src/Router/index.js
|
358
|
+
- webpack/src/Router/routes.js
|
359
|
+
- webpack/src/index.js
|
360
|
+
- webpack/src/reducers.js
|
412
361
|
homepage: https://github.com/ludovicus3/foreman_patch
|
413
362
|
licenses:
|
414
363
|
- GPL-3.0
|
@@ -428,7 +377,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
428
377
|
- !ruby/object:Gem::Version
|
429
378
|
version: '0'
|
430
379
|
requirements: []
|
431
|
-
rubygems_version: 3.
|
380
|
+
rubygems_version: 3.3.25
|
432
381
|
signing_key:
|
433
382
|
specification_version: 4
|
434
383
|
summary: Foreman Plugin for Managing Patching
|
@@ -1,47 +0,0 @@
|
|
1
|
-
module Actions
|
2
|
-
module ForemanPatch
|
3
|
-
module Invocation
|
4
|
-
class EnsureServices < Actions::EntryAction
|
5
|
-
include Actions::Helpers::WithFeatureAction
|
6
|
-
|
7
|
-
def resource_locks
|
8
|
-
:link
|
9
|
-
end
|
10
|
-
|
11
|
-
def plan(host)
|
12
|
-
action_subject(host)
|
13
|
-
|
14
|
-
sequence do
|
15
|
-
plan_feature_action('ensure_services', host)
|
16
|
-
plan_self
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def run
|
21
|
-
if exit_status != 0
|
22
|
-
users = ::User.select { |user| user.receives?(:patch_invocation_failure) }.compact
|
23
|
-
|
24
|
-
begin
|
25
|
-
MailNotification[:patch_invocation_failure].deliver(users: users, host: host, output: live_output) unless users.blank?
|
26
|
-
rescue => error
|
27
|
-
message = _('Unable to send patch invocation failure: %{error}') % {error: error}
|
28
|
-
Rails.logger.error(message)
|
29
|
-
end
|
30
|
-
|
31
|
-
fail _('Ensure services failed')
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def rescue_strategy
|
36
|
-
::Dynflow::Action::Rescue::Skip
|
37
|
-
end
|
38
|
-
|
39
|
-
def host
|
40
|
-
@host ||= ::Host.find(input[:host][:id])
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
@@ -1,101 +0,0 @@
|
|
1
|
-
module Actions
|
2
|
-
module ForemanPatch
|
3
|
-
module Invocation
|
4
|
-
class Restart < Actions::EntryAction
|
5
|
-
include Actions::Helpers::WithFeatureAction
|
6
|
-
include Dynflow::Action::Polling
|
7
|
-
|
8
|
-
def plan(host)
|
9
|
-
action_subject(host)
|
10
|
-
|
11
|
-
sequence do
|
12
|
-
plan_feature_action('power_action', host, action: 'restart')
|
13
|
-
plan_self
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def done?
|
18
|
-
external_task[:status] == :running
|
19
|
-
end
|
20
|
-
|
21
|
-
def invoke_external_task
|
22
|
-
if exit_status != 0
|
23
|
-
send_failure_notification
|
24
|
-
fail(_('Restart command failed to execute'))
|
25
|
-
end
|
26
|
-
|
27
|
-
schedule_timeout(Setting[:host_max_wait_for_up]) if Setting[:host_max_wait_for_up]
|
28
|
-
|
29
|
-
{ status: :stopping }
|
30
|
-
end
|
31
|
-
|
32
|
-
def poll_external_task
|
33
|
-
socket = TCPSocket.new(host.ip, Setting[:remote_execution_ssh_port])
|
34
|
-
socket.close
|
35
|
-
|
36
|
-
if external_task[:status] == :stopping
|
37
|
-
log_poll_result(_('Server status: stopping'))
|
38
|
-
{ status: :stopping }
|
39
|
-
else
|
40
|
-
log_poll_result(_('Server status: running'))
|
41
|
-
{ status: :running }
|
42
|
-
end
|
43
|
-
rescue
|
44
|
-
log_poll_result(_('Server status: starting'))
|
45
|
-
|
46
|
-
{ status: :starting }
|
47
|
-
end
|
48
|
-
|
49
|
-
def poll_intervals
|
50
|
-
case external_task[:status]
|
51
|
-
when :stopping
|
52
|
-
[1]
|
53
|
-
when :starting
|
54
|
-
[10]
|
55
|
-
else
|
56
|
-
super
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def process_timeout
|
61
|
-
continuous_output.add_output(_('Server did not respond within alloted time after restart.'))
|
62
|
-
|
63
|
-
send_failure_notification
|
64
|
-
|
65
|
-
fail("Timeout exceeded.")
|
66
|
-
end
|
67
|
-
|
68
|
-
def log_poll_result(status)
|
69
|
-
results = delegated_output.fetch('result', [])
|
70
|
-
|
71
|
-
results << {
|
72
|
-
'output_type' => 'debug',
|
73
|
-
'output' => status,
|
74
|
-
'timestamp' => Time.now.getlocal
|
75
|
-
}
|
76
|
-
end
|
77
|
-
|
78
|
-
def send_failure_notification
|
79
|
-
users = ::User.select { |user| user.receives?(:patch_invocation_failure) }.compact
|
80
|
-
|
81
|
-
begin
|
82
|
-
MailNotification[:patch_invocation_failure].deliver(user: users, host: host, output: live_output) unless users.blank?
|
83
|
-
rescue => error
|
84
|
-
message = _('Unable to send patch invocation failure: %{error}') % {error: error}
|
85
|
-
Rails.logger.error(message)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def rescue_strategy
|
90
|
-
::Dynflow::Action::Rescue::Fail
|
91
|
-
end
|
92
|
-
|
93
|
-
def host
|
94
|
-
@host ||= ::Host.find(input[:host][:id])
|
95
|
-
end
|
96
|
-
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
@@ -1,52 +0,0 @@
|
|
1
|
-
module Actions
|
2
|
-
module ForemanPatch
|
3
|
-
module Invocation
|
4
|
-
class UpdatePackages < Actions::EntryAction
|
5
|
-
include Actions::Helpers::WithFeatureAction
|
6
|
-
|
7
|
-
def resource_locks
|
8
|
-
:link
|
9
|
-
end
|
10
|
-
|
11
|
-
def plan(host)
|
12
|
-
action_subject(host)
|
13
|
-
|
14
|
-
sequence do
|
15
|
-
plan_feature_action('katello_package_update', host,
|
16
|
-
pre_script: 'yum clean all; subscription-manager refresh',
|
17
|
-
package: Setting[:skip_broken_patches] ? '--skip-broken' : nil)
|
18
|
-
plan_self
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def run
|
23
|
-
if exit_status != 0
|
24
|
-
users = ::User.select { |user| user.receives?(:patch_invocation_failure) }.compact
|
25
|
-
|
26
|
-
begin
|
27
|
-
MailNotification[:patch_invocation_failure].deliver(users: users, host: host, output: live_output) unless users.blank?
|
28
|
-
rescue => error
|
29
|
-
message = _('Unable to send patch invocation failure: %{error}') % {error: error}
|
30
|
-
Rails.logger.error(message)
|
31
|
-
end
|
32
|
-
|
33
|
-
fail _('Package update failed')
|
34
|
-
else
|
35
|
-
host.group_facet.last_patched_at = Time.current
|
36
|
-
host.group_facet.save!
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def rescue_strategy
|
41
|
-
::Dynflow::Action::Rescue::Fail
|
42
|
-
end
|
43
|
-
|
44
|
-
def host
|
45
|
-
@host ||= ::Host.find(input[:host][:id])
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|