mirror of
https://github.com/intel/intel-device-plugins-for-kubernetes.git
synced 2025-06-03 03:59:37 +00:00
Merge pull request #358 from rojkov/webhook-modeless
fpga: make admission webhook mode-less
This commit is contained in:
commit
8b429fd99d
2
DEVEL.md
2
DEVEL.md
@ -162,7 +162,7 @@ https://github.com/kubernetes/code-generator/blob/master/generate-groups.sh
|
||||
```
|
||||
$ generate-groups.sh all github.com/intel/intel-device-plugins-for-kubernetes/pkg/client \
|
||||
github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis \
|
||||
fpga.intel.com:v1
|
||||
fpga.intel.com:v2
|
||||
```
|
||||
|
||||
Please note that the script (at least of v0.18.2-beta.0) expects the device plugins
|
||||
|
@ -30,16 +30,6 @@ The admission controller also keeps the user from bypassing namespaced mapping r
|
||||
by denying admission of any pods that are trying to use internal knowledge of InterfaceID or
|
||||
Bitstream ID environment variables used by the prestart hook.
|
||||
|
||||
The admission controller can operate in two separate modes - preprogrammed or orchestration programmed.
|
||||
The mode must be chosen to match that of the [FPGA plugin](../fpga_plugin/README.md) configuraton, as
|
||||
shown in the following table:
|
||||
|
||||
| FPGA plugin mode | matching admission controller mode |
|
||||
|:---------------- |:---------------------------------- |
|
||||
| region | orchestrated |
|
||||
| af | preprogrammed |
|
||||
|
||||
|
||||
# Dependencies
|
||||
|
||||
This component is one of a set of components that work together. You may also want to
|
||||
@ -118,14 +108,6 @@ Register webhook
|
||||
mutatingwebhookconfiguration.admissionregistration.k8s.io/fpga-mutator-webhook-cfg created
|
||||
```
|
||||
|
||||
By default, the script deploys the webhook in a preprogrammed mode.
|
||||
|
||||
Use the option `--mode` script option to deploy the webhook in orchestrated mode:
|
||||
|
||||
```bash
|
||||
$ ./scripts/webhook-deploy.sh --mode orchestrated
|
||||
```
|
||||
|
||||
The script needs the CA bundle used for signing certificate requests in your cluster.
|
||||
By default, the script fetches the bundle stored in the configmap
|
||||
`extension-apiserver-authentication`. However, your cluster may use a different signing
|
||||
@ -138,13 +120,41 @@ $ ./scripts/webhook-deploy.sh --ca-bundle-path /var/run/kubernetes/server-ca.crt
|
||||
|
||||
# Mappings
|
||||
|
||||
Requested FPGA resources are translated to AF resources. For example,
|
||||
`fpga.intel.com/arria10.dcp1.1-nlb0` is translated to `fpga.intel.com/af-d8424dc4a4a3c413f89e433683f9040b`.
|
||||
Mappings is a an essential part of the setup that gives a flexible instrument to a cluster
|
||||
administrator to manage FPGA bitstreams and to control access to them. Being a set of
|
||||
custom resource definitions they are used to configure the way FPGA resource requests get
|
||||
translated into actual resources provided by the cluster.
|
||||
|
||||
In orchestrated mode, `fpga.intel.com/arria10.dcp1.1-nlb0` gets translated to
|
||||
`fpga.intel.com/region-9926ab6d6c925a68aabca7d84c545738`, and, the corresponding AF IDs are set in
|
||||
environment variables for the container. The [FPGA CRI-O hook](../fpga_crihook/README.md)
|
||||
then loads the requested bitstream to a region before the container is started.
|
||||
For the following mapping
|
||||
|
||||
```yaml
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: arria10.dcp1.2-nlb0-preprogrammed
|
||||
spec:
|
||||
afuId: d8424dc4a4a3c413f89e433683f9040b
|
||||
interfaceId: 69528db6eb31577a8c3668f9faa081f6
|
||||
mode: af
|
||||
```
|
||||
|
||||
requested FPGA resources are translated to AF resources. For example,
|
||||
`fpga.intel.com/arria10.dcp1.2-nlb0-preprogrammed` is translated to
|
||||
`fpga.intel.com/af-695.d84.aVKNtusxV3qMNmj5-qCB9thCTcSko8QT-J5DNoP5BAs` where the `af-`
|
||||
prefix indicates the plugin's mode (`af`), `695` is the first three characters of
|
||||
the region interface ID, `d84` is the first three characters of the accelerator function ID
|
||||
and the last part `aVKNtusxV3qMNmj5-qCB9thCTcSko8QT-J5DNoP5BAs` is a base64-encoded concatenation
|
||||
of the full region interface ID and accelerator function ID.
|
||||
The format of resource names (e.g. `arria10.dcp1.2-nlb0-preprogrammed`) can be any and is up
|
||||
to a cluster administrator.
|
||||
|
||||
The same mapping, but with its mode field set to `region`, would translate
|
||||
`fpga.intel.com/arria10.dcp1.2-nlb0-preprogrammed` to `fpga.intel.com/region-69528db6eb31577a8c3668f9faa081f6`,
|
||||
and the corresponding AF IDs are set in environment variables for the container.
|
||||
Though in this case the cluster administrator would probably want to rename
|
||||
the mapping `arria10.dcp1.2-nlb0-preprogrammed` to something like `arria10.dcp1.2-nlb0-orchestrated`
|
||||
to reflect its mode. The [FPGA CRI-O hook](../fpga_crihook/README.md) then loads the requested
|
||||
bitstream to a region before the container is started.
|
||||
|
||||
Mappings of resource names are configured with objects of `AcceleratorFunction` and
|
||||
`FpgaRegion` custom resource definitions found respectively in
|
||||
|
@ -29,7 +29,7 @@ import (
|
||||
|
||||
clientset "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/clientset/versioned"
|
||||
informers "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/informers/externalversions"
|
||||
listers "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/listers/fpga.intel.com/v1"
|
||||
listers "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/listers/fpga.intel.com/v2"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -42,7 +42,7 @@ type fpgaObjectKey struct {
|
||||
}
|
||||
|
||||
type controller struct {
|
||||
patcherManager *patcherManager
|
||||
patcherManager patcherManager
|
||||
informerFactory informers.SharedInformerFactory
|
||||
afsSynced cache.InformerSynced
|
||||
regionsSynced cache.InformerSynced
|
||||
@ -52,7 +52,7 @@ type controller struct {
|
||||
stopCh chan struct{}
|
||||
}
|
||||
|
||||
func newController(patcherManager *patcherManager, config *rest.Config) (*controller, error) {
|
||||
func newController(patcherManager patcherManager, config *rest.Config) (*controller, error) {
|
||||
clientset, err := clientset.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to create REST clientset")
|
||||
@ -61,8 +61,8 @@ func newController(patcherManager *patcherManager, config *rest.Config) (*contro
|
||||
informerFactory := informers.NewSharedInformerFactory(clientset, resyncPeriod)
|
||||
stopCh := make(chan struct{})
|
||||
|
||||
afInformer := informerFactory.Fpga().V1().AcceleratorFunctions()
|
||||
regionInformer := informerFactory.Fpga().V1().FpgaRegions()
|
||||
afInformer := informerFactory.Fpga().V2().AcceleratorFunctions()
|
||||
regionInformer := informerFactory.Fpga().V2().FpgaRegions()
|
||||
|
||||
controller := &controller{
|
||||
patcherManager: patcherManager,
|
||||
@ -172,11 +172,7 @@ func (c *controller) syncAfHandler(key string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
patcher, err := c.patcherManager.getPatcher(namespace)
|
||||
if err != nil {
|
||||
runtime.HandleError(errors.Wrapf(err, "can't get patcher for namespace %s", namespace))
|
||||
return nil
|
||||
}
|
||||
patcher := c.patcherManager.getPatcher(namespace)
|
||||
|
||||
// Get the AcceleratorFunction resource with this namespace/name
|
||||
af, err := c.afLister.AcceleratorFunctions(namespace).Get(name)
|
||||
@ -194,8 +190,7 @@ func (c *controller) syncAfHandler(key string) error {
|
||||
}
|
||||
|
||||
klog.V(4).Info("Received", af)
|
||||
patcher.addAf(af)
|
||||
return nil
|
||||
return patcher.addAf(af)
|
||||
}
|
||||
|
||||
func (c *controller) syncRegionHandler(key string) error {
|
||||
@ -206,11 +201,7 @@ func (c *controller) syncRegionHandler(key string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
patcher, err := c.patcherManager.getPatcher(namespace)
|
||||
if err != nil {
|
||||
runtime.HandleError(errors.Wrapf(err, "can't get patcher for namespace %s", namespace))
|
||||
return nil
|
||||
}
|
||||
patcher := c.patcherManager.getPatcher(namespace)
|
||||
|
||||
// Get the FpgaRegion resource with this namespace/name
|
||||
region, err := c.regionLister.FpgaRegions(namespace).Get(name)
|
||||
|
@ -24,12 +24,12 @@ import (
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
v1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v1"
|
||||
listers "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/listers/fpga.intel.com/v1"
|
||||
v2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v2"
|
||||
listers "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/listers/fpga.intel.com/v2"
|
||||
)
|
||||
|
||||
type fakeAfNamespaceLister struct {
|
||||
af *v1.AcceleratorFunction
|
||||
af *v2.AcceleratorFunction
|
||||
err error
|
||||
}
|
||||
|
||||
@ -37,16 +37,16 @@ func init() {
|
||||
flag.Set("v", "4") ///Enable debug output
|
||||
}
|
||||
|
||||
func (nl *fakeAfNamespaceLister) Get(name string) (*v1.AcceleratorFunction, error) {
|
||||
func (nl *fakeAfNamespaceLister) Get(name string) (*v2.AcceleratorFunction, error) {
|
||||
return nl.af, nl.err
|
||||
}
|
||||
|
||||
func (nl *fakeAfNamespaceLister) List(selector labels.Selector) (ret []*v1.AcceleratorFunction, err error) {
|
||||
func (nl *fakeAfNamespaceLister) List(selector labels.Selector) (ret []*v2.AcceleratorFunction, err error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type fakeAfLister struct {
|
||||
af *v1.AcceleratorFunction
|
||||
af *v2.AcceleratorFunction
|
||||
err error
|
||||
}
|
||||
|
||||
@ -57,17 +57,16 @@ func (l *fakeAfLister) AcceleratorFunctions(namespace string) listers.Accelerato
|
||||
}
|
||||
}
|
||||
|
||||
func (l *fakeAfLister) List(selector labels.Selector) (ret []*v1.AcceleratorFunction, err error) {
|
||||
func (l *fakeAfLister) List(selector labels.Selector) (ret []*v2.AcceleratorFunction, err error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func TestSyncAfHandler(t *testing.T) {
|
||||
tcases := []struct {
|
||||
name string
|
||||
key string
|
||||
afLister *fakeAfLister
|
||||
patcherManagerIsBroken bool
|
||||
expectedErr bool
|
||||
name string
|
||||
key string
|
||||
afLister *fakeAfLister
|
||||
expectedErr bool
|
||||
}{
|
||||
{
|
||||
name: "Wrong key format",
|
||||
@ -77,21 +76,16 @@ func TestSyncAfHandler(t *testing.T) {
|
||||
name: "Known key",
|
||||
key: "default/arria10-nlb0",
|
||||
afLister: &fakeAfLister{
|
||||
af: &v1.AcceleratorFunction{
|
||||
af: &v2.AcceleratorFunction{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "arria10-nlb0",
|
||||
},
|
||||
Spec: v1.AcceleratorFunctionSpec{
|
||||
Spec: v2.AcceleratorFunctionSpec{
|
||||
AfuID: "d8424dc4a4a3c413f89e433683f9040b",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Broken patcher manager",
|
||||
key: "default/arria10-nlb0",
|
||||
patcherManagerIsBroken: true,
|
||||
},
|
||||
{
|
||||
name: "Unknown key",
|
||||
key: "default/unknown",
|
||||
@ -107,13 +101,7 @@ func TestSyncAfHandler(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tt := range tcases {
|
||||
pm, err := newPatcherManager(preprogrammed)
|
||||
if err != nil {
|
||||
t.Fatalf("Test case '%s': %+v", tt.name, err)
|
||||
}
|
||||
if tt.patcherManagerIsBroken {
|
||||
pm.defaultMode = "broken"
|
||||
}
|
||||
pm := newPatcherManager()
|
||||
c, err := newController(pm, &rest.Config{})
|
||||
if err != nil {
|
||||
t.Fatalf("Test case '%s': %+v", tt.name, err)
|
||||
@ -132,20 +120,20 @@ func TestSyncAfHandler(t *testing.T) {
|
||||
}
|
||||
|
||||
type fakeRegionNamespaceLister struct {
|
||||
region *v1.FpgaRegion
|
||||
region *v2.FpgaRegion
|
||||
err error
|
||||
}
|
||||
|
||||
func (nl *fakeRegionNamespaceLister) Get(name string) (*v1.FpgaRegion, error) {
|
||||
func (nl *fakeRegionNamespaceLister) Get(name string) (*v2.FpgaRegion, error) {
|
||||
return nl.region, nl.err
|
||||
}
|
||||
|
||||
func (nl *fakeRegionNamespaceLister) List(selector labels.Selector) (ret []*v1.FpgaRegion, err error) {
|
||||
func (nl *fakeRegionNamespaceLister) List(selector labels.Selector) (ret []*v2.FpgaRegion, err error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type fakeRegionLister struct {
|
||||
region *v1.FpgaRegion
|
||||
region *v2.FpgaRegion
|
||||
err error
|
||||
}
|
||||
|
||||
@ -156,17 +144,16 @@ func (l *fakeRegionLister) FpgaRegions(namespace string) listers.FpgaRegionNames
|
||||
}
|
||||
}
|
||||
|
||||
func (l *fakeRegionLister) List(selector labels.Selector) (ret []*v1.FpgaRegion, err error) {
|
||||
func (l *fakeRegionLister) List(selector labels.Selector) (ret []*v2.FpgaRegion, err error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func TestSyncRegionHandler(t *testing.T) {
|
||||
tcases := []struct {
|
||||
name string
|
||||
key string
|
||||
patcherManagerIsBroken bool
|
||||
regionLister *fakeRegionLister
|
||||
expectedErr bool
|
||||
name string
|
||||
key string
|
||||
regionLister *fakeRegionLister
|
||||
expectedErr bool
|
||||
}{
|
||||
{
|
||||
name: "Wrong key format",
|
||||
@ -176,21 +163,16 @@ func TestSyncRegionHandler(t *testing.T) {
|
||||
name: "Known key",
|
||||
key: "default/arria10",
|
||||
regionLister: &fakeRegionLister{
|
||||
region: &v1.FpgaRegion{
|
||||
region: &v2.FpgaRegion{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "arria10",
|
||||
},
|
||||
Spec: v1.FpgaRegionSpec{
|
||||
Spec: v2.FpgaRegionSpec{
|
||||
InterfaceID: "ce48969398f05f33946d560708be108a",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Broken patcher manager",
|
||||
key: "default/arria10",
|
||||
patcherManagerIsBroken: true,
|
||||
},
|
||||
{
|
||||
name: "Unknown key",
|
||||
key: "default/unknown",
|
||||
@ -206,13 +188,7 @@ func TestSyncRegionHandler(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tt := range tcases {
|
||||
pm, err := newPatcherManager(preprogrammed)
|
||||
if err != nil {
|
||||
t.Fatalf("Test case '%s': %+v", tt.name, err)
|
||||
}
|
||||
if tt.patcherManagerIsBroken {
|
||||
pm.defaultMode = "broken"
|
||||
}
|
||||
pm := newPatcherManager()
|
||||
c, err := newController(pm, &rest.Config{})
|
||||
if err != nil {
|
||||
t.Fatalf("Test case '%s': %+v", tt.name, err)
|
||||
@ -328,7 +304,7 @@ func TestProcessNextWorkItem(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tcases {
|
||||
pm, _ := newPatcherManager(preprogrammed)
|
||||
pm := newPatcherManager()
|
||||
c, err := newController(pm, &rest.Config{})
|
||||
if err != nil {
|
||||
t.Fatalf("Test case '%s': %+v", tt.name, err)
|
||||
@ -352,9 +328,9 @@ func TestProcessNextWorkItem(t *testing.T) {
|
||||
|
||||
func TestCreateEventhandler(t *testing.T) {
|
||||
funcs := createEventHandler("testkind", &fakeQueue{})
|
||||
funcs.AddFunc(&v1.FpgaRegion{})
|
||||
funcs.UpdateFunc(nil, &v1.FpgaRegion{})
|
||||
funcs.DeleteFunc(&v1.FpgaRegion{})
|
||||
funcs.AddFunc(&v2.FpgaRegion{})
|
||||
funcs.UpdateFunc(nil, &v2.FpgaRegion{})
|
||||
funcs.DeleteFunc(&v2.FpgaRegion{})
|
||||
}
|
||||
|
||||
func TestRun(t *testing.T) {
|
||||
@ -369,7 +345,7 @@ func TestRun(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tt := range tcases {
|
||||
pm := &patcherManager{}
|
||||
pm := newPatcherManager()
|
||||
c, err := newController(pm, &rest.Config{})
|
||||
if err != nil {
|
||||
t.Fatalf("Test case '%s': %+v", tt.name, err)
|
||||
@ -404,7 +380,7 @@ func TestNewController(t *testing.T) {
|
||||
config := &rest.Config{
|
||||
Host: tt.configHost,
|
||||
}
|
||||
pm := &patcherManager{}
|
||||
pm := newPatcherManager()
|
||||
c, err := newController(pm, config)
|
||||
if err != nil && !tt.expectedErr {
|
||||
t.Errorf("Test case '%s': unexpected error: %+v", tt.name, err)
|
||||
|
@ -18,7 +18,6 @@ import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
@ -39,8 +38,6 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
preprogrammed = "preprogrammed"
|
||||
orchestrated = "orchestrated"
|
||||
controllerThreadNum = 1
|
||||
)
|
||||
|
||||
@ -69,7 +66,7 @@ func getTLSConfig(certFile string, keyFile string) *tls.Config {
|
||||
}
|
||||
}
|
||||
|
||||
func mutatePods(ar v1beta1.AdmissionReview, pm *patcherManager) *v1beta1.AdmissionResponse {
|
||||
func mutatePods(ar v1beta1.AdmissionReview, pm patcherManager) *v1beta1.AdmissionResponse {
|
||||
var ops []string
|
||||
|
||||
klog.V(4).Info("mutating pods")
|
||||
@ -97,11 +94,7 @@ func mutatePods(ar v1beta1.AdmissionReview, pm *patcherManager) *v1beta1.Admissi
|
||||
name = pod.ObjectMeta.GenerateName
|
||||
}
|
||||
klog.V(4).Infof("Received pod '%s' in name space '%s'", name, namespace)
|
||||
patcher, err := pm.getPatcher(namespace)
|
||||
if err != nil {
|
||||
klog.Warningf("%+v", err)
|
||||
return toAdmissionResponse(err)
|
||||
}
|
||||
patcher := pm.getPatcher(namespace)
|
||||
|
||||
reviewResponse := v1beta1.AdmissionResponse{}
|
||||
reviewResponse.Allowed = true
|
||||
@ -198,7 +191,7 @@ func serve(w http.ResponseWriter, r *http.Request, admit admitFunc) {
|
||||
}
|
||||
}
|
||||
|
||||
func makePodsHandler(pm *patcherManager) func(w http.ResponseWriter, r *http.Request) {
|
||||
func makePodsHandler(pm patcherManager) func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
serve(w, r, func(ar v1beta1.AdmissionReview) *v1beta1.AdmissionResponse {
|
||||
return mutatePods(ar, pm)
|
||||
@ -211,7 +204,6 @@ func main() {
|
||||
var master string
|
||||
var certFile string
|
||||
var keyFile string
|
||||
var mode string
|
||||
var config *rest.Config
|
||||
var err error
|
||||
|
||||
@ -220,7 +212,6 @@ func main() {
|
||||
flag.StringVar(&certFile, "tls-cert-file", certFile,
|
||||
"File containing the x509 Certificate for HTTPS. (CA cert, if any, concatenated after server cert).")
|
||||
flag.StringVar(&keyFile, "tls-private-key-file", keyFile, "File containing the x509 private key matching --tls-cert-file.")
|
||||
flag.StringVar(&mode, "mode", preprogrammed, fmt.Sprintf("webhook mode: '%s' (default) or '%s'", preprogrammed, orchestrated))
|
||||
flag.Parse()
|
||||
|
||||
if certFile == "" {
|
||||
@ -248,18 +239,15 @@ func main() {
|
||||
klog.Fatal("Failed to get cluster config ", err)
|
||||
}
|
||||
|
||||
patcherManager, err := newPatcherManager(mode)
|
||||
if err != nil {
|
||||
klog.Fatalf("%+v", err)
|
||||
}
|
||||
pm := newPatcherManager()
|
||||
|
||||
controller, err := newController(patcherManager, config)
|
||||
controller, err := newController(pm, config)
|
||||
if err != nil {
|
||||
klog.Fatalf("%+v", err)
|
||||
}
|
||||
go controller.run(controllerThreadNum)
|
||||
|
||||
http.HandleFunc("/pods", makePodsHandler(patcherManager))
|
||||
http.HandleFunc("/pods", makePodsHandler(pm))
|
||||
|
||||
klog.V(4).Info("Webhook started")
|
||||
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
fpgav2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v2"
|
||||
"k8s.io/api/admission/v1beta1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
@ -144,16 +145,39 @@ func TestMutatePods(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
brokenPod := corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
Containers: []corev1.Container{
|
||||
{
|
||||
Name: "test-container",
|
||||
Image: "test-image",
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Limits: corev1.ResourceList{
|
||||
"cpu": resource.MustParse("1"),
|
||||
"fpga.intel.com/arria10": resource.MustParse("1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
podRaw, err := json.Marshal(pod)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
brokenPodRaw, err := json.Marshal(brokenPod)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
tcases := []struct {
|
||||
name string
|
||||
mode string
|
||||
ar v1beta1.AdmissionReview
|
||||
expectedResponse bool
|
||||
expectedAllowed bool
|
||||
expectedPatchOps int
|
||||
}{
|
||||
{
|
||||
@ -161,7 +185,6 @@ func TestMutatePods(t *testing.T) {
|
||||
ar: v1beta1.AdmissionReview{
|
||||
Request: &v1beta1.AdmissionRequest{},
|
||||
},
|
||||
mode: preprogrammed,
|
||||
},
|
||||
{
|
||||
name: "admission request without object",
|
||||
@ -170,8 +193,8 @@ func TestMutatePods(t *testing.T) {
|
||||
Resource: metav1.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"},
|
||||
},
|
||||
},
|
||||
mode: preprogrammed,
|
||||
expectedResponse: true,
|
||||
expectedAllowed: true,
|
||||
},
|
||||
{
|
||||
name: "admission request with corrupted object",
|
||||
@ -183,11 +206,10 @@ func TestMutatePods(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
mode: preprogrammed,
|
||||
expectedResponse: true,
|
||||
},
|
||||
{
|
||||
name: "non-empty admission request in preprogrammed mode",
|
||||
name: "successful non-empty admission request",
|
||||
ar: v1beta1.AdmissionReview{
|
||||
Request: &v1beta1.AdmissionRequest{
|
||||
Resource: metav1.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"},
|
||||
@ -196,23 +218,9 @@ func TestMutatePods(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
mode: preprogrammed,
|
||||
expectedResponse: true,
|
||||
expectedPatchOps: 4,
|
||||
},
|
||||
{
|
||||
name: "non-empty admission request in orchestrated mode",
|
||||
ar: v1beta1.AdmissionReview{
|
||||
Request: &v1beta1.AdmissionRequest{
|
||||
Resource: metav1.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"},
|
||||
Object: runtime.RawExtension{
|
||||
Raw: podRaw,
|
||||
},
|
||||
},
|
||||
},
|
||||
mode: orchestrated,
|
||||
expectedResponse: true,
|
||||
expectedPatchOps: 5,
|
||||
expectedAllowed: true,
|
||||
},
|
||||
{
|
||||
name: "handle error after wrong getPatchOps()",
|
||||
@ -220,48 +228,54 @@ func TestMutatePods(t *testing.T) {
|
||||
Request: &v1beta1.AdmissionRequest{
|
||||
Resource: metav1.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"},
|
||||
Object: runtime.RawExtension{
|
||||
Raw: podRaw,
|
||||
Raw: brokenPodRaw,
|
||||
},
|
||||
},
|
||||
},
|
||||
mode: "unknown mode",
|
||||
expectedResponse: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tcase := range tcases {
|
||||
p := &patcher{
|
||||
mode: tcase.mode,
|
||||
regionMap: map[string]string{
|
||||
"arria10": "ce48969398f05f33946d560708be108a",
|
||||
},
|
||||
resourceMap: map[string]string{
|
||||
"fpga.intel.com/arria10": "ce48969398f05f33946d560708be108a",
|
||||
},
|
||||
}
|
||||
pm := &patcherManager{
|
||||
defaultMode: tcase.mode,
|
||||
patchers: map[string]*patcher{
|
||||
"default": p,
|
||||
},
|
||||
}
|
||||
resp := mutatePods(tcase.ar, pm)
|
||||
t.Run(tcase.name, func(t *testing.T) {
|
||||
p := newPatcher()
|
||||
p.addRegion(&fpgav2.FpgaRegion{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "arria10",
|
||||
},
|
||||
Spec: fpgav2.FpgaRegionSpec{
|
||||
InterfaceID: "ce48969398f05f33946d560708be108a",
|
||||
},
|
||||
})
|
||||
pm := newPatcherManager()
|
||||
pm["default"] = p
|
||||
resp := mutatePods(tcase.ar, pm)
|
||||
|
||||
if !tcase.expectedResponse && resp != nil {
|
||||
t.Errorf("Test case '%s': got unexpected response", tcase.name)
|
||||
} else if tcase.expectedResponse && resp == nil {
|
||||
t.Errorf("Test case '%s': got no response", tcase.name)
|
||||
} else if tcase.expectedResponse && tcase.expectedPatchOps > 0 {
|
||||
var ops interface{}
|
||||
actualPatchOps := 0
|
||||
if !tcase.expectedResponse && resp != nil {
|
||||
t.Errorf("Test case '%s': got unexpected response", tcase.name)
|
||||
} else if tcase.expectedResponse && resp == nil {
|
||||
t.Errorf("Test case '%s': got no response", tcase.name)
|
||||
} else if tcase.expectedResponse {
|
||||
if tcase.expectedAllowed != resp.Allowed {
|
||||
t.Errorf("Allowed expected to be %t but got %t", tcase.expectedAllowed, resp.Allowed)
|
||||
} else if resp.Allowed && resp.Patch != nil {
|
||||
var ops interface{}
|
||||
|
||||
err := json.Unmarshal(resp.Patch, &ops)
|
||||
if err != nil {
|
||||
t.Errorf("Test case '%s': got unparsable patch '%s'", tcase.name, resp.Patch)
|
||||
} else if len(ops.([]interface{})) != tcase.expectedPatchOps {
|
||||
t.Errorf("Test case '%s': got wrong number of operations in the patch. Expected %d, but got %d\n%s",
|
||||
tcase.name, tcase.expectedPatchOps, len(ops.([]interface{})), string(resp.Patch))
|
||||
err := json.Unmarshal(resp.Patch, &ops)
|
||||
if err != nil {
|
||||
t.Errorf("Test case '%s': got unparsable patch '%s'", tcase.name, resp.Patch)
|
||||
} else {
|
||||
actualPatchOps = len(ops.([]interface{}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if actualPatchOps != tcase.expectedPatchOps {
|
||||
t.Errorf("Test case '%s': got wrong number of operations in the patch. Expected %d, but got %d\n%s",
|
||||
tcase.name, tcase.expectedPatchOps, actualPatchOps, string(resp.Patch))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -280,6 +294,6 @@ func (*fakeResponseWriter) WriteHeader(int) {
|
||||
}
|
||||
|
||||
func TestMakePodsHandler(t *testing.T) {
|
||||
serveFunc := makePodsHandler(&patcherManager{})
|
||||
serveFunc := makePodsHandler(newPatcherManager())
|
||||
serveFunc(&fakeResponseWriter{}, &http.Request{})
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ package main
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"text/template"
|
||||
@ -27,20 +26,19 @@ import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/klog"
|
||||
|
||||
fpgav1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v1"
|
||||
fpgav2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v2"
|
||||
"github.com/intel/intel-device-plugins-for-kubernetes/pkg/fpga"
|
||||
)
|
||||
|
||||
const (
|
||||
namespace = "fpga.intel.com"
|
||||
|
||||
resourceReplaceOp = `{
|
||||
"op": "remove",
|
||||
"path": "/spec/containers/%d/resources/%s/%s"
|
||||
}, {
|
||||
"op": "add",
|
||||
"path": "/spec/containers/%d/resources/%s/%s",
|
||||
"value": %s
|
||||
}`
|
||||
af = "af"
|
||||
region = "region"
|
||||
// "regiondevel" corresponds to the FPGA plugin's regiondevel mode. It requires
|
||||
// FpgaRegion CRDs to be added to the cluster.
|
||||
regiondevel = "regiondevel"
|
||||
|
||||
resourceRemoveOp = `{
|
||||
"op": "remove",
|
||||
"path": "/spec/containers/%d/resources/%s/%s"
|
||||
@ -68,44 +66,49 @@ const (
|
||||
|
||||
var (
|
||||
rfc6901Escaper = strings.NewReplacer("~", "~0", "/", "~1")
|
||||
resourceRe = regexp.MustCompile(namespace + `/(?P<Region>[[:alnum:].]+)(-(?P<Af>[[:alnum:]]+))?`)
|
||||
)
|
||||
|
||||
type patcher struct {
|
||||
sync.Mutex
|
||||
|
||||
mode string
|
||||
regionMap map[string]string
|
||||
afMap map[string]string
|
||||
resourceMap map[string]string
|
||||
afMap map[string]*fpgav2.AcceleratorFunction
|
||||
resourceMap map[string]string
|
||||
resourceModeMap map[string]string
|
||||
}
|
||||
|
||||
func newPatcher(mode string) (*patcher, error) {
|
||||
if mode != preprogrammed && mode != orchestrated {
|
||||
return nil, errors.Errorf("Unknown mode: %s", mode)
|
||||
}
|
||||
|
||||
func newPatcher() *patcher {
|
||||
return &patcher{
|
||||
mode: mode,
|
||||
regionMap: make(map[string]string),
|
||||
afMap: make(map[string]string),
|
||||
resourceMap: make(map[string]string),
|
||||
}, nil
|
||||
afMap: make(map[string]*fpgav2.AcceleratorFunction),
|
||||
resourceMap: make(map[string]string),
|
||||
resourceModeMap: make(map[string]string),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *patcher) addAf(af *fpgav1.AcceleratorFunction) {
|
||||
func (p *patcher) addAf(accfunc *fpgav2.AcceleratorFunction) error {
|
||||
defer p.Unlock()
|
||||
p.Lock()
|
||||
|
||||
p.afMap[af.Name] = af.Spec.AfuID
|
||||
p.resourceMap[namespace+"/"+af.Name] = rfc6901Escaper.Replace(namespace + "/af-" + af.Spec.AfuID)
|
||||
p.afMap[namespace+"/"+accfunc.Name] = accfunc
|
||||
if accfunc.Spec.Mode == af {
|
||||
devtype, err := fpga.GetAfuDevType(accfunc.Spec.InterfaceID, accfunc.Spec.AfuID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.resourceMap[namespace+"/"+accfunc.Name] = rfc6901Escaper.Replace(namespace + "/" + devtype)
|
||||
} else {
|
||||
p.resourceMap[namespace+"/"+accfunc.Name] = rfc6901Escaper.Replace(namespace + "/region-" + accfunc.Spec.InterfaceID)
|
||||
}
|
||||
p.resourceModeMap[namespace+"/"+accfunc.Name] = accfunc.Spec.Mode
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *patcher) addRegion(region *fpgav1.FpgaRegion) {
|
||||
func (p *patcher) addRegion(region *fpgav2.FpgaRegion) {
|
||||
defer p.Unlock()
|
||||
p.Lock()
|
||||
|
||||
p.regionMap[region.Name] = region.Spec.InterfaceID
|
||||
p.resourceModeMap[namespace+"/"+region.Name] = regiondevel
|
||||
p.resourceMap[namespace+"/"+region.Name] = rfc6901Escaper.Replace(namespace + "/region-" + region.Spec.InterfaceID)
|
||||
}
|
||||
|
||||
@ -113,149 +116,138 @@ func (p *patcher) removeAf(name string) {
|
||||
defer p.Unlock()
|
||||
p.Lock()
|
||||
|
||||
delete(p.afMap, name)
|
||||
delete(p.afMap, namespace+"/"+name)
|
||||
delete(p.resourceMap, namespace+"/"+name)
|
||||
delete(p.resourceModeMap, namespace+"/"+name)
|
||||
}
|
||||
|
||||
func (p *patcher) removeRegion(name string) {
|
||||
defer p.Unlock()
|
||||
p.Lock()
|
||||
|
||||
delete(p.regionMap, name)
|
||||
delete(p.resourceMap, namespace+"/"+name)
|
||||
delete(p.resourceModeMap, namespace+"/"+name)
|
||||
}
|
||||
|
||||
// getRequestedResources validates the container's requirements first, then returns them as a map.
|
||||
func getRequestedResources(container corev1.Container) (map[string]int64, error) {
|
||||
for _, v := range container.Env {
|
||||
if strings.HasPrefix(v.Name, "FPGA_REGION") || strings.HasPrefix(v.Name, "FPGA_AFU") {
|
||||
return nil, errors.Errorf("environment variable '%s' is not allowed", v.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// Container may happen to have Requests, but not Limits. Check Requests first,
|
||||
// then in the next loop iterate over Limits.
|
||||
for resourceName, resourceQuantity := range container.Resources.Requests {
|
||||
rname := strings.ToLower(string(resourceName))
|
||||
if !strings.HasPrefix(rname, namespace) {
|
||||
// Skip non-FPGA resources in Requests.
|
||||
continue
|
||||
}
|
||||
|
||||
if container.Resources.Limits[resourceName] != resourceQuantity {
|
||||
return nil, errors.Errorf(
|
||||
"'limits' and 'requests' for %q must be equal as extended resources cannot be overcommitted",
|
||||
rname)
|
||||
}
|
||||
}
|
||||
|
||||
resources := make(map[string]int64)
|
||||
for resourceName, resourceQuantity := range container.Resources.Limits {
|
||||
rname := strings.ToLower(string(resourceName))
|
||||
if !strings.HasPrefix(rname, namespace) {
|
||||
// Skip non-FPGA resources in Limits.
|
||||
continue
|
||||
}
|
||||
|
||||
if container.Resources.Requests[resourceName] != resourceQuantity {
|
||||
return nil, errors.Errorf(
|
||||
"'limits' and 'requests' for %q must be equal as extended resources cannot be overcommitted",
|
||||
rname)
|
||||
}
|
||||
|
||||
quantity, ok := resourceQuantity.AsInt64()
|
||||
if !ok {
|
||||
return nil, errors.Errorf("resource quantity isn't of integral type for %q", rname)
|
||||
}
|
||||
|
||||
resources[rname] = quantity
|
||||
}
|
||||
|
||||
return resources, nil
|
||||
}
|
||||
|
||||
func (p *patcher) getPatchOps(containerIdx int, container corev1.Container) ([]string, error) {
|
||||
switch p.mode {
|
||||
case preprogrammed:
|
||||
return p.getPatchOpsPreprogrammed(containerIdx, container)
|
||||
case orchestrated:
|
||||
return p.getPatchOpsOrchestrated(containerIdx, container)
|
||||
}
|
||||
|
||||
return nil, errors.Errorf("Uknown mode: %s", p.mode)
|
||||
}
|
||||
|
||||
func (p *patcher) getPatchOpsPreprogrammed(containerIdx int, container corev1.Container) ([]string, error) {
|
||||
var ops []string
|
||||
|
||||
for resourceName, resourceQuantity := range container.Resources.Limits {
|
||||
newName, err := p.translateFpgaResourceName(resourceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(newName) > 0 {
|
||||
op := fmt.Sprintf(resourceReplaceOp, containerIdx,
|
||||
"limits", rfc6901Escaper.Replace(string(resourceName)),
|
||||
containerIdx, "limits", newName, resourceQuantity.String())
|
||||
ops = append(ops, op)
|
||||
}
|
||||
}
|
||||
for resourceName, resourceQuantity := range container.Resources.Requests {
|
||||
newName, err := p.translateFpgaResourceName(resourceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(newName) > 0 {
|
||||
op := fmt.Sprintf(resourceReplaceOp, containerIdx,
|
||||
"requests", rfc6901Escaper.Replace(string(resourceName)),
|
||||
containerIdx, "requests", newName, resourceQuantity.String())
|
||||
ops = append(ops, op)
|
||||
}
|
||||
}
|
||||
|
||||
return ops, nil
|
||||
}
|
||||
|
||||
func (p *patcher) translateFpgaResourceName(oldname corev1.ResourceName) (string, error) {
|
||||
rname := strings.ToLower(string(oldname))
|
||||
if !strings.HasPrefix(rname, namespace) {
|
||||
return "", nil
|
||||
requestedResources, err := getRequestedResources(container)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer p.Unlock()
|
||||
p.Lock()
|
||||
|
||||
if newname, ok := p.resourceMap[rname]; ok {
|
||||
return newname, nil
|
||||
}
|
||||
|
||||
return "", errors.Errorf("Unknown FPGA resource: %s", rname)
|
||||
}
|
||||
|
||||
func (p *patcher) checkResourceRequests(container corev1.Container) error {
|
||||
for resourceName, resourceQuantity := range container.Resources.Requests {
|
||||
interfaceID, _, err := p.parseResourceName(string(resourceName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if interfaceID == "" {
|
||||
// Skip non-FPGA resources
|
||||
continue
|
||||
}
|
||||
if container.Resources.Limits[resourceName] != resourceQuantity {
|
||||
return errors.Errorf("'limits' and 'requests' for %s must be equal", string(resourceName))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *patcher) getPatchOpsOrchestrated(containerIdx int, container corev1.Container) ([]string, error) {
|
||||
var ops []string
|
||||
|
||||
for _, v := range container.Env {
|
||||
if strings.HasPrefix(v.Name, "FPGA_REGION") || strings.HasPrefix(v.Name, "FPGA_AFU") {
|
||||
return nil, errors.Errorf("The environment variable '%s' is not allowed", v.Name)
|
||||
}
|
||||
}
|
||||
|
||||
if err := p.checkResourceRequests(container); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
regions := make(map[string]int64)
|
||||
fpgaPluginMode := ""
|
||||
resources := make(map[string]int64)
|
||||
envVars := make(map[string]string)
|
||||
counter := 0
|
||||
for resourceName, resourceQuantity := range container.Resources.Limits {
|
||||
interfaceID, afuID, err := p.parseResourceName(string(resourceName))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
for rname, quantity := range requestedResources {
|
||||
|
||||
mode, found := p.resourceModeMap[rname]
|
||||
if !found {
|
||||
return nil, errors.Errorf("no such resource: %q", rname)
|
||||
}
|
||||
|
||||
if interfaceID == "" && afuID == "" {
|
||||
// Skip non-FPGA resources
|
||||
continue
|
||||
switch mode {
|
||||
case regiondevel:
|
||||
// Do nothing.
|
||||
// The requested resources are exposed by FPGA plugins working in "regiondevel" mode.
|
||||
// In this mode the workload is supposed to program FPGA regions.
|
||||
// A cluster admin has to add FpgaRegion CRDs to allow this.
|
||||
case af:
|
||||
// Do nothing.
|
||||
// The requested resources are exposed by FPGA plugins working in "af" mode.
|
||||
case region:
|
||||
// Let fpga_crihook know how to program the regions by setting ENV variables.
|
||||
// The requested resources are exposed by FPGA plugins working in "region" mode.
|
||||
for i := int64(0); i < quantity; i++ {
|
||||
counter++
|
||||
envVars[fmt.Sprintf("FPGA_REGION_%d", counter)] = p.afMap[rname].Spec.InterfaceID
|
||||
envVars[fmt.Sprintf("FPGA_AFU_%d", counter)] = p.afMap[rname].Spec.AfuID
|
||||
}
|
||||
default:
|
||||
msg := fmt.Sprintf("%q is registered with unknown mode %q instead of %q or %q",
|
||||
rname, p.resourceModeMap[rname], af, region)
|
||||
// Let admin know about broken af CRD.
|
||||
klog.Error(msg)
|
||||
return nil, errors.New(msg)
|
||||
}
|
||||
|
||||
if container.Resources.Requests[resourceName] != resourceQuantity {
|
||||
return nil, errors.Errorf("'limits' and 'requests' for %s must be equal", string(resourceName))
|
||||
if fpgaPluginMode == "" {
|
||||
fpgaPluginMode = mode
|
||||
} else if fpgaPluginMode != mode {
|
||||
return nil, errors.New("container cannot be scheduled as it requires resources operated in different modes")
|
||||
}
|
||||
|
||||
quantity, ok := resourceQuantity.AsInt64()
|
||||
if !ok {
|
||||
return nil, errors.New("Resource quantity isn't of integral type")
|
||||
}
|
||||
regions[interfaceID] = regions[interfaceID] + quantity
|
||||
mappedName := p.resourceMap[rname]
|
||||
resources[mappedName] = resources[mappedName] + quantity
|
||||
|
||||
for i := int64(0); i < quantity; i++ {
|
||||
counter++
|
||||
envVars[fmt.Sprintf("FPGA_REGION_%d", counter)] = interfaceID
|
||||
envVars[fmt.Sprintf("FPGA_AFU_%d", counter)] = afuID
|
||||
}
|
||||
|
||||
ops = append(ops, fmt.Sprintf(resourceRemoveOp, containerIdx, "limits", rfc6901Escaper.Replace(string(resourceName))))
|
||||
ops = append(ops, fmt.Sprintf(resourceRemoveOp, containerIdx, "requests", rfc6901Escaper.Replace(string(resourceName))))
|
||||
// Add operations to remove unresolved resources from the pod.
|
||||
ops = append(ops, fmt.Sprintf(resourceRemoveOp, containerIdx, "limits", rfc6901Escaper.Replace(rname)))
|
||||
ops = append(ops, fmt.Sprintf(resourceRemoveOp, containerIdx, "requests", rfc6901Escaper.Replace(rname)))
|
||||
}
|
||||
|
||||
for interfaceID, quantity := range regions {
|
||||
op := fmt.Sprintf(resourceAddOp, containerIdx, "limits", rfc6901Escaper.Replace(namespace+"/region-"+interfaceID), quantity)
|
||||
// Add operations to add resolved resources to the pod.
|
||||
for resource, quantity := range resources {
|
||||
op := fmt.Sprintf(resourceAddOp, containerIdx, "limits", resource, quantity)
|
||||
ops = append(ops, op)
|
||||
op = fmt.Sprintf(resourceAddOp, containerIdx, "requests", rfc6901Escaper.Replace(namespace+"/region-"+interfaceID), quantity)
|
||||
op = fmt.Sprintf(resourceAddOp, containerIdx, "requests", resource, quantity)
|
||||
ops = append(ops, op)
|
||||
}
|
||||
|
||||
// Add the ENV variables to the pod if needed.
|
||||
if len(envVars) > 0 {
|
||||
for _, envvar := range container.Env {
|
||||
envVars[envvar.Name] = envvar.Value
|
||||
@ -276,69 +268,21 @@ func (p *patcher) getPatchOpsOrchestrated(containerIdx int, container corev1.Con
|
||||
return ops, nil
|
||||
}
|
||||
|
||||
func (p *patcher) parseResourceName(input string) (string, string, error) {
|
||||
var interfaceID, afuID string
|
||||
var regionName, afName string
|
||||
var ok bool
|
||||
|
||||
result := resourceRe.FindStringSubmatch(input)
|
||||
if result == nil {
|
||||
return "", "", nil
|
||||
}
|
||||
|
||||
defer p.Unlock()
|
||||
p.Lock()
|
||||
|
||||
for num, group := range resourceRe.SubexpNames() {
|
||||
switch group {
|
||||
case "Region":
|
||||
regionName = result[num]
|
||||
if interfaceID, ok = p.regionMap[result[num]]; !ok {
|
||||
return "", "", errors.Errorf("Unknown region name: %s", result[num])
|
||||
}
|
||||
case "Af":
|
||||
afName = result[num]
|
||||
}
|
||||
}
|
||||
|
||||
if afName != "" {
|
||||
if afuID, ok = p.afMap[regionName+"-"+afName]; !ok {
|
||||
return "", "", errors.Errorf("Unknown AF name: %s", regionName+"-"+afName)
|
||||
}
|
||||
}
|
||||
|
||||
return interfaceID, afuID, nil
|
||||
}
|
||||
|
||||
// patcherManager keeps track of patchers registered for different Kubernetes namespaces.
|
||||
type patcherManager struct {
|
||||
defaultMode string
|
||||
patchers map[string]*patcher
|
||||
type patcherManager map[string]*patcher
|
||||
|
||||
func newPatcherManager() patcherManager {
|
||||
return make(map[string]*patcher)
|
||||
}
|
||||
|
||||
func newPatcherManager(defaultMode string) (*patcherManager, error) {
|
||||
if defaultMode != preprogrammed && defaultMode != orchestrated {
|
||||
return nil, errors.Errorf("Unknown mode: %s", defaultMode)
|
||||
func (pm patcherManager) getPatcher(namespace string) *patcher {
|
||||
if p, ok := pm[namespace]; ok {
|
||||
return p
|
||||
}
|
||||
|
||||
return &patcherManager{
|
||||
defaultMode: defaultMode,
|
||||
patchers: make(map[string]*patcher),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (pm *patcherManager) getPatcher(namespace string) (*patcher, error) {
|
||||
if p, ok := pm.patchers[namespace]; ok {
|
||||
return p, nil
|
||||
}
|
||||
|
||||
p, err := newPatcher(pm.defaultMode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pm.patchers[namespace] = p
|
||||
p := newPatcher()
|
||||
pm[namespace] = p
|
||||
klog.V(4).Info("created new patcher for namespace", namespace)
|
||||
|
||||
return p, nil
|
||||
return p
|
||||
}
|
||||
|
@ -21,9 +21,8 @@ import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/klog"
|
||||
|
||||
fpgav1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v1"
|
||||
fpgav2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -31,203 +30,68 @@ func init() {
|
||||
}
|
||||
|
||||
func TestPatcherStorageFunctions(t *testing.T) {
|
||||
af := &fpgav1.AcceleratorFunction{
|
||||
af := &fpgav2.AcceleratorFunction{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "arria10-nlb0",
|
||||
},
|
||||
Spec: fpgav1.AcceleratorFunctionSpec{
|
||||
Spec: fpgav2.AcceleratorFunctionSpec{
|
||||
AfuID: "d8424dc4a4a3c413f89e433683f9040b",
|
||||
},
|
||||
}
|
||||
region := &fpgav1.FpgaRegion{
|
||||
region := &fpgav2.FpgaRegion{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "arria10",
|
||||
},
|
||||
Spec: fpgav1.FpgaRegionSpec{
|
||||
Spec: fpgav2.FpgaRegionSpec{
|
||||
InterfaceID: "ce48969398f05f33946d560708be108a",
|
||||
},
|
||||
}
|
||||
|
||||
p, err := newPatcher(preprogrammed)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
p := newPatcher()
|
||||
|
||||
p.addAf(af)
|
||||
if len(p.afMap) != 1 || len(p.resourceMap) != 1 {
|
||||
if len(p.resourceModeMap) != 1 || len(p.afMap) != 1 || len(p.resourceMap) != 1 {
|
||||
t.Error("Failed to add AF to patcher")
|
||||
}
|
||||
|
||||
p.removeAf(af.Name)
|
||||
if len(p.afMap) != 0 || len(p.resourceMap) != 0 {
|
||||
if len(p.resourceModeMap) != 0 || len(p.afMap) != 0 || len(p.resourceMap) != 0 {
|
||||
t.Error("Failed to remove AF from patcher")
|
||||
}
|
||||
|
||||
p.addRegion(region)
|
||||
if len(p.regionMap) != 1 || len(p.resourceMap) != 1 {
|
||||
if len(p.resourceModeMap) != 1 || len(p.resourceMap) != 1 {
|
||||
t.Error("Failed to add fpga region to patcher")
|
||||
}
|
||||
|
||||
p.removeRegion(region.Name)
|
||||
if len(p.regionMap) != 0 || len(p.resourceMap) != 0 {
|
||||
if len(p.resourceModeMap) != 0 || len(p.resourceMap) != 0 {
|
||||
t.Error("Failed to remove fpga region from patcher")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPatchOpsPreprogrammed(t *testing.T) {
|
||||
func TestGetPatchOps(t *testing.T) {
|
||||
tcases := []struct {
|
||||
name string
|
||||
resourceMap map[string]string
|
||||
container corev1.Container
|
||||
afs []*fpgav2.AcceleratorFunction
|
||||
regions []*fpgav2.FpgaRegion
|
||||
expectedErr bool
|
||||
expectedOps int
|
||||
}{
|
||||
{
|
||||
name: "Empty container",
|
||||
},
|
||||
{
|
||||
name: "Unknown resource in limits",
|
||||
name: "Successful handling for region mode",
|
||||
container: corev1.Container{
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Limits: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10-unknown": resource.MustParse("1"),
|
||||
"cpu": resource.MustParse("1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedErr: true,
|
||||
},
|
||||
{
|
||||
name: "Unknown resource in requests",
|
||||
container: corev1.Container{
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Requests: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10-unknown": resource.MustParse("1"),
|
||||
"cpu": resource.MustParse("1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedErr: true,
|
||||
},
|
||||
{
|
||||
name: "Successful case",
|
||||
container: corev1.Container{
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Limits: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10-nlb0": resource.MustParse("1"),
|
||||
"cpu": resource.MustParse("1"),
|
||||
"fpga.intel.com/arria10-nlb0": resource.MustParse("1"),
|
||||
"fpga.intel.com/arria10-nlb0-alias": resource.MustParse("2"),
|
||||
"cpu": resource.MustParse("1"),
|
||||
},
|
||||
Requests: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10-nlb0": resource.MustParse("1"),
|
||||
"cpu": resource.MustParse("1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
resourceMap: map[string]string{
|
||||
"fpga.intel.com/arria10-nlb0": rfc6901Escaper.Replace("fpga.intel.com/af-d8424dc4a4a3c413f89e433683f9040b"),
|
||||
},
|
||||
expectedOps: 2,
|
||||
},
|
||||
}
|
||||
for _, tt := range tcases {
|
||||
p := &patcher{
|
||||
resourceMap: tt.resourceMap,
|
||||
}
|
||||
ops, err := p.getPatchOpsPreprogrammed(0, tt.container)
|
||||
if tt.expectedErr && err == nil {
|
||||
t.Errorf("Test case '%s': no error returned", tt.name)
|
||||
}
|
||||
if !tt.expectedErr && err != nil {
|
||||
t.Errorf("Test case '%s': unexpected error %v", tt.name, err)
|
||||
}
|
||||
if len(ops) != tt.expectedOps {
|
||||
t.Errorf("test case '%s': expected %d ops, but got %d\n%v", tt.name, tt.expectedOps, len(ops), ops)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseResourceName(t *testing.T) {
|
||||
tcases := []struct {
|
||||
input string
|
||||
interfaceID string
|
||||
afuID string
|
||||
afMap map[string]string
|
||||
regionMap map[string]string
|
||||
expectedErr bool
|
||||
}{
|
||||
{
|
||||
input: "fpga.intel.com/arria10",
|
||||
regionMap: map[string]string{
|
||||
"arria10": "ce48969398f05f33946d560708be108a",
|
||||
},
|
||||
interfaceID: "ce48969398f05f33946d560708be108a",
|
||||
},
|
||||
{
|
||||
input: "fpga.intel.com/arria10-unknown",
|
||||
regionMap: map[string]string{
|
||||
"arria10": "ce48969398f05f33946d560708be108a",
|
||||
},
|
||||
expectedErr: true,
|
||||
},
|
||||
{
|
||||
input: "fpga.intel.com/unknown",
|
||||
expectedErr: true,
|
||||
},
|
||||
{
|
||||
input: "fpga.example.com/something",
|
||||
},
|
||||
{
|
||||
input: "fpga.intel.com/arria10-nlb0",
|
||||
regionMap: map[string]string{
|
||||
"arria10": "ce48969398f05f33946d560708be108a",
|
||||
},
|
||||
afMap: map[string]string{
|
||||
"arria10-nlb0": "d8424dc4a4a3c413f89e433683f9040b",
|
||||
},
|
||||
interfaceID: "ce48969398f05f33946d560708be108a",
|
||||
afuID: "d8424dc4a4a3c413f89e433683f9040b",
|
||||
},
|
||||
}
|
||||
|
||||
for num, tt := range tcases {
|
||||
p := &patcher{
|
||||
afMap: tt.afMap,
|
||||
regionMap: tt.regionMap,
|
||||
}
|
||||
interfaceID, afuID, err := p.parseResourceName(tt.input)
|
||||
if tt.expectedErr {
|
||||
if err != nil {
|
||||
continue
|
||||
} else {
|
||||
t.Errorf("In case %d we didn't get error", num)
|
||||
}
|
||||
}
|
||||
if tt.interfaceID != interfaceID || tt.afuID != afuID {
|
||||
t.Errorf("In case %d expected (%s, %s), but got (%s, %s)", num, tt.interfaceID, tt.afuID, interfaceID, afuID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPatchOpsOrchestrated(t *testing.T) {
|
||||
tcases := []struct {
|
||||
name string
|
||||
container corev1.Container
|
||||
afMap map[string]string
|
||||
regionMap map[string]string
|
||||
expectedErr bool
|
||||
expectedOps int
|
||||
}{
|
||||
{
|
||||
name: "Successful handling",
|
||||
container: corev1.Container{
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Limits: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10-nlb0": resource.MustParse("1"),
|
||||
"cpu": resource.MustParse("1"),
|
||||
},
|
||||
Requests: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10-nlb0": resource.MustParse("1"),
|
||||
"cpu": resource.MustParse("1"),
|
||||
"fpga.intel.com/arria10-nlb0": resource.MustParse("1"),
|
||||
"fpga.intel.com/arria10-nlb0-alias": resource.MustParse("2"),
|
||||
"cpu": resource.MustParse("3"),
|
||||
},
|
||||
},
|
||||
Env: []corev1.EnvVar{
|
||||
@ -237,13 +101,79 @@ func TestGetPatchOpsOrchestrated(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
regionMap: map[string]string{
|
||||
"arria10": "ce48969398f05f33946d560708be108a",
|
||||
afs: []*fpgav2.AcceleratorFunction{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "arria10-nlb0",
|
||||
},
|
||||
Spec: fpgav2.AcceleratorFunctionSpec{
|
||||
AfuID: "d8424dc4a4a3c413f89e433683f9040b",
|
||||
InterfaceID: "ce48969398f05f33946d560708be108a",
|
||||
Mode: region,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "arria10-nlb0-alias",
|
||||
},
|
||||
Spec: fpgav2.AcceleratorFunctionSpec{
|
||||
AfuID: "d8424dc4a4a3c413f89e433683f9040b",
|
||||
InterfaceID: "ce48969398f05f33946d560708be108a",
|
||||
Mode: region,
|
||||
},
|
||||
},
|
||||
},
|
||||
afMap: map[string]string{
|
||||
"arria10-nlb0": "d8424dc4a4a3c413f89e433683f9040b",
|
||||
expectedOps: 7,
|
||||
},
|
||||
{
|
||||
name: "Successful handling for af mode",
|
||||
container: corev1.Container{
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Limits: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10-nlb0": resource.MustParse("1"),
|
||||
},
|
||||
Requests: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10-nlb0": resource.MustParse("1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedOps: 5,
|
||||
afs: []*fpgav2.AcceleratorFunction{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "arria10-nlb0",
|
||||
},
|
||||
Spec: fpgav2.AcceleratorFunctionSpec{
|
||||
AfuID: "d8424dc4a4a3c413f89e433683f9040b",
|
||||
InterfaceID: "ce48969398f05f33946d560708be108a",
|
||||
Mode: af,
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedOps: 4,
|
||||
},
|
||||
{
|
||||
name: "Successful handling for regiondevel mode",
|
||||
container: corev1.Container{
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Limits: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10": resource.MustParse("1"),
|
||||
},
|
||||
Requests: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10": resource.MustParse("1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
regions: []*fpgav2.FpgaRegion{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "arria10",
|
||||
},
|
||||
Spec: fpgav2.FpgaRegionSpec{
|
||||
InterfaceID: "ce48969398f05f33946d560708be108a",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedOps: 4,
|
||||
},
|
||||
{
|
||||
name: "Unequal FPGA resources in Limits and Requests 1",
|
||||
@ -255,13 +185,6 @@ func TestGetPatchOpsOrchestrated(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
regionMap: map[string]string{
|
||||
"arria10": "ce48969398f05f33946d560708be108a",
|
||||
},
|
||||
afMap: map[string]string{
|
||||
"arria10-nlb0": "d8424dc4a4a3c413f89e433683f9040b",
|
||||
"arria10-nlb3": "f7df405cbd7acf7222f144b0b93acd18",
|
||||
},
|
||||
expectedErr: true,
|
||||
},
|
||||
{
|
||||
@ -270,45 +193,19 @@ func TestGetPatchOpsOrchestrated(t *testing.T) {
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Requests: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10-nlb0": resource.MustParse("1"),
|
||||
"fpga.intel.com/arria10-nlb3": resource.MustParse("1"),
|
||||
"fpga.intel.com/arria10-nlb3": resource.MustParse("2"),
|
||||
},
|
||||
},
|
||||
},
|
||||
regionMap: map[string]string{
|
||||
"arria10": "ce48969398f05f33946d560708be108a",
|
||||
},
|
||||
afMap: map[string]string{
|
||||
"arria10-nlb0": "d8424dc4a4a3c413f89e433683f9040b",
|
||||
"arria10-nlb3": "f7df405cbd7acf7222f144b0b93acd18",
|
||||
},
|
||||
expectedErr: true,
|
||||
},
|
||||
{
|
||||
name: "Unknown FPGA model in Requests",
|
||||
name: "Unknown FPGA resources in container requirements",
|
||||
container: corev1.Container{
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Requests: corev1.ResourceList{
|
||||
"fpga.intel.com/unknown-nlb0": resource.MustParse("1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedErr: true,
|
||||
},
|
||||
{
|
||||
name: "Unknown AFU in Requests",
|
||||
container: corev1.Container{
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Requests: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10-unknown": resource.MustParse("1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedErr: true,
|
||||
},
|
||||
{
|
||||
name: "Unknown FPGA model in Limits",
|
||||
container: corev1.Container{
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Limits: corev1.ResourceList{
|
||||
"fpga.intel.com/unknown-nlb0": resource.MustParse("1"),
|
||||
},
|
||||
@ -316,23 +213,12 @@ func TestGetPatchOpsOrchestrated(t *testing.T) {
|
||||
},
|
||||
expectedErr: true,
|
||||
},
|
||||
{
|
||||
name: "Unknown AFU in Limits",
|
||||
container: corev1.Container{
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Limits: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10-unknown": resource.MustParse("1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedErr: true,
|
||||
},
|
||||
{
|
||||
name: "Wrong ENV",
|
||||
container: corev1.Container{
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Limits: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10-nlb0": resource.MustParse("1"),
|
||||
"cpu": resource.MustParse("1"),
|
||||
},
|
||||
},
|
||||
Env: []corev1.EnvVar{
|
||||
@ -342,12 +228,6 @@ func TestGetPatchOpsOrchestrated(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
regionMap: map[string]string{
|
||||
"arria10": "ce48969398f05f33946d560708be108a",
|
||||
},
|
||||
afMap: map[string]string{
|
||||
"arria10-nlb0": "d8424dc4a4a3c413f89e433683f9040b",
|
||||
},
|
||||
expectedErr: true,
|
||||
},
|
||||
{
|
||||
@ -362,59 +242,119 @@ func TestGetPatchOpsOrchestrated(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
regionMap: map[string]string{
|
||||
"arria10": "ce48969398f05f33946d560708be108a",
|
||||
expectedErr: true,
|
||||
},
|
||||
{
|
||||
name: "Require resources operated in af and region modes",
|
||||
container: corev1.Container{
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Limits: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10-nlb0": resource.MustParse("1"),
|
||||
"fpga.intel.com/arria10-nlb3": resource.MustParse("2"),
|
||||
"cpu": resource.MustParse("1"),
|
||||
},
|
||||
Requests: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10-nlb0": resource.MustParse("1"),
|
||||
"fpga.intel.com/arria10-nlb3": resource.MustParse("2"),
|
||||
"cpu": resource.MustParse("3"),
|
||||
},
|
||||
},
|
||||
},
|
||||
afMap: map[string]string{
|
||||
"arria10-nlb0": "d8424dc4a4a3c413f89e433683f9040b",
|
||||
afs: []*fpgav2.AcceleratorFunction{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "arria10-nlb0",
|
||||
},
|
||||
Spec: fpgav2.AcceleratorFunctionSpec{
|
||||
AfuID: "d8424dc4a4a3c413f89e433683f9040b",
|
||||
InterfaceID: "ce48969398f05f33946d560708be108a",
|
||||
Mode: region,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "arria10-nlb3",
|
||||
},
|
||||
Spec: fpgav2.AcceleratorFunctionSpec{
|
||||
AfuID: "d8424dc4a4a3c413f89e433683f9040b",
|
||||
InterfaceID: "f7df405cbd7acf7222f144b0b93acd18",
|
||||
Mode: af,
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedErr: true,
|
||||
},
|
||||
{
|
||||
name: "Unknown mode",
|
||||
container: corev1.Container{
|
||||
Resources: corev1.ResourceRequirements{
|
||||
Limits: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10-nlb0": resource.MustParse("1"),
|
||||
},
|
||||
Requests: corev1.ResourceList{
|
||||
"fpga.intel.com/arria10-nlb0": resource.MustParse("1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
afs: []*fpgav2.AcceleratorFunction{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "arria10-nlb0",
|
||||
},
|
||||
Spec: fpgav2.AcceleratorFunctionSpec{
|
||||
AfuID: "d8424dc4a4a3c413f89e433683f9040b",
|
||||
InterfaceID: "ce48969398f05f33946d560708be108a",
|
||||
Mode: "unknown",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tcases {
|
||||
p := &patcher{
|
||||
afMap: tt.afMap,
|
||||
regionMap: tt.regionMap,
|
||||
}
|
||||
klog.V(4).Info(tt.name)
|
||||
ops, err := p.getPatchOpsOrchestrated(0, tt.container)
|
||||
if tt.expectedErr && err == nil {
|
||||
t.Errorf("Test case '%s': no error returned", tt.name)
|
||||
}
|
||||
if !tt.expectedErr && err != nil {
|
||||
t.Errorf("Test case '%s': unexpected error %+v", tt.name, err)
|
||||
}
|
||||
if len(ops) != tt.expectedOps {
|
||||
t.Errorf("test case '%s': expected %d ops, but got %d\n%v", tt.name, tt.expectedOps, len(ops), ops)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewPatcherManager(t *testing.T) {
|
||||
tcases := []struct {
|
||||
name string
|
||||
defaultMode string
|
||||
expectedErr bool
|
||||
}{
|
||||
{
|
||||
name: "Everything is OK",
|
||||
defaultMode: preprogrammed,
|
||||
},
|
||||
{
|
||||
name: "Unknown default mode",
|
||||
defaultMode: "unknownMode",
|
||||
expectedErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tcases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := newPatcherManager(tt.defaultMode)
|
||||
p := newPatcher()
|
||||
for _, af := range tt.afs {
|
||||
p.addAf(af)
|
||||
}
|
||||
for _, region := range tt.regions {
|
||||
p.addRegion(region)
|
||||
}
|
||||
ops, err := p.getPatchOps(0, tt.container)
|
||||
if tt.expectedErr && err == nil {
|
||||
t.Errorf("Test case '%s': no error returned", tt.name)
|
||||
}
|
||||
if !tt.expectedErr && err != nil {
|
||||
t.Errorf("Test case '%s': unexpected error %+v", tt.name, err)
|
||||
t.Errorf("Test case '%s': unexpected error: %+v", tt.name, err)
|
||||
}
|
||||
if len(ops) != tt.expectedOps {
|
||||
t.Errorf("test case '%s': expected %d ops, but got %d\n%v", tt.name, tt.expectedOps, len(ops), ops)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPatcher(t *testing.T) {
|
||||
namespace := "test"
|
||||
tcases := []struct {
|
||||
name string
|
||||
pm patcherManager
|
||||
}{
|
||||
{
|
||||
name: "Create new patcher",
|
||||
pm: newPatcherManager(),
|
||||
},
|
||||
{
|
||||
name: "Return existing patcher",
|
||||
pm: map[string]*patcher{namespace: newPatcher()},
|
||||
},
|
||||
}
|
||||
for _, tt := range tcases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
p := tt.pm.getPatcher(namespace)
|
||||
if p != tt.pm[namespace] {
|
||||
t.Error("stored and received patchers are not equal")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
* [Verify node kubelet config](#verify-node-kubelet-config)
|
||||
* [Deploying as a DaemonSet](#deploying-as-a-daemonset)
|
||||
* [Create a service account](#create-a-service-account)
|
||||
* [Deploying `orchestrated` mode](#deploying-orchestrated-mode)
|
||||
* [Deploying `region` mode](#deploying-region-mode)
|
||||
* [Deploying `af` mode](#deploying-af-mode)
|
||||
* [Deploy the DaemonSet](#deploy-the-daemonset)
|
||||
* [Verify plugin registration](#verify-plugin-registration)
|
||||
@ -75,26 +75,26 @@ development, initial deployment and debugging.
|
||||
|
||||
The FPGA plugin set can run in one of two modes:
|
||||
|
||||
- `region`/`orchestrated` mode, where the plugins locate and advertise
|
||||
- `region` mode, where the plugins locate and advertise
|
||||
regions of the FPGA, and facilitate programing of those regions with the
|
||||
requested bistreams.
|
||||
- `af`/`preprogrammed` mode, where the FPGA bitstreams are already loaded
|
||||
- `af` mode, where the FPGA bitstreams are already loaded
|
||||
onto the FPGA, and the plugins discover and advertises the existing
|
||||
Accelerator Functions (AF).
|
||||
|
||||
The example YAML deployments described in this document only currently support
|
||||
`af`/`preprogrammed` mode. To utilise `region`/`orchestrated` mode, either modify
|
||||
the existing YAML appropriately, or deploy 'by hand'.
|
||||
`af` mode. To utilise `region` mode, either modify the existing YAML appropriately,
|
||||
or deploy 'by hand'.
|
||||
|
||||
Overview diagrams of `preprogrammed` and `orchestrated` modes are below:
|
||||
Overview diagrams of `af` and `region` modes are below:
|
||||
|
||||
Orchestrated/region mode:
|
||||
region mode:
|
||||
|
||||

|
||||

|
||||
|
||||
Preprogrammed/af mode:
|
||||
af mode:
|
||||
|
||||

|
||||

|
||||
|
||||
# Installation
|
||||
|
||||
@ -136,12 +136,11 @@ major components:
|
||||
- [FPGA admission controller webhook](../fpga_admissionwebhook/README.md)
|
||||
- [FPGA prestart CRI-O hook](../fpga_crihook/README.md)
|
||||
|
||||
The CRI-O hook is only *required* if `orchestrated` FPGA bitstream programming mode is
|
||||
being used, but is installed by default by the
|
||||
The CRI-O hook is only *required* if `region` mode is being used, but is installed by default by the
|
||||
[FPGA plugin DaemonSet YAML](../../deployments/fpga_plugin/fpga_plugin.yaml), and is benign
|
||||
in `preprogrammed` mode.
|
||||
in `af` mode.
|
||||
|
||||
If using the `preprogrammed` mode, and therefore *not* using the
|
||||
If using the `af` mode, and therefore *not* using the
|
||||
CRI-O prestart hook, runtimes other than CRI-O can be used (that is, the CRI-O hook presently
|
||||
*only* works with the CRI-O runtime).
|
||||
|
||||
@ -192,8 +191,8 @@ YAML deployment files to reference your required image.
|
||||
### For beta testing: new deployment model
|
||||
|
||||
The FPGA plugin deployment is currently being rewritten to enable
|
||||
straight-forward deployment of both `af/preprogrammed` and
|
||||
`region/orchestrated` modes. The deployment has two steps:
|
||||
straight-forward deployment of both `af` and
|
||||
`region` modes. The deployment has two steps:
|
||||
|
||||
1. Run `scripts/fpga-plugin-prepare-for-kustomization.sh`. This will
|
||||
create the necessary secrets: a key and a signed certificate for
|
||||
@ -226,19 +225,16 @@ clusterrole.rbac.authorization.k8s.io/node-getter created
|
||||
clusterrolebinding.rbac.authorization.k8s.io/get-nodes created
|
||||
```
|
||||
|
||||
### Deploying `orchestrated` mode
|
||||
### Deploying `region` mode
|
||||
|
||||
To deploy the FPGA plugin DaemonSet in `orchestrated` (`region`) mode, you need to set the plugin
|
||||
To deploy the FPGA plugin DaemonSet in `region` mode, you need to set the plugin
|
||||
mode annotation on all of your nodes, otherwise the FPGA plugin will run in its default
|
||||
`af` (`preprogrammed`) mode.
|
||||
`af` mode.
|
||||
|
||||
```bash
|
||||
$ kubectl annotate node --all 'fpga.intel.com/device-plugin-mode=region'
|
||||
```
|
||||
|
||||
Mixing of the two modes (`orchestrated` and `af`) across nodes in the same cluster is
|
||||
*not currently supported*.
|
||||
|
||||
### Deploying `af` mode
|
||||
|
||||
To deploy the FPGA plugin DaemonSet in `af` mode, you do not need to set the mode annotation on
|
||||
@ -260,7 +256,7 @@ daemonset.apps/intel-fpga-plugin created
|
||||
### Verify plugin registration
|
||||
|
||||
Verify the FPGA plugin has been deployed on the nodes. The below shows the output
|
||||
you can expect in `region` mode, but similar output should be expected for `preprogrammed`
|
||||
you can expect in `region` mode, but similar output should be expected for `af`
|
||||
mode:
|
||||
|
||||
```bash
|
||||
|
@ -116,7 +116,7 @@ func getDevicesDFL() []device {
|
||||
},
|
||||
{
|
||||
id: "dfl-port.4",
|
||||
afuID: "d8424dc4a4a3c413f89e433683f9040b",
|
||||
afuID: unhealthyAfuID,
|
||||
devNode: "/dev/dfl-port.4",
|
||||
},
|
||||
},
|
||||
@ -240,7 +240,7 @@ func TestGetAfuTreeDFL(t *testing.T) {
|
||||
Permissions: "rw",
|
||||
},
|
||||
}
|
||||
expected.AddDevice(afMode+"-d8424dc4a4a3c413f89e433683f9040b", "dfl-port.0", dpapi.NewDeviceInfo(pluginapi.Healthy, nodes, nil, nil))
|
||||
expected.AddDevice("af-ce4.d84.zkiWk5jwXzOUbVYHCL4QithCTcSko8QT-J5DNoP5BAs", "dfl-port.0", dpapi.NewDeviceInfo(pluginapi.Healthy, nodes, nil, nil))
|
||||
|
||||
nodes = []pluginapi.DeviceSpec{
|
||||
{
|
||||
@ -250,7 +250,7 @@ func TestGetAfuTreeDFL(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
expected.AddDevice(afMode+"-d8424dc4a4a3c413f89e433683f9040b", "dfl-port.1", dpapi.NewDeviceInfo(pluginapi.Healthy, nodes, nil, nil))
|
||||
expected.AddDevice("af-ce4.d84.zkiWk5jwXzOUbVYHCL4QithCTcSko8QT-J5DNoP5BAs", "dfl-port.1", dpapi.NewDeviceInfo(pluginapi.Healthy, nodes, nil, nil))
|
||||
|
||||
nodes = []pluginapi.DeviceSpec{
|
||||
{
|
||||
@ -259,7 +259,7 @@ func TestGetAfuTreeDFL(t *testing.T) {
|
||||
Permissions: "rw",
|
||||
},
|
||||
}
|
||||
expected.AddDevice(afMode+"-d8424dc4a4a3c413f89e433683f9040b", "dfl-port.2", dpapi.NewDeviceInfo(pluginapi.Healthy, nodes, nil, nil))
|
||||
expected.AddDevice("af-ce4.d84.zkiWk5jwXzOUbVYHCL4QithCTcSko8QT-J5DNoP5BAs", "dfl-port.2", dpapi.NewDeviceInfo(pluginapi.Healthy, nodes, nil, nil))
|
||||
|
||||
nodes = []pluginapi.DeviceSpec{
|
||||
{
|
||||
@ -268,7 +268,7 @@ func TestGetAfuTreeDFL(t *testing.T) {
|
||||
Permissions: "rw",
|
||||
},
|
||||
}
|
||||
expected.AddDevice(afMode+"-"+unhealthyAfuID, "dfl-port.3", dpapi.NewDeviceInfo(pluginapi.Unhealthy, nodes, nil, nil))
|
||||
expected.AddDevice("af-fff.fff.__________________________________________8", "dfl-port.3", dpapi.NewDeviceInfo(pluginapi.Unhealthy, nodes, nil, nil))
|
||||
|
||||
nodes = []pluginapi.DeviceSpec{
|
||||
{
|
||||
@ -277,11 +277,11 @@ func TestGetAfuTreeDFL(t *testing.T) {
|
||||
Permissions: "rw",
|
||||
},
|
||||
}
|
||||
expected.AddDevice(afMode+"-d8424dc4a4a3c413f89e433683f9040b", "dfl-port.4", dpapi.NewDeviceInfo(pluginapi.Healthy, nodes, nil, nil))
|
||||
expected.AddDevice("af-fff.fff.__________________________________________8", "dfl-port.4", dpapi.NewDeviceInfo(pluginapi.Unhealthy, nodes, nil, nil))
|
||||
|
||||
result := getAfuTree(getDevicesDFL())
|
||||
if !reflect.DeepEqual(result, expected) {
|
||||
t.Errorf("Got unexpected result: %v, expected: %v", result, expected)
|
||||
t.Errorf("Got unexpected result:\n%v\nexpected:\n%v", result, expected)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ import (
|
||||
pluginapi "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1"
|
||||
|
||||
dpapi "github.com/intel/intel-device-plugins-for-kubernetes/pkg/deviceplugin"
|
||||
"github.com/intel/intel-device-plugins-for-kubernetes/pkg/fpga"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@ -125,7 +126,11 @@ func getAfuTree(devices []device) dpapi.DeviceTree {
|
||||
if afu.afuID == unhealthyAfuID {
|
||||
health = pluginapi.Unhealthy
|
||||
}
|
||||
devType := fmt.Sprintf("%s-%s", afMode, afu.afuID)
|
||||
devType, err := fpga.GetAfuDevType(region.interfaceID, afu.afuID)
|
||||
if err != nil {
|
||||
klog.Warningf("failed to get devtype: %+v", err)
|
||||
continue
|
||||
}
|
||||
devNodes := []pluginapi.DeviceSpec{
|
||||
{
|
||||
HostPath: afu.devNode,
|
||||
|
@ -210,7 +210,7 @@ func TestGetAfuTreeOPAE(t *testing.T) {
|
||||
Permissions: "rw",
|
||||
},
|
||||
}
|
||||
expected.AddDevice(afMode+"-d8424dc4a4a3c413f89e433683f9040b", "intel-fpga-port.0", dpapi.NewDeviceInfo(pluginapi.Healthy, nodes, nil, nil))
|
||||
expected.AddDevice("af-ce4.d84.zkiWk5jwXzOUbVYHCL4QithCTcSko8QT-J5DNoP5BAs", "intel-fpga-port.0", dpapi.NewDeviceInfo(pluginapi.Healthy, nodes, nil, nil))
|
||||
|
||||
nodes = []pluginapi.DeviceSpec{
|
||||
{
|
||||
@ -219,7 +219,7 @@ func TestGetAfuTreeOPAE(t *testing.T) {
|
||||
Permissions: "rw",
|
||||
},
|
||||
}
|
||||
expected.AddDevice(afMode+"-d8424dc4a4a3c413f89e433683f9040b", "intel-fpga-port.1", dpapi.NewDeviceInfo(pluginapi.Healthy, nodes, nil, nil))
|
||||
expected.AddDevice("af-ce4.d84.zkiWk5jwXzOUbVYHCL4QithCTcSko8QT-J5DNoP5BAs", "intel-fpga-port.1", dpapi.NewDeviceInfo(pluginapi.Healthy, nodes, nil, nil))
|
||||
|
||||
nodes = []pluginapi.DeviceSpec{
|
||||
{
|
||||
@ -228,7 +228,7 @@ func TestGetAfuTreeOPAE(t *testing.T) {
|
||||
Permissions: "rw",
|
||||
},
|
||||
}
|
||||
expected.AddDevice(afMode+"-"+unhealthyAfuID, "intel-fpga-port.2", dpapi.NewDeviceInfo(pluginapi.Unhealthy, nodes, nil, nil))
|
||||
expected.AddDevice("af-fff.fff.__________________________________________8", "intel-fpga-port.2", dpapi.NewDeviceInfo(pluginapi.Unhealthy, nodes, nil, nil))
|
||||
|
||||
result := getAfuTree(getDevicesOPAE())
|
||||
if !reflect.DeepEqual(result, expected) {
|
||||
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
@ -4,7 +4,7 @@ metadata:
|
||||
name: acceleratorfunctions.fpga.intel.com
|
||||
spec:
|
||||
group: fpga.intel.com
|
||||
version: v1
|
||||
version: v2
|
||||
scope: Namespaced
|
||||
names:
|
||||
plural: acceleratorfunctions
|
||||
@ -19,4 +19,10 @@ spec:
|
||||
properties:
|
||||
afuId:
|
||||
type: string
|
||||
pattern: '^[0-9a-f]{8,128}$'
|
||||
pattern: '^[0-9a-f]{8,32}$'
|
||||
interfaceId:
|
||||
type: string
|
||||
pattern: '^[0-9a-f]{8,32}$'
|
||||
mode:
|
||||
type: string
|
||||
pattern: '^af|region$'
|
||||
|
@ -1,19 +1,12 @@
|
||||
# DCP 1.0
|
||||
apiVersion: fpga.intel.com/v1
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: arria10.dcp1.0-compress
|
||||
spec:
|
||||
afuId: 946c21d1e49704a5e5daa0805bc6b0785e1765bf
|
||||
---
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: arria10.dcp1.0-nlb0
|
||||
spec:
|
||||
afuId: d8424dc4a4a3c413f89e433683f9040b
|
||||
---
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: arria10.dcp1.0-nlb3
|
||||
@ -21,14 +14,14 @@ spec:
|
||||
afuId: f7df405cbd7acf7222f144b0b93acd18
|
||||
---
|
||||
# DCP 1.1
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: arria10.dcp1.1-nlb0
|
||||
spec:
|
||||
afuId: d8424dc4a4a3c413f89e433683f9040b
|
||||
---
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: arria10.dcp1.1-nlb3
|
||||
@ -36,14 +29,14 @@ spec:
|
||||
afuId: f7df405cbd7acf7222f144b0b93acd18
|
||||
---
|
||||
# DCP 1.2
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: arria10.dcp1.2-nlb0
|
||||
spec:
|
||||
afuId: d8424dc4a4a3c413f89e433683f9040b
|
||||
---
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: arria10.dcp1.2-nlb3
|
||||
@ -51,14 +44,14 @@ spec:
|
||||
afuId: f7df405cbd7acf7222f144b0b93acd18
|
||||
---
|
||||
# D5005
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: d5005-nlb0
|
||||
spec:
|
||||
afuId: d8424dc4a4a3c413f89e433683f9040b
|
||||
---
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: d5005-nlb3
|
||||
|
@ -1,5 +1,5 @@
|
||||
# DCP 1.0
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: FpgaRegion
|
||||
metadata:
|
||||
name: arria10.dcp1.0
|
||||
@ -7,7 +7,7 @@ spec:
|
||||
interfaceId: ce48969398f05f33946d560708be108a
|
||||
---
|
||||
# DCP 1.1
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: FpgaRegion
|
||||
metadata:
|
||||
name: arria10.dcp1.1
|
||||
@ -15,7 +15,7 @@ spec:
|
||||
interfaceId: 9926ab6d6c925a68aabca7d84c545738
|
||||
---
|
||||
# DCP 1.2
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: FpgaRegion
|
||||
metadata:
|
||||
name: arria10.dcp1.2
|
||||
@ -23,7 +23,7 @@ spec:
|
||||
interfaceId: 69528db6eb31577a8c3668f9faa081f6
|
||||
---
|
||||
# D5005
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: FpgaRegion
|
||||
metadata:
|
||||
name: d5005
|
||||
|
@ -29,7 +29,6 @@ spec:
|
||||
args:
|
||||
- -tls-cert-file=/etc/webhook/certs/cert.pem
|
||||
- -tls-private-key-file=/etc/webhook/certs/key.pem
|
||||
- -mode={MODE}
|
||||
- -v=1
|
||||
volumeMounts:
|
||||
- name: webhook-certs
|
||||
|
@ -1,94 +1,121 @@
|
||||
# DCP 1.0
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: FpgaRegion
|
||||
metadata:
|
||||
name: arria10.dcp1.0
|
||||
spec:
|
||||
interfaceId: ce48969398f05f33946d560708be108a
|
||||
---
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: arria10.dcp1.0-compress
|
||||
spec:
|
||||
afuId: 946c21d1e49704a5e5daa0805bc6b0785e1765bf
|
||||
---
|
||||
apiVersion: fpga.intel.com/v1
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: arria10.dcp1.0-nlb0
|
||||
name: arria10.dcp1.0-nlb0-orchestrated
|
||||
spec:
|
||||
afuId: d8424dc4a4a3c413f89e433683f9040b
|
||||
interfaceId: ce48969398f05f33946d560708be108a
|
||||
mode: region
|
||||
---
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: arria10.dcp1.0-nlb3
|
||||
name: arria10.dcp1.0-nlb3-orchestrated
|
||||
spec:
|
||||
afuId: f7df405cbd7acf7222f144b0b93acd18
|
||||
interfaceId: ce48969398f05f33946d560708be108a
|
||||
mode: region
|
||||
---
|
||||
# DCP 1.1
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: FpgaRegion
|
||||
metadata:
|
||||
name: arria10.dcp1.1
|
||||
spec:
|
||||
interfaceId: 9926ab6d6c925a68aabca7d84c545738
|
||||
---
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: arria10.dcp1.1-nlb0
|
||||
name: arria10.dcp1.1-nlb0-orchestrated
|
||||
spec:
|
||||
afuId: d8424dc4a4a3c413f89e433683f9040b
|
||||
interfaceId: 9926ab6d6c925a68aabca7d84c545738
|
||||
mode: region
|
||||
---
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: arria10.dcp1.1-nlb3
|
||||
name: arria10.dcp1.1-nlb3-orchestrated
|
||||
spec:
|
||||
afuId: f7df405cbd7acf7222f144b0b93acd18
|
||||
interfaceId: 9926ab6d6c925a68aabca7d84c545738
|
||||
mode: region
|
||||
---
|
||||
# DCP 1.2
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: FpgaRegion
|
||||
metadata:
|
||||
name: arria10.dcp1.2
|
||||
spec:
|
||||
interfaceId: 69528db6eb31577a8c3668f9faa081f6
|
||||
---
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: arria10.dcp1.2-nlb0
|
||||
name: arria10.dcp1.2-nlb0-orchestrated
|
||||
spec:
|
||||
afuId: d8424dc4a4a3c413f89e433683f9040b
|
||||
interfaceId: 69528db6eb31577a8c3668f9faa081f6
|
||||
mode: region
|
||||
---
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: arria10.dcp1.2-nlb3
|
||||
name: arria10.dcp1.2-nlb0-preprogrammed
|
||||
spec:
|
||||
afuId: d8424dc4a4a3c413f89e433683f9040b
|
||||
interfaceId: 69528db6eb31577a8c3668f9faa081f6
|
||||
mode: af
|
||||
---
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: arria10.dcp1.2-nlb3-orchestrated
|
||||
spec:
|
||||
afuId: f7df405cbd7acf7222f144b0b93acd18
|
||||
interfaceId: 69528db6eb31577a8c3668f9faa081f6
|
||||
mode: region
|
||||
---
|
||||
# D5005
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: FpgaRegion
|
||||
metadata:
|
||||
name: d5005
|
||||
spec:
|
||||
interfaceId: bfac4d851ee856fe8c95865ce1bbaa2d
|
||||
---
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: d5005-nlb0
|
||||
name: d5005-nlb0-orchestrated
|
||||
spec:
|
||||
afuId: d8424dc4a4a3c413f89e433683f9040b
|
||||
interfaceId: bfac4d851ee856fe8c95865ce1bbaa2d
|
||||
mode: region
|
||||
---
|
||||
apiVersion: fpga.intel.com/v1
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: d5005-nlb3
|
||||
name: d5005-nlb3-orchestrated
|
||||
spec:
|
||||
afuId: f7df405cbd7acf7222f144b0b93acd18
|
||||
interfaceId: bfac4d851ee856fe8c95865ce1bbaa2d
|
||||
mode: region
|
||||
---
|
||||
apiVersion: fpga.intel.com/v2
|
||||
kind: AcceleratorFunction
|
||||
metadata:
|
||||
name: d5005-nlb3-preprogrammed
|
||||
spec:
|
||||
afuId: f7df405cbd7acf7222f144b0b93acd18
|
||||
interfaceId: bfac4d851ee856fe8c95865ce1bbaa2d
|
||||
mode: af
|
||||
|
@ -4,7 +4,7 @@ metadata:
|
||||
name: fpgaregions.fpga.intel.com
|
||||
spec:
|
||||
group: fpga.intel.com
|
||||
version: v1
|
||||
version: v2
|
||||
scope: Namespaced
|
||||
names:
|
||||
plural: fpgaregions
|
||||
@ -19,4 +19,4 @@ spec:
|
||||
properties:
|
||||
interfaceId:
|
||||
type: string
|
||||
pattern: '^[0-9a-f]{8,128}$'
|
||||
pattern: '^[0-9a-f]{8,32}$'
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
// +groupName=fpga.intel.com
|
||||
|
||||
package v1
|
||||
package v2
|
@ -1,4 +1,4 @@
|
||||
package v1
|
||||
package v2
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: fpgaintel.GroupName, Version: "v1"}
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: fpgaintel.GroupName, Version: "v2"}
|
||||
|
||||
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
|
||||
func Kind(kind string) schema.GroupKind {
|
@ -1,4 +1,4 @@
|
||||
package v1
|
||||
package v2
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@ -18,7 +18,9 @@ type AcceleratorFunction struct {
|
||||
|
||||
// AcceleratorFunctionSpec contains actual specs for AcceleratorFunction
|
||||
type AcceleratorFunctionSpec struct {
|
||||
AfuID string `json:"afuId"`
|
||||
AfuID string `json:"afuId"`
|
||||
InterfaceID string `json:"interfaceId"`
|
||||
Mode string `json:"mode"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
@ -16,7 +16,7 @@
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
package v2
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
@ -19,7 +19,7 @@ package versioned
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
fpgav1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/clientset/versioned/typed/fpga.intel.com/v1"
|
||||
fpgav2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/clientset/versioned/typed/fpga.intel.com/v2"
|
||||
discovery "k8s.io/client-go/discovery"
|
||||
rest "k8s.io/client-go/rest"
|
||||
flowcontrol "k8s.io/client-go/util/flowcontrol"
|
||||
@ -27,19 +27,19 @@ import (
|
||||
|
||||
type Interface interface {
|
||||
Discovery() discovery.DiscoveryInterface
|
||||
FpgaV1() fpgav1.FpgaV1Interface
|
||||
FpgaV2() fpgav2.FpgaV2Interface
|
||||
}
|
||||
|
||||
// Clientset contains the clients for groups. Each group has exactly one
|
||||
// version included in a Clientset.
|
||||
type Clientset struct {
|
||||
*discovery.DiscoveryClient
|
||||
fpgaV1 *fpgav1.FpgaV1Client
|
||||
fpgaV2 *fpgav2.FpgaV2Client
|
||||
}
|
||||
|
||||
// FpgaV1 retrieves the FpgaV1Client
|
||||
func (c *Clientset) FpgaV1() fpgav1.FpgaV1Interface {
|
||||
return c.fpgaV1
|
||||
// FpgaV2 retrieves the FpgaV2Client
|
||||
func (c *Clientset) FpgaV2() fpgav2.FpgaV2Interface {
|
||||
return c.fpgaV2
|
||||
}
|
||||
|
||||
// Discovery retrieves the DiscoveryClient
|
||||
@ -63,7 +63,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
}
|
||||
var cs Clientset
|
||||
var err error
|
||||
cs.fpgaV1, err = fpgav1.NewForConfig(&configShallowCopy)
|
||||
cs.fpgaV2, err = fpgav2.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -79,7 +79,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
var cs Clientset
|
||||
cs.fpgaV1 = fpgav1.NewForConfigOrDie(c)
|
||||
cs.fpgaV2 = fpgav2.NewForConfigOrDie(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
|
||||
return &cs
|
||||
@ -88,7 +88,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
// New creates a new Clientset for the given RESTClient.
|
||||
func New(c rest.Interface) *Clientset {
|
||||
var cs Clientset
|
||||
cs.fpgaV1 = fpgav1.New(c)
|
||||
cs.fpgaV2 = fpgav2.New(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
|
||||
return &cs
|
||||
|
@ -18,8 +18,8 @@ package fake
|
||||
|
||||
import (
|
||||
clientset "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/clientset/versioned"
|
||||
fpgav1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/clientset/versioned/typed/fpga.intel.com/v1"
|
||||
fakefpgav1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/clientset/versioned/typed/fpga.intel.com/v1/fake"
|
||||
fpgav2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/clientset/versioned/typed/fpga.intel.com/v2"
|
||||
fakefpgav2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/clientset/versioned/typed/fpga.intel.com/v2/fake"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/discovery"
|
||||
@ -74,7 +74,7 @@ func (c *Clientset) Tracker() testing.ObjectTracker {
|
||||
|
||||
var _ clientset.Interface = &Clientset{}
|
||||
|
||||
// FpgaV1 retrieves the FpgaV1Client
|
||||
func (c *Clientset) FpgaV1() fpgav1.FpgaV1Interface {
|
||||
return &fakefpgav1.FakeFpgaV1{Fake: &c.Fake}
|
||||
// FpgaV2 retrieves the FpgaV2Client
|
||||
func (c *Clientset) FpgaV2() fpgav2.FpgaV2Interface {
|
||||
return &fakefpgav2.FakeFpgaV2{Fake: &c.Fake}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
package fake
|
||||
|
||||
import (
|
||||
fpgav1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v1"
|
||||
fpgav2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v2"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@ -29,7 +29,7 @@ var scheme = runtime.NewScheme()
|
||||
var codecs = serializer.NewCodecFactory(scheme)
|
||||
var parameterCodec = runtime.NewParameterCodec(scheme)
|
||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
fpgav1.AddToScheme,
|
||||
fpgav2.AddToScheme,
|
||||
}
|
||||
|
||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||
|
@ -17,7 +17,7 @@
|
||||
package scheme
|
||||
|
||||
import (
|
||||
fpgav1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v1"
|
||||
fpgav2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v2"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@ -29,7 +29,7 @@ var Scheme = runtime.NewScheme()
|
||||
var Codecs = serializer.NewCodecFactory(Scheme)
|
||||
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
fpgav1.AddToScheme,
|
||||
fpgav2.AddToScheme,
|
||||
}
|
||||
|
||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||
|
@ -14,15 +14,15 @@
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v1"
|
||||
v2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v2"
|
||||
scheme "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/clientset/versioned/scheme"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
@ -36,14 +36,14 @@ type AcceleratorFunctionsGetter interface {
|
||||
|
||||
// AcceleratorFunctionInterface has methods to work with AcceleratorFunction resources.
|
||||
type AcceleratorFunctionInterface interface {
|
||||
Create(ctx context.Context, acceleratorFunction *v1.AcceleratorFunction, opts metav1.CreateOptions) (*v1.AcceleratorFunction, error)
|
||||
Update(ctx context.Context, acceleratorFunction *v1.AcceleratorFunction, opts metav1.UpdateOptions) (*v1.AcceleratorFunction, error)
|
||||
Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.AcceleratorFunction, error)
|
||||
List(ctx context.Context, opts metav1.ListOptions) (*v1.AcceleratorFunctionList, error)
|
||||
Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.AcceleratorFunction, err error)
|
||||
Create(ctx context.Context, acceleratorFunction *v2.AcceleratorFunction, opts v1.CreateOptions) (*v2.AcceleratorFunction, error)
|
||||
Update(ctx context.Context, acceleratorFunction *v2.AcceleratorFunction, opts v1.UpdateOptions) (*v2.AcceleratorFunction, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*v2.AcceleratorFunction, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v2.AcceleratorFunctionList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2.AcceleratorFunction, err error)
|
||||
AcceleratorFunctionExpansion
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ type acceleratorFunctions struct {
|
||||
}
|
||||
|
||||
// newAcceleratorFunctions returns a AcceleratorFunctions
|
||||
func newAcceleratorFunctions(c *FpgaV1Client, namespace string) *acceleratorFunctions {
|
||||
func newAcceleratorFunctions(c *FpgaV2Client, namespace string) *acceleratorFunctions {
|
||||
return &acceleratorFunctions{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
@ -62,8 +62,8 @@ func newAcceleratorFunctions(c *FpgaV1Client, namespace string) *acceleratorFunc
|
||||
}
|
||||
|
||||
// Get takes name of the acceleratorFunction, and returns the corresponding acceleratorFunction object, and an error if there is any.
|
||||
func (c *acceleratorFunctions) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.AcceleratorFunction, err error) {
|
||||
result = &v1.AcceleratorFunction{}
|
||||
func (c *acceleratorFunctions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v2.AcceleratorFunction, err error) {
|
||||
result = &v2.AcceleratorFunction{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("acceleratorfunctions").
|
||||
@ -75,12 +75,12 @@ func (c *acceleratorFunctions) Get(ctx context.Context, name string, options met
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of AcceleratorFunctions that match those selectors.
|
||||
func (c *acceleratorFunctions) List(ctx context.Context, opts metav1.ListOptions) (result *v1.AcceleratorFunctionList, err error) {
|
||||
func (c *acceleratorFunctions) List(ctx context.Context, opts v1.ListOptions) (result *v2.AcceleratorFunctionList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1.AcceleratorFunctionList{}
|
||||
result = &v2.AcceleratorFunctionList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("acceleratorfunctions").
|
||||
@ -92,7 +92,7 @@ func (c *acceleratorFunctions) List(ctx context.Context, opts metav1.ListOptions
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested acceleratorFunctions.
|
||||
func (c *acceleratorFunctions) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) {
|
||||
func (c *acceleratorFunctions) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
@ -107,8 +107,8 @@ func (c *acceleratorFunctions) Watch(ctx context.Context, opts metav1.ListOption
|
||||
}
|
||||
|
||||
// Create takes the representation of a acceleratorFunction and creates it. Returns the server's representation of the acceleratorFunction, and an error, if there is any.
|
||||
func (c *acceleratorFunctions) Create(ctx context.Context, acceleratorFunction *v1.AcceleratorFunction, opts metav1.CreateOptions) (result *v1.AcceleratorFunction, err error) {
|
||||
result = &v1.AcceleratorFunction{}
|
||||
func (c *acceleratorFunctions) Create(ctx context.Context, acceleratorFunction *v2.AcceleratorFunction, opts v1.CreateOptions) (result *v2.AcceleratorFunction, err error) {
|
||||
result = &v2.AcceleratorFunction{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("acceleratorfunctions").
|
||||
@ -120,8 +120,8 @@ func (c *acceleratorFunctions) Create(ctx context.Context, acceleratorFunction *
|
||||
}
|
||||
|
||||
// Update takes the representation of a acceleratorFunction and updates it. Returns the server's representation of the acceleratorFunction, and an error, if there is any.
|
||||
func (c *acceleratorFunctions) Update(ctx context.Context, acceleratorFunction *v1.AcceleratorFunction, opts metav1.UpdateOptions) (result *v1.AcceleratorFunction, err error) {
|
||||
result = &v1.AcceleratorFunction{}
|
||||
func (c *acceleratorFunctions) Update(ctx context.Context, acceleratorFunction *v2.AcceleratorFunction, opts v1.UpdateOptions) (result *v2.AcceleratorFunction, err error) {
|
||||
result = &v2.AcceleratorFunction{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("acceleratorfunctions").
|
||||
@ -134,7 +134,7 @@ func (c *acceleratorFunctions) Update(ctx context.Context, acceleratorFunction *
|
||||
}
|
||||
|
||||
// Delete takes name of the acceleratorFunction and deletes it. Returns an error if one occurs.
|
||||
func (c *acceleratorFunctions) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
|
||||
func (c *acceleratorFunctions) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("acceleratorfunctions").
|
||||
@ -145,7 +145,7 @@ func (c *acceleratorFunctions) Delete(ctx context.Context, name string, opts met
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *acceleratorFunctions) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||
func (c *acceleratorFunctions) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
@ -161,8 +161,8 @@ func (c *acceleratorFunctions) DeleteCollection(ctx context.Context, opts metav1
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched acceleratorFunction.
|
||||
func (c *acceleratorFunctions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.AcceleratorFunction, err error) {
|
||||
result = &v1.AcceleratorFunction{}
|
||||
func (c *acceleratorFunctions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2.AcceleratorFunction, err error) {
|
||||
result = &v2.AcceleratorFunction{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("acceleratorfunctions").
|
@ -15,4 +15,4 @@
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1
|
||||
package v2
|
@ -19,7 +19,7 @@ package fake
|
||||
import (
|
||||
"context"
|
||||
|
||||
fpgaintelcomv1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v1"
|
||||
v2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v2"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@ -30,29 +30,29 @@ import (
|
||||
|
||||
// FakeAcceleratorFunctions implements AcceleratorFunctionInterface
|
||||
type FakeAcceleratorFunctions struct {
|
||||
Fake *FakeFpgaV1
|
||||
Fake *FakeFpgaV2
|
||||
ns string
|
||||
}
|
||||
|
||||
var acceleratorfunctionsResource = schema.GroupVersionResource{Group: "fpga.intel.com", Version: "v1", Resource: "acceleratorfunctions"}
|
||||
var acceleratorfunctionsResource = schema.GroupVersionResource{Group: "fpga.intel.com", Version: "v2", Resource: "acceleratorfunctions"}
|
||||
|
||||
var acceleratorfunctionsKind = schema.GroupVersionKind{Group: "fpga.intel.com", Version: "v1", Kind: "AcceleratorFunction"}
|
||||
var acceleratorfunctionsKind = schema.GroupVersionKind{Group: "fpga.intel.com", Version: "v2", Kind: "AcceleratorFunction"}
|
||||
|
||||
// Get takes name of the acceleratorFunction, and returns the corresponding acceleratorFunction object, and an error if there is any.
|
||||
func (c *FakeAcceleratorFunctions) Get(ctx context.Context, name string, options v1.GetOptions) (result *fpgaintelcomv1.AcceleratorFunction, err error) {
|
||||
func (c *FakeAcceleratorFunctions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v2.AcceleratorFunction, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(acceleratorfunctionsResource, c.ns, name), &fpgaintelcomv1.AcceleratorFunction{})
|
||||
Invokes(testing.NewGetAction(acceleratorfunctionsResource, c.ns, name), &v2.AcceleratorFunction{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*fpgaintelcomv1.AcceleratorFunction), err
|
||||
return obj.(*v2.AcceleratorFunction), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of AcceleratorFunctions that match those selectors.
|
||||
func (c *FakeAcceleratorFunctions) List(ctx context.Context, opts v1.ListOptions) (result *fpgaintelcomv1.AcceleratorFunctionList, err error) {
|
||||
func (c *FakeAcceleratorFunctions) List(ctx context.Context, opts v1.ListOptions) (result *v2.AcceleratorFunctionList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(acceleratorfunctionsResource, acceleratorfunctionsKind, c.ns, opts), &fpgaintelcomv1.AcceleratorFunctionList{})
|
||||
Invokes(testing.NewListAction(acceleratorfunctionsResource, acceleratorfunctionsKind, c.ns, opts), &v2.AcceleratorFunctionList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
@ -62,8 +62,8 @@ func (c *FakeAcceleratorFunctions) List(ctx context.Context, opts v1.ListOptions
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &fpgaintelcomv1.AcceleratorFunctionList{ListMeta: obj.(*fpgaintelcomv1.AcceleratorFunctionList).ListMeta}
|
||||
for _, item := range obj.(*fpgaintelcomv1.AcceleratorFunctionList).Items {
|
||||
list := &v2.AcceleratorFunctionList{ListMeta: obj.(*v2.AcceleratorFunctionList).ListMeta}
|
||||
for _, item := range obj.(*v2.AcceleratorFunctionList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
@ -79,31 +79,31 @@ func (c *FakeAcceleratorFunctions) Watch(ctx context.Context, opts v1.ListOption
|
||||
}
|
||||
|
||||
// Create takes the representation of a acceleratorFunction and creates it. Returns the server's representation of the acceleratorFunction, and an error, if there is any.
|
||||
func (c *FakeAcceleratorFunctions) Create(ctx context.Context, acceleratorFunction *fpgaintelcomv1.AcceleratorFunction, opts v1.CreateOptions) (result *fpgaintelcomv1.AcceleratorFunction, err error) {
|
||||
func (c *FakeAcceleratorFunctions) Create(ctx context.Context, acceleratorFunction *v2.AcceleratorFunction, opts v1.CreateOptions) (result *v2.AcceleratorFunction, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(acceleratorfunctionsResource, c.ns, acceleratorFunction), &fpgaintelcomv1.AcceleratorFunction{})
|
||||
Invokes(testing.NewCreateAction(acceleratorfunctionsResource, c.ns, acceleratorFunction), &v2.AcceleratorFunction{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*fpgaintelcomv1.AcceleratorFunction), err
|
||||
return obj.(*v2.AcceleratorFunction), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a acceleratorFunction and updates it. Returns the server's representation of the acceleratorFunction, and an error, if there is any.
|
||||
func (c *FakeAcceleratorFunctions) Update(ctx context.Context, acceleratorFunction *fpgaintelcomv1.AcceleratorFunction, opts v1.UpdateOptions) (result *fpgaintelcomv1.AcceleratorFunction, err error) {
|
||||
func (c *FakeAcceleratorFunctions) Update(ctx context.Context, acceleratorFunction *v2.AcceleratorFunction, opts v1.UpdateOptions) (result *v2.AcceleratorFunction, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(acceleratorfunctionsResource, c.ns, acceleratorFunction), &fpgaintelcomv1.AcceleratorFunction{})
|
||||
Invokes(testing.NewUpdateAction(acceleratorfunctionsResource, c.ns, acceleratorFunction), &v2.AcceleratorFunction{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*fpgaintelcomv1.AcceleratorFunction), err
|
||||
return obj.(*v2.AcceleratorFunction), err
|
||||
}
|
||||
|
||||
// Delete takes name of the acceleratorFunction and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeAcceleratorFunctions) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(acceleratorfunctionsResource, c.ns, name), &fpgaintelcomv1.AcceleratorFunction{})
|
||||
Invokes(testing.NewDeleteAction(acceleratorfunctionsResource, c.ns, name), &v2.AcceleratorFunction{})
|
||||
|
||||
return err
|
||||
}
|
||||
@ -112,17 +112,17 @@ func (c *FakeAcceleratorFunctions) Delete(ctx context.Context, name string, opts
|
||||
func (c *FakeAcceleratorFunctions) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(acceleratorfunctionsResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &fpgaintelcomv1.AcceleratorFunctionList{})
|
||||
_, err := c.Fake.Invokes(action, &v2.AcceleratorFunctionList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched acceleratorFunction.
|
||||
func (c *FakeAcceleratorFunctions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *fpgaintelcomv1.AcceleratorFunction, err error) {
|
||||
func (c *FakeAcceleratorFunctions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2.AcceleratorFunction, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(acceleratorfunctionsResource, c.ns, name, pt, data, subresources...), &fpgaintelcomv1.AcceleratorFunction{})
|
||||
Invokes(testing.NewPatchSubresourceAction(acceleratorfunctionsResource, c.ns, name, pt, data, subresources...), &v2.AcceleratorFunction{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*fpgaintelcomv1.AcceleratorFunction), err
|
||||
return obj.(*v2.AcceleratorFunction), err
|
||||
}
|
@ -17,26 +17,26 @@
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/clientset/versioned/typed/fpga.intel.com/v1"
|
||||
v2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/clientset/versioned/typed/fpga.intel.com/v2"
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
type FakeFpgaV1 struct {
|
||||
type FakeFpgaV2 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeFpgaV1) AcceleratorFunctions(namespace string) v1.AcceleratorFunctionInterface {
|
||||
func (c *FakeFpgaV2) AcceleratorFunctions(namespace string) v2.AcceleratorFunctionInterface {
|
||||
return &FakeAcceleratorFunctions{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeFpgaV1) FpgaRegions(namespace string) v1.FpgaRegionInterface {
|
||||
func (c *FakeFpgaV2) FpgaRegions(namespace string) v2.FpgaRegionInterface {
|
||||
return &FakeFpgaRegions{c, namespace}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeFpgaV1) RESTClient() rest.Interface {
|
||||
func (c *FakeFpgaV2) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
@ -19,7 +19,7 @@ package fake
|
||||
import (
|
||||
"context"
|
||||
|
||||
fpgaintelcomv1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v1"
|
||||
v2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v2"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@ -30,29 +30,29 @@ import (
|
||||
|
||||
// FakeFpgaRegions implements FpgaRegionInterface
|
||||
type FakeFpgaRegions struct {
|
||||
Fake *FakeFpgaV1
|
||||
Fake *FakeFpgaV2
|
||||
ns string
|
||||
}
|
||||
|
||||
var fpgaregionsResource = schema.GroupVersionResource{Group: "fpga.intel.com", Version: "v1", Resource: "fpgaregions"}
|
||||
var fpgaregionsResource = schema.GroupVersionResource{Group: "fpga.intel.com", Version: "v2", Resource: "fpgaregions"}
|
||||
|
||||
var fpgaregionsKind = schema.GroupVersionKind{Group: "fpga.intel.com", Version: "v1", Kind: "FpgaRegion"}
|
||||
var fpgaregionsKind = schema.GroupVersionKind{Group: "fpga.intel.com", Version: "v2", Kind: "FpgaRegion"}
|
||||
|
||||
// Get takes name of the fpgaRegion, and returns the corresponding fpgaRegion object, and an error if there is any.
|
||||
func (c *FakeFpgaRegions) Get(ctx context.Context, name string, options v1.GetOptions) (result *fpgaintelcomv1.FpgaRegion, err error) {
|
||||
func (c *FakeFpgaRegions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v2.FpgaRegion, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(fpgaregionsResource, c.ns, name), &fpgaintelcomv1.FpgaRegion{})
|
||||
Invokes(testing.NewGetAction(fpgaregionsResource, c.ns, name), &v2.FpgaRegion{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*fpgaintelcomv1.FpgaRegion), err
|
||||
return obj.(*v2.FpgaRegion), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of FpgaRegions that match those selectors.
|
||||
func (c *FakeFpgaRegions) List(ctx context.Context, opts v1.ListOptions) (result *fpgaintelcomv1.FpgaRegionList, err error) {
|
||||
func (c *FakeFpgaRegions) List(ctx context.Context, opts v1.ListOptions) (result *v2.FpgaRegionList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(fpgaregionsResource, fpgaregionsKind, c.ns, opts), &fpgaintelcomv1.FpgaRegionList{})
|
||||
Invokes(testing.NewListAction(fpgaregionsResource, fpgaregionsKind, c.ns, opts), &v2.FpgaRegionList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
@ -62,8 +62,8 @@ func (c *FakeFpgaRegions) List(ctx context.Context, opts v1.ListOptions) (result
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &fpgaintelcomv1.FpgaRegionList{ListMeta: obj.(*fpgaintelcomv1.FpgaRegionList).ListMeta}
|
||||
for _, item := range obj.(*fpgaintelcomv1.FpgaRegionList).Items {
|
||||
list := &v2.FpgaRegionList{ListMeta: obj.(*v2.FpgaRegionList).ListMeta}
|
||||
for _, item := range obj.(*v2.FpgaRegionList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
@ -79,31 +79,31 @@ func (c *FakeFpgaRegions) Watch(ctx context.Context, opts v1.ListOptions) (watch
|
||||
}
|
||||
|
||||
// Create takes the representation of a fpgaRegion and creates it. Returns the server's representation of the fpgaRegion, and an error, if there is any.
|
||||
func (c *FakeFpgaRegions) Create(ctx context.Context, fpgaRegion *fpgaintelcomv1.FpgaRegion, opts v1.CreateOptions) (result *fpgaintelcomv1.FpgaRegion, err error) {
|
||||
func (c *FakeFpgaRegions) Create(ctx context.Context, fpgaRegion *v2.FpgaRegion, opts v1.CreateOptions) (result *v2.FpgaRegion, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(fpgaregionsResource, c.ns, fpgaRegion), &fpgaintelcomv1.FpgaRegion{})
|
||||
Invokes(testing.NewCreateAction(fpgaregionsResource, c.ns, fpgaRegion), &v2.FpgaRegion{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*fpgaintelcomv1.FpgaRegion), err
|
||||
return obj.(*v2.FpgaRegion), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a fpgaRegion and updates it. Returns the server's representation of the fpgaRegion, and an error, if there is any.
|
||||
func (c *FakeFpgaRegions) Update(ctx context.Context, fpgaRegion *fpgaintelcomv1.FpgaRegion, opts v1.UpdateOptions) (result *fpgaintelcomv1.FpgaRegion, err error) {
|
||||
func (c *FakeFpgaRegions) Update(ctx context.Context, fpgaRegion *v2.FpgaRegion, opts v1.UpdateOptions) (result *v2.FpgaRegion, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(fpgaregionsResource, c.ns, fpgaRegion), &fpgaintelcomv1.FpgaRegion{})
|
||||
Invokes(testing.NewUpdateAction(fpgaregionsResource, c.ns, fpgaRegion), &v2.FpgaRegion{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*fpgaintelcomv1.FpgaRegion), err
|
||||
return obj.(*v2.FpgaRegion), err
|
||||
}
|
||||
|
||||
// Delete takes name of the fpgaRegion and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeFpgaRegions) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(fpgaregionsResource, c.ns, name), &fpgaintelcomv1.FpgaRegion{})
|
||||
Invokes(testing.NewDeleteAction(fpgaregionsResource, c.ns, name), &v2.FpgaRegion{})
|
||||
|
||||
return err
|
||||
}
|
||||
@ -112,17 +112,17 @@ func (c *FakeFpgaRegions) Delete(ctx context.Context, name string, opts v1.Delet
|
||||
func (c *FakeFpgaRegions) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(fpgaregionsResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &fpgaintelcomv1.FpgaRegionList{})
|
||||
_, err := c.Fake.Invokes(action, &v2.FpgaRegionList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched fpgaRegion.
|
||||
func (c *FakeFpgaRegions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *fpgaintelcomv1.FpgaRegion, err error) {
|
||||
func (c *FakeFpgaRegions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2.FpgaRegion, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(fpgaregionsResource, c.ns, name, pt, data, subresources...), &fpgaintelcomv1.FpgaRegion{})
|
||||
Invokes(testing.NewPatchSubresourceAction(fpgaregionsResource, c.ns, name, pt, data, subresources...), &v2.FpgaRegion{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*fpgaintelcomv1.FpgaRegion), err
|
||||
return obj.(*v2.FpgaRegion), err
|
||||
}
|
@ -14,35 +14,35 @@
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
package v2
|
||||
|
||||
import (
|
||||
v1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v1"
|
||||
v2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v2"
|
||||
"github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/clientset/versioned/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type FpgaV1Interface interface {
|
||||
type FpgaV2Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
AcceleratorFunctionsGetter
|
||||
FpgaRegionsGetter
|
||||
}
|
||||
|
||||
// FpgaV1Client is used to interact with features provided by the fpga.intel.com group.
|
||||
type FpgaV1Client struct {
|
||||
// FpgaV2Client is used to interact with features provided by the fpga.intel.com group.
|
||||
type FpgaV2Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *FpgaV1Client) AcceleratorFunctions(namespace string) AcceleratorFunctionInterface {
|
||||
func (c *FpgaV2Client) AcceleratorFunctions(namespace string) AcceleratorFunctionInterface {
|
||||
return newAcceleratorFunctions(c, namespace)
|
||||
}
|
||||
|
||||
func (c *FpgaV1Client) FpgaRegions(namespace string) FpgaRegionInterface {
|
||||
func (c *FpgaV2Client) FpgaRegions(namespace string) FpgaRegionInterface {
|
||||
return newFpgaRegions(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new FpgaV1Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*FpgaV1Client, error) {
|
||||
// NewForConfig creates a new FpgaV2Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*FpgaV2Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
@ -51,12 +51,12 @@ func NewForConfig(c *rest.Config) (*FpgaV1Client, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &FpgaV1Client{client}, nil
|
||||
return &FpgaV2Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new FpgaV1Client for the given config and
|
||||
// NewForConfigOrDie creates a new FpgaV2Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *FpgaV1Client {
|
||||
func NewForConfigOrDie(c *rest.Config) *FpgaV2Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@ -64,13 +64,13 @@ func NewForConfigOrDie(c *rest.Config) *FpgaV1Client {
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new FpgaV1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *FpgaV1Client {
|
||||
return &FpgaV1Client{c}
|
||||
// New creates a new FpgaV2Client for the given RESTClient.
|
||||
func New(c rest.Interface) *FpgaV2Client {
|
||||
return &FpgaV2Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
gv := v1.SchemeGroupVersion
|
||||
gv := v2.SchemeGroupVersion
|
||||
config.GroupVersion = &gv
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
|
||||
@ -84,7 +84,7 @@ func setConfigDefaults(config *rest.Config) error {
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FpgaV1Client) RESTClient() rest.Interface {
|
||||
func (c *FpgaV2Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
@ -14,15 +14,15 @@
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v1"
|
||||
v2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v2"
|
||||
scheme "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/clientset/versioned/scheme"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
@ -36,14 +36,14 @@ type FpgaRegionsGetter interface {
|
||||
|
||||
// FpgaRegionInterface has methods to work with FpgaRegion resources.
|
||||
type FpgaRegionInterface interface {
|
||||
Create(ctx context.Context, fpgaRegion *v1.FpgaRegion, opts metav1.CreateOptions) (*v1.FpgaRegion, error)
|
||||
Update(ctx context.Context, fpgaRegion *v1.FpgaRegion, opts metav1.UpdateOptions) (*v1.FpgaRegion, error)
|
||||
Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.FpgaRegion, error)
|
||||
List(ctx context.Context, opts metav1.ListOptions) (*v1.FpgaRegionList, error)
|
||||
Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.FpgaRegion, err error)
|
||||
Create(ctx context.Context, fpgaRegion *v2.FpgaRegion, opts v1.CreateOptions) (*v2.FpgaRegion, error)
|
||||
Update(ctx context.Context, fpgaRegion *v2.FpgaRegion, opts v1.UpdateOptions) (*v2.FpgaRegion, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*v2.FpgaRegion, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v2.FpgaRegionList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2.FpgaRegion, err error)
|
||||
FpgaRegionExpansion
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ type fpgaRegions struct {
|
||||
}
|
||||
|
||||
// newFpgaRegions returns a FpgaRegions
|
||||
func newFpgaRegions(c *FpgaV1Client, namespace string) *fpgaRegions {
|
||||
func newFpgaRegions(c *FpgaV2Client, namespace string) *fpgaRegions {
|
||||
return &fpgaRegions{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
@ -62,8 +62,8 @@ func newFpgaRegions(c *FpgaV1Client, namespace string) *fpgaRegions {
|
||||
}
|
||||
|
||||
// Get takes name of the fpgaRegion, and returns the corresponding fpgaRegion object, and an error if there is any.
|
||||
func (c *fpgaRegions) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.FpgaRegion, err error) {
|
||||
result = &v1.FpgaRegion{}
|
||||
func (c *fpgaRegions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v2.FpgaRegion, err error) {
|
||||
result = &v2.FpgaRegion{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("fpgaregions").
|
||||
@ -75,12 +75,12 @@ func (c *fpgaRegions) Get(ctx context.Context, name string, options metav1.GetOp
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of FpgaRegions that match those selectors.
|
||||
func (c *fpgaRegions) List(ctx context.Context, opts metav1.ListOptions) (result *v1.FpgaRegionList, err error) {
|
||||
func (c *fpgaRegions) List(ctx context.Context, opts v1.ListOptions) (result *v2.FpgaRegionList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1.FpgaRegionList{}
|
||||
result = &v2.FpgaRegionList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("fpgaregions").
|
||||
@ -92,7 +92,7 @@ func (c *fpgaRegions) List(ctx context.Context, opts metav1.ListOptions) (result
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested fpgaRegions.
|
||||
func (c *fpgaRegions) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) {
|
||||
func (c *fpgaRegions) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
@ -107,8 +107,8 @@ func (c *fpgaRegions) Watch(ctx context.Context, opts metav1.ListOptions) (watch
|
||||
}
|
||||
|
||||
// Create takes the representation of a fpgaRegion and creates it. Returns the server's representation of the fpgaRegion, and an error, if there is any.
|
||||
func (c *fpgaRegions) Create(ctx context.Context, fpgaRegion *v1.FpgaRegion, opts metav1.CreateOptions) (result *v1.FpgaRegion, err error) {
|
||||
result = &v1.FpgaRegion{}
|
||||
func (c *fpgaRegions) Create(ctx context.Context, fpgaRegion *v2.FpgaRegion, opts v1.CreateOptions) (result *v2.FpgaRegion, err error) {
|
||||
result = &v2.FpgaRegion{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("fpgaregions").
|
||||
@ -120,8 +120,8 @@ func (c *fpgaRegions) Create(ctx context.Context, fpgaRegion *v1.FpgaRegion, opt
|
||||
}
|
||||
|
||||
// Update takes the representation of a fpgaRegion and updates it. Returns the server's representation of the fpgaRegion, and an error, if there is any.
|
||||
func (c *fpgaRegions) Update(ctx context.Context, fpgaRegion *v1.FpgaRegion, opts metav1.UpdateOptions) (result *v1.FpgaRegion, err error) {
|
||||
result = &v1.FpgaRegion{}
|
||||
func (c *fpgaRegions) Update(ctx context.Context, fpgaRegion *v2.FpgaRegion, opts v1.UpdateOptions) (result *v2.FpgaRegion, err error) {
|
||||
result = &v2.FpgaRegion{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("fpgaregions").
|
||||
@ -134,7 +134,7 @@ func (c *fpgaRegions) Update(ctx context.Context, fpgaRegion *v1.FpgaRegion, opt
|
||||
}
|
||||
|
||||
// Delete takes name of the fpgaRegion and deletes it. Returns an error if one occurs.
|
||||
func (c *fpgaRegions) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
|
||||
func (c *fpgaRegions) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("fpgaregions").
|
||||
@ -145,7 +145,7 @@ func (c *fpgaRegions) Delete(ctx context.Context, name string, opts metav1.Delet
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *fpgaRegions) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||
func (c *fpgaRegions) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
@ -161,8 +161,8 @@ func (c *fpgaRegions) DeleteCollection(ctx context.Context, opts metav1.DeleteOp
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched fpgaRegion.
|
||||
func (c *fpgaRegions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.FpgaRegion, err error) {
|
||||
result = &v1.FpgaRegion{}
|
||||
func (c *fpgaRegions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v2.FpgaRegion, err error) {
|
||||
result = &v2.FpgaRegion{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("fpgaregions").
|
@ -14,7 +14,7 @@
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
package v2
|
||||
|
||||
type AcceleratorFunctionExpansion interface{}
|
||||
|
@ -17,14 +17,14 @@
|
||||
package fpga
|
||||
|
||||
import (
|
||||
v1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/informers/externalversions/fpga.intel.com/v1"
|
||||
v2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/informers/externalversions/fpga.intel.com/v2"
|
||||
internalinterfaces "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to each of this group's versions.
|
||||
type Interface interface {
|
||||
// V1 provides access to shared informers for resources in V1.
|
||||
V1() v1.Interface
|
||||
// V2 provides access to shared informers for resources in V2.
|
||||
V2() v2.Interface
|
||||
}
|
||||
|
||||
type group struct {
|
||||
@ -38,7 +38,7 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
|
||||
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// V1 returns a new v1.Interface.
|
||||
func (g *group) V1() v1.Interface {
|
||||
return v1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
// V2 returns a new v2.Interface.
|
||||
func (g *group) V2() v2.Interface {
|
||||
return v2.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
|
@ -14,17 +14,17 @@
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
time "time"
|
||||
|
||||
fpgaintelcomv1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v1"
|
||||
fpgaintelcomv2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v2"
|
||||
versioned "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/clientset/versioned"
|
||||
internalinterfaces "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/listers/fpga.intel.com/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
v2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/listers/fpga.intel.com/v2"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
@ -34,7 +34,7 @@ import (
|
||||
// AcceleratorFunctions.
|
||||
type AcceleratorFunctionInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1.AcceleratorFunctionLister
|
||||
Lister() v2.AcceleratorFunctionLister
|
||||
}
|
||||
|
||||
type acceleratorFunctionInformer struct {
|
||||
@ -56,20 +56,20 @@ func NewAcceleratorFunctionInformer(client versioned.Interface, namespace string
|
||||
func NewFilteredAcceleratorFunctionInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.FpgaV1().AcceleratorFunctions(namespace).List(context.TODO(), options)
|
||||
return client.FpgaV2().AcceleratorFunctions(namespace).List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.FpgaV1().AcceleratorFunctions(namespace).Watch(context.TODO(), options)
|
||||
return client.FpgaV2().AcceleratorFunctions(namespace).Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
&fpgaintelcomv1.AcceleratorFunction{},
|
||||
&fpgaintelcomv2.AcceleratorFunction{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@ -80,9 +80,9 @@ func (f *acceleratorFunctionInformer) defaultInformer(client versioned.Interface
|
||||
}
|
||||
|
||||
func (f *acceleratorFunctionInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&fpgaintelcomv1.AcceleratorFunction{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&fpgaintelcomv2.AcceleratorFunction{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *acceleratorFunctionInformer) Lister() v1.AcceleratorFunctionLister {
|
||||
return v1.NewAcceleratorFunctionLister(f.Informer().GetIndexer())
|
||||
func (f *acceleratorFunctionInformer) Lister() v2.AcceleratorFunctionLister {
|
||||
return v2.NewAcceleratorFunctionLister(f.Informer().GetIndexer())
|
||||
}
|
@ -14,17 +14,17 @@
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
time "time"
|
||||
|
||||
fpgaintelcomv1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v1"
|
||||
fpgaintelcomv2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v2"
|
||||
versioned "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/clientset/versioned"
|
||||
internalinterfaces "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/listers/fpga.intel.com/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
v2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/listers/fpga.intel.com/v2"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
@ -34,7 +34,7 @@ import (
|
||||
// FpgaRegions.
|
||||
type FpgaRegionInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1.FpgaRegionLister
|
||||
Lister() v2.FpgaRegionLister
|
||||
}
|
||||
|
||||
type fpgaRegionInformer struct {
|
||||
@ -56,20 +56,20 @@ func NewFpgaRegionInformer(client versioned.Interface, namespace string, resyncP
|
||||
func NewFilteredFpgaRegionInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.FpgaV1().FpgaRegions(namespace).List(context.TODO(), options)
|
||||
return client.FpgaV2().FpgaRegions(namespace).List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.FpgaV1().FpgaRegions(namespace).Watch(context.TODO(), options)
|
||||
return client.FpgaV2().FpgaRegions(namespace).Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
&fpgaintelcomv1.FpgaRegion{},
|
||||
&fpgaintelcomv2.FpgaRegion{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@ -80,9 +80,9 @@ func (f *fpgaRegionInformer) defaultInformer(client versioned.Interface, resyncP
|
||||
}
|
||||
|
||||
func (f *fpgaRegionInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&fpgaintelcomv1.FpgaRegion{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&fpgaintelcomv2.FpgaRegion{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *fpgaRegionInformer) Lister() v1.FpgaRegionLister {
|
||||
return v1.NewFpgaRegionLister(f.Informer().GetIndexer())
|
||||
func (f *fpgaRegionInformer) Lister() v2.FpgaRegionLister {
|
||||
return v2.NewFpgaRegionLister(f.Informer().GetIndexer())
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
package v2
|
||||
|
||||
import (
|
||||
internalinterfaces "github.com/intel/intel-device-plugins-for-kubernetes/pkg/client/informers/externalversions/internalinterfaces"
|
@ -19,7 +19,7 @@ package externalversions
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v1"
|
||||
v2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v2"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
@ -50,11 +50,11 @@ func (f *genericInformer) Lister() cache.GenericLister {
|
||||
// TODO extend this to unknown resources with a client pool
|
||||
func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) {
|
||||
switch resource {
|
||||
// Group=fpga.intel.com, Version=v1
|
||||
case v1.SchemeGroupVersion.WithResource("acceleratorfunctions"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Fpga().V1().AcceleratorFunctions().Informer()}, nil
|
||||
case v1.SchemeGroupVersion.WithResource("fpgaregions"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Fpga().V1().FpgaRegions().Informer()}, nil
|
||||
// Group=fpga.intel.com, Version=v2
|
||||
case v2.SchemeGroupVersion.WithResource("acceleratorfunctions"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Fpga().V2().AcceleratorFunctions().Informer()}, nil
|
||||
case v2.SchemeGroupVersion.WithResource("fpgaregions"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Fpga().V2().FpgaRegions().Informer()}, nil
|
||||
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,10 @@
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
package v2
|
||||
|
||||
import (
|
||||
v1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v1"
|
||||
v2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v2"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
@ -26,7 +26,7 @@ import (
|
||||
// AcceleratorFunctionLister helps list AcceleratorFunctions.
|
||||
type AcceleratorFunctionLister interface {
|
||||
// List lists all AcceleratorFunctions in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1.AcceleratorFunction, err error)
|
||||
List(selector labels.Selector) (ret []*v2.AcceleratorFunction, err error)
|
||||
// AcceleratorFunctions returns an object that can list and get AcceleratorFunctions.
|
||||
AcceleratorFunctions(namespace string) AcceleratorFunctionNamespaceLister
|
||||
AcceleratorFunctionListerExpansion
|
||||
@ -43,9 +43,9 @@ func NewAcceleratorFunctionLister(indexer cache.Indexer) AcceleratorFunctionList
|
||||
}
|
||||
|
||||
// List lists all AcceleratorFunctions in the indexer.
|
||||
func (s *acceleratorFunctionLister) List(selector labels.Selector) (ret []*v1.AcceleratorFunction, err error) {
|
||||
func (s *acceleratorFunctionLister) List(selector labels.Selector) (ret []*v2.AcceleratorFunction, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1.AcceleratorFunction))
|
||||
ret = append(ret, m.(*v2.AcceleratorFunction))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
@ -58,9 +58,9 @@ func (s *acceleratorFunctionLister) AcceleratorFunctions(namespace string) Accel
|
||||
// AcceleratorFunctionNamespaceLister helps list and get AcceleratorFunctions.
|
||||
type AcceleratorFunctionNamespaceLister interface {
|
||||
// List lists all AcceleratorFunctions in the indexer for a given namespace.
|
||||
List(selector labels.Selector) (ret []*v1.AcceleratorFunction, err error)
|
||||
List(selector labels.Selector) (ret []*v2.AcceleratorFunction, err error)
|
||||
// Get retrieves the AcceleratorFunction from the indexer for a given namespace and name.
|
||||
Get(name string) (*v1.AcceleratorFunction, error)
|
||||
Get(name string) (*v2.AcceleratorFunction, error)
|
||||
AcceleratorFunctionNamespaceListerExpansion
|
||||
}
|
||||
|
||||
@ -72,21 +72,21 @@ type acceleratorFunctionNamespaceLister struct {
|
||||
}
|
||||
|
||||
// List lists all AcceleratorFunctions in the indexer for a given namespace.
|
||||
func (s acceleratorFunctionNamespaceLister) List(selector labels.Selector) (ret []*v1.AcceleratorFunction, err error) {
|
||||
func (s acceleratorFunctionNamespaceLister) List(selector labels.Selector) (ret []*v2.AcceleratorFunction, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1.AcceleratorFunction))
|
||||
ret = append(ret, m.(*v2.AcceleratorFunction))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the AcceleratorFunction from the indexer for a given namespace and name.
|
||||
func (s acceleratorFunctionNamespaceLister) Get(name string) (*v1.AcceleratorFunction, error) {
|
||||
func (s acceleratorFunctionNamespaceLister) Get(name string) (*v2.AcceleratorFunction, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1.Resource("acceleratorfunction"), name)
|
||||
return nil, errors.NewNotFound(v2.Resource("acceleratorfunction"), name)
|
||||
}
|
||||
return obj.(*v1.AcceleratorFunction), nil
|
||||
return obj.(*v2.AcceleratorFunction), nil
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
package v2
|
||||
|
||||
// AcceleratorFunctionListerExpansion allows custom methods to be added to
|
||||
// AcceleratorFunctionLister.
|
@ -14,10 +14,10 @@
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
package v2
|
||||
|
||||
import (
|
||||
v1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v1"
|
||||
v2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga.intel.com/v2"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
@ -26,7 +26,7 @@ import (
|
||||
// FpgaRegionLister helps list FpgaRegions.
|
||||
type FpgaRegionLister interface {
|
||||
// List lists all FpgaRegions in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1.FpgaRegion, err error)
|
||||
List(selector labels.Selector) (ret []*v2.FpgaRegion, err error)
|
||||
// FpgaRegions returns an object that can list and get FpgaRegions.
|
||||
FpgaRegions(namespace string) FpgaRegionNamespaceLister
|
||||
FpgaRegionListerExpansion
|
||||
@ -43,9 +43,9 @@ func NewFpgaRegionLister(indexer cache.Indexer) FpgaRegionLister {
|
||||
}
|
||||
|
||||
// List lists all FpgaRegions in the indexer.
|
||||
func (s *fpgaRegionLister) List(selector labels.Selector) (ret []*v1.FpgaRegion, err error) {
|
||||
func (s *fpgaRegionLister) List(selector labels.Selector) (ret []*v2.FpgaRegion, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1.FpgaRegion))
|
||||
ret = append(ret, m.(*v2.FpgaRegion))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
@ -58,9 +58,9 @@ func (s *fpgaRegionLister) FpgaRegions(namespace string) FpgaRegionNamespaceList
|
||||
// FpgaRegionNamespaceLister helps list and get FpgaRegions.
|
||||
type FpgaRegionNamespaceLister interface {
|
||||
// List lists all FpgaRegions in the indexer for a given namespace.
|
||||
List(selector labels.Selector) (ret []*v1.FpgaRegion, err error)
|
||||
List(selector labels.Selector) (ret []*v2.FpgaRegion, err error)
|
||||
// Get retrieves the FpgaRegion from the indexer for a given namespace and name.
|
||||
Get(name string) (*v1.FpgaRegion, error)
|
||||
Get(name string) (*v2.FpgaRegion, error)
|
||||
FpgaRegionNamespaceListerExpansion
|
||||
}
|
||||
|
||||
@ -72,21 +72,21 @@ type fpgaRegionNamespaceLister struct {
|
||||
}
|
||||
|
||||
// List lists all FpgaRegions in the indexer for a given namespace.
|
||||
func (s fpgaRegionNamespaceLister) List(selector labels.Selector) (ret []*v1.FpgaRegion, err error) {
|
||||
func (s fpgaRegionNamespaceLister) List(selector labels.Selector) (ret []*v2.FpgaRegion, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1.FpgaRegion))
|
||||
ret = append(ret, m.(*v2.FpgaRegion))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the FpgaRegion from the indexer for a given namespace and name.
|
||||
func (s fpgaRegionNamespaceLister) Get(name string) (*v1.FpgaRegion, error) {
|
||||
func (s fpgaRegionNamespaceLister) Get(name string) (*v2.FpgaRegion, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1.Resource("fpgaregion"), name)
|
||||
return nil, errors.NewNotFound(v2.Resource("fpgaregion"), name)
|
||||
}
|
||||
return obj.(*v1.FpgaRegion), nil
|
||||
return obj.(*v2.FpgaRegion), nil
|
||||
}
|
36
pkg/fpga/devtypes.go
Normal file
36
pkg/fpga/devtypes.go
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright 2020 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package fpga
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// GetAfuDevType returns extended resource name for AFU without namespace.
|
||||
// Since in Linux unix socket addresses can't be longer than 108 chars we need
|
||||
// to compress devtype a bit, because it's used as a part of the socket's address.
|
||||
// Also names of extended resources (without namespace) cannot be longer than 63 characters.
|
||||
func GetAfuDevType(interfaceID, afuID string) (string, error) {
|
||||
bin, err := hex.DecodeString(interfaceID + afuID)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "failed to decode %q and %q", interfaceID, afuID)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("af-%s.%s.%s", interfaceID[:3], afuID[:3], base64.RawURLEncoding.EncodeToString(bin)), nil
|
||||
}
|
66
pkg/fpga/devtypes_test.go
Normal file
66
pkg/fpga/devtypes_test.go
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright 2020 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package fpga
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.Set("v", "4")
|
||||
}
|
||||
|
||||
func TestGetAfuDevType(t *testing.T) {
|
||||
tcases := []struct {
|
||||
name string
|
||||
interfaceID string
|
||||
afuID string
|
||||
expectedDevType string
|
||||
expectedErr bool
|
||||
}{
|
||||
{
|
||||
name: "Everything is correct 1",
|
||||
interfaceID: "ce48969398f05f33946d560708be108a",
|
||||
afuID: "d8424dc4a4a3c413f89e433683f9040b",
|
||||
expectedDevType: "af-ce4.d84.zkiWk5jwXzOUbVYHCL4QithCTcSko8QT-J5DNoP5BAs",
|
||||
},
|
||||
{
|
||||
name: "Everything is correct 2",
|
||||
interfaceID: "bfac4d851ee856fe8c95865ce1bbaa2d",
|
||||
afuID: "f7df405cbd7acf7222f144b0b93acd18",
|
||||
expectedDevType: "af-bfa.f7d.v6xNhR7oVv6MlYZc4buqLfffQFy9es9yIvFEsLk6zRg",
|
||||
},
|
||||
{
|
||||
name: "unparsable interfaceID",
|
||||
interfaceID: "unparsable",
|
||||
expectedErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tcases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
devtype, err := GetAfuDevType(tt.interfaceID, tt.afuID)
|
||||
if tt.expectedErr && err == nil {
|
||||
t.Errorf("no error returned")
|
||||
}
|
||||
if !tt.expectedErr && err != nil {
|
||||
t.Errorf("unexpected error: %+v", err)
|
||||
}
|
||||
if tt.expectedDevType != devtype {
|
||||
t.Errorf("expected %q, but got %q", tt.expectedDevType, devtype)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -28,6 +28,6 @@ PKG_PATH="github.com/intel/intel-device-plugins-for-kubernetes/pkg"
|
||||
# instead of the $GOPATH directly. For normal projects this can be dropped.
|
||||
${CODEGEN_PKG}/generate-groups.sh "deepcopy,client,informer,lister" \
|
||||
${PKG_PATH}/client ${PKG_PATH}/apis \
|
||||
fpga.intel.com:v1 \
|
||||
fpga.intel.com:v2 \
|
||||
--output-base "$(dirname ${BASH_SOURCE})/../../../.." \
|
||||
--go-header-file ${SCRIPT_ROOT}/build/boilerplate/boilerplate.go.txt
|
||||
|
@ -15,7 +15,6 @@ function help {
|
||||
echo ''
|
||||
echo ' Options:'
|
||||
echo ' --kubectl <kubectl> - path to the kubectl utility'
|
||||
echo ' --mode <mode> - "preprogrammed" (default) or "orchestrated" mode of operation'
|
||||
echo ' --ca-bundle-path <path> - path to CA bundle used for signing cerificates in the cluster'
|
||||
echo ' --namespace <name> - namespace to deploy the webhook in'
|
||||
}
|
||||
@ -30,10 +29,6 @@ while [[ $# -gt 0 ]]; do
|
||||
cabundlepath="$2"
|
||||
shift
|
||||
;;
|
||||
--mode)
|
||||
mode="$2"
|
||||
shift
|
||||
;;
|
||||
--namespace)
|
||||
namespace="$2"
|
||||
shift
|
||||
@ -54,7 +49,6 @@ while [[ $# -gt 0 ]]; do
|
||||
done
|
||||
|
||||
[ -z ${kubectl} ] && kubectl="kubectl"
|
||||
[ -z ${mode} ] && mode="preprogrammed"
|
||||
[ -z ${namespace} ] && namespace="default"
|
||||
|
||||
which ${kubectl} > /dev/null 2>&1 || { echo "ERROR: ${kubectl} not found"; exit 1; }
|
||||
@ -75,11 +69,6 @@ if [ "x${command}" = "xcleanup" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "x${mode}" != "xpreprogrammed" -a "x${mode}" != "xorchestrated" ]; then
|
||||
echo "ERROR: supported modes are 'preprogrammed' and 'orchestrated'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z ${cabundlepath} ]; then
|
||||
CA_BUNDLE=$(${kubectl} get configmap -n kube-system extension-apiserver-authentication -o=jsonpath='{.data.client-ca-file}' | base64 -w 0)
|
||||
else
|
||||
@ -98,7 +87,7 @@ cat ${srcroot}/deployments/fpga_admissionwebhook/rbac-config-tpl.yaml | \
|
||||
${kubectl} create -f -
|
||||
|
||||
echo "Create webhook deployment"
|
||||
cat ${srcroot}/deployments/fpga_admissionwebhook/deployment-tpl.yaml | sed -e "s/{MODE}/${mode}/g" -e "s/{uid}/${uid}/g" -e "s/{gid}/${gid}/g" | ${kubectl} --namespace ${namespace} create -f -
|
||||
cat ${srcroot}/deployments/fpga_admissionwebhook/deployment-tpl.yaml | sed -e "s/{uid}/${uid}/g" -e "s/{gid}/${gid}/g" | ${kubectl} --namespace ${namespace} create -f -
|
||||
|
||||
echo "Create webhook service"
|
||||
${kubectl} --namespace ${namespace} create -f ${srcroot}/deployments/fpga_admissionwebhook/service.yaml
|
||||
|
@ -33,9 +33,10 @@ import (
|
||||
const (
|
||||
pluginDeployScript = "scripts/deploy-fpgaplugin.sh"
|
||||
webhookDeployScript = "scripts/webhook-deploy.sh"
|
||||
nlb0NodeResource = "fpga.intel.com/af-d8424dc4a4a3c413f89e433683f9040b"
|
||||
nlb0PodResource = "fpga.intel.com/arria10.dcp1.2-nlb0"
|
||||
nlb3PodResource = "fpga.intel.com/arria10.dcp1.2-nlb3"
|
||||
nlb0NodeResource = "fpga.intel.com/af-695.d84.aVKNtusxV3qMNmj5-qCB9thCTcSko8QT-J5DNoP5BAs"
|
||||
nlb0PodResource = "fpga.intel.com/arria10.dcp1.2-nlb0-orchestrated"
|
||||
nlb3PodResource = "fpga.intel.com/arria10.dcp1.2-nlb3-orchestrated"
|
||||
nlb0PodResourceAF = "fpga.intel.com/arria10.dcp1.2-nlb0-preprogrammed"
|
||||
arria10NodeResource = "fpga.intel.com/region-69528db6eb31577a8c3668f9faa081f6"
|
||||
)
|
||||
|
||||
@ -57,23 +58,23 @@ func describe() {
|
||||
fmw := framework.NewDefaultFramework("fpgaplugin-e2e")
|
||||
|
||||
ginkgo.It("Run FPGA plugin tests", func() {
|
||||
// Deploy webhook
|
||||
ginkgo.By(fmt.Sprintf("namespace %s: deploying webhook", fmw.Namespace.Name))
|
||||
_, _, err := framework.RunCmd(webhookDeployScriptPath, "--namespace", fmw.Namespace.Name)
|
||||
framework.ExpectNoError(err)
|
||||
waitForPod(fmw, "intel-fpga-webhook")
|
||||
|
||||
// Run region test case twice to ensure that device is reprogrammed at least once
|
||||
runTestCase(fmw, webhookDeployScriptPath, pluginDeployScriptPath, "region", "orchestrated", arria10NodeResource, nlb3PodResource, "nlb3", "nlb0")
|
||||
runTestCase(fmw, webhookDeployScriptPath, pluginDeployScriptPath, "region", "orchestrated", arria10NodeResource, nlb0PodResource, "nlb0", "nlb3")
|
||||
runTestCase(fmw, pluginDeployScriptPath, "region", arria10NodeResource, nlb3PodResource, "nlb3", "nlb0")
|
||||
runTestCase(fmw, pluginDeployScriptPath, "region", arria10NodeResource, nlb0PodResource, "nlb0", "nlb3")
|
||||
// Run af test case
|
||||
runTestCase(fmw, webhookDeployScriptPath, pluginDeployScriptPath, "af", "preprogrammed", nlb0NodeResource, nlb0PodResource, "nlb0", "nlb3")
|
||||
runTestCase(fmw, pluginDeployScriptPath, "af", nlb0NodeResource, nlb0PodResourceAF, "nlb0", "nlb3")
|
||||
})
|
||||
}
|
||||
|
||||
func runTestCase(fmw *framework.Framework, webhookDeployScriptPath, pluginDeployScriptPath, pluginMode, webhookMode, nodeResource, podResource, cmd1, cmd2 string) {
|
||||
ginkgo.By(fmt.Sprintf("deploying webhook in %s mode", webhookMode))
|
||||
_, _, err := framework.RunCmd(webhookDeployScriptPath, "--mode", webhookMode, "--namespace", fmw.Namespace.Name)
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
waitForPod(fmw, "intel-fpga-webhook")
|
||||
|
||||
ginkgo.By(fmt.Sprintf("deploying FPGA plugin in %s mode", pluginMode))
|
||||
_, _, err = framework.RunCmd(pluginDeployScriptPath, "--mode", pluginMode, "--namespace", fmw.Namespace.Name)
|
||||
func runTestCase(fmw *framework.Framework, pluginDeployScriptPath, pluginMode, nodeResource, podResource, cmd1, cmd2 string) {
|
||||
ginkgo.By(fmt.Sprintf("namespace %s: deploying FPGA plugin in %s mode", fmw.Namespace.Name, pluginMode))
|
||||
_, _, err := framework.RunCmd(pluginDeployScriptPath, "--mode", pluginMode, "--namespace", fmw.Namespace.Name)
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
waitForPod(fmw, "intel-fpga-plugin")
|
||||
@ -88,18 +89,17 @@ func runTestCase(fmw *framework.Framework, webhookDeployScriptPath, pluginDeploy
|
||||
image := "intel/opae-nlb-demo:devel"
|
||||
|
||||
ginkgo.By("submitting a pod requesting correct FPGA resources")
|
||||
pod := createPod(fmw, fmt.Sprintf("fpgaplugin-nlb-%s-%s-%s-correct", pluginMode, cmd1, cmd2), resource, image, []string{cmd1})
|
||||
pod := createPod(fmw, fmt.Sprintf("fpgaplugin-%s-%s-%s-correct", pluginMode, cmd1, cmd2), resource, image, []string{cmd1, "-S0"})
|
||||
|
||||
ginkgo.By("waiting the pod to finish successfully")
|
||||
fmw.PodClient().WaitForSuccess(pod.ObjectMeta.Name, 60*time.Second)
|
||||
// If WaitForSuccess fails, ginkgo doesn't show the logs of the failed container.
|
||||
// Replacing WaitForSuccess with WaitForFinish + 'kubelet logs' would show the logs
|
||||
// fmw.PodClient().WaitForFinish(pod.ObjectMeta.Name, 60*time.Second)
|
||||
// framework.RunKubectlOrDie(fmw.Namespace.Name, "--namespace", fmw.Namespace.Name, "logs", pod.ObjectMeta.Name)
|
||||
// return
|
||||
//fmw.PodClient().WaitForFinish(pod.ObjectMeta.Name, 60*time.Second)
|
||||
//framework.RunKubectlOrDie(fmw.Namespace.Name, "--namespace", fmw.Namespace.Name, "logs", pod.ObjectMeta.Name)
|
||||
|
||||
ginkgo.By("submitting a pod requesting incorrect FPGA resources")
|
||||
pod = createPod(fmw, fmt.Sprintf("fpgaplugin-nlb-%s-%s-%s-incorrect", pluginMode, cmd1, cmd2), resource, image, []string{cmd2})
|
||||
pod = createPod(fmw, fmt.Sprintf("fpgaplugin-%s-%s-%s-incorrect", pluginMode, cmd1, cmd2), resource, image, []string{cmd2, "-S0"})
|
||||
|
||||
ginkgo.By("waiting the pod failure")
|
||||
utils.WaitForPodFailure(fmw, pod.ObjectMeta.Name, 60*time.Second)
|
||||
|
@ -51,25 +51,37 @@ func describe() {
|
||||
return append(os.Environ(), "KUBECONFIG="+framework.TestContext.KubeConfig)
|
||||
}
|
||||
|
||||
ginkgo.It("mutates created pods to reference resolved AFs in preprogrammed mode", func() {
|
||||
ginkgo.By("deploying webhook in preprogrammed mode")
|
||||
ginkgo.It("mutates created pods to reference resolved AFs", func() {
|
||||
ginkgo.By("deploying webhook")
|
||||
_, _, err := framework.RunCmdEnv(getEnv(), webhookDeployPath, "--kubectl", framework.TestContext.KubectlPath, "--namespace", f.Namespace.Name)
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
checkPodMutation(f, "fpga.intel.com/af-d8424dc4a4a3c413f89e433683f9040b")
|
||||
checkPodMutation(f, "fpga.intel.com/d5005-nlb3-preprogrammed",
|
||||
"fpga.intel.com/af-bfa.f7d.v6xNhR7oVv6MlYZc4buqLfffQFy9es9yIvFEsLk6zRg")
|
||||
})
|
||||
|
||||
ginkgo.It("mutates created pods to reference resolved Regions in orchestrated mode", func() {
|
||||
ginkgo.By("deploying webhook in orchestrated mode")
|
||||
_, _, err := framework.RunCmdEnv(getEnv(), webhookDeployPath, "--kubectl", framework.TestContext.KubectlPath, "--namespace", f.Namespace.Name, "--mode", "orchestrated")
|
||||
ginkgo.It("mutates created pods to reference resolved Regions", func() {
|
||||
ginkgo.By("deploying webhook")
|
||||
_, _, err := framework.RunCmdEnv(getEnv(), webhookDeployPath, "--kubectl", framework.TestContext.KubectlPath, "--namespace", f.Namespace.Name)
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
checkPodMutation(f, "fpga.intel.com/region-ce48969398f05f33946d560708be108a")
|
||||
checkPodMutation(f, "fpga.intel.com/arria10.dcp1.0-nlb0-orchestrated",
|
||||
"fpga.intel.com/region-ce48969398f05f33946d560708be108a")
|
||||
|
||||
})
|
||||
|
||||
ginkgo.It("mutates created pods to reference resolved Regions in regiondevel mode", func() {
|
||||
ginkgo.By("deploying webhook")
|
||||
_, _, err := framework.RunCmdEnv(getEnv(), webhookDeployPath, "--kubectl", framework.TestContext.KubectlPath, "--namespace", f.Namespace.Name)
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
checkPodMutation(f, "fpga.intel.com/arria10.dcp1.0",
|
||||
"fpga.intel.com/region-ce48969398f05f33946d560708be108a")
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func checkPodMutation(f *framework.Framework, expectedMutation v1.ResourceName) {
|
||||
func checkPodMutation(f *framework.Framework, source, expectedMutation v1.ResourceName) {
|
||||
ginkgo.By("waiting for webhook's availability")
|
||||
if _, err := e2epod.WaitForPodsWithLabelRunningReady(f.ClientSet, f.Namespace.Name,
|
||||
labels.Set{"app": "intel-fpga-webhook"}.AsSelector(), 1 /* one replica */, 10*time.Second); err != nil {
|
||||
@ -80,8 +92,8 @@ func checkPodMutation(f *framework.Framework, expectedMutation v1.ResourceName)
|
||||
|
||||
ginkgo.By("submitting a pod for addmission")
|
||||
podSpec := f.NewTestPod("webhook-tester",
|
||||
v1.ResourceList{"fpga.intel.com/arria10.dcp1.0-nlb0": resource.MustParse("1")},
|
||||
v1.ResourceList{"fpga.intel.com/arria10.dcp1.0-nlb0": resource.MustParse("1")})
|
||||
v1.ResourceList{source: resource.MustParse("1")},
|
||||
v1.ResourceList{source: resource.MustParse("1")})
|
||||
pod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(context.TODO(),
|
||||
podSpec, metav1.CreateOptions{})
|
||||
framework.ExpectNoError(err, "pod Create API error")
|
||||
|
Loading…
Reference in New Issue
Block a user