Skip to content

[release-4.19] OCPBUGS-56651: Recognize Detached BMH status #15083

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: release-4.19
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions frontend/packages/metal3-plugin/locales/en/metal3-plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,16 @@
"Edit Bare Metal Host": "Edit Bare Metal Host",
"Add Bare Metal Host": "Add Bare Metal Host",
"Expand the hardware inventory by registering a new Bare Metal Host.": "Expand the hardware inventory by registering a new Bare Metal Host.",
"Detached": "Detached",
"No power management": "No power management",
"Restart pending": "Restart pending",
"Bare Metal Host Details": "Bare Metal Host Details",
"Host Addresses": "Host Addresses",
"Machine": "Machine",
"Node": "Node",
"Created at": "Created at",
"Status": "Status",
"Power Status": "Power Status",
"No power management": "No power management",
"Restart pending": "Restart pending",
"Role": "Role",
"Model": "Model",
"Bios": "Bios",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,38 @@ import {
getHostBootMACAddress,
isHostScheduledForRestart,
hasPowerManagement,
isDetached,
} from '../../selectors';
import { getHostStatus } from '../../status/host-status';
import { BareMetalHostKind } from '../../types';
import BareMetalHostPowerStatusIcon from './BareMetalHostPowerStatusIcon';
import BareMetalHostStatus from './BareMetalHostStatus';
import MachineLink from './MachineLink';

const PowerStatus = ({ host }: { host: BareMetalHostKind }) => {
const { t } = useTranslation();
if (isDetached(host)) {
return <SecondaryStatus status={t('metal3-plugin~Detached')} />;
}

if (!hasPowerManagement(host)) {
return <SecondaryStatus status={t('metal3-plugin~No power management')} />;
}

const powerStatus = getHostPowerStatus(host);
return (
<>
<StatusIconAndText
title={powerStatus}
icon={<BareMetalHostPowerStatusIcon powerStatus={powerStatus} />}
/>
{isHostScheduledForRestart(host) && (
<StatusIconAndText title={t('metal3-plugin~Restart pending')} icon={<RebootingIcon />} />
)}
</>
);
};

