Skip to content

Commit

Permalink
Show pod details
Browse files Browse the repository at this point in the history
Show the port details of a pod using a popover.

`podman pod create --name testpod -p 8080:80`
  • Loading branch information
jelly committed Aug 10, 2022
1 parent 1b9ea70 commit 2f99bae
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 3 deletions.
106 changes: 103 additions & 3 deletions src/Containers.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import {
Dropdown, DropdownItem, DropdownSeparator,
Flex,
KebabToggle,
Popover,
LabelGroup,
List, ListItem,
Text, TextVariants, FormSelect, FormSelectOption,
Toolbar, ToolbarContent, ToolbarItem,
} from '@patternfly/react-core';
Expand Down Expand Up @@ -37,6 +39,26 @@ import { PodActions } from './PodActions.jsx';

const _ = cockpit.gettext;

const render_container_published_ports = (ports) => {
if (!ports)
return null;

const result = ports.map(port => {
// podman v4 has different names than v3
const protocol = port.protocol;
const host_port = port.hostPort || port.host_port;
const container_port = port.containerPort || port.container_port;
const host_ip = port.hostIP || port.host_ip || '0.0.0.0';
return (
<ListItem key={ protocol + host_port + container_port }>
{ host_ip }:{ host_port } &rarr; { container_port }/{ protocol }
</ListItem>
);
});

return <List isPlain>{result}</List>;
};

const ContainerActions = ({ container, healthcheck, onAddNotification, version, localImages, updateContainerAfterEvent }) => {
const Dialogs = useDialogs();
const [isActionsKebabOpen, setActionsKebabOpen] = useState(false);
Expand Down Expand Up @@ -326,6 +348,7 @@ class Containers extends React.Component {
};
this.renderRow = this.renderRow.bind(this);
this.onWindowResize = this.onWindowResize.bind(this);
this.podStats = this.podStats.bind(this);

this.cardRef = React.createRef();

Expand Down Expand Up @@ -442,6 +465,52 @@ class Containers extends React.Component {
this.setState({ width: this.cardRef.current.clientWidth });
}

podStats(pod) {
const { containersStats } = this.props;
// when no containers exists pod.Containers is null
if (!containersStats || !pod.Containers) {
return null;
}

let cpu = "";
let mem = "";

for (const container of pod.Containers) {
const containerStats = containersStats[container.Id + pod.isSystem.toString()];
if (!containerStats) {
continue;
}
if (containerStats.CPU != undefined)
cpu = containerStats.CPU.toFixed(2) + "%";
if (containerStats.MemUsage != undefined && containerStats.MemLimit != undefined)
mem = utils.format_memory_and_limit(containerStats.MemUsage);
}

return {
cpu,
mem,
};
}

podDetails(pod) {
const { containers } = this.props;
if (!containers) {
return null;
}

// The infra container binds all networking/mount together and contains all networking/mount information.
const container = containers[pod.InfraId + pod.isSystem.toString()];
console.log(container);

const ports = "";
const mounts = "";

return {
ports,
mounts,
};
}

render() {
const Dialogs = this.context;
const columnTitles = [
Expand Down Expand Up @@ -626,11 +695,16 @@ class Containers extends React.Component {
localImages);
});
let caption;
let podStats;
let podStatus;
let infraContainer = null;
if (section !== 'no-pod') {
tableProps['aria-label'] = cockpit.format("Containers of Pod $0", this.props.pods[section].Name);
podStatus = this.props.pods[section].Status;
caption = this.props.pods[section].Name;
const pod = this.props.pods[section];
tableProps['aria-label'] = cockpit.format("Containers of pod $0", pod.Name);
podStatus = pod.Status;
caption = pod.Name;
podStats = this.podStats(pod);
infraContainer = this.props.containers[pod.InfraId + pod.isSystem.toString()];
} else {
tableProps['aria-label'] = _("Containers");
}
Expand All @@ -656,6 +730,32 @@ class Containers extends React.Component {
<PodActions onAddNotification={this.props.onAddNotification} pod={this.props.pods[section]} />
</CardActions>
</CardHeader>}
{section !== "no-pod" &&
<Badge className="pod-header-details" isRead>
<Flex justifyContent={{ default: 'justifyContentFlexStart' }}>
{podStats && podStatus === "Running" &&
<>
<Text component={TextVariants.p}>{_("CPU") + " " + podStats.cpu}</Text>
<Text component={TextVariants.p}>{_("Memory") + " " + podStats.mem}</Text>
</>
}
{infraContainer && podStatus === "Running" &&
<>
{infraContainer.Ports && infraContainer.Ports.length !== 0 &&
<Popover
enableFlip
bodyContent={render_container_published_ports(infraContainer.Ports)}
>
<Button variant="plain" className="pod-ports-popover-button">
{cockpit.format(cockpit.ngettext("$0 port", "$0 ports", infraContainer.Ports.length), infraContainer.Ports.length)}
</Button>
</Popover>
}
</>
}
</Flex>
</Badge>
}
<ListingTable variant='compact'
emptyCaption={section == "no-pod" ? emptyCaption : emptyCaptionPod}
columns={columnTitles}
Expand Down
11 changes: 11 additions & 0 deletions src/Containers.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@
padding-top: var(--pf-global--spacer--md);
}

.pod-header-details {
border-color: #ddd;
margin-top: var(--pf-global--spacer--md);
margin-left: var(--pf-global--spacer--md);
margin-right: var(--pf-global--spacer--md);
}

.pod-ports-popover-button {
color: var(--pf-c-button--m-secondary--Color);
}

.pf-c-card__title {
padding: 0;
font-weight: var(--pf-global--FontWeight--normal);
Expand Down

0 comments on commit 2f99bae

Please sign in to comment.