Skip to content

Commit fc8ec86

Browse files
Merge pull request #15056 from rawagner/bmh_detached
OCPBUGS-56410: Recognize Detached BMH status
2 parents 99460d1 + 5b2100c commit fc8ec86

File tree

8 files changed

+94
-58
lines changed

8 files changed

+94
-58
lines changed

frontend/packages/metal3-plugin/locales/en/metal3-plugin.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,16 @@
2727
"Edit Bare Metal Host": "Edit Bare Metal Host",
2828
"Add Bare Metal Host": "Add Bare Metal Host",
2929
"Expand the hardware inventory by registering a new Bare Metal Host.": "Expand the hardware inventory by registering a new Bare Metal Host.",
30+
"Detached": "Detached",
31+
"No power management": "No power management",
32+
"Restart pending": "Restart pending",
3033
"Bare Metal Host Details": "Bare Metal Host Details",
3134
"Host Addresses": "Host Addresses",
3235
"Machine": "Machine",
3336
"Node": "Node",
3437
"Created at": "Created at",
3538
"Status": "Status",
3639
"Power Status": "Power Status",
37-
"No power management": "No power management",
38-
"Restart pending": "Restart pending",
3940
"Role": "Role",
4041
"Model": "Model",
4142
"Bios": "Bios",

frontend/packages/metal3-plugin/src/components/baremetal-hosts/BareMetalHostDetails.tsx

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,38 @@ import {
5454
getHostBootMACAddress,
5555
isHostScheduledForRestart,
5656
hasPowerManagement,
57+
isDetached,
5758
} from '../../selectors';
5859
import { getHostStatus } from '../../status/host-status';
5960
import { BareMetalHostKind } from '../../types';
6061
import BareMetalHostPowerStatusIcon from './BareMetalHostPowerStatusIcon';
6162
import BareMetalHostStatus from './BareMetalHostStatus';
6263
import MachineLink from './MachineLink';
6364

