mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-13 22:05:59 +00:00
Look for pods in ownerReferences of PVC (#120427)
* Look for pods in ownerReferences of PVC * Implement for loop instead of using slices package * Add tests for getPodsForPVC function * Make PVC names consistent * Remove volumes part of the pvc owner pod * Do not store result of append in another variable * Fix lint error
This commit is contained in:
parent
a08ee80807
commit
710dceded5
@ -1645,7 +1645,7 @@ func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string, descri
|
|||||||
|
|
||||||
pc := d.CoreV1().Pods(namespace)
|
pc := d.CoreV1().Pods(namespace)
|
||||||
|
|
||||||
pods, err := getPodsForPVC(pc, pvc.Name, describerSettings)
|
pods, err := getPodsForPVC(pc, pvc, describerSettings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -1655,7 +1655,7 @@ func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string, descri
|
|||||||
return describePersistentVolumeClaim(pvc, events, pods)
|
return describePersistentVolumeClaim(pvc, events, pods)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPodsForPVC(c corev1client.PodInterface, pvcName string, settings DescriberSettings) ([]corev1.Pod, error) {
|
func getPodsForPVC(c corev1client.PodInterface, pvc *corev1.PersistentVolumeClaim, settings DescriberSettings) ([]corev1.Pod, error) {
|
||||||
nsPods, err := getPodsInChunks(c, metav1.ListOptions{Limit: settings.ChunkSize})
|
nsPods, err := getPodsInChunks(c, metav1.ListOptions{Limit: settings.ChunkSize})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []corev1.Pod{}, err
|
return []corev1.Pod{}, err
|
||||||
@ -1665,12 +1665,40 @@ func getPodsForPVC(c corev1client.PodInterface, pvcName string, settings Describ
|
|||||||
|
|
||||||
for _, pod := range nsPods.Items {
|
for _, pod := range nsPods.Items {
|
||||||
for _, volume := range pod.Spec.Volumes {
|
for _, volume := range pod.Spec.Volumes {
|
||||||
if volume.VolumeSource.PersistentVolumeClaim != nil && volume.VolumeSource.PersistentVolumeClaim.ClaimName == pvcName {
|
if volume.VolumeSource.PersistentVolumeClaim != nil && volume.VolumeSource.PersistentVolumeClaim.ClaimName == pvc.Name {
|
||||||
pods = append(pods, pod)
|
pods = append(pods, pod)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ownersLoop:
|
||||||
|
for _, ownerRef := range pvc.ObjectMeta.OwnerReferences {
|
||||||
|
if ownerRef.Kind != "Pod" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
podIndex := -1
|
||||||
|
for i, pod := range nsPods.Items {
|
||||||
|
if pod.UID == ownerRef.UID {
|
||||||
|
podIndex = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if podIndex == -1 {
|
||||||
|
// Maybe the pod has been deleted
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pod := range pods {
|
||||||
|
if pod.UID == nsPods.Items[podIndex].UID {
|
||||||
|
// This owner pod is already recorded, look for pods between other owners
|
||||||
|
continue ownersLoop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pods = append(pods, nsPods.Items[podIndex])
|
||||||
|
}
|
||||||
|
|
||||||
return pods, nil
|
return pods, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1994,6 +1994,123 @@ func TestPersistentVolumeClaimDescriber(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetPodsForPVC(t *testing.T) {
|
||||||
|
goldClassName := "gold"
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
pvc *corev1.PersistentVolumeClaim
|
||||||
|
requiredObjects []runtime.Object
|
||||||
|
expectedPods []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "pvc-unused",
|
||||||
|
pvc: &corev1.PersistentVolumeClaim{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Namespace: "ns", Name: "pvc-name"},
|
||||||
|
Spec: corev1.PersistentVolumeClaimSpec{
|
||||||
|
VolumeName: "volume1",
|
||||||
|
StorageClassName: &goldClassName,
|
||||||
|
},
|
||||||
|
Status: corev1.PersistentVolumeClaimStatus{
|
||||||
|
Phase: corev1.ClaimBound,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedPods: []string{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "pvc-in-pods-volumes-list",
|
||||||
|
pvc: &corev1.PersistentVolumeClaim{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Namespace: "ns", Name: "pvc-name"},
|
||||||
|
Spec: corev1.PersistentVolumeClaimSpec{
|
||||||
|
VolumeName: "volume1",
|
||||||
|
StorageClassName: &goldClassName,
|
||||||
|
},
|
||||||
|
Status: corev1.PersistentVolumeClaimStatus{
|
||||||
|
Phase: corev1.ClaimBound,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
requiredObjects: []runtime.Object{
|
||||||
|
&corev1.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Namespace: "ns", Name: "pod-name"},
|
||||||
|
Spec: corev1.PodSpec{
|
||||||
|
Volumes: []corev1.Volume{
|
||||||
|
{
|
||||||
|
Name: "volume",
|
||||||
|
VolumeSource: corev1.VolumeSource{
|
||||||
|
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
|
||||||
|
ClaimName: "pvc-name",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedPods: []string{"pod-name"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "pvc-owned-by-pod",
|
||||||
|
pvc: &corev1.PersistentVolumeClaim{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Namespace: "ns",
|
||||||
|
Name: "pvc-name",
|
||||||
|
OwnerReferences: []metav1.OwnerReference{
|
||||||
|
{
|
||||||
|
Kind: "Pod",
|
||||||
|
Name: "pod-name",
|
||||||
|
UID: "pod-uid",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: corev1.PersistentVolumeClaimSpec{
|
||||||
|
VolumeName: "volume1",
|
||||||
|
StorageClassName: &goldClassName,
|
||||||
|
},
|
||||||
|
Status: corev1.PersistentVolumeClaimStatus{
|
||||||
|
Phase: corev1.ClaimBound,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
requiredObjects: []runtime.Object{
|
||||||
|
&corev1.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Namespace: "ns", Name: "pod-name", UID: "pod-uid"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedPods: []string{"pod-name"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
var objects []runtime.Object
|
||||||
|
objects = append(objects, test.requiredObjects...)
|
||||||
|
objects = append(objects, test.pvc)
|
||||||
|
fake := fake.NewSimpleClientset(objects...)
|
||||||
|
|
||||||
|
pods, err := getPodsForPVC(fake.CoreV1().Pods(test.pvc.ObjectMeta.Namespace), test.pvc, DescriberSettings{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error for test %s: %v", test.name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, expectedPod := range test.expectedPods {
|
||||||
|
foundPod := false
|
||||||
|
for _, pod := range pods {
|
||||||
|
if pod.Name == expectedPod {
|
||||||
|
foundPod = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !foundPod {
|
||||||
|
t.Errorf("Expected pod %s, but it was not returned: %v", expectedPod, pods)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(test.expectedPods) != len(pods) {
|
||||||
|
t.Errorf("Expected %d pods, but got %d pods", len(test.expectedPods), len(pods))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDescribeDeployment(t *testing.T) {
|
func TestDescribeDeployment(t *testing.T) {
|
||||||
labels := map[string]string{"k8s-app": "bar"}
|
labels := map[string]string{"k8s-app": "bar"}
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user