Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9817061
cpu-mem-requests-added
surajyadav1108 Nov 1, 2024
afcd1ec
lint
surajyadav1108 Nov 1, 2024
64c15e0
Merge branch 'master' into pod-view-cpu-mem
surajyadav1108 Nov 3, 2024
c7b702f
Merge branch 'argoproj:master' into pod-view-cpu-mem
surajyadav1108 Nov 9, 2024
2dbfd7c
refactor-changes
surajyadav1108 Nov 9, 2024
1819d3f
added-as-constants
surajyadav1108 Nov 9, 2024
b4ef9b5
another-one
surajyadav1108 Nov 9, 2024
d5b30e7
parenethesis
surajyadav1108 Nov 9, 2024
3534c5f
ci-fixes
surajyadav1108 Nov 10, 2024
1fcbb04
Merge branch 'master' into pod-view-cpu-mem
surajyadav1108 Nov 25, 2024
246c2ce
ci-fix
surajyadav1108 Nov 26, 2024
23198a4
Merge branch 'master' into pod-view-cpu-mem
surajyadav1108 Nov 26, 2024
5a77b8f
Merge branch 'master' into pod-view-cpu-mem
surajyadav1108 May 17, 2025
62dce40
Update v1 to corev1
surajyadav1108 May 19, 2025
087837b
replace sprintf with strconv
surajyadav1108 May 19, 2025
4917c25
remove-grouped-requests
surajyadav1108 May 20, 2025
093c084
Merge branch 'master' into pod-view-cpu-mem
surajyadav1108 May 20, 2025
a8a8ff5
Merge branch 'master' into pod-view-cpu-mem
surajyadav1108 Jun 30, 2025
1d13ed1
Merge branch 'master' into pod-view-cpu-mem
surajyadav1108 Jul 2, 2025
17c0d29
Merge branch 'master' into pod-view-cpu-mem
surajyadav1108 Jul 23, 2025
2f565e1
refactor-with-new-changes
surajyadav1108 Jul 23, 2025
7f0a616
lint-ci-fixes
surajyadav1108 Jul 23, 2025
ac6c992
remove-export
surajyadav1108 Jul 24, 2025
3a27e86
Merge branch 'master' into pod-view-cpu-mem
surajyadav1108 Jul 24, 2025
4b394b8
Merge branch 'master' into pod-view-cpu-mem
surajyadav1108 Jul 28, 2025
32299ea
Merge branch 'master' into pod-view-cpu-mem
surajyadav1108 Jul 30, 2025
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
9 changes: 9 additions & 0 deletions controller/cache/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,8 @@ func populatePodInfo(un *unstructured.Unstructured, res *ResourceInfo) {
}

req, _ := resourcehelper.PodRequestsAndLimits(&pod)
CPUReq, MemoryReq := req[v1.ResourceCPU], req[v1.ResourceMemory]

res.PodInfo = &PodInfo{NodeName: pod.Spec.NodeName, ResourceRequests: req, Phase: pod.Status.Phase}

res.Info = append(res.Info, v1alpha1.InfoItem{Name: "Node", Value: pod.Spec.NodeName})
Expand All @@ -454,6 +456,13 @@ func populatePodInfo(un *unstructured.Unstructured, res *ResourceInfo) {
res.Info = append(res.Info, v1alpha1.InfoItem{Name: "Restart Count", Value: fmt.Sprintf("%d", restarts)})
}

// requests will be released for terminated pods either with success or failed state termination.

if reason != "Completed" && reason != "Error" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the code above, it is very likely that the reason string could be set to a more "detailed" value, such as ExitCode:%s. Instead of basing the condition on the string, use the bool variable available above such as initializing and hasRunning, or add a new one.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, used !isPodPhaseTerminal no need to use these initializing hasRunning as these are requests. It's also helpful for the user to see when pods aren't scheduled.

res.Info = append(res.Info, v1alpha1.InfoItem{Name: "Requests (CPU)", Value: fmt.Sprintf("%d", CPUReq.MilliValue())})
res.Info = append(res.Info, v1alpha1.InfoItem{Name: "Requests (MEM)", Value: fmt.Sprintf("%d", MemoryReq.MilliValue())})
}

