Skip to content
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

[release-4.6] Bug 1891499: Show additional machine config pools while updating #7008

Merged
merged 1 commit into from
Dec 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 10 additions & 13 deletions frontend/__tests__/components/cluster-settings.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ import {
CurrentChannel,
CurrentVersion,
CurrentVersionHeader,
NodesUpdatesGroup,
UpdateInProgress,
UpdateLink,
UpdatesGraph,
UpdatesProgress,
UpdateStatus,
UpdatingMessageText,
WorkerNodes,
} from '../../public/components/cluster-settings/cluster-settings';
import { GlobalConfigPage } from '../../public/components/cluster-settings/global-config';
import { Firehose, HorizontalNav, ResourceLink, Timestamp } from '../../public/components/utils';
Expand Down Expand Up @@ -406,10 +406,7 @@ describe('Update In Progress while updating', () => {
<UpdateInProgress
desiredVersion={cv.spec.desiredUpdate.version}
machineConfigPools={machineConfigPoolsProps.items}
percentWorkerNodes={100}
workerMachinePoolConfig={workerMachineConfigPoolProp}
totalWorkerNodes={workerMachineConfigPoolProp.status.machineCount}
updatedWorkerNodes={3}
workerMachineConfigPool={workerMachineConfigPoolProp}
updateStartedTime="2020-08-05T21:09:02Z"
/>,
);
Expand All @@ -426,16 +423,16 @@ describe('Update In Progress while updating', () => {
).toBe('Cluster Operators');
expect(
wrapper
.find(Link)
.at(1)
.text(),
).toBe('Master Nodes');
.find(NodesUpdatesGroup)
.at(0)
.props().name,
).toBe('Master');
expect(
wrapper
.find(WorkerNodes)
.at(0)
.exists(),
).toBe(true);
.find(NodesUpdatesGroup)
.at(1)
.props().name,
).toBe('Worker');
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,10 +248,16 @@ $co-channel-height: 60px;
&--divided {
border-top: 1px solid $color-pf-black-200;
padding-top: var(--pf-global--spacer--lg);

// only add border and padding to first instance
& ~ & {
border-top: 0;
padding-top: 0;
}
}
}

