fpga: set container annotations

Plugin sets container annotation com.intel.fpga.mode to
intel.com/fpga-region in region mode.

This should allow to configure CRI-O to run reprogramming hooks
only when annotation is set.
This commit is contained in:
Ed Bartosh 2018-06-29 14:46:48 +03:00
parent 0bbc22ba15
commit cbd7173b1f
2 changed files with 34 additions and 8 deletions

View File

@ -40,6 +40,7 @@ const (
// Device plugin settings.
pluginEndpointPrefix = "intel-fpga"
resourceNamePrefix = "intel.com/fpga"
annotationName = "com.intel.fpga.mode"
)
// deviceManager manages Intel FPGA devices.
@ -47,14 +48,16 @@ type deviceManager struct {
srv deviceplugin.Server
fpgaID string
name string
mode string
ch chan map[string]deviceplugin.DeviceInfo
devices map[string]deviceplugin.DeviceInfo
}
func newDeviceManager(resourceName string, fpgaID string, ch chan map[string]deviceplugin.DeviceInfo) *deviceManager {
func newDeviceManager(resourceName string, fpgaID string, mode string, ch chan map[string]deviceplugin.DeviceInfo) *deviceManager {
return &deviceManager{
fpgaID: fpgaID,
name: resourceName,
mode: mode,
ch: ch,
devices: make(map[string]deviceplugin.DeviceInfo),
}
@ -86,7 +89,16 @@ func (dm *deviceManager) ListAndWatch(empty *pluginapi.Empty, stream pluginapi.D
}
func (dm *deviceManager) Allocate(ctx context.Context, rqt *pluginapi.AllocateRequest) (*pluginapi.AllocateResponse, error) {
return deviceplugin.MakeAllocateResponse(rqt, dm.devices)
response, err := deviceplugin.MakeAllocateResponse(rqt, dm.devices)
// Set container annotations when programming is allowed
if dm.mode == devicecache.RegionMode {
for _, containerResponse := range response.GetContainerResponses() {
containerResponse.Annotations = map[string]string{
annotationName: fmt.Sprintf("%s-%s", resourceNamePrefix, dm.mode),
}
}
}
return response, err
}
func (dm *deviceManager) PreStartContainer(ctx context.Context, rqt *pluginapi.PreStartContainerRequest) (*pluginapi.PreStartContainerResponse, error) {
@ -101,13 +113,13 @@ func startDeviceManager(dm *deviceManager, pluginPrefix string) {
}
}
func handleUpdate(dms map[string]*deviceManager, updateInfo devicecache.UpdateInfo, start func(*deviceManager, string)) {
func handleUpdate(dms map[string]*deviceManager, updateInfo devicecache.UpdateInfo, start func(*deviceManager, string), mode string) {
glog.V(2).Info("Received dev updates: ", updateInfo)
for fpgaID, devices := range updateInfo.Added {
devCh := make(chan map[string]deviceplugin.DeviceInfo, 1)
resourceName := resourceNamePrefix + "-" + fpgaID
pPrefix := pluginEndpointPrefix + "-" + fpgaID
dms[fpgaID] = newDeviceManager(resourceName, fpgaID, devCh)
dms[fpgaID] = newDeviceManager(resourceName, fpgaID, mode, devCh)
go start(dms[fpgaID], pPrefix)
devCh <- devices
}
@ -180,6 +192,6 @@ func main() {
dms := make(map[string]*deviceManager)
for updateInfo := range updatesCh {
handleUpdate(dms, updateInfo, startDeviceManager)
handleUpdate(dms, updateInfo, startDeviceManager, mode)
}
}

View File

@ -114,7 +114,7 @@ func TestListAndWatch(t *testing.T) {
for _, tt := range tcases {
devCh := make(chan map[string]deviceplugin.DeviceInfo, len(tt.updates))
testDM := newDeviceManager("intel.com/fpgatest-fpgaID", "fpgaID", devCh)
testDM := newDeviceManager("intel.com/fpgatest-fpgaID", "fpgaID", devicecache.AfMode, devCh)
server := &listAndWatchServerStub{
testDM: testDM,
@ -139,7 +139,7 @@ func TestListAndWatch(t *testing.T) {
}
func TestAllocate(t *testing.T) {
testDM := newDeviceManager("", "", nil)
testDM := newDeviceManager("", "", devicecache.RegionMode, nil)
if testDM == nil {
t.Fatal("Failed to create a deviceManager")
}
@ -164,6 +164,20 @@ func TestAllocate(t *testing.T) {
if len(resp.ContainerResponses[0].Devices) != 1 {
t.Fatal("Allocated wrong number of devices")
}
if len(resp.ContainerResponses[0].Annotations) != 1 {
t.Fatal("Set wrong number of annotations")
}
annotation, ok := resp.ContainerResponses[0].Annotations[annotationName]
if ok == false {
t.Fatalf("%s annotation is not set", annotationName)
}
expectedAnnotationValue := fmt.Sprintf("%s-%s", resourceNamePrefix, devicecache.RegionMode)
if annotation != expectedAnnotationValue {
t.Fatalf("Set wrong %s annotation value %s, should be %s", resourceNamePrefix, annotation, expectedAnnotationValue)
}
}
func startDeviceManagerStub(dm *deviceManager, pluginPrefix string) {
@ -238,7 +252,7 @@ func TestHandleUpdate(t *testing.T) {
if tt.dms == nil {
tt.dms = make(map[string]*deviceManager)
}
handleUpdate(tt.dms, tt.updateInfo, startDeviceManagerStub)
handleUpdate(tt.dms, tt.updateInfo, startDeviceManagerStub, devicecache.AfMode)
if len(tt.dms) != tt.expectedDMs {
t.Errorf("Test case '%s': expected %d runnig device managers, but got %d",
tt.name, tt.expectedDMs, len(tt.dms))