Skip to content

Commit

Permalink
CONSOLE-3972: add Last Status to Pod details Container list and Conta…
Browse files Browse the repository at this point in the history
…iner details
  • Loading branch information
rhamilto committed Mar 18, 2024
1 parent 3e708b7 commit 4b98677
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 24 deletions.
13 changes: 9 additions & 4 deletions frontend/__tests__/components/pod.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ describe(ContainerRow.displayName, () => {
},
},
restartCount: 10,
lastState: {},
},
],
},
Expand All @@ -204,19 +205,23 @@ describe(ContainerRow.displayName, () => {
expect(wrapper.childAt(2).find({ status: 'Running' }).exists()).toBe(true);
});

it('renders the container last state', () => {
expect(wrapper.childAt(3).find({ containerLastState: {} }).exists()).toBe(true);
});

it('renders the container restart times', () => {
expect(wrapper.childAt(3).text()).toBe('10');
expect(wrapper.childAt(4).text()).toBe('10');
});

it('renders the container started time', () => {
expect(wrapper.childAt(4).find({ timestamp: { startTime } }).exists()).toBe(true);
expect(wrapper.childAt(5).find({ timestamp: { startTime } }).exists()).toBe(true);
});

it('renders the container finished time', () => {
expect(wrapper.childAt(5).find({ timestamp: { finishTime } }).exists()).toBe(true);
expect(wrapper.childAt(6).find({ timestamp: { finishTime } }).exists()).toBe(true);
});