65+
const PowerStatus = ({ host }: { host: BareMetalHostKind }) => {
66+
const { t } = useTranslation();
67+
if (isDetached(host)) {
68+
return <SecondaryStatus status={t('metal3-plugin~Detached')} />;
69+
}
70+
71+
if (!hasPowerManagement(host)) {
72+
return <SecondaryStatus status={t('metal3-plugin~No power management')} />;
73+
}
74+
75+
const powerStatus = getHostPowerStatus(host);
76+
return (
77+
<>
78+
<StatusIconAndText
79+
title={powerStatus}
80+
icon={<BareMetalHostPowerStatusIcon powerStatus={powerStatus} />}
81+
/>
82+
{isHostScheduledForRestart(host) && (
83+
<StatusIconAndText title={t('metal3-plugin~Restart pending')} icon={<RebootingIcon />} />
84+
)}
85+
</>
86+
);
87+
};
88+
6489
type BareMetalHostDetailsProps = {
6590
obj: BareMetalHostKind;
6691
machines: MachineKind[];
@@ -89,7 +114,6 @@ const BareMetalHostDetails: React.FC<BareMetalHostDetailsProps> = ({
89114
const hostStorage = getHostTotalStorageCapacity(host);
90115
const totalStorageCapacity = hostStorage ? humanizeDecimalBytes(hostStorage).string : DASH;
91116
const description = getHostDescription(host);
92-
const powerStatus = getHostPowerStatus(host);
93117
const provisioningState = getHostProvisioningState(host);
94118
const { count: CPUCount, model: CPUModel } = getHostCPU(host);
95119
const { manufacturer, productName, serialNumber } = getHostVendorInfo(host);
@@ -170,22 +194,7 @@ const BareMetalHostDetails: React.FC<BareMetalHostDetailsProps> = ({
170194
<DescriptionListGroup>
171195
<DescriptionListTerm>{t('metal3-plugin~Power Status')}</DescriptionListTerm>
172196
<DescriptionListDescription>
173-
{!hasPowerManagement(host) ? (
174-
<SecondaryStatus status={t('metal3-plugin~No power management')} />
175-
) : (
176-
<>
177-
<StatusIconAndText
178-
title={powerStatus}
179-
icon={<BareMetalHostPowerStatusIcon powerStatus={powerStatus} />}
180-
/>
181-
{isHostScheduledForRestart(host) && (
182-
<StatusIconAndText
183-
title={t('metal3-plugin~Restart pending')}
184-
icon={<RebootingIcon />}
185-
/>
186-
)}
187-
</>
188-
)}
197+
<PowerStatus host={host} />
189198
</DescriptionListDescription>
190199
</DescriptionListGroup>
191200
)}

frontend/packages/metal3-plugin/src/components/baremetal-hosts/BareMetalHostSecondaryStatus.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
getHostProvisioningState,
88
isHostScheduledForRestart,
99
hasPowerManagement,
10+
isDetached,
1011
} from '../../selectors';
1112
import { BareMetalHostKind } from '../../types';
1213

@@ -20,17 +21,19 @@ const BareMetalHostSecondaryStatus: React.FC<BareMetalHostSecondaryStatusProps>
2021
const provisioningState = getHostProvisioningState(host);
2122
const status = [];
2223

23-
if (!hasPowerManagement(host)) {
24-
status.push(t('metal3-plugin~No power management'));
25-
// don't show power status when host registration/inspection hasn't finished
26-
} else if (!HOST_REGISTERING_STATES.includes(provisioningState)) {
27-
if (isHostScheduledForRestart(host)) {
28-
status.push(t('metal3-plugin~Restart pending'));
29-
}
24+
if (!isDetached(host)) {
25+
if (!hasPowerManagement(host)) {
26+
status.push(t('metal3-plugin~No power management'));
27+
// don't show power status when host registration/inspection hasn't finished
28+
} else if (!HOST_REGISTERING_STATES.includes(provisioningState)) {
29+
if (isHostScheduledForRestart(host)) {
30+
status.push(t('metal3-plugin~Restart pending'));
31+
}
3032

31-
// don't show power status when host is powered on
32-
if (powerStatus !== HOST_POWER_STATUS_POWERED_ON) {
33-
status.push(powerStatus);
33+
// don't show power status when host is powered on
34+
if (powerStatus !== HOST_POWER_STATUS_POWERED_ON) {
35+
status.push(powerStatus);
36+
}
3437
}
3538
}
3639

frontend/packages/metal3-plugin/src/components/baremetal-hosts/dashboard/StatusCard.tsx

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import {
3737
getHostPowerStatus,
3838
getHostProvisioningState,
3939
hasPowerManagement,
40+
isDetached,
4041
isHostScheduledForRestart,
4142
} from '../../../selectors';
4243
import { getBareMetalHostStatus, getHostStatus } from '../../../status/host-status';
@@ -64,6 +65,37 @@ const getHostHardwareHealthState = (obj): HostHealthState => {
6465
const filterAlerts = (alerts: Alert[]): Alert[] =>
6566
alerts.filter((alert) => _.get(alert, 'labels.hwalert'));
6667

68+
const PowerStatus = ({ obj }: { obj: BareMetalHostKind }) => {
69+
const hasPowerMgmt = hasPowerManagement(obj);
70+
const powerStatus = getHostPowerStatus(obj);
71+
const restartScheduled = isHostScheduledForRestart(obj);
72+
const { t } = useTranslation();
73+
if (isDetached(obj)) {
74+
return <HealthItem title={t('metal3-plugin~Detached')} state={HealthState.UNKNOWN} />;
75+
}
76+
if (!hasPowerMgmt) {
77+
return (
78+
<HealthItem
79+
title={t('metal3-plugin~No power management')}
80+
state={HealthState.NOT_AVAILABLE}
81+
/>
82+
);
83+
}
84+
return (
85+
<StatusIconAndText
86+
title={restartScheduled ? t('metal3-plugin~Restart pending') : powerStatus}
87+
icon={
88+
restartScheduled ? (
89+
<RebootingIcon />
90+
) : (
91+
<BareMetalHostPowerStatusIcon powerStatus={powerStatus} />
92+
)
93+
}
94+
className="bmh-health__status"
95+
/>
96+
);
97+
};
98+
6799
const HealthCard: React.FC<HealthCardProps> = ({
68100
watchAlerts,
69101
stopWatchAlerts,
@@ -86,8 +118,6 @@ const HealthCard: React.FC<HealthCardProps> = ({
86118

87119
const hasPowerMgmt = hasPowerManagement(obj);
88120
const provisioningState = getHostProvisioningState(obj);
89-
const powerStatus = getHostPowerStatus(obj);
90-
const restartScheduled = isHostScheduledForRestart(obj);
91121

92122
return (
93123
<Card>
@@ -114,30 +144,13 @@ const HealthCard: React.FC<HealthCardProps> = ({
114144
</GalleryItem>
115145
{!HOST_REGISTERING_STATES.includes(provisioningState) && (
116146
<GalleryItem>
117-
{!hasPowerMgmt ? (
118-
<HealthItem
119-
title={t('metal3-plugin~No power management')}
120-
state={HealthState.NOT_AVAILABLE}
121-
/>
122-
) : (
123-
<StatusIconAndText
124-
title={restartScheduled ? t('metal3-plugin~Restart pending') : powerStatus}
125-
icon={
126-
restartScheduled ? (
127-
<RebootingIcon />
128-
) : (
129-
<BareMetalHostPowerStatusIcon powerStatus={powerStatus} />
130-
)
131-
}
132-
className="bmh-health__status"
133-
/>
134-
)}
147+
<PowerStatus obj={obj} />
135148
</GalleryItem>
136149
)}
137150
</Gallery>
138151
</HealthBody>
139152
<AlertsBody error={!_.isEmpty(loadError)}>
140-
{!hasPowerMgmt && (
153+
{!hasPowerMgmt && !isDetached(obj) && (
141154
<StatusItem
142155
Icon={BlueInfoCircleIcon}
143156
message={t(HOST_STATUS_DESCRIPTION_KEYS[HOST_STATUS_UNMANAGED])}

frontend/packages/metal3-plugin/src/components/baremetal-hosts/host-menu-actions.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import {
4141
isHostScheduledForRestart,
4242
hasPowerManagement,
4343
getPoweroffAnnotation,
44+
isDetached,
4445
} from '../../selectors';
4546
import { getMachineMachineSetOwner } from '../../selectors/machine';
4647
import { findMachineSet } from '../../selectors/machine-set';
@@ -106,7 +107,8 @@ export const PowerOn = (
106107
getHostPowerStatus(host),
107108
) ||
108109
!hasPowerManagement(host) ||
109-
!bmoEnabled,
110+
!bmoEnabled ||
111+
isDetached(host),
110112
label: title,
111113
callback: () => {
112114
const patches: Patch[] = [{ op: 'replace', path: '/spec/online', value: true }];
@@ -137,7 +139,8 @@ export const Deprovision = (
137139
!machine ||
138140
!!getAnnotations(machine, {})[DELETE_MACHINE_ANNOTATION] ||
139141
(getMachineMachineSetOwner(machine) && !machineSet) ||
140-
!bmoEnabled,
142+
!bmoEnabled ||
143+
isDetached(host),
141144
label: t('metal3-plugin~Deprovision'),
142145
callback: () =>
143146
confirmModal({
@@ -171,7 +174,8 @@ export const PowerOff = (
171174
getHostPowerStatus(host),
172175
) ||
173176
!hasPowerManagement(host) ||
174-
!bmoEnabled,
177+
!bmoEnabled ||
178+
isDetached(host),
175179
label: t('metal3-plugin~Power Off'),
176180
callback: () => powerOffHostModal({ host, nodeName, status }),
177181
accessReview: host && asAccessReview(BareMetalHostModel, host, 'update'),
@@ -188,7 +192,8 @@ export const Restart = (
188192
) ||
189193
isHostScheduledForRestart(host) ||
190194
!hasPowerManagement(host) ||
191-
!bmoEnabled,
195+
!bmoEnabled ||
196+
isDetached(host),
192197
label: t('metal3-plugin~Restart'),
193198
callback: () => restartHostModal({ host }),
194199
accessReview: host && asAccessReview(BareMetalHostModel, host, 'update'),

frontend/packages/metal3-plugin/src/plugin.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import {
3434
NodeMaintenanceKubevirtAlphaModel,
3535
NodeMaintenanceKubevirtBetaModel,
3636
} from './models';
37-
import { getHostPowerStatus, hasPowerManagement } from './selectors';
37+
import { getHostPowerStatus, hasPowerManagement, isDetached } from './selectors';
3838
import { BareMetalHostKind } from './types';
3939

4040
type ConsumedExtensions =
@@ -300,7 +300,9 @@ const plugin: Plugin<ConsumedExtensions> = [
300300
isActivity: (resource: BareMetalHostKind) =>
301301
[HOST_POWER_STATUS_POWERING_OFF, HOST_POWER_STATUS_POWERING_ON].includes(
302302
getHostPowerStatus(resource),
303-
) && hasPowerManagement(resource),
303+
) &&
304+
hasPowerManagement(resource) &&
305+
!isDetached(resource),
304306
loader: () =>
305307
import(
306308
'./components/baremetal-hosts/dashboard/BareMetalStatusActivity' /* webpackChunkName: "metal3-powering" */

frontend/packages/metal3-plugin/src/selectors/baremetal-hosts.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,6 @@ export const getHostMachine = (
8686

8787
export const hasPowerManagement = (host: BareMetalHostKind): boolean =>
8888
getHostProvisioningState(host) !== HOST_STATUS_UNMANAGED;
89+
90+
export const isDetached = (host: BareMetalHostKind): boolean =>
91+
host.status?.operationalStatus === 'detached';

frontend/packages/metal3-plugin/src/status/baremetal-node-status.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { nodeStatus } from '@console/app/src/status/node';
22
import { NodeKind, K8sResourceKind } from '@console/internal/module/k8s';
33
import { isNodeUnschedulable } from '@console/shared/src/selectors/node';
44
import { StatusProps } from '../components/types';
5-
import { isHostPoweredOn, hasPowerManagement } from '../selectors';
5+
import { isHostPoweredOn, hasPowerManagement, isDetached } from '../selectors';
66
import { BareMetalHostKind, CertificateSigningRequestKind } from '../types';
77
import { getNodeMaintenanceStatus } from './node-maintenance-status';
88

@@ -46,7 +46,7 @@ export const baremetalNodeSecondaryStatus = ({
4646
states.push('Scheduling disabled');
4747
}
4848
// show host power status only if there is actual host associated to node
49-
if (host && hasPowerManagement(host) && !isHostPoweredOn(host)) {
49+
if (host && hasPowerManagement(host) && !isHostPoweredOn(host) && !isDetached(host)) {
5050
states.push('Host is powered off');
5151
}
5252
return states;

0 commit comments

Comments
 (0)