&__updates-progress {
&__updates-progress:not(:empty) {
padding: var(--pf-global--spacer--sm) var(--pf-global--spacer--lg) 0 0;
}

Expand Down
186 changes: 107 additions & 79 deletions frontend/public/components/cluster-settings/cluster-settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
ClusterOperatorModel,
ClusterVersionModel,
MachineConfigPoolModel,
NodeModel,
} from '../../models';
import {
ClusterOperator,
Expand Down Expand Up @@ -481,44 +482,81 @@ const UpdatesType: React.FC<UpdatesTypeProps> = ({ children }) => {
return <div className="co-cluster-settings__updates-type">{children}</div>;
};

export const WorkerNodes: React.FC<WorkerNodesProps> = ({
percentWorkerNodes,
totalWorkerNodes,
updatedWorkerNodes,
export const NodesUpdatesGroup: React.FC<NodesUpdatesGroupProps> = ({
divided,
hideIfComplete,
machineConfigPool,
name,
updateStartedTime,
}) => {
return (
<UpdatesGroup divided>
const MCPUpdatingTime = getUpdatingTimeForMCP(machineConfigPool);
const totalMCPNodes = machineConfigPool?.status?.machineCount || 0;
const updatedMCPNodes =
MCPUpdatingTime > updateStartedTime ? machineConfigPool?.status?.updatedMachineCount : 0;
const percentMCPNodes = calculatePercentage(updatedMCPNodes, totalMCPNodes);
return hideIfComplete && percentMCPNodes === 100 ? null : (
<UpdatesGroup divided={divided}>
<UpdatesType>
<Link to="/k8s/cluster/nodes?rowFilter-node-role=worker">Worker Nodes</Link>
<Popover
bodyContent={
<>
Worker nodes may continue to update after the update of master nodes and operators are
complete.
</>
}
>
<Button
variant="plain"
aria-label="Help"
className="co-help-popover-button co-help-popover-button--space-l"
<Link to={`/k8s/cluster/nodes?rowFilter-node-role=${machineConfigPool.metadata.name}`}>
{name} {NodeModel.labelPlural}
</Link>
{name !== 'Master' && (
<Popover
bodyContent={
<>
{name} {NodeModel.labelPlural} may continue to update after the update of Master{' '}
{NodeModel.labelPlural} and Cluster Operators are complete.
</>
}
>
<OutlinedQuestionCircleIcon />
</Button>
</Popover>
<Button
variant="plain"
aria-label="Help"
className="co-help-popover-button co-help-popover-button--space-l"
>
<OutlinedQuestionCircleIcon />
</Button>
</Popover>
)}
</UpdatesType>
<UpdatesBar>
<Progress
title={`${updatedWorkerNodes} of ${totalWorkerNodes}`}
value={!_.isNaN(percentWorkerNodes) ? percentWorkerNodes : null}
title={`${updatedMCPNodes} of ${totalMCPNodes}`}
value={!_.isNaN(percentMCPNodes) ? percentMCPNodes : null}
size={ProgressSize.sm}
variant={percentWorkerNodes === 100 ? ProgressVariant.success : null}
variant={percentMCPNodes === 100 ? ProgressVariant.success : null}
/>
</UpdatesBar>
</UpdatesGroup>
);
};

const OtherNodes: React.FC<OtherNodesProps> = ({
hideIfComplete,
machineConfigPools,
updateStartedTime,
}) => {
const otherNodes = machineConfigPools
.filter((mcp) => mcp.metadata.name !== 'master' && mcp.metadata.name !== 'worker')
.sort((a, b) => a.metadata.creationTimestamp.localeCompare(b.metadata.creationTimestamp));
return (
<>
{otherNodes.map((mcp) => {
return (
<NodesUpdatesGroup
divided
hideIfComplete={hideIfComplete}
key={mcp.metadata.uid}
name={mcp.metadata.name}
machineConfigPool={mcp}
updateStartedTime={updateStartedTime}
/>
);
})}
</>
);
};

export const UpdatesGraph: React.FC<UpdatesGraphProps> = ({ cv }) => {
const availableUpdates = getSortedUpdates(cv);
const lastVersion = getLastCompletedUpdate(cv);
Expand Down Expand Up @@ -594,24 +632,14 @@ const MachineConfigPoolsResource: WatchK8sResource = {
export const UpdateInProgress: React.FC<UpdateInProgressProps> = ({
desiredVersion,
machineConfigPools,
percentWorkerNodes,
workerMachinePoolConfig,
totalWorkerNodes,
updatedWorkerNodes,
workerMachineConfigPool,
updateStartedTime,
}) => {
const [clusterOperators] = useK8sWatchResource<ClusterOperator[]>(ClusterOperatorsResource);
const totalOperatorsCount = clusterOperators?.length || 0;
const updatedOperatorsCount = getUpdatedOperatorsCount(clusterOperators, desiredVersion);
const percentOperators = calculatePercentage(updatedOperatorsCount, totalOperatorsCount);
const masterMachinePoolConfig = getMCPByName(machineConfigPools, 'master');
const masterMachinePoolConfigUpdatingTime = getUpdatingTimeForMCP(masterMachinePoolConfig);
const totalMasterNodes = masterMachinePoolConfig?.status?.machineCount || 0;
const updatedMasterNodes =
masterMachinePoolConfigUpdatingTime > updateStartedTime
? masterMachinePoolConfig?.status?.updatedMachineCount
: 0;
const percentMasterNodes = calculatePercentage(updatedMasterNodes, totalMasterNodes);

return (
<UpdatesProgress>
Expand All @@ -629,27 +657,23 @@ export const UpdateInProgress: React.FC<UpdateInProgressProps> = ({
</UpdatesBar>
</UpdatesGroup>
{masterMachinePoolConfig && (
<UpdatesGroup>
<UpdatesType>
<Link to="/k8s/cluster/nodes?rowFilter-node-role=master">Master Nodes</Link>
</UpdatesType>
<UpdatesBar>
<Progress
title={`${updatedMasterNodes} of ${totalMasterNodes}`}
value={!_.isNaN(percentMasterNodes) ? percentMasterNodes : null}
size={ProgressSize.sm}
variant={percentMasterNodes === 100 ? ProgressVariant.success : null}
/>
</UpdatesBar>
</UpdatesGroup>
<NodesUpdatesGroup
machineConfigPool={masterMachinePoolConfig}
name="Master"
updateStartedTime={updateStartedTime}
/>
)}
{workerMachinePoolConfig && (
<WorkerNodes
percentWorkerNodes={percentWorkerNodes}
totalWorkerNodes={totalWorkerNodes}
updatedWorkerNodes={updatedWorkerNodes}
{workerMachineConfigPool && (
<NodesUpdatesGroup
divided
machineConfigPool={workerMachineConfigPool}
name="Worker"
updateStartedTime={updateStartedTime}
/>
)}
{machineConfigPools.length > 2 && (
<OtherNodes machineConfigPools={machineConfigPools} updateStartedTime={updateStartedTime} />
)}
</UpdatesProgress>
);
};
Expand Down Expand Up @@ -677,14 +701,7 @@ export const ClusterVersionDetailsTable: React.FC<ClusterVersionDetailsTableProp
);
const desiredVersion = getDesiredClusterVersion(cv);
const updateStartedTime = getStartedTimeForCVDesiredVersion(cv, desiredVersion);
const workerMachinePoolConfig = getMCPByName(machineConfigPools, 'worker');
const workerMachinePoolConfigUpdatingTime = getUpdatingTimeForMCP(workerMachinePoolConfig);
const totalWorkerNodes = workerMachinePoolConfig?.status?.machineCount || 0;
const updatedWorkerNodes =
workerMachinePoolConfigUpdatingTime > updateStartedTime
? workerMachinePoolConfig?.status?.updatedMachineCount
: 0;
const percentWorkerNodes = calculatePercentage(updatedWorkerNodes, totalWorkerNodes);
const workerMachineConfigPool = getMCPByName(machineConfigPools, 'worker');
if (new URLSearchParams(window.location.search).has('showVersions')) {
clusterUpdateModal({ cv })
.then(() => removeQueryArgument('showVersions'))
Expand Down Expand Up @@ -738,13 +755,22 @@ export const ClusterVersionDetailsTable: React.FC<ClusterVersionDetailsTableProp
status === ClusterUpdateStatus.UpdatesAvailable) && (
<>
<UpdatesGraph cv={cv} />
{workerMachinePoolConfig && percentWorkerNodes < 100 && (
{workerMachineConfigPool && (
<UpdatesProgress>
<WorkerNodes
percentWorkerNodes={percentWorkerNodes}
totalWorkerNodes={totalWorkerNodes}
updatedWorkerNodes={updatedWorkerNodes}
<NodesUpdatesGroup
divided
hideIfComplete
machineConfigPool={workerMachineConfigPool}
name="Worker"
updateStartedTime={updateStartedTime}
/>
{machineConfigPools.length > 2 && (
<OtherNodes
hideIfComplete
machineConfigPools={machineConfigPools}
updateStartedTime={updateStartedTime}
/>
)}
</UpdatesProgress>
)}
</>
Expand All @@ -756,10 +782,7 @@ export const ClusterVersionDetailsTable: React.FC<ClusterVersionDetailsTableProp
desiredVersion={desiredVersion}
machineConfigPools={machineConfigPools}
updateStartedTime={updateStartedTime}
workerMachinePoolConfig={workerMachinePoolConfig}
percentWorkerNodes={percentWorkerNodes}
totalWorkerNodes={totalWorkerNodes}
updatedWorkerNodes={updatedWorkerNodes}
workerMachineConfigPool={workerMachineConfigPool}
/>
)}
</div>
Expand Down Expand Up @@ -993,19 +1016,24 @@ type UpdatesTypeProps = {
children: React.ReactNode;
};

type WorkerNodesProps = {
percentWorkerNodes: number;
totalWorkerNodes: number;
updatedWorkerNodes: number;
type NodesUpdatesGroupProps = {
divided?: boolean;
hideIfComplete?: boolean;
name: string;
machineConfigPool: MachineConfigPoolKind;
updateStartedTime: string;
};

type OtherNodesProps = {
hideIfComplete?: boolean;
machineConfigPools: MachineConfigPoolKind[];
updateStartedTime: string;
};

type UpdateInProgressProps = {
desiredVersion: string;
machineConfigPools: MachineConfigPoolKind[];
percentWorkerNodes: number;
workerMachinePoolConfig: MachineConfigPoolKind;
totalWorkerNodes: number;
updatedWorkerNodes: number;
workerMachineConfigPool: MachineConfigPoolKind;
updateStartedTime: string;
};

Expand Down