it('renders the container exit code', () => {
expect(wrapper.childAt(6).text()).toBe('-');
expect(wrapper.childAt(7).text()).toBe('-');
});
});
16 changes: 13 additions & 3 deletions frontend/public/components/container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ import {
VolumeMount,
} from '../module/k8s';
import * as k8sProbe from '../module/k8s/probe';
import { getContainerState, getContainerStatus, getPullPolicyLabel } from '../module/k8s/container';
import {
getContainerRestartCount,
getContainerState,
getContainerStatus,
getPullPolicyLabel,
} from '../module/k8s/container';
import {
Firehose,
HorizontalNav,
Expand All @@ -35,6 +40,7 @@ import {
import { getBreadcrumbPath } from '@console/internal/components/utils/breadcrumbs';
import i18n from 'i18next';
import { ErrorPage404 } from './error';
import { ContainerLastState } from './pod';

const formatComputeResources = (resources: ResourceList) =>
_.map(resources, (v, k) => `${k}: ${v}`).join(', ');
Expand Down Expand Up @@ -282,16 +288,20 @@ export const ContainerDetailsList: React.FC<ContainerDetailsListProps> = (props)
<dd>
<Status status={stateValue} />
</dd>
<dt>{t('public~Last State')}</dt>
<dd>
<ContainerLastState containerLastState={status?.lastState} />
</dd>
<dt>{t('public~ID')}</dt>
<dd>
{status.containerID ? (
{status?.containerID ? (
<div className="co-break-all co-select-to-copy">{status.containerID}</div>
) : (
'-'
)}
</dd>
<dt>{t('public~Restarts')}</dt>
<dd>{status.restartCount}</dd>
<dd>{getContainerRestartCount(status)}</dd>
<dt>{t('public~Resource requests')}</dt>
<dd>{getResourceRequestsValue(container) || '-'}</dd>
<dt>{t('public~Resource limits')}</dt>
Expand Down
122 changes: 105 additions & 17 deletions frontend/public/components/pod.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Link } from 'react-router-dom-v5-compat';
import { sortable } from '@patternfly/react-table';
import { useTranslation } from 'react-i18next';
import { Trans, useTranslation } from 'react-i18next';
import { TFunction } from 'i18next';
import * as classNames from 'classnames';
import * as _ from 'lodash-es';
Expand Down Expand Up @@ -49,6 +49,7 @@ import {
referenceForModel,
referenceFor,
Selector,
ContainerState,
} from '../module/k8s';
import {
getRestartPolicyLabel,
Expand All @@ -59,7 +60,11 @@ import {
isWindowsPod,
isContainerCrashLoopBackOff,
} from '../module/k8s/pods';
import { getContainerState, getContainerStatus } from '../module/k8s/container';
import {
getContainerRestartCount,
getContainerState,
getContainerStatus,
} from '../module/k8s/container';
import { ResourceEventStream } from './events';
import { DetailsPage } from './factory';
import ListPageHeader from './factory/ListPage/ListPageHeader';
Expand Down Expand Up @@ -484,6 +489,67 @@ export const ContainerLink: React.FC<ContainerLinkProps> = ({ pod, name }) => (
);
ContainerLink.displayName = 'ContainerLink';

const ContainerRunningSince: React.FC<ContainerRunningSinceProps> = ({ startedAt }) => {
const { t } = useTranslation();
return startedAt ? (
<Trans t={t} ns="public">
since <Timestamp timestamp={startedAt} simple />
</Trans>
) : null;
};

const ContainerTerminatedAt: React.FC<ContainerTerminatedAtProps> = ({ finishedAt }) => {
const { t } = useTranslation();
return finishedAt ? (
<Trans t={t} ns="public">
at <Timestamp timestamp={finishedAt} simple />{' '}
</Trans>
) : null;
};

const ContainerTerminatedExitCode: React.FC<ContainerTerminatedExitCodeProps> = ({ exitCode }) => {
const { t } = useTranslation();
return exitCode ? t('public~with exit code {{exitCode}} ', { exitCode }) : null;
};

const ContainerTerminatedReason: React.FC<ContainerTerminatedReasonProps> = ({ reason }) => {
const { t } = useTranslation();
return reason ? t('public~({{reason}})', { reason }) : null;
};

export const ContainerLastState: React.FC<ContainerLastStateProps> = ({ containerLastState }) => {
const { t } = useTranslation();
if (containerLastState?.waiting) {
return t('public~Waiting {{reason}}', { reason: containerLastState.waiting?.reason });
} else if (containerLastState?.running) {
return (
<Trans t={t} ns="public">
Running <ContainerRunningSince startedAt={containerLastState.running?.startedAt} />
</Trans>
);
} else if (containerLastState?.terminated) {
return (
<Trans t={t} ns="public">
Terminated <ContainerTerminatedAt finishedAt={containerLastState.terminated?.finishedAt} />
<ContainerTerminatedExitCode exitCode={containerLastState.terminated?.exitCode} />
<ContainerTerminatedReason reason={containerLastState.terminated?.reason} />
</Trans>
);
}
return <>-</>;
};

const podContainerClassNames = [
'col-lg-2 col-md-3 col-sm-4 col-xs-5',
'col-lg-2 col-md-3 col-sm-5 col-xs-7 ',
'col-lg-2 col-md-1 col-sm-3 hidden-xs',
'col-lg-2 hidden-md hidden-sm hidden-xs',
'col-lg-1 col-md-2 hidden-sm hidden-xs',
'col-lg-1 col-md-2 hidden-sm hidden-xs',
'col-lg-1 hidden-md hidden-sm hidden-xs',
'col-lg-1 hidden-md hidden-sm hidden-xs',
];

export const ContainerRow: React.FC<ContainerRowProps> = ({ pod, container }) => {
const cstatus = getContainerStatus(pod, container.name);
const cstate = getContainerState(cstatus);
Expand All @@ -492,25 +558,26 @@ export const ContainerRow: React.FC<ContainerRowProps> = ({ pod, container }) =>

return (
<div className="row">
<div className="col-lg-2 col-md-3 col-sm-4 col-xs-5">
<div className={podContainerClassNames[0]}>
<ContainerLink pod={pod} name={container.name} />
</div>
<div className="col-lg-2 col-md-3 col-sm-5 col-xs-7 co-truncate co-nowrap co-select-to-copy">
<div className={`${podContainerClassNames[1]} co-truncate co-nowrap co-select-to-copy`}>
{container.image || '-'}
</div>
<div className="col-lg-2 col-md-2 col-sm-3 hidden-xs">
<div className={podContainerClassNames[2]}>
<Status status={cstate.label} />
</div>
<div className="col-lg-1 col-md-2 hidden-sm hidden-xs">
{_.get(cstatus, 'restartCount', '0')}
<div className={podContainerClassNames[3]}>
<ContainerLastState containerLastState={cstatus?.lastState} />
</div>
<div className="col-lg-2 col-md-2 hidden-sm hidden-xs">
<div className={podContainerClassNames[4]}>{getContainerRestartCount(cstatus)}</div>
<div className={podContainerClassNames[5]}>
<Timestamp timestamp={startedAt} />
</div>
<div className="col-lg-2 hidden-md hidden-sm hidden-xs">
<div className={podContainerClassNames[6]}>
<Timestamp timestamp={finishedAt} />
</div>
<div className="col-lg-1 hidden-md hidden-sm hidden-xs">{_.get(cstate, 'exitCode', '-')}</div>
<div className={podContainerClassNames[7]}>{_.get(cstate, 'exitCode', '-')}</div>
</div>
);
};
Expand All @@ -527,13 +594,14 @@ export const PodContainerTable: React.FC<PodContainerTableProps> = ({
<SectionHeading text={heading} />
<div className="co-m-table-grid co-m-table-grid--bordered">
<div className="row co-m-table-grid__head">
<div className="col-lg-2 col-md-3 col-sm-4 col-xs-5">{t('public~Name')}</div>
<div className="col-lg-2 col-md-3 col-sm-5 col-xs-7">{t('public~Image')}</div>
<div className="col-lg-2 col-md-2 col-sm-3 hidden-xs">{t('public~State')}</div>
<div className="col-lg-1 col-md-2 hidden-sm hidden-xs">{t('public~Restarts')}</div>
<div className="col-lg-2 col-md-2 hidden-sm hidden-xs">{t('public~Started')}</div>
<div className="col-lg-2 hidden-md hidden-sm hidden-xs">{t('public~Finished')}</div>
<div className="col-lg-1 hidden-md hidden-sm hidden-xs">{t('public~Exit code')}</div>
<div className={podContainerClassNames[0]}>{t('public~Name')}</div>
<div className={podContainerClassNames[1]}>{t('public~Image')}</div>
<div className={podContainerClassNames[2]}>{t('public~State')}</div>
<div className={podContainerClassNames[3]}>{t('public~Last State')}</div>
<div className={podContainerClassNames[4]}>{t('public~Restarts')}</div>
<div className={podContainerClassNames[5]}>{t('public~Started')}</div>
<div className={podContainerClassNames[6]}>{t('public~Finished')}</div>
<div className={podContainerClassNames[7]}>{t('public~Exit code')}</div>
</div>
<div className="co-m-table-grid__body">
{containers.map((c: any, i: number) => (
Expand Down Expand Up @@ -1104,6 +1172,26 @@ type ContainerLinkProps = {
name: string;
};

type ContainerRunningSinceProps = {
startedAt?: string | number | Date;
};

type ContainerTerminatedAtProps = {
finishedAt?: string | number | Date;
};

type ContainerTerminatedExitCodeProps = {
exitCode?: string;
};

type ContainerTerminatedReasonProps = {
reason?: string;
};

type ContainerLastStateProps = {
containerLastState?: ContainerState;
};

type ContainerRowProps = {
pod: PodKind;
container: ContainerSpec;
Expand Down
8 changes: 8 additions & 0 deletions frontend/public/locales/en/public.json
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@
"Value": "Value",
"{{label}} with exit code {{exitCode}}": "{{label}} with exit code {{exitCode}}",
"Container details": "Container details",
"Last State": "Last State",
"Restarts": "Restarts",
"Resource requests": "Resource requests",
"Resource limits": "Resource limits",
Expand Down Expand Up @@ -1324,6 +1325,13 @@
"Owner": "Owner",
"IP address": "IP address",
"{{numCores}} cores": "{{numCores}} cores",
"since <1></1>": "since <1></1>",
"at <1></1> ": "at <1></1> ",
"with exit code {{exitCode}} ": "with exit code {{exitCode}} ",
"({{reason}})": "({{reason}})",
"Waiting {{reason}}": "Waiting {{reason}}",
"Running <1></1>": "Running <1></1>",
"Terminated <1></1><2></2><3></3>": "Terminated <1></1><2></2><3></3>",
"Exit code": "Exit code",
"View in query browser": "View in query browser",
"Pod unschedulable": "Pod unschedulable",
Expand Down
3 changes: 3 additions & 0 deletions frontend/public/module/k8s/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ export const getContainerStatus = (pod: PodKind, containerName: string): Contain
return _.find(statuses, identity) || _.find(initStatuses, identity);
};

export const getContainerRestartCount = (status: ContainerStatus): number =>
status.restartCount ?? 0;

const getPullPolicy = (container: ContainerSpec) => {
const pullPolicy = {
Always: {
Expand Down

0 comments on commit 4b98677

Please sign in to comment.