var urls []string
if res.NetworkingInfo != nil {
urls = res.NetworkingInfo.ExternalURLs
Expand Down
171 changes: 171 additions & 0 deletions controller/cache/info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,8 @@ func TestGetPodInfo(t *testing.T) {
assert.Equal(t, []v1alpha1.InfoItem{
{Name: "Node", Value: "minikube"},
{Name: "Containers", Value: "0/1"},
{Name: "Requests (CPU)", Value: "0"},
{Name: "Requests (MEM)", Value: "134217728000"},
}, info.Info)
assert.Equal(t, []string{"bar"}, info.Images)
assert.Equal(t, &PodInfo{
Expand Down Expand Up @@ -367,9 +369,81 @@ func TestGetPodInfo(t *testing.T) {
{Name: "Status Reason", Value: "Running"},
{Name: "Node", Value: "minikube"},
{Name: "Containers", Value: "1/1"},
{Name: "Requests (CPU)", Value: "0"},
{Name: "Requests (MEM)", Value: "0"},
}, info.Info)
})

t.Run("TestGetPodWithInitialContainerInfoWithResources", func(t *testing.T) {
pod := strToUnstructured(`
apiVersion: "v1"
kind: "Pod"
metadata:
labels:
app: "app-with-initial-container"
name: "app-with-initial-container-5f46976fdb-vd6rv"
namespace: "default"
ownerReferences:
- apiVersion: "apps/v1"
kind: "ReplicaSet"
name: "app-with-initial-container-5f46976fdb"
spec:
containers:
- image: "alpine:latest"
imagePullPolicy: "Always"
name: "app-with-initial-container"
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"
initContainers:
- image: "alpine:latest"
imagePullPolicy: "Always"
name: "app-with-initial-container-logshipper"
resources:
requests:
cpu: "50m"
memory: "64Mi"
limits:
cpu: "250m"
memory: "256Mi"
nodeName: "minikube"
status:
containerStatuses:
- image: "alpine:latest"
name: "app-with-initial-container"
ready: true
restartCount: 0
started: true
state:
running:
startedAt: "2024-10-08T08:44:25Z"
initContainerStatuses:
- image: "alpine:latest"
name: "app-with-initial-container-logshipper"
ready: true
restartCount: 0
started: false
state:
terminated:
exitCode: 0
reason: "Completed"
phase: "Running"
`)

info := &ResourceInfo{}
populateNodeInfo(pod, info, []string{})
assert.Equal(t, []v1alpha1.InfoItem{
{Name: "Status Reason", Value: "Running"},
{Name: "Node", Value: "minikube"},
{Name: "Containers", Value: "1/1"},
{Name: "Requests (CPU)", Value: "100"},
{Name: "Requests (MEM)", Value: "134217728000"},
}, info.Info)
})
t.Run("TestGetPodInfoWithSidecar", func(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -424,6 +498,8 @@ func TestGetPodInfo(t *testing.T) {
{Name: "Status Reason", Value: "Running"},
{Name: "Node", Value: "minikube"},
{Name: "Containers", Value: "2/2"},
{Name: "Requests (CPU)", Value: "0"},
{Name: "Requests (MEM)", Value: "0"},
}, info.Info)
})

Expand Down Expand Up @@ -482,6 +558,8 @@ func TestGetPodInfo(t *testing.T) {
{Name: "Status Reason", Value: "Init:0/1"},
{Name: "Node", Value: "minikube"},
{Name: "Containers", Value: "0/1"},
{Name: "Requests (CPU)", Value: "0"},
{Name: "Requests (MEM)", Value: "0"},
}, info.Info)
})

Expand Down Expand Up @@ -539,6 +617,8 @@ func TestGetPodInfo(t *testing.T) {
{Name: "Node", Value: "minikube"},
{Name: "Containers", Value: "0/3"},
{Name: "Restart Count", Value: "3"},
{Name: "Requests (CPU)", Value: "0"},
{Name: "Requests (MEM)", Value: "0"},
}, info.Info)
})

Expand Down Expand Up @@ -596,6 +676,8 @@ func TestGetPodInfo(t *testing.T) {
{Name: "Node", Value: "minikube"},
{Name: "Containers", Value: "0/3"},
{Name: "Restart Count", Value: "3"},
{Name: "Requests (CPU)", Value: "0"},
{Name: "Requests (MEM)", Value: "0"},
}, info.Info)
})

Expand Down Expand Up @@ -656,6 +738,8 @@ func TestGetPodInfo(t *testing.T) {
{Name: "Node", Value: "minikube"},
{Name: "Containers", Value: "1/3"},
{Name: "Restart Count", Value: "7"},
{Name: "Requests (CPU)", Value: "0"},
{Name: "Requests (MEM)", Value: "0"},
}, info.Info)
})

Expand Down Expand Up @@ -698,6 +782,8 @@ func TestGetPodInfo(t *testing.T) {
{Name: "Node", Value: "minikube"},
{Name: "Containers", Value: "0/1"},
{Name: "Restart Count", Value: "3"},
{Name: "Requests (CPU)", Value: "0"},
{Name: "Requests (MEM)", Value: "0"},
}, info.Info)
})

Expand Down Expand Up @@ -733,6 +819,45 @@ func TestGetPodInfo(t *testing.T) {
}, info.Info)
})

// Test pod condition succeed which had some allocated resources
t.Run("TestPodConditionSucceededWithResources", func(t *testing.T) {
t.Parallel()

pod := strToUnstructured(`
apiVersion: v1
kind: Pod
metadata:
name: test8
spec:
nodeName: minikube
containers:
- name: container
resources:
requests:
cpu: "50m"
memory: "64Mi"
limits:
cpu: "250m"
memory: "256Mi"
status:
phase: Succeeded
containerStatuses:
- ready: false
restartCount: 0
state:
terminated:
reason: Completed
exitCode: 0
`)
info := &ResourceInfo{}
populateNodeInfo(pod, info, []string{})
assert.Equal(t, []v1alpha1.InfoItem{
{Name: "Status Reason", Value: "Completed"},
{Name: "Node", Value: "minikube"},
{Name: "Containers", Value: "0/1"},
}, info.Info)
})

