k8s.io/perf-tests/clusterloader2@v0.0.0-20240304094227-64bdb12da87e/pkg/measurement/util/pvcs.go (about) 1 /* 2 Copyright 2019 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package util 18 19 import ( 20 "fmt" 21 22 corev1 "k8s.io/api/core/v1" 23 "k8s.io/apimachinery/pkg/util/sets" 24 ) 25 26 // PVCsStartupStatus represents phase of a pvc group. 27 type PVCsStartupStatus struct { 28 Pending int 29 Bound int 30 Lost int 31 Expected int 32 Created int 33 } 34 35 // String returns string representation for PVCsStartupStatus. 36 func (s *PVCsStartupStatus) String() string { 37 return fmt.Sprintf("PVCs: %d out of %d created, %d bound, %d pending, %d lost", s.Created, s.Expected, s.Bound, s.Pending, s.Lost) 38 } 39 40 // ComputePVCsStartupStatus computes PVCsStartupStatus for a group of PVCs. 41 func ComputePVCsStartupStatus(pvcs []*corev1.PersistentVolumeClaim, expected int) PVCsStartupStatus { 42 startupStatus := PVCsStartupStatus{ 43 Expected: expected, 44 } 45 for _, p := range pvcs { 46 startupStatus.Created++ 47 if p.Status.Phase == corev1.ClaimPending { 48 startupStatus.Pending++ 49 } else if p.Status.Phase == corev1.ClaimBound { 50 startupStatus.Bound++ 51 } else if p.Status.Phase == corev1.ClaimLost { 52 startupStatus.Lost++ 53 } 54 } 55 return startupStatus 56 } 57 58 type pvcInfo struct { 59 oldPhase string 60 phase string 61 } 62 63 // PVCDiff represets diff between old and new group of pvcs. 64 type PVCDiff map[string]*pvcInfo 65 66 // Print formats and prints the give PVCDiff. 67 func (p PVCDiff) String(ignorePhases sets.String) string { 68 ret := "" 69 for name, info := range p { 70 if ignorePhases.Has(info.phase) { 71 continue 72 } 73 if info.phase == nonExist { 74 ret += fmt.Sprintf("PVC %v was deleted, had phase %v\n", name, info.oldPhase) 75 continue 76 } 77 msg := fmt.Sprintf("PVC %v ", name) 78 if info.oldPhase != info.phase { 79 if info.oldPhase == nonExist { 80 msg += fmt.Sprintf("in phase %v ", info.phase) 81 } else { 82 msg += fmt.Sprintf("went from phase: %v -> %v ", info.oldPhase, info.phase) 83 } 84 ret += msg + "\n" 85 } 86 } 87 return ret 88 } 89 90 // DeletedPVCs returns a slice of PVCs that were present at the beginning 91 // and then disappeared. 92 func (p PVCDiff) DeletedPVCs() []string { 93 var deletedPVCs []string 94 for pvcName, pvcInfo := range p { 95 if pvcInfo.phase == nonExist { 96 deletedPVCs = append(deletedPVCs, pvcName) 97 } 98 } 99 return deletedPVCs 100 } 101 102 // AddedPVCs returns a slice of PVCs that were added. 103 func (p PVCDiff) AddedPVCs() []string { 104 var addedPVCs []string 105 for pvcName, pvcInfo := range p { 106 if pvcInfo.oldPhase == nonExist { 107 addedPVCs = append(addedPVCs, pvcName) 108 } 109 } 110 return addedPVCs 111 } 112 113 // DiffPVCs computes a PVCDiff given 2 lists of PVCs. 114 func DiffPVCs(oldPVCs []*corev1.PersistentVolumeClaim, curPVCs []*corev1.PersistentVolumeClaim) PVCDiff { 115 pvcInfoMap := PVCDiff{} 116 117 // New PVCs will show up in the curPVCs list but not in oldPVCs. They have oldhostname/phase == nonexist. 118 for _, pvc := range curPVCs { 119 pvcInfoMap[pvc.Name] = &pvcInfo{phase: string(pvc.Status.Phase), oldPhase: nonExist} 120 } 121 122 // Deleted PVCs will show up in the oldPVCs list but not in curPVCs. They have a hostname/phase == nonexist. 123 for _, pvc := range oldPVCs { 124 if info, ok := pvcInfoMap[pvc.Name]; ok { 125 info.oldPhase = string(pvc.Status.Phase) 126 } else { 127 pvcInfoMap[pvc.Name] = &pvcInfo{phase: nonExist, oldPhase: string(pvc.Status.Phase)} 128 } 129 } 130 return pvcInfoMap 131 }