diff --git a/ui/src/app/applications/components/application-node-info/application-node-info.scss b/ui/src/app/applications/components/application-node-info/application-node-info.scss
index 4edf2235eea22..1d1fbf941fac7 100644
--- a/ui/src/app/applications/components/application-node-info/application-node-info.scss
+++ b/ui/src/app/applications/components/application-node-info/application-node-info.scss
@@ -39,4 +39,31 @@
color: $argo-color-gray-8;
}
}
+
+ &__container {
+ display: flex;
+ align-items: center;
+ flex-direction: row;
+ line-height: 1.8;
+ border-bottom: 1px solid rgba(222, 230, 235, 0.7);
+
+ &--name {
+ width: 15%;
+ }
+ &--highlight {
+ font-style: italic;
+ }
+
+ &--hint {
+ text-decoration: underline;
+ text-decoration-style: dashed;
+ cursor: pointer;
+ &:hover {
+ text-decoration: none;
+ }
+ }
+ &:last-child {
+ border-bottom: none;
+ }
+ }
}
diff --git a/ui/src/app/applications/components/application-node-info/application-node-info.tsx b/ui/src/app/applications/components/application-node-info/application-node-info.tsx
index ee0e2516cce15..8ecb965a1ab8b 100644
--- a/ui/src/app/applications/components/application-node-info/application-node-info.tsx
+++ b/ui/src/app/applications/components/application-node-info/application-node-info.tsx
@@ -1,4 +1,5 @@
import {Checkbox, DataLoader, Tab, Tabs} from 'argo-ui';
+import classNames from 'classnames';
import * as deepMerge from 'deepmerge';
import * as React from 'react';
@@ -16,10 +17,72 @@ import {
getPodStateReason,
HealthStatusIcon
} from '../utils';
-
import './application-node-info.scss';
import {ReadinessGatesFailedWarning} from './readiness-gates-failed-warning';
+const RenderContainerState = (props: {container: any}) => {
+ const state = (props.container.state?.waiting && 'waiting') || (props.container.state?.terminated && 'terminated') || (props.container.state?.running && 'running');
+ const status = props.container.state.waiting?.reason || props.container.state.terminated?.reason || props.container.state.running?.reason;
+ const lastState = props.container.lastState?.terminated;
+ const msg = props.container.state.waiting?.message || props.container.state.terminated?.message || props.container.state.running?.message;
+
+ return (
+
+
{props.container.name}
+
+ {state && (
+ <>
+ Container is {state}
+ {status && ' because of '}
+ >
+ )}
+
+ {status && (
+
+ {status}
+
+ )}
+
+ {'.'}
+ {(props.container.state.terminated?.exitCode === 0 || props.container.state.terminated?.exitCode) && (
+ <>
+ {' '}
+ It exited with exit code {props.container.state.terminated.exitCode}.
+ >
+ )}
+ <>
+ {' '}
+ It is {props.container?.started ? 'started' : 'not started'} and
+ {props.container?.ready ? ' ready.' : ' not ready.'}
+ >
+
+ {lastState && (
+ <>
+ <>
+ The container last terminated with exit code {lastState?.exitCode}
+ >
+ {lastState?.reason && ' because of '}
+
+ {lastState?.reason && (
+
+ {lastState?.reason}
+
+ )}
+
+ {'.'}
+ >
+ )}
+
+
+ );
+};
+
export const ApplicationNodeInfo = (props: {
application: models.Application;
node: models.ResourceNode;
@@ -54,11 +117,23 @@ export const ApplicationNodeInfo = (props: {
}
if (props.live) {
if (props.node.kind === 'Pod') {
- const {reason, message} = getPodStateReason(props.live);
+ const {reason, message, netContainerStatuses} = getPodStateReason(props.live);
attributes.push({title: 'STATE', value: reason});
if (message) {
attributes.push({title: 'STATE DETAILS', value: message});
}
+ if (netContainerStatuses.length > 0) {
+ attributes.push({
+ title: 'CONTAINER STATE',
+ value: (
+
+ {netContainerStatuses.map((container, i) => {
+ return ;
+ })}
+
+ )
+ });
+ }
} else if (props.node.kind === 'Service') {
attributes.push({title: 'TYPE', value: props.live.spec.type});
let hostNames = '';
diff --git a/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx b/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx
index e58282acada04..29707816b7e05 100644
--- a/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx
+++ b/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx
@@ -3,6 +3,7 @@ import * as classNames from 'classnames';
import * as dagre from 'dagre';
import * as React from 'react';
import Moment from 'react-moment';
+import * as moment from 'moment';
import * as models from '../../../shared/models';
@@ -611,6 +612,61 @@ function expandCollapse(node: ResourceTreeNode, props: ApplicationResourceTreePr
props.setNodeExpansion(node.uid, isExpanded);
}
+function NodeInfoDetails({tag: tag, kind: kind}: {tag: models.InfoItem; kind: string}) {
+ if (kind === 'Pod') {
+ const val = `${tag.name}`;
+ if (val === 'Status Reason') {
+ if (`${tag.value}` !== 'ImagePullBackOff')
+ return (
+
+ {tag.value}
+
+ );
+ else {
+ return (
+
+ {tag.value}
+
+ );
+ }
+ } else if (val === 'Containers') {
+ const arr = `${tag.value}`.split('/');
+ const title = `Number of containers in total: ${arr[1]} \nNumber of ready containers: ${arr[0]}`;
+ return (
+
+ {tag.value}
+
+ );
+ } else if (val === 'Restart Count') {
+ return (
+
+ {tag.value}
+
+ );
+ } else if (val === 'Revision') {
+ return (
+
+ {tag.value}
+
+ );
+ } else {
+ return (
+
+ {tag.value}
+
+ );
+ }
+ } else {
+ return (
+
+ {tag.value}
+
+ );
+ }
+}
+
function renderResourceNode(props: ApplicationResourceTreeProps, id: string, node: ResourceTreeNode & dagre.Node, nodesHavingChildren: Map) {
const fullName = nodeKey(node);
let comparisonStatus: models.SyncStatusCode = null;
@@ -685,18 +741,18 @@ function renderResourceNode(props: ApplicationResourceTreeProps, id: string, nod
{node.createdAt || rootNode ? (
-
- {node.createdAt || props.app.metadata.creationTimestamp}
-
+
+
+ {node.createdAt || props.app.metadata.creationTimestamp}
+
+
) : null}
{(node.info || [])
.filter(tag => !tag.name.includes('Node'))
.slice(0, 4)
- .map((tag, i) => (
-
- {tag.value}
-
- ))}
+ .map((tag, i) => {
+ return ;
+ })}
{(node.info || []).length > 4 && (
(
diff --git a/ui/src/app/applications/components/utils.tsx b/ui/src/app/applications/components/utils.tsx
index 7e4fed73cbd17..3819f7d911074 100644
--- a/ui/src/app/applications/components/utils.tsx
+++ b/ui/src/app/applications/components/utils.tsx
@@ -872,7 +872,7 @@ export const OperationState = ({app, quiet}: {app: appModels.Application; quiet?
);
};
-export function getPodStateReason(pod: appModels.State): {message: string; reason: string} {
+export function getPodStateReason(pod: appModels.State): {message: string; reason: string; netContainerStatuses: any[]} {
let reason = pod.status.phase;
let message = '';
if (pod.status.reason) {
@@ -880,6 +880,10 @@ export function getPodStateReason(pod: appModels.State): {message: string; reaso
}
let initializing = false;
+
+ let netContainerStatuses = pod.status.initContainerStatuses || [];
+ netContainerStatuses = netContainerStatuses.concat(pod.status.containerStatuses || []);
+
for (const container of (pod.status.initContainerStatuses || []).slice().reverse()) {
if (container.state.terminated && container.state.terminated.exitCode === 0) {
continue;
@@ -939,7 +943,7 @@ export function getPodStateReason(pod: appModels.State): {message: string; reaso
message = '';
}
- return {reason, message};
+ return {reason, message, netContainerStatuses};
}
export const getPodReadinessGatesState = (pod: appModels.State): {nonExistingConditions: string[]; failedConditions: string[]} => {