// Test pod condition failed
t.Run("TestPodConditionFailed", func(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -765,6 +890,46 @@ func TestGetPodInfo(t *testing.T) {
}, info.Info)
})

// Test pod condition failed with allocated resources

t.Run("TestPodConditionFailedWithResources", func(t *testing.T) {
t.Parallel()

pod := strToUnstructured(`
apiVersion: v1
kind: Pod
metadata:
name: test9
spec:
nodeName: minikube
containers:
- name: container
resources:
requests:
cpu: "50m"
memory: "64Mi"
limits:
cpu: "250m"
memory: "256Mi"
status:
phase: Failed
containerStatuses:
- ready: false
restartCount: 0
state:
terminated:
reason: Error
exitCode: 1
`)
info := &ResourceInfo{}
populateNodeInfo(pod, info, []string{})
assert.Equal(t, []v1alpha1.InfoItem{
{Name: "Status Reason", Value: "Error"},
{Name: "Node", Value: "minikube"},
{Name: "Containers", Value: "0/1"},
}, info.Info)
})

// Test pod condition succeed with deletion
t.Run("TestPodConditionSucceededWithDeletion", func(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -826,6 +991,8 @@ func TestGetPodInfo(t *testing.T) {
{Name: "Status Reason", Value: "Terminating"},
{Name: "Node", Value: "minikube"},
{Name: "Containers", Value: "0/1"},
{Name: "Requests (CPU)", Value: "0"},
{Name: "Requests (MEM)", Value: "0"},
}, info.Info)
})

Expand All @@ -852,6 +1019,8 @@ func TestGetPodInfo(t *testing.T) {
{Name: "Status Reason", Value: "Terminating"},
{Name: "Node", Value: "minikube"},
{Name: "Containers", Value: "0/1"},
{Name: "Requests (CPU)", Value: "0"},
{Name: "Requests (MEM)", Value: "0"},
}, info.Info)
})

Expand Down Expand Up @@ -882,6 +1051,8 @@ func TestGetPodInfo(t *testing.T) {
{Name: "Status Reason", Value: "SchedulingGated"},
{Name: "Node", Value: "minikube"},
{Name: "Containers", Value: "0/2"},
{Name: "Requests (CPU)", Value: "0"},
{Name: "Requests (MEM)", Value: "0"},
}, info.Info)
})
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as React from 'react';
import Moment from 'react-moment';
import {Pod} from '../../../shared/models';
import {isYoungerThanXMinutes} from '../utils';
import {isYoungerThanXMinutes, podRequests} from '../utils';
import {formatSize} from './pod-view';

export const PodTooltip = (props: {pod: Pod}) => {
const pod = props.pod;
Expand All @@ -16,15 +17,22 @@ export const PodTooltip = (props: {pod: Pod}) => {
<div className='columns small-6'>{pod.health}</div>
</div>
{(pod.info || [])
.filter(i => i.name !== 'Node')
.map(i => (
<div className='row' key={i.name}>
<div className='columns small-6' style={{whiteSpace: 'nowrap'}}>
{i.name}:
.filter(i => {
//filter out 0 values for CPU and mem on pod info
return i.name !== 'Node' && !((i.name === 'Requests (CPU)' || i.name === 'Requests (MEM)') && parseInt(i.value, 10) === 0);
})
.map(i => {
//formatted the values for cpu and mem
const formattedValue = formatPodMetric(i.name, i.value);
return (
<div className='row' key={i.name}>
<div className='columns small-6' style={{whiteSpace: 'nowrap'}}>
{i.name}:
</div>
<div className='columns small-6'>{formattedValue}</div>
</div>
<div className='columns small-6'>{i.value}</div>
</div>
))}
);
})}
{pod.createdAt && (
<div className='row'>
<div className='columns small-6'>
Expand All @@ -49,3 +57,17 @@ export const PodTooltip = (props: {pod: Pod}) => {
</div>
);
};

function formatPodMetric(name: string, value: string) {
const numericValue = parseInt(value, 10);

switch (name) {
case podRequests.CPU:
return `${numericValue}m`;
case podRequests.MEMORY: {
return formatSize(numericValue / 1000); // divide by 1000 to convert "milli bytes" to bytes
}
default:
return value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ $pod-age-icon-clr: #ffce25;
}
}
&__info {
margin-top: 1em;
margin-top: 3em;
display: flex;
justify-content: end;
div {
Expand All @@ -69,6 +69,22 @@ $pod-age-icon-clr: #ffce25;
margin-right: 5px;
padding: 3px 5px;
}
#cost {
background-color: $argo-color-gray-7;
color: whitesmoke;
padding: 5px 8px;
font-weight: bold;
margin-right: auto;
transition: background-color 0.3s ease, box-shadow 0.3s ease, transform 0.2s ease;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
border: 1px solid lighten($argo-color-gray-7, 10%);


&:hover {
background-color: darken($argo-color-gray-7, 10%);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.2);
}
}
}
&__info--large {
margin: 1em 0;
Expand Down
Loading