type BareMetalHostDetailsProps = {
obj: BareMetalHostKind;
machines: MachineKind[];
Expand Down Expand Up @@ -87,7 +112,6 @@ const BareMetalHostDetails: React.FC<BareMetalHostDetailsProps> = ({
const hostStorage = getHostTotalStorageCapacity(host);
const totalStorageCapacity = hostStorage ? humanizeDecimalBytes(hostStorage).string : DASH;
const description = getHostDescription(host);
const powerStatus = getHostPowerStatus(host);
const provisioningState = getHostProvisioningState(host);
const { count: CPUCount, model: CPUModel } = getHostCPU(host);
const { manufacturer, productName, serialNumber } = getHostVendorInfo(host);
Expand Down Expand Up @@ -168,22 +192,7 @@ const BareMetalHostDetails: React.FC<BareMetalHostDetailsProps> = ({
<DescriptionListGroup>
<DescriptionListTerm>{t('metal3-plugin~Power Status')}</DescriptionListTerm>
<DescriptionListDescription>
{!hasPowerManagement(host) ? (
<SecondaryStatus status={t('metal3-plugin~No power management')} />
) : (
<>
<StatusIconAndText
title={powerStatus}
icon={<BareMetalHostPowerStatusIcon powerStatus={powerStatus} />}
/>
{isHostScheduledForRestart(host) && (
<StatusIconAndText
title={t('metal3-plugin~Restart pending')}
icon={<RebootingIcon />}
/>
)}
</>
)}
<PowerStatus host={host} />
</DescriptionListDescription>
</DescriptionListGroup>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
getHostProvisioningState,
isHostScheduledForRestart,
hasPowerManagement,
isDetached,
} from '../../selectors';
import { BareMetalHostKind } from '../../types';

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

if (!hasPowerManagement(host)) {
status.push(t('metal3-plugin~No power management'));
// don't show power status when host registration/inspection hasn't finished
} else if (!HOST_REGISTERING_STATES.includes(provisioningState)) {
if (isHostScheduledForRestart(host)) {
status.push(t('metal3-plugin~Restart pending'));
}
if (!isDetached(host)) {
if (!hasPowerManagement(host)) {
status.push(t('metal3-plugin~No power management'));
// don't show power status when host registration/inspection hasn't finished
} else if (!HOST_REGISTERING_STATES.includes(provisioningState)) {
if (isHostScheduledForRestart(host)) {
status.push(t('metal3-plugin~Restart pending'));
}

// don't show power status when host is powered on
if (powerStatus !== HOST_POWER_STATUS_POWERED_ON) {
status.push(powerStatus);
// don't show power status when host is powered on
if (powerStatus !== HOST_POWER_STATUS_POWERED_ON) {
status.push(powerStatus);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
getHostPowerStatus,
getHostProvisioningState,
hasPowerManagement,
isDetached,
isHostScheduledForRestart,
} from '../../../selectors';
import { getBareMetalHostStatus, getHostStatus } from '../../../status/host-status';
Expand Down Expand Up @@ -64,6 +65,37 @@ const getHostHardwareHealthState = (obj): HostHealthState => {
const filterAlerts = (alerts: Alert[]): Alert[] =>
alerts.filter((alert) => _.get(alert, 'labels.hwalert'));

const PowerStatus = ({ obj }: { obj: BareMetalHostKind }) => {
const hasPowerMgmt = hasPowerManagement(obj);
const powerStatus = getHostPowerStatus(obj);
const restartScheduled = isHostScheduledForRestart(obj);
const { t } = useTranslation();
if (isDetached(obj)) {
return <HealthItem title={t('metal3-plugin~Detached')} state={HealthState.UNKNOWN} />;
}
if (!hasPowerMgmt) {
return (
<HealthItem
title={t('metal3-plugin~No power management')}
state={HealthState.NOT_AVAILABLE}
/>
);
}
return (
<StatusIconAndText
title={restartScheduled ? t('metal3-plugin~Restart pending') : powerStatus}
icon={
restartScheduled ? (
<RebootingIcon />
) : (
<BareMetalHostPowerStatusIcon powerStatus={powerStatus} />
)
}
className="bmh-health__status"
/>
);
};

const HealthCard: React.FC<HealthCardProps> = ({
watchAlerts,
stopWatchAlerts,
Expand All @@ -86,8 +118,6 @@ const HealthCard: React.FC<HealthCardProps> = ({

const hasPowerMgmt = hasPowerManagement(obj);
const provisioningState = getHostProvisioningState(obj);
const powerStatus = getHostPowerStatus(obj);
const restartScheduled = isHostScheduledForRestart(obj);

return (
<Card>
Expand All @@ -114,30 +144,13 @@ const HealthCard: React.FC<HealthCardProps> = ({
</GalleryItem>
{!HOST_REGISTERING_STATES.includes(provisioningState) && (
<GalleryItem>
{!hasPowerMgmt ? (
<HealthItem
title={t('metal3-plugin~No power management')}
state={HealthState.NOT_AVAILABLE}
/>
) : (
<StatusIconAndText
title={restartScheduled ? t('metal3-plugin~Restart pending') : powerStatus}
icon={
restartScheduled ? (
<RebootingIcon />
) : (
<BareMetalHostPowerStatusIcon powerStatus={powerStatus} />
)
}
className="bmh-health__status"
/>
)}
<PowerStatus obj={obj} />
</GalleryItem>
)}
</Gallery>
</HealthBody>
<AlertsBody error={!_.isEmpty(loadError)}>
{!hasPowerMgmt && (
{!hasPowerMgmt && !isDetached(obj) && (
<StatusItem
Icon={BlueInfoCircleIcon}
message={t(HOST_STATUS_DESCRIPTION_KEYS[HOST_STATUS_UNMANAGED])}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
isHostScheduledForRestart,
hasPowerManagement,
getPoweroffAnnotation,
isDetached,
} from '../../selectors';
import { getMachineMachineSetOwner } from '../../selectors/machine';
import { findMachineSet } from '../../selectors/machine-set';
Expand Down Expand Up @@ -106,7 +107,8 @@ export const PowerOn = (
getHostPowerStatus(host),
) ||
!hasPowerManagement(host) ||
!bmoEnabled,
!bmoEnabled ||
isDetached(host),
label: title,
callback: () => {
const patches: Patch[] = [{ op: 'replace', path: '/spec/online', value: true }];
Expand Down Expand Up @@ -137,7 +139,8 @@ export const Deprovision = (
!machine ||
!!getAnnotations(machine, {})[DELETE_MACHINE_ANNOTATION] ||
(getMachineMachineSetOwner(machine) && !machineSet) ||
!bmoEnabled,
!bmoEnabled ||
isDetached(host),
label: t('metal3-plugin~Deprovision'),
callback: () =>
confirmModal({
Expand Down Expand Up @@ -171,7 +174,8 @@ export const PowerOff = (
getHostPowerStatus(host),
) ||
!hasPowerManagement(host) ||
!bmoEnabled,
!bmoEnabled ||
isDetached(host),
label: t('metal3-plugin~Power Off'),
callback: () => powerOffHostModal({ host, nodeName, status }),
accessReview: host && asAccessReview(BareMetalHostModel, host, 'update'),
Expand All @@ -188,7 +192,8 @@ export const Restart = (
) ||
isHostScheduledForRestart(host) ||
!hasPowerManagement(host) ||
!bmoEnabled,
!bmoEnabled ||
isDetached(host),
label: t('metal3-plugin~Restart'),
callback: () => restartHostModal({ host }),
accessReview: host && asAccessReview(BareMetalHostModel, host, 'update'),
Expand Down
6 changes: 4 additions & 2 deletions frontend/packages/metal3-plugin/src/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import {
NodeMaintenanceKubevirtAlphaModel,
NodeMaintenanceKubevirtBetaModel,
} from './models';
import { getHostPowerStatus, hasPowerManagement } from './selectors';
import { getHostPowerStatus, hasPowerManagement, isDetached } from './selectors';
import { BareMetalHostKind } from './types';

type ConsumedExtensions =
Expand Down Expand Up @@ -300,7 +300,9 @@ const plugin: Plugin<ConsumedExtensions> = [
isActivity: (resource: BareMetalHostKind) =>
[HOST_POWER_STATUS_POWERING_OFF, HOST_POWER_STATUS_POWERING_ON].includes(
getHostPowerStatus(resource),
) && hasPowerManagement(resource),
) &&
hasPowerManagement(resource) &&
!isDetached(resource),
loader: () =>
import(
'./components/baremetal-hosts/dashboard/BareMetalStatusActivity' /* webpackChunkName: "metal3-powering" */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,6 @@ export const getHostMachine = (

export const hasPowerManagement = (host: BareMetalHostKind): boolean =>
getHostProvisioningState(host) !== HOST_STATUS_UNMANAGED;

export const isDetached = (host: BareMetalHostKind): boolean =>
host.status?.operationalStatus === 'detached';
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { nodeStatus } from '@console/app/src/status/node';
import { NodeKind, K8sResourceKind } from '@console/internal/module/k8s';
import { isNodeUnschedulable } from '@console/shared/src/selectors/node';
import { StatusProps } from '../components/types';
import { isHostPoweredOn, hasPowerManagement } from '../selectors';
import { isHostPoweredOn, hasPowerManagement, isDetached } from '../selectors';
import { BareMetalHostKind, CertificateSigningRequestKind } from '../types';
import { getNodeMaintenanceStatus } from './node-maintenance-status';

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