@@ -28,6 +28,36 @@ import (
28
28
"k8s.io/utils/ptr"
29
29
)
30
30
31
+ // foreachAllocatedDevice invokes the provided callback for each
32
+ // device in the claim's allocation result which was allocated
33
+ // exclusively for the claim.
34
+ //
35
+ // Devices allocated with admin access can be shared with other
36
+ // claims and are skipped without invoking the callback.
37
+ //
38
+ // foreachAllocatedDevice does nothing if the claim is not allocated.
39
+ func foreachAllocatedDevice (claim * resourceapi.ResourceClaim , cb func (deviceID structured.DeviceID )) {
40
+ if claim .Status .Allocation == nil {
41
+ return
42
+ }
43
+ for _ , result := range claim .Status .Allocation .Devices .Results {
44
+ // Kubernetes 1.31 did not set this, 1.32 always does.
45
+ // Supporting 1.31 is not worth the additional code that
46
+ // would have to be written (= looking up in request) because
47
+ // it is extremely unlikely that there really is a result
48
+ // that still exists in a cluster from 1.31 where this matters.
49
+ if ptr .Deref (result .AdminAccess , false ) {
50
+ // Is not considered as allocated.
51
+ continue
52
+ }
53
+ deviceID := structured .MakeDeviceID (result .Driver , result .Pool , result .Device )
54
+
55
+ // None of the users of this helper need to abort iterating,
56
+ // therefore it's not supported as it only would add overhead.
57
+ cb (deviceID )
58
+ }
59
+ }
60
+
31
61
// allocatedDevices reacts to events in a cache and maintains a set of all allocated devices.
32
62
// This is cheaper than repeatedly calling List, making strings unique, and building the set
33
63
// each time PreFilter is called.
@@ -112,16 +142,10 @@ func (a *allocatedDevices) addDevices(claim *resourceapi.ResourceClaim) {
112
142
// Locking of the mutex gets minimized by pre-computing what needs to be done
113
143
// without holding the lock.
114
144
deviceIDs := make ([]structured.DeviceID , 0 , 20 )
115
-
116
- for _ , result := range claim .Status .Allocation .Devices .Results {
117
- if ptr .Deref (result .AdminAccess , false ) {
118
- // Is not considered as allocated.
119
- continue
120
- }
121
- deviceID := structured .MakeDeviceID (result .Driver , result .Pool , result .Device )
145
+ foreachAllocatedDevice (claim , func (deviceID structured.DeviceID ) {
122
146
a .logger .V (6 ).Info ("Observed device allocation" , "device" , deviceID , "claim" , klog .KObj (claim ))
123
147
deviceIDs = append (deviceIDs , deviceID )
124
- }
148
+ })
125
149
126
150
a .mutex .Lock ()
127
151
defer a .mutex .Unlock ()
@@ -138,17 +162,10 @@ func (a *allocatedDevices) removeDevices(claim *resourceapi.ResourceClaim) {
138
162
// Locking of the mutex gets minimized by pre-computing what needs to be done
139
163
// without holding the lock.
140
164
deviceIDs := make ([]structured.DeviceID , 0 , 20 )
141
-
142
- for _ , result := range claim .Status .Allocation .Devices .Results {
143
- if ptr .Deref (result .AdminAccess , false ) {
144
- // Is not considered as allocated and thus does not need to be removed
145
- // because of this claim.
146
- continue
147
- }
148
- deviceID := structured .MakeDeviceID (result .Driver , result .Pool , result .Device )
165
+ foreachAllocatedDevice (claim , func (deviceID structured.DeviceID ) {
149
166
a .logger .V (6 ).Info ("Observed device deallocation" , "device" , deviceID , "claim" , klog .KObj (claim ))
150
167
deviceIDs = append (deviceIDs , deviceID )
151
- }
168
+ })
152
169
153
170
a .mutex .Lock ()
154
171
defer a .mutex .Unlock ()
0 commit comments