Skip to content

Commit a01f0ba

Browse files
committed
cnsCode to just errorCode
1 parent 6a3f54e commit a01f0ba

File tree

5 files changed

+325
-10
lines changed

5 files changed

+325
-10
lines changed

cns/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ type AssignIBDevicesToPodRequest struct {
397397

398398
// AssignIBDevicesToPodResponse represents the response for assigning InfiniBand devices to a pod
399399
type AssignIBDevicesToPodResponse struct {
400-
Response Response `json:"response"` // Contains cnsCode (int) and message (string)
400+
Response Response `json:"response"` // Contains errorCode (int) and message (string)
401401
}
402402

403403
// GetIBDeviceInfoRequest represents the request to get InfiniBand device information

cns/grpc/proto/server.proto

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ message AssignIBDevicesToPodRequest {
5656

5757
// AssignIBDevicesToPodResponse is the response message for assigning InfiniBand devices to a pod.
5858
message AssignIBDevicesToPodResponse {
59-
int32 cnsCode = 1; // CNS response code (0 for success).
59+
int32 errorCode = 1; // Error code (0 for success).
6060
string message = 2; // Response message.
6161
}
6262

cns/grpc/v1alpha/server.pb.go

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cns/restserver/ibdevice.go

Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
// Copyright 2017 Microsoft. All rights reserved.
2+
// MIT License
3+
4+
package restserver
5+
6+
import (
7+
"fmt"
8+
"sync"
9+
"time"
10+
11+
"github.com/Azure/azure-container-networking/cns/logger"
12+
"github.com/Azure/azure-container-networking/cns/types"
13+
)
14+
15+
// IBDeviceState represents the state of an InfiniBand device
16+
type IBDeviceState int
17+
18+
const (
19+
IBDeviceAvailable IBDeviceState = iota
20+
IBDeviceAssigned
21+
IBDevicePendingRelease
22+
)
23+
24+
func (s IBDeviceState) String() string {
25+
switch s {
26+
case IBDeviceAvailable:
27+
return "available"
28+
case IBDeviceAssigned:
29+
return "assigned"
30+
case IBDevicePendingRelease:
31+
return "pendingrelease"
32+
default:
33+
return "unknown"
34+
}
35+
}
36+
37+
// IBDeviceInfo contains information about an InfiniBand device
38+
type IBDeviceInfo struct {
39+
DeviceID string `json:"deviceID"`
40+
MacAddress string `json:"macAddress"`
41+
State IBDeviceState `json:"state"`
42+
PodID string `json:"podID,omitempty"`
43+
AssignedAt time.Time `json:"assignedAt,omitempty"`
44+
LastStateTransition time.Time `json:"lastStateTransition"`
45+
ErrorCode int `json:"errorCode"`
46+
ErrorMessage string `json:"errorMessage,omitempty"`
47+
mu sync.RWMutex `json:"-"`
48+
}
49+
50+
// SetState updates the device state and timestamp
51+
func (d *IBDeviceInfo) SetState(newState IBDeviceState) {
52+
d.mu.Lock()
53+
defer d.mu.Unlock()
54+
d.State = newState
55+
d.LastStateTransition = time.Now()
56+
}
57+
58+
// GetState returns the current device state
59+
func (d *IBDeviceInfo) GetState() IBDeviceState {
60+
d.mu.RLock()
61+
defer d.mu.RUnlock()
62+
return d.State
63+
}
64+
65+
// Assign assigns the device to a pod
66+
func (d *IBDeviceInfo) Assign(podID string) {
67+
d.mu.Lock()
68+
defer d.mu.Unlock()
69+
d.PodID = podID
70+
d.State = IBDeviceAssigned
71+
d.AssignedAt = time.Now()
72+
d.LastStateTransition = time.Now()
73+
d.ErrorCode = 0
74+
d.ErrorMessage = ""
75+
}
76+
77+
// Release releases the device from a pod
78+
func (d *IBDeviceInfo) Release() {
79+
d.mu.Lock()
80+
defer d.mu.Unlock()
81+
d.PodID = ""
82+
d.State = IBDeviceAvailable
83+
d.AssignedAt = time.Time{}
84+
d.LastStateTransition = time.Now()
85+
d.ErrorCode = 0
86+
d.ErrorMessage = ""
87+
}
88+
89+
// SetError sets an error state for the device
90+
func (d *IBDeviceInfo) SetError(code int, message string) {
91+
d.mu.Lock()
92+
defer d.mu.Unlock()
93+
d.ErrorCode = code
94+
d.ErrorMessage = message
95+
d.LastStateTransition = time.Now()
96+
}
97+
98+
// IBDeviceManager manages the state of InfiniBand devices
99+
type IBDeviceManager struct {
100+
devices map[string]*IBDeviceInfo // deviceID -> device info
101+
podDevices map[string][]string // podID -> list of deviceIDs
102+
devicesByMac map[string]string // macAddress -> deviceID
103+
mu sync.RWMutex
104+
}
105+
106+
// NewIBDeviceManager creates a new IB device manager
107+
func NewIBDeviceManager() *IBDeviceManager {
108+
return &IBDeviceManager{
109+
devices: make(map[string]*IBDeviceInfo),
110+
podDevices: make(map[string][]string),
111+
devicesByMac: make(map[string]string),
112+
}
113+
}
114+
115+
// RegisterDevice registers a new IB device
116+
func (m *IBDeviceManager) RegisterDevice(deviceID, macAddress string) error {
117+
m.mu.Lock()
118+
defer m.mu.Unlock()
119+
120+
// Check if device already exists
121+
if _, exists := m.devices[deviceID]; exists {
122+
logger.Printf("[IBDeviceManager] Device %s already registered", deviceID)
123+
return nil
124+
}
125+
126+
// Check if MAC address is already registered
127+
if existingDeviceID, exists := m.devicesByMac[macAddress]; exists {
128+
logger.Printf("[IBDeviceManager] MAC address %s already registered to device %s", macAddress, existingDeviceID)
129+
return nil
130+
}
131+
132+
device := &IBDeviceInfo{
133+
DeviceID: deviceID,
134+
MacAddress: macAddress,
135+
State: IBDeviceAvailable,
136+
LastStateTransition: time.Now(),
137+
ErrorCode: 0,
138+
}
139+
140+
m.devices[deviceID] = device
141+
m.devicesByMac[macAddress] = deviceID
142+
143+
logger.Printf("[IBDeviceManager] Registered device %s with MAC %s", deviceID, macAddress)
144+
return nil
145+
}
146+
147+
// GetDevice returns device information by device ID
148+
func (m *IBDeviceManager) GetDevice(deviceID string) (*IBDeviceInfo, bool) {
149+
m.mu.RLock()
150+
defer m.mu.RUnlock()
151+
152+
device, exists := m.devices[deviceID]
153+
if !exists {
154+
return nil, false
155+
}
156+
157+
// Return a copy to avoid race conditions
158+
deviceCopy := *device
159+
return &deviceCopy, true
160+
}
161+
162+
// GetDeviceByMac returns device information by MAC address
163+
func (m *IBDeviceManager) GetDeviceByMac(macAddress string) (*IBDeviceInfo, bool) {
164+
m.mu.RLock()
165+
defer m.mu.RUnlock()
166+
167+
deviceID, exists := m.devicesByMac[macAddress]
168+
if !exists {
169+
return nil, false
170+
}
171+
172+
device, exists := m.devices[deviceID]
173+
if !exists {
174+
return nil, false
175+
}
176+
177+
// Return a copy to avoid race conditions
178+
deviceCopy := *device
179+
return &deviceCopy, true
180+
}
181+
182+
// AssignDevicesToPod assigns multiple devices to a pod
183+
func (m *IBDeviceManager) AssignDevicesToPod(podID string, deviceIDs []string) (types.ResponseCode, string) {
184+
m.mu.Lock()
185+
defer m.mu.Unlock()
186+
187+
// Validate all devices first
188+
for _, deviceID := range deviceIDs {
189+
device, exists := m.devices[deviceID]
190+
if !exists {
191+
return types.NotFound, "Device " + deviceID + " not found"
192+
}
193+
194+
if device.GetState() != IBDeviceAvailable {
195+
if device.GetState() == IBDeviceAssigned {
196+
return types.InvalidRequest, "Device " + deviceID + " is already assigned to pod " + device.PodID
197+
}
198+
return types.InvalidRequest, "Device " + deviceID + " is not available (state: " + device.GetState().String() + ")"
199+
}
200+
}
201+
202+
// Check if pod already has devices assigned
203+
if existingDevices, exists := m.podDevices[podID]; exists && len(existingDevices) > 0 {
204+
return types.InvalidRequest, "Pod " + podID + " already has devices assigned"
205+
}
206+
207+
// Assign all devices
208+
assignedDevices := make([]string, 0, len(deviceIDs))
209+
for _, deviceID := range deviceIDs {
210+
device := m.devices[deviceID]
211+
device.Assign(podID)
212+
assignedDevices = append(assignedDevices, deviceID)
213+
logger.Printf("[IBDeviceManager] Assigned device %s to pod %s", deviceID, podID)
214+
}
215+
216+
// Update pod device mapping
217+
m.podDevices[podID] = assignedDevices
218+
219+
return types.Success, "Successfully assigned " + fmt.Sprintf("%d", len(deviceIDs)) + " devices to pod " + podID
220+
}
221+
222+
// ReleaseDevicesFromPod releases all devices assigned to a pod
223+
func (m *IBDeviceManager) ReleaseDevicesFromPod(podID string) (types.ResponseCode, string) {
224+
m.mu.Lock()
225+
defer m.mu.Unlock()
226+
227+
deviceIDs, exists := m.podDevices[podID]
228+
if !exists || len(deviceIDs) == 0 {
229+
return types.NotFound, "No devices assigned to pod " + podID
230+
}
231+
232+
// Release all devices
233+
for _, deviceID := range deviceIDs {
234+
if device, exists := m.devices[deviceID]; exists {
235+
device.Release()
236+
logger.Printf("[IBDeviceManager] Released device %s from pod %s", deviceID, podID)
237+
}
238+
}
239+
240+
// Remove pod device mapping
241+
delete(m.podDevices, podID)
242+
243+
return types.Success, "Successfully released devices from pod " + podID
244+
}
245+
246+
// GetPodDevices returns the list of devices assigned to a pod
247+
func (m *IBDeviceManager) GetPodDevices(podID string) []string {
248+
m.mu.RLock()
249+
defer m.mu.RUnlock()
250+
251+
if devices, exists := m.podDevices[podID]; exists {
252+
// Return a copy
253+
result := make([]string, len(devices))
254+
copy(result, devices)
255+
return result
256+
}
257+
258+
return nil
259+
}
260+
261+
// GetAvailableDevices returns a list of available devices
262+
func (m *IBDeviceManager) GetAvailableDevices() []string {
263+
m.mu.RLock()
264+
defer m.mu.RUnlock()
265+
266+
var available []string
267+
for deviceID, device := range m.devices {
268+
if device.GetState() == IBDeviceAvailable {
269+
available = append(available, deviceID)
270+
}
271+
}
272+
273+
return available
274+
}
275+
276+
// GetAssignedDevices returns a list of assigned devices
277+
func (m *IBDeviceManager) GetAssignedDevices() []string {
278+
m.mu.RLock()
279+
defer m.mu.RUnlock()
280+
281+
var assigned []string
282+
for deviceID, device := range m.devices {
283+
if device.GetState() == IBDeviceAssigned {
284+
assigned = append(assigned, deviceID)
285+
}
286+
}
287+
288+
return assigned
289+
}
290+
291+
// IsValidMacAddress validates MAC address format
292+
func IsValidMacAddress(mac string) bool {
293+
if len(mac) != 17 {
294+
return false
295+
}
296+
297+
for i, c := range mac {
298+
if i%3 == 2 {
299+
if c != ':' {
300+
return false
301+
}
302+
} else {
303+
if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
304+
return false
305+
}
306+
}
307+
}
308+
309+
return true
310+
}
311+
312+
// GetIBDeviceManager returns the IB device manager
313+
func (service *HTTPRestService) GetIBDeviceManager() *IBDeviceManager {
314+
return service.ibDeviceManager
315+
}

examples/cns-ibdevice-client/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func exampleGRPCClient() {
5656
log.Printf("AssignIBDevicesToPod failed: %v", err)
5757
} else {
5858
log.Printf("Assignment result: code=%d, message=%s",
59-
assignResp.CnsCode, assignResp.Message)
59+
assignResp.ErrorCode, assignResp.Message)
6060
}
6161

6262
// Example 2: Get device info

0 commit comments

Comments
 (0)