├── .gitignore ├── CONTRIBUTING.md ├── COPYRIGHT ├── DEVELOPING.md ├── Dockerfile ├── Dockerfile.daemon ├── Dockerfile.labeler ├── Dockerfile.sriov-fec-index ├── LICENSE ├── Makefile ├── PROJECT ├── Security.md ├── api ├── sriovfec │ ├── v1 │ │ ├── groupversion_info.go │ │ ├── sriovfecclusterconfig_types.go │ │ ├── sriovfecnodeconfig_types.go │ │ └── zz_generated.deepcopy.go │ └── v2 │ │ ├── deepcopy_test.go │ │ ├── groupversion_info.go │ │ ├── helper.go │ │ ├── helper_test.go │ │ ├── sriovfecclusterconfig_types.go │ │ ├── sriovfecclusterconfig_types_test.go │ │ ├── sriovfecclusterconfig_webhook.go │ │ ├── sriovfecnodeconfig_types.go │ │ ├── webhook_suite_test.go │ │ └── zz_generated.deepcopy.go └── sriovvrb │ └── v1 │ ├── groupversion_info.go │ ├── helper.go │ ├── sriovvrbclusterconfig_types.go │ ├── sriovvrbclusterconfig_webhook.go │ ├── sriovvrbnodeconfig_types.go │ ├── webhook_suite_test.go │ └── zz_generated.deepcopy.go ├── assets ├── 100-labeler.yaml └── 200-device-plugin.yaml ├── cmd ├── daemon │ └── main.go └── labeler │ ├── main.go │ ├── main_test.go │ └── testdata │ ├── invalid.json │ └── valid.json ├── config ├── certmanager │ ├── certificate.yaml │ ├── kustomization.yaml │ └── kustomizeconfig.yaml ├── crd │ ├── kustomization.yaml │ ├── kustomizeconfig.yaml │ └── patches │ │ ├── cainjection_in_sriovfecclusterconfigs.yaml │ │ ├── cainjection_in_sriovfecnodeconfigs.yaml │ │ ├── cainjection_in_sriovvrb_sriovvrbclusterconfigs.yaml │ │ ├── cainjection_in_sriovvrb_sriovvrbnodeconfigs.yaml │ │ ├── webhook_in_sriovfecclusterconfigs.yaml │ │ ├── webhook_in_sriovfecnodeconfigs.yaml │ │ ├── webhook_in_sriovvrb_sriovvrbclusterconfigs.yaml │ │ └── webhook_in_sriovvrb_sriovvrbnodeconfigs.yaml ├── default │ ├── kustomization.yaml │ ├── manager_auth_proxy_patch.yaml │ ├── manager_config_patch.yaml │ ├── manager_webhook_patch.yaml │ └── webhookcainjection_patch.yaml ├── manager │ ├── controller_manager_config.yaml │ ├── kustomization.yaml │ └── manager.yaml ├── manifests │ ├── bases │ │ └── sriov-fec.clusterserviceversion.yaml │ └── kustomization.yaml ├── prometheus │ ├── kustomization.yaml │ └── monitor.yaml ├── rbac │ ├── auth_proxy_client_clusterrole.yaml │ ├── auth_proxy_role.yaml │ ├── auth_proxy_role_binding.yaml │ ├── auth_proxy_service.yaml │ ├── kustomization.yaml │ ├── leader_election_role.yaml │ ├── leader_election_role_binding.yaml │ ├── role.yaml │ ├── role_binding.yaml │ ├── sriovfecclusterconfig_editor_role.yaml │ ├── sriovfecclusterconfig_viewer_role.yaml │ ├── sriovfecnodeconfig_editor_role.yaml │ ├── sriovfecnodeconfig_viewer_role.yaml │ ├── sriovvrb_sriovvrbclusterconfig_editor_role.yaml │ ├── sriovvrb_sriovvrbclusterconfig_viewer_role.yaml │ ├── sriovvrb_sriovvrbnodeconfig_editor_role.yaml │ └── sriovvrb_sriovvrbnodeconfig_viewer_role.yaml ├── samples │ ├── kustomization.yaml │ ├── sriovfec_v2_sriovfecclusterconfig_acc100.yaml │ ├── sriovfec_v2_sriovfecclusterconfig_n3000.yaml │ ├── sriovfec_v2_sriovfecnodeconfig_acc100.yaml │ ├── sriovfec_v2_sriovfecnodeconfig_n3000.yaml │ ├── sriovvrb_v1_sriovvrbclusterconfig.yaml │ └── sriovvrb_v1_sriovvrbnodeconfig.yaml ├── scorecard │ ├── bases │ │ └── config.yaml │ ├── kustomization.yaml │ └── patches │ │ ├── basic.config.yaml │ │ └── olm.config.yaml └── webhook │ ├── kustomization.yaml │ ├── kustomizeconfig.yaml │ ├── manifests.yaml │ └── service.yaml ├── controllers ├── sriovfec │ ├── sriovfecclusterconfig_controller.go │ ├── sriovfecclusterconfig_controller_test.go │ ├── suite_test.go │ └── testdata │ │ └── clusterconfig │ │ ├── correct │ │ ├── acc100_no_maxqueuesize.yaml │ │ ├── acc100_no_pfmode.yaml │ │ ├── acc100_pfmode_equals_false.yaml │ │ ├── label_and_device_id.yaml │ │ ├── labels_and_device_id.yaml │ │ ├── labels_no_accelerator.yaml │ │ ├── missing_priority.yaml │ │ ├── n3000_no_pfmode.yaml │ │ ├── n3000_pfmode_equals_false.yaml │ │ ├── no_labels_and_no_accelerator.yaml │ │ ├── no_labels_and_only_device_id.yaml │ │ ├── no_labels_and_only_driver.yaml │ │ ├── no_labels_and_only_max_vfs.yaml │ │ ├── no_labels_and_only_pci_addr.yaml │ │ ├── no_labels_and_only_vendor_id#1.yaml │ │ └── no_labels_and_only_vendor_id#2.yaml │ │ └── incorrect │ │ ├── acc100_drainSkip_wrong_value.yaml │ │ ├── acc100_pfmode_equals_true.yaml │ │ └── n3000_pfmode_equals_true.yaml └── sriovvrb │ ├── sriovvrbclusterconfig_controller.go │ ├── sriovvrbclusterconfig_controller_test.go │ ├── suite_test.go │ └── testdata │ └── clusterconfig │ ├── correct │ ├── label_and_device_id.yaml │ ├── labels_and_device_id.yaml │ ├── labels_no_accelerator.yaml │ ├── missing_priority.yaml │ ├── no_labels_and_no_accelerator.yaml │ ├── no_labels_and_only_device_id.yaml │ ├── no_labels_and_only_driver.yaml │ ├── no_labels_and_only_max_vfs.yaml │ ├── no_labels_and_only_pci_addr.yaml │ ├── no_labels_and_only_vendor_id#1.yaml │ ├── no_labels_and_only_vendor_id#2.yaml │ ├── vrb1_no_maxqueuesize.yaml │ ├── vrb1_no_pfmode.yaml │ ├── vrb1_pfmode_equals_false.yaml │ ├── vrb2_no_maxqueuesize.yaml │ ├── vrb2_no_pfmode.yaml │ └── vrb2_pfmode_equals_false.yaml │ └── incorrect │ ├── vrb1_drainSkip_wrong_value.yaml │ ├── vrb1_pfmode_equals_true.yaml │ └── vrb2_pfmode_equals_true.yaml ├── copyright.sh ├── gather_sriovfec_logs.sh ├── go.mod ├── go.sum ├── hack └── boilerplate.go.txt ├── main.go ├── misc └── src │ ├── README.md │ ├── kmod-28.tar.gz │ ├── pciutils-3.7.0.tar.gz │ └── procps-v3.3.17.tar.gz ├── pkg ├── common │ ├── assets │ │ ├── asset.go │ │ ├── manager.go │ │ ├── manager_test.go │ │ ├── suite_test.go │ │ └── test │ │ │ └── 101-fake-labeler.yaml │ ├── drainhelper │ │ ├── drainhelper.go │ │ ├── drainhelper_test.go │ │ └── suite_test.go │ └── utils │ │ ├── logger_wrapper.go │ │ ├── slices.go │ │ ├── testdata │ │ ├── invalid.json │ │ └── valid.json │ │ ├── utils.go │ │ └── utils_test.go └── daemon │ ├── bbdevconfig.go │ ├── bbdevconfig_ini_generator.go │ ├── bbdevconfig_test.go │ ├── common.go │ ├── common_test.go │ ├── daemon.go │ ├── daemon_fec.go │ ├── daemon_reconcile_test.go │ ├── daemon_test.go │ ├── daemon_vrb.go │ ├── device_plugin_controller.go │ ├── inventory.go │ ├── inventory_test.go │ ├── node_management.go │ ├── package_config.go │ ├── pf_bb_config_cli.go │ ├── pf_bb_config_cli_test.go │ ├── suite_test.go │ ├── telemetry.go │ ├── telemetry_test.go │ ├── testdata │ ├── accelerators.json │ ├── accelerators_vrb.json │ ├── archives │ │ └── sample-archive │ │ │ ├── inner-dir │ │ │ └── inner-file-1 │ │ │ ├── outer-file-1 │ │ │ └── outer-file-2 │ ├── bbdevconfig_test1.cfg │ ├── bbdevconfig_test2.cfg │ ├── centos_os_release │ ├── cmdline_test │ ├── cmdline_test_missing_param │ ├── node_config.json │ ├── rhcos_os_release │ ├── rhel_os_release │ └── unknown_os_release │ ├── utils.go │ └── utils_test.go └── spec ├── images ├── acc100-diagram.png ├── sriov_fec_operator_acc100.png └── vfio │ ├── vfio-pci-support-in-operator.svg │ └── vfio-pci.svg ├── kubernetes-deployment.md ├── openshift-deployment.md ├── sriov-fec-operator-release-notes.md ├── sriov-fec-operator.md ├── sriov-fec-operator.svg.graphml ├── sriov-fec-selector-based-api.puml └── vran-accelerators-supported-by-operator.md /.gitignore: -------------------------------------------------------------------------------- 1 | testbin/ 2 | 3 | # Binaries for programs and plugins 4 | *.exe 5 | *.exe~ 6 | *.dll 7 | *.so 8 | *.dylib 9 | bin 10 | 11 | # Test binary, build with `go test -c` 12 | *.test 13 | 14 | # Output of the go coverage tool, specifically when used with LiteIDE 15 | *.out 16 | 17 | # Kubernetes Generated files - skip generated files, except for vendored files 18 | 19 | !vendor/**/zz_generated.* 20 | 21 | # operator-sdk generated files 22 | config/crd/bases/ 23 | bundle/ 24 | bundle_tmp* 25 | bundle.Dockerfile 26 | 27 | # editor and IDE paraphernalia 28 | .idea/* 29 | *.swp 30 | *.swo 31 | *~ 32 | .vscode 33 | 34 | # duplicate license file used in dockerfiles 35 | TEMP_LICENSE_COPY 36 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ```text 2 | SPDX-License-Identifier: Apache-2.0 3 | Copyright (c) 2020-2025 Intel Corporation 4 | ``` 5 | 6 | # Contribution Guide 7 | Welcome to the SRIOV-FEC project. This is an open-source solution that is enriched by people like — you. Your contributions drive the network & enterprise edge computing! 8 | 9 | The rest of this document consists of the following sections: 10 | 11 | - [Code of Conduct](#code-of-conduct) 12 | - [Maintainers](#maintainers) 13 | - [Submitting Changes](#submitting-changes) 14 | - [Contribution Acceptance Flow](#contribution-acceptance-flow) 15 | - [How to report an issue/bug/enhancement](#how-to-report-an-issuebugenhancement) 16 | - [Resources](#resources) 17 | - [Style Guide / Coding conventions](#style-guide--coding-conventions) 18 | - [License](#license) 19 | 20 | ## Code of Conduct 21 | We at the SRIOV-FEC community adhere to [Contributor Covenant](https://www.contributor-covenant.org/) as our Code of Conduct, and we expect project participants to adhere to it. Please read [the full text](CODE_OF_CONDUCT.md) so that you can understand what actions will and will not be tolerated. 22 | 23 | ## Maintainers 24 | Maintainers act as the gatekeeper to the code - ensuring that coding standards, quality, and functionality of code are maintained by the contributors. Any additions to the source code must be approved by the appropriate maintainer before they are added. The maintainers' role include: 25 | 26 | * Ensuring that any code submitted is of the appropriate quality. 27 | * Ensuring that any code submitted is accompanied with appropriate documentation. 28 | * Ensuring that any code submitted has been reviewed by peers. 29 | * Ensuring that the relevant documentation is kept up to date with the code. 30 | * Ensuring that any identified bugs in the relevant code are captured in the issues backlog. 31 | * Ensuring that the unit, integration, and regression tests are appropriate for the relevant components. 32 | * Ensuring that the contribution does not infringe others' Intellectual Property or the appropriate license and that it is in compliance with [Developer Certificate of Origin](http://developercertificate.org/). 33 | * Answering questions/emails on the relevant areas of the SRIOV-FEC code base. 34 | 35 | ## Submitting Changes 36 | Inbound contributions are done through [pull requests](https://github.com/intel/sriov-fec-operator/pulls) which include code changes, enhancements, bug fixes or new applications/features. If you are getting started, you may refer to Github's [how-to](https://help.github.com/articles/using-pull-requests/). With your contributions, we expect that you: 37 | 38 | * certify that you wrote and/or have the right to submit the pull request, 39 | * agree with the [Developer Certificate of Origin](http://developercertificate.org/), 40 | * sign-off your contribution with `Signed-off-by` tag in the commit message(s) 41 | * comply with SRIOV-FEC [licensing](#license), 42 | * pass all Continuous Integration & Continuous Delivery (CI/CD) tools' checks, 43 | * test and verify the proper behaviour of your code, and 44 | * accompany the contribution with good quality documentation. 45 | 46 | Signing off the contribution is performed by the command `git commit --signoff` which certifies that you wrote it or otherwise have the right to pass it on as an open-source contribution. 47 | 48 | Application contributors have the implicit commitment to continually support their applications in whenever a bug is discovered or a test is broken due to the publication of a new release. 49 | 50 | It is always admired when application contributors provide end-to-end acceptance test methods. 51 | 52 | Big contributions, ideas or controversial features should be discussed with the developers' community and with the Technical Steering Committee through a Request for Comments (RFC). This is an essential early step to bring everybody to a common level of understanding so that when the final implementation is pushed, there will be common consensus of the acceptability of the contribution and smooth integration of it to the mainline. Requests for Comments should be submitted through a pull request prefixed with `[RFC]` in the title. 53 | 54 | ## Contribution Acceptance Flow 55 | 1. A contributor creates a pull request with their changes. 56 | 2. Continuous Integration & Continuous Delivery (CI/CD) tools will be automatically triggered and their results are returned into the pull request. 57 | 3. The contributor resolves all findings reported by CI/CD verifications. 58 | 4. The contributor invites reviewers to the pull request and addresses their comments/feedback. 59 | 5. Every pull request must receive 2 approvals in order to go forward with merging. 60 | 6. The maintainer(s) must review and ensure that the change(s) introduced by the pull request meets the acceptance criteria. 61 | 6. Merging the pull requests can only be performed by the maintainer(s). 62 | 63 | ## How to report an issue/bug/enhancement 64 | It is encouraged to use the [GitHub Issues](https://github.com/intel/sriov-fec-operator/issues) tool to report any bug, issue, enhancement or to seek help. 65 | 66 | ## Style Guide / Coding conventions 67 | All contributions must follow the [Development Guide](DEVELOPING.md). 68 | 69 | ## License 70 | Operator is licensed under [Apache License, Version 2.0](LICENSE). By contributing to the project, you agree to the license and copyright terms therein and release your contribution under these terms. 71 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ## SPDX-License-Identifier: Apache-2.0 2 | ## Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # Build the manager binary 5 | FROM golang:1.23.4 AS builder 6 | 7 | WORKDIR /workspace 8 | # Copy the Go Modules manifests 9 | COPY go.mod go.mod 10 | COPY go.sum go.sum 11 | 12 | # cache deps before building and copying source so that we don't need to re-download as much 13 | # and so that source changes don't invalidate our downloaded layer 14 | RUN go mod download 15 | 16 | # Copy the go source 17 | COPY main.go main.go 18 | COPY api/ api/ 19 | COPY pkg/ pkg/ 20 | COPY controllers/ controllers/ 21 | 22 | # Build 23 | RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o manager main.go 24 | 25 | FROM registry.access.redhat.com/ubi9/ubi-micro:9.5-1744118077 26 | 27 | ARG VERSION 28 | ### Required OpenShift Labels 29 | LABEL name="SRIOV-FEC Operator for Intel® vRAN Boost accelerators" \ 30 | vendor="Intel Corporation" \ 31 | version=$VERSION \ 32 | release="1" \ 33 | maintainer="Intel Corporation" \ 34 | summary="SRIOV-FEC Operator for Intel® vRAN Boost accelerators for vRAN cloudnative deployments" \ 35 | description="SRIOV-FEC Operator for Intel® vRAN Boost accelerators for vRAN cloudnative deployments" 36 | 37 | COPY TEMP_LICENSE_COPY /licenses/LICENSE 38 | 39 | WORKDIR / 40 | COPY --from=builder /workspace/manager . 41 | COPY assets assets/ 42 | 43 | USER 1001 44 | 45 | ENTRYPOINT ["/manager"] 46 | -------------------------------------------------------------------------------- /Dockerfile.daemon: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | FROM golang:1.23.4 AS builder 5 | 6 | WORKDIR /workspace-pf 7 | 8 | RUN git clone --depth 1 --branch v25.01 https://github.com/intel/pf-bb-config /workspace-pf/pf-bb-config 9 | 10 | WORKDIR /workspace-pf/pf-bb-config 11 | 12 | RUN ./build.sh 13 | 14 | WORKDIR /workspace-go 15 | 16 | COPY go.mod go.sum ./ 17 | 18 | RUN go mod download 19 | 20 | COPY cmd/daemon/ cmd/daemon/ 21 | COPY pkg pkg/ 22 | COPY api api/ 23 | 24 | RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o sriov_fec_daemon cmd/daemon/main.go 25 | 26 | FROM registry.access.redhat.com/ubi9/ubi:9.5-1744101466 AS package_installer 27 | 28 | RUN yum install \ 29 | kmod-28-10.el9 \ 30 | pciutils-3.7.0-5.el9 \ 31 | procps-ng-3.3.17-14.el9 \ 32 | --releasever 9 --setopt install_weak_deps=false --nodocs -y && \ 33 | yum clean all 34 | 35 | WORKDIR /workspace 36 | 37 | RUN curl -L https://pci-ids.ucw.cz/v2.2/pci.ids.gz -o pci.ids.gz && \ 38 | gzip -d -v pci.ids.gz && \ 39 | rm -rfv ./pci.ids.gz 40 | 41 | FROM registry.access.redhat.com/ubi9/ubi-minimal:9.5-1742914212 42 | 43 | 44 | 45 | ARG VERSION 46 | ### Required OpenShift Labels 47 | LABEL name="Intel® vRAN Boost accelerator operator daemonset container" \ 48 | vendor="Intel Corporation" \ 49 | version=$VERSION \ 50 | release="1" \ 51 | maintainer="Intel Corporation" \ 52 | summary="Manages SR-IOV resources on Intel® vRAN Boost accelerator" \ 53 | description="The daemonset container is responsible for building the nodes inventory and configuring the SR-IOV portion of the supported accelerators" 54 | 55 | COPY --from=package_installer \ 56 | /lib64/libpci.so.3 \ 57 | /lib64/libkmod.so.2 \ 58 | /lib64/libprocps.so.8.0.3 \ 59 | /lib64/ 60 | 61 | RUN ln -sf /usr/lib64/libprocps.so.8.0.3 /usr/lib64/libprocps.so.8 62 | 63 | COPY --from=package_installer \ 64 | /usr/sbin/lspci \ 65 | /usr/sbin/setpci \ 66 | /usr/sbin/modprobe \ 67 | /usr/sbin/ 68 | 69 | COPY --from=package_installer \ 70 | /usr/bin/kmod \ 71 | /usr/bin/pkill \ 72 | /usr/bin/pgrep \ 73 | /usr/bin/ 74 | 75 | RUN mkdir -p /usr/share/hwdata && \ 76 | mkdir -p /usr/share/misc && \ 77 | mkdir -p /sriov_workdir && \ 78 | mkdir -p /sriov_workdir/vrb1 && \ 79 | mkdir -p /sriov_workdir/vrb2 80 | 81 | COPY --from=package_installer /workspace/pci.ids /usr/share/misc/pci.ids 82 | RUN ln -sf /usr/share/misc/pci.ids /usr/share/hwdata/pci.ids 83 | 84 | USER 1001 85 | 86 | COPY TEMP_LICENSE_COPY /licenses/LICENSE 87 | WORKDIR /sriov_workdir 88 | COPY --from=builder /workspace-go/sriov_fec_daemon . 89 | COPY --from=builder /workspace-pf/pf-bb-config/pf_bb_config . 90 | COPY --from=builder /workspace-pf/pf-bb-config/vrb1/srs_fft_windows_coefficient.bin vrb1/ 91 | COPY --from=builder /workspace-pf/pf-bb-config/vrb2/srs_fft_windows_coefficient.bin vrb2/ 92 | 93 | ENTRYPOINT ["/sriov_workdir/sriov_fec_daemon"] 94 | -------------------------------------------------------------------------------- /Dockerfile.labeler: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | FROM golang:1.23.4 AS builder 5 | 6 | WORKDIR /workspace 7 | COPY go.mod go.sum ./ 8 | RUN go mod download 9 | 10 | COPY cmd/labeler/ cmd/labeler/ 11 | COPY pkg/ pkg/ 12 | 13 | RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o node_labeler cmd/labeler/main.go 14 | 15 | 16 | RUN wget --progress=dot:giga https://pci-ids.ucw.cz/v2.2/pci.ids.gz -O pci.ids.gz && gunzip pci.ids.gz 17 | 18 | FROM registry.access.redhat.com/ubi9/ubi-micro:9.5-1744118077 19 | 20 | ARG VERSION 21 | ### Required OpenShift Labels 22 | LABEL name="Intel® vRAN Boost accelerator operator discovery container" \ 23 | vendor="Intel Corporation" \ 24 | version=$VERSION \ 25 | release="1" \ 26 | maintainer="Intel Corporation" \ 27 | summary="Detects and labels kubernetes nodes that include Intel® vRAN Boost accelerator" \ 28 | description="The container tries to detect Intel® vRAN Boost accelerators and label the nodes that contain them \ 29 | and remove the label for nodes that do not." 30 | 31 | RUN mkdir -p /usr/share/misc/ 32 | 33 | COPY --from=builder /workspace/pci.ids /usr/share/misc/pci.ids 34 | 35 | COPY TEMP_LICENSE_COPY /licenses/LICENSE 36 | USER 1001 37 | WORKDIR /labeler-workspace 38 | COPY --from=builder /workspace/node_labeler . 39 | 40 | ENTRYPOINT ["bash", "-c", "/labeler-workspace/node_labeler && sleep infinity"] 41 | -------------------------------------------------------------------------------- /Dockerfile.sriov-fec-index: -------------------------------------------------------------------------------- 1 | ## SPDX-License-Identifier: Apache-2.0 2 | ## Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # The base image is expected to contain 5 | # /bin/opm (with a serve subcommand) and /bin/grpc_health_probe 6 | FROM quay.io/operator-framework/opm:v1.33.0 7 | 8 | # Configure the entrypoint and command 9 | ENTRYPOINT ["/bin/opm"] 10 | CMD ["serve", "/configs"] 11 | 12 | # Copy declarative config root into image at /configs 13 | COPY sriov-fec-index /configs 14 | 15 | # Set DC-specific label for the location of the DC root directory 16 | # in the image 17 | LABEL operators.operatorframework.io.index.configs.v1=/configs 18 | 19 | USER 1001 20 | -------------------------------------------------------------------------------- /PROJECT: -------------------------------------------------------------------------------- 1 | # Code generated by tool. DO NOT EDIT. 2 | # This file is used to track the info used to scaffold your project 3 | # and allow the plugins properly work. 4 | # More info: https://book.kubebuilder.io/reference/project-config.html 5 | domain: intel.com 6 | layout: 7 | - go.kubebuilder.io/v3 8 | multigroup: true 9 | plugins: 10 | manifests.sdk.operatorframework.io/v2: {} 11 | scorecard.sdk.operatorframework.io/v2: {} 12 | projectName: sriov-fec 13 | repo: github.com/intel/sriov-fec-operator 14 | resources: 15 | - api: 16 | crdVersion: v1 17 | namespaced: true 18 | controller: true 19 | domain: intel.com 20 | group: sriovfec 21 | kind: SriovFecClusterConfig 22 | path: github.com/intel/sriov-fec-operator/api/sriovfec/v2 23 | version: v2 24 | webhooks: 25 | validation: true 26 | webhookVersion: v1 27 | - api: 28 | crdVersion: v1 29 | namespaced: true 30 | domain: intel.com 31 | group: sriovfec 32 | kind: SriovFecNodeConfig 33 | path: github.com/intel/sriov-fec-operator/api/sriovfec/v2 34 | version: v2 35 | - api: 36 | crdVersion: v1 37 | namespaced: true 38 | controller: true 39 | domain: intel.com 40 | group: sriovvrb 41 | kind: SriovVrbClusterConfig 42 | path: github.com/intel/sriov-fec-operator/api/sriovvrb/v1 43 | version: v1 44 | webhooks: 45 | validation: true 46 | webhookVersion: v1 47 | - api: 48 | crdVersion: v1 49 | namespaced: true 50 | domain: intel.com 51 | group: sriovvrb 52 | kind: SriovVrbNodeConfig 53 | path: github.com/intel/sriov-fec-operator/api/sriovvrb/v1 54 | version: v1 55 | version: "3" 56 | -------------------------------------------------------------------------------- /Security.md: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # Security Policy 5 | Intel is committed to rapidly addressing security vulnerabilities affecting our customers and providing clear guidance on the solution, impact, severity and mitigation. 6 | 7 | ## Reporting a Vulnerability 8 | Please report any security vulnerabilities in this project [utilizing the guidelines here](https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html). 9 | 10 | -------------------------------------------------------------------------------- /api/sriovfec/v1/groupversion_info.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | /* 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | // Package v1 contains API Schema definitions for the sriovfec v1 API group 20 | // +kubebuilder:object:generate=true 21 | // +groupName=sriovfec.intel.com 22 | package v1 23 | 24 | import ( 25 | "k8s.io/apimachinery/pkg/runtime/schema" 26 | "sigs.k8s.io/controller-runtime/pkg/scheme" 27 | ) 28 | 29 | var ( 30 | // GroupVersion is group version used to register these objects 31 | GroupVersion = schema.GroupVersion{Group: "sriovfec.intel.com", Version: "v1"} 32 | 33 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 34 | SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} 35 | 36 | // AddToScheme adds the types in this group-version to the given scheme. 37 | AddToScheme = SchemeBuilder.AddToScheme 38 | ) 39 | -------------------------------------------------------------------------------- /api/sriovfec/v1/sriovfecnodeconfig_types.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package v1 5 | 6 | import ( 7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | ) 9 | 10 | type VF struct { 11 | PCIAddress string `json:"pciAddress"` 12 | Driver string `json:"driver"` 13 | DeviceID string `json:"deviceID"` 14 | } 15 | 16 | type SriovAccelerator struct { 17 | VendorID string `json:"vendorID"` 18 | DeviceID string `json:"deviceID"` 19 | PCIAddress string `json:"pciAddress"` 20 | Driver string `json:"driver"` 21 | MaxVFs int `json:"maxVirtualFunctions"` 22 | VFs []VF `json:"virtualFunctions"` 23 | } 24 | 25 | type NodeInventory struct { 26 | SriovAccelerators []SriovAccelerator `json:"sriovAccelerators,omitempty"` 27 | } 28 | 29 | // SriovFecNodeConfigSpec defines the desired state of SriovFecNodeConfig 30 | type SriovFecNodeConfigSpec struct { 31 | // List of PhysicalFunctions configs 32 | // +operator-sdk:csv:customresourcedefinitions:type=spec 33 | PhysicalFunctions []PhysicalFunctionConfig `json:"physicalFunctions"` 34 | DrainSkip bool `json:"drainSkip,omitempty"` 35 | } 36 | 37 | // SriovFecNodeConfigStatus defines the observed state of SriovFecNodeConfig 38 | type SriovFecNodeConfigStatus struct { 39 | // Provides information about device update status 40 | Conditions []metav1.Condition `json:"conditions,omitempty"` 41 | // Provides information about FPGA inventory on the node 42 | // +operator-sdk:csv:customresourcedefinitions:type=status 43 | Inventory NodeInventory `json:"inventory,omitempty"` 44 | } 45 | 46 | // +kubebuilder:object:root=true 47 | // +kubebuilder:subresource:status 48 | // +kubebuilder:printcolumn:name="Configured",type=string,JSONPath=`.status.conditions[?(@.type=="Configured")].reason` 49 | // +kubebuilder:unservedversion 50 | // SriovFecNodeConfig is the Schema for the sriovfecnodeconfigs API 51 | // +operator-sdk:csv:customresourcedefinitions:displayName="SriovFecNodeConfig",resources={{SriovFecNodeConfig,v1,node}} 52 | type SriovFecNodeConfig struct { 53 | metav1.TypeMeta `json:",inline"` 54 | metav1.ObjectMeta `json:"metadata,omitempty"` 55 | 56 | Spec SriovFecNodeConfigSpec `json:"spec,omitempty"` 57 | Status SriovFecNodeConfigStatus `json:"status,omitempty"` 58 | } 59 | 60 | // +kubebuilder:object:root=true 61 | 62 | // SriovFecNodeConfigList contains a list of SriovFecNodeConfig 63 | type SriovFecNodeConfigList struct { 64 | metav1.TypeMeta `json:",inline"` 65 | metav1.ListMeta `json:"metadata,omitempty"` 66 | Items []SriovFecNodeConfig `json:"items"` 67 | } 68 | 69 | func init() { 70 | SchemeBuilder.Register(&SriovFecNodeConfig{}, &SriovFecNodeConfigList{}) 71 | } 72 | -------------------------------------------------------------------------------- /api/sriovfec/v2/groupversion_info.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | // Package v2 contains API Schema definitions for the sriovfec v2 API group 5 | // +kubebuilder:object:generate=true 6 | // +groupName=sriovfec.intel.com 7 | package v2 8 | 9 | import ( 10 | "k8s.io/apimachinery/pkg/runtime/schema" 11 | "sigs.k8s.io/controller-runtime/pkg/scheme" 12 | ) 13 | 14 | var ( 15 | // GroupVersion is group version used to register these objects 16 | GroupVersion = schema.GroupVersion{Group: "sriovfec.intel.com", Version: "v2"} 17 | 18 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 19 | SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} 20 | 21 | // AddToScheme adds the types in this group-version to the given scheme. 22 | AddToScheme = SchemeBuilder.AddToScheme 23 | ) 24 | -------------------------------------------------------------------------------- /api/sriovfec/v2/helper.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package v2 5 | 6 | import ( 7 | "k8s.io/apimachinery/pkg/api/meta" 8 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 9 | "reflect" 10 | ) 11 | 12 | type ByPriority []SriovFecClusterConfig 13 | 14 | func (a ByPriority) Len() int { 15 | return len(a) 16 | } 17 | 18 | func (a ByPriority) Less(i, j int) bool { 19 | if a[i].Spec.Priority != a[j].Spec.Priority { 20 | return a[i].Spec.Priority > a[j].Spec.Priority 21 | } 22 | return a[i].GetName() < a[j].GetName() 23 | } 24 | 25 | func (a ByPriority) Swap(i, j int) { 26 | a[i], a[j] = a[j], a[i] 27 | } 28 | 29 | func (s AcceleratorSelector) Matches(a SriovAccelerator) bool { 30 | return s.isVendorMatching(a) && s.isPciAddressMatching(a) && 31 | s.isPFDriverMatching(a) && s.isMaxVFsMatching(a) && s.isDeviceIDMatching(a) 32 | } 33 | 34 | func (s AcceleratorSelector) isVendorMatching(a SriovAccelerator) bool { 35 | return s.VendorID == "" || s.VendorID == a.VendorID 36 | } 37 | 38 | func (s AcceleratorSelector) isPciAddressMatching(a SriovAccelerator) bool { 39 | return s.PCIAddress == "" || s.PCIAddress == a.PCIAddress 40 | } 41 | 42 | func (s AcceleratorSelector) isPFDriverMatching(a SriovAccelerator) bool { 43 | return s.PFDriver == "" || s.PFDriver == a.PFDriver 44 | } 45 | 46 | func (s AcceleratorSelector) isMaxVFsMatching(a SriovAccelerator) bool { 47 | return s.MaxVFs == 0 || s.MaxVFs == a.MaxVFs 48 | } 49 | 50 | func (s AcceleratorSelector) isDeviceIDMatching(a SriovAccelerator) bool { 51 | return s.DeviceID == "" || s.DeviceID == a.DeviceID 52 | } 53 | 54 | func (in *SriovFecNodeConfig) FindCondition(conditionType string) *metav1.Condition { 55 | return meta.FindStatusCondition(in.Status.Conditions, conditionType) 56 | } 57 | 58 | func isNil(v interface{}) bool { 59 | return v == nil || (reflect.ValueOf(v).Kind() == reflect.Ptr && reflect.ValueOf(v).IsNil()) 60 | } 61 | -------------------------------------------------------------------------------- /api/sriovfec/v2/helper_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package v2 5 | 6 | import ( 7 | "sort" 8 | 9 | . "github.com/onsi/ginkgo" 10 | . "github.com/onsi/gomega" 11 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 12 | ) 13 | 14 | var _ = Describe("helperFunctionsTest", func() { 15 | var _ = Describe("Sorting Cluster Configs by Priority", func() { 16 | It("should sort the cluster configs by priority in descending order and then by name in ascending order", func() { 17 | clusterConfig := []SriovFecClusterConfig{ 18 | {Spec: SriovFecClusterConfigSpec{Priority: 3}}, 19 | {Spec: SriovFecClusterConfigSpec{Priority: 1}}, 20 | {Spec: SriovFecClusterConfigSpec{Priority: 3}}, 21 | {Spec: SriovFecClusterConfigSpec{Priority: 2}}, 22 | } 23 | 24 | // Assuming GetName() method exists and returns the Name field 25 | sort.Sort(ByPriority(clusterConfig)) 26 | 27 | // Assert that the elements are sorted by Priority in descending order 28 | Expect(clusterConfig[0].Spec.Priority).To(Equal(3)) 29 | Expect(clusterConfig[1].Spec.Priority).To(Equal(3)) 30 | Expect(clusterConfig[2].Spec.Priority).To(Equal(2)) 31 | Expect(clusterConfig[3].Spec.Priority).To(Equal(1)) 32 | }) 33 | }) 34 | 35 | var _ = Describe("AcceleratorSelector", func() { 36 | Describe("Matches function", func() { 37 | It("should match an accelerator when all criteria are met", func() { 38 | selector := AcceleratorSelector{ 39 | VendorID: "8086", 40 | PCIAddress: "0000:00:02.0", 41 | PFDriver: "i40e", 42 | MaxVFs: 32, 43 | DeviceID: "154c", 44 | } 45 | 46 | accelerator := SriovAccelerator{ 47 | VendorID: "8086", 48 | PCIAddress: "0000:00:02.0", 49 | PFDriver: "i40e", 50 | MaxVFs: 32, 51 | DeviceID: "154c", 52 | } 53 | 54 | Expect(selector.Matches(accelerator)).To(BeTrue()) 55 | }) 56 | 57 | It("should not match an accelerator when one criterion does not match", func() { 58 | selector := AcceleratorSelector{ 59 | VendorID: "8086", 60 | PCIAddress: "0000:00:02.0", 61 | PFDriver: "i40e", 62 | MaxVFs: 32, 63 | DeviceID: "154c", 64 | } 65 | 66 | accelerator := SriovAccelerator{ 67 | VendorID: "8086", 68 | PCIAddress: "0000:00:02.0", 69 | PFDriver: "ixgbe", 70 | MaxVFs: 32, 71 | DeviceID: "154c", 72 | } 73 | 74 | Expect(selector.Matches(accelerator)).To(BeFalse()) 75 | }) 76 | 77 | Context("when optional fields are empty", func() { 78 | It("should match an accelerator if only mandatory criteria are met", func() { 79 | selector := AcceleratorSelector{ 80 | VendorID: "8086", 81 | } 82 | 83 | accelerator := SriovAccelerator{ 84 | VendorID: "8086", 85 | PCIAddress: "0000:00:02.0", 86 | PFDriver: "i40e", 87 | MaxVFs: 32, 88 | DeviceID: "154c", 89 | } 90 | 91 | Expect(selector.Matches(accelerator)).To(BeTrue()) 92 | }) 93 | }) 94 | }) 95 | }) 96 | 97 | var _ = Describe("SriovFecNodeConfig", func() { 98 | Describe("FindCondition function", func() { 99 | var nodeConfig *SriovFecNodeConfig 100 | 101 | BeforeEach(func() { 102 | nodeConfig = &SriovFecNodeConfig{ 103 | Status: SriovFecNodeConfigStatus{ 104 | Conditions: []metav1.Condition{ 105 | { 106 | Type: "Ready", 107 | Status: metav1.ConditionTrue, 108 | Reason: "NodeIsReady", 109 | }, 110 | { 111 | Type: "Degraded", 112 | Status: metav1.ConditionFalse, 113 | Reason: "NodeIsHealthy", 114 | }, 115 | }, 116 | }, 117 | } 118 | }) 119 | 120 | It("should find the condition by type", func() { 121 | condition := nodeConfig.FindCondition("Ready") 122 | Expect(condition).NotTo(BeNil()) 123 | Expect(condition.Type).To(Equal("Ready")) 124 | Expect(condition.Status).To(Equal(metav1.ConditionTrue)) 125 | Expect(condition.Reason).To(Equal("NodeIsReady")) 126 | }) 127 | 128 | It("should return nil if the condition is not found", func() { 129 | condition := nodeConfig.FindCondition("NonExistent") 130 | Expect(condition).To(BeNil()) 131 | }) 132 | }) 133 | }) 134 | }) 135 | -------------------------------------------------------------------------------- /api/sriovfec/v2/sriovfecclusterconfig_types_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package v2 5 | 6 | import ( 7 | "fmt" 8 | 9 | . "github.com/onsi/ginkgo" 10 | . "github.com/onsi/gomega" 11 | "k8s.io/apimachinery/pkg/util/validation/field" 12 | ) 13 | 14 | var _ = Describe("UplinkDownlinkQueues", func() { 15 | Describe("String method", func() { 16 | It("should correctly format the struct's fields into a string", func() { 17 | udq := UplinkDownlinkQueues{ 18 | VF0: 1, VF1: 2, VF2: 3, VF3: 4, 19 | VF4: 5, VF5: 6, VF6: 7, VF7: 8, 20 | } 21 | 22 | expectedString := "1,2,3,4,5,6,7,8" 23 | Expect(udq.String()).To(Equal(expectedString)) 24 | }) 25 | 26 | It("should correctly format the struct's fields into a string with zeros", func() { 27 | udq := UplinkDownlinkQueues{ 28 | VF0: 0, VF1: 0, VF2: 0, VF3: 0, 29 | VF4: 0, VF5: 0, VF6: 0, VF7: 0, 30 | } 31 | 32 | expectedString := "0,0,0,0,0,0,0,0" 33 | Expect(udq.String()).To(Equal(expectedString)) 34 | }) 35 | 36 | It("should correctly format the struct's fields into a string with negative values", func() { 37 | udq := UplinkDownlinkQueues{ 38 | VF0: -1, VF1: -2, VF2: -3, VF3: -4, 39 | VF4: -5, VF5: -6, VF6: -7, VF7: -8, 40 | } 41 | 42 | expectedString := "-1,-2,-3,-4,-5,-6,-7,-8" 43 | Expect(udq.String()).To(Equal(expectedString)) 44 | }) 45 | }) 46 | }) 47 | 48 | var _ = Describe("ACC100BBDevConfig Validation", func() { 49 | var ( 50 | config ACC100BBDevConfig 51 | ) 52 | 53 | BeforeEach(func() { 54 | config = ACC100BBDevConfig{ 55 | NumVfBundles: 1, // Valid value within the expected range. 56 | Uplink4G: QueueGroupConfig{NumQueueGroups: 2, NumAqsPerGroups: 2, AqDepthLog2: 2}, 57 | Downlink4G: QueueGroupConfig{NumQueueGroups: 2, NumAqsPerGroups: 2, AqDepthLog2: 2}, 58 | Uplink5G: QueueGroupConfig{NumQueueGroups: 2, NumAqsPerGroups: 2, AqDepthLog2: 2}, 59 | Downlink5G: QueueGroupConfig{NumQueueGroups: 2, NumAqsPerGroups: 2, AqDepthLog2: 2}, 60 | } 61 | }) 62 | 63 | Context("when the total number of queue groups is within the maximum limit", func() { 64 | It("should return an error", func() { 65 | // Adjusting to not exceed the max limit 66 | config.Uplink4G.NumQueueGroups = 0 67 | config.Downlink4G.NumQueueGroups = 0 68 | err := config.Validate() 69 | Expect(err).NotTo(HaveOccurred()) 70 | }) 71 | }) 72 | 73 | Context("when the total number of queue groups is equal to the maximum limit", func() { 74 | It("should return an error", func() { 75 | err := config.Validate() 76 | Expect(err).NotTo(HaveOccurred()) 77 | }) 78 | }) 79 | 80 | Context("when the total number of queue groups exceeds the maximum limit", func() { 81 | It("should return an error", func() { 82 | // Adjusting to exceed the max limit 83 | config.Uplink4G.NumQueueGroups = 4 84 | err := config.Validate() 85 | Expect(err).To(HaveOccurred()) 86 | Expect(err.Error()).To(Equal(fmt.Sprintf("total number of requested queue groups (4G/5G) %v exceeds the maximum (%d)", 10, acc100maxQueueGroups))) 87 | }) 88 | }) 89 | }) 90 | 91 | var _ = Describe("ACC200BBDevConfig Validation", func() { 92 | var ( 93 | config ACC200BBDevConfig 94 | ) 95 | 96 | BeforeEach(func() { 97 | config = ACC200BBDevConfig{ 98 | ACC100BBDevConfig: ACC100BBDevConfig{ 99 | NumVfBundles: 1, 100 | Uplink4G: QueueGroupConfig{NumQueueGroups: 2, NumAqsPerGroups: 2, AqDepthLog2: 2}, 101 | Downlink4G: QueueGroupConfig{NumQueueGroups: 2, NumAqsPerGroups: 2, AqDepthLog2: 2}, 102 | Uplink5G: QueueGroupConfig{NumQueueGroups: 2, NumAqsPerGroups: 2, AqDepthLog2: 2}, 103 | Downlink5G: QueueGroupConfig{NumQueueGroups: 2, NumAqsPerGroups: 2, AqDepthLog2: 2}, 104 | }, 105 | QFFT: QueueGroupConfig{NumQueueGroups: 4, NumAqsPerGroups: 2, AqDepthLog2: 2}, 106 | } 107 | }) 108 | 109 | Context("when the total number of queue groups is within the maximum limit", func() { 110 | It("should return an error", func() { 111 | err := config.Validate() 112 | Expect(err).NotTo(HaveOccurred()) 113 | }) 114 | }) 115 | 116 | Context("when the total number of queue groups is equal to the maximum limit", func() { 117 | It("should return an error", func() { 118 | config.Uplink5G.NumQueueGroups = 4 119 | config.Downlink5G.NumQueueGroups = 4 120 | config.Uplink4G.NumQueueGroups = 2 121 | config.Downlink4G.NumQueueGroups = 2 122 | err := config.Validate() 123 | Expect(err).NotTo(HaveOccurred()) 124 | }) 125 | }) 126 | 127 | Context("when the total number of queue groups exceeds the maximum limit", func() { 128 | It("should return an error", func() { 129 | config.Uplink5G.NumQueueGroups = 4 130 | config.Downlink5G.NumQueueGroups = 4 131 | config.Uplink4G.NumQueueGroups = 4 132 | config.Downlink4G.NumQueueGroups = 4 133 | err := config.Validate() 134 | Expect(err).To(HaveOccurred()) 135 | Expect(err.Error()).To(Equal(fmt.Sprintf("total number of requested queue groups (4G/5G/QFFT) %v exceeds the maximum (%d)", 20, acc200maxQueueGroups))) 136 | }) 137 | }) 138 | }) 139 | 140 | var _ = Describe("BBDevConfig Validation", func() { 141 | Context("when there are ambiguous configurations", func() { 142 | It("should return a field forbidden error", func() { 143 | config := BBDevConfig{ 144 | ACC100: &ACC100BBDevConfig{}, 145 | ACC200: &ACC200BBDevConfig{}, 146 | } 147 | err := config.Validate() 148 | Expect(err).To(HaveOccurred()) 149 | Expect(err).To(BeAssignableToTypeOf(&field.Error{})) 150 | fieldErr := err.(*field.Error) 151 | Expect(fieldErr.Type).To(Equal(field.ErrorTypeForbidden)) 152 | Expect(fieldErr.Field).To(Equal("spec.physicalFunction.bbDevConfig")) 153 | Expect(fieldErr.Detail).To(Equal("specified bbDevConfig cannot contain multiple configurations")) 154 | }) 155 | }) 156 | 157 | Context("when there is a single valid configuration", func() { 158 | It("should not return an error", func() { 159 | config := BBDevConfig{ 160 | ACC100: &ACC100BBDevConfig{}, 161 | } 162 | err := config.Validate() 163 | Expect(err).ToNot(HaveOccurred()) 164 | Expect(err).To(BeNil()) 165 | }) 166 | }) 167 | }) 168 | -------------------------------------------------------------------------------- /api/sriovfec/v2/sriovfecnodeconfig_types.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package v2 5 | 6 | import ( 7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | ) 9 | 10 | type VF struct { 11 | PCIAddress string `json:"pciAddress"` 12 | Driver string `json:"driver"` 13 | DeviceID string `json:"deviceID"` 14 | } 15 | 16 | type SriovAccelerator struct { 17 | VendorID string `json:"vendorID"` 18 | DeviceID string `json:"deviceID"` 19 | PCIAddress string `json:"pciAddress"` 20 | PFDriver string `json:"driver"` 21 | MaxVFs int `json:"maxVirtualFunctions"` 22 | VFs []VF `json:"virtualFunctions"` 23 | } 24 | 25 | type NodeInventory struct { 26 | SriovAccelerators []SriovAccelerator `json:"sriovAccelerators,omitempty"` 27 | } 28 | 29 | // SriovFecNodeConfigSpec defines the desired state of SriovFecNodeConfig 30 | type SriovFecNodeConfigSpec struct { 31 | // List of PhysicalFunctions configs 32 | // +operator-sdk:csv:customresourcedefinitions:type=spec 33 | PhysicalFunctions []PhysicalFunctionConfigExt `json:"physicalFunctions"` 34 | 35 | // +operator-sdk:csv:customresourcedefinitions:type=spec 36 | // Skips drain process when true; default false. Should be true if operator is running on SNO 37 | DrainSkip bool `json:"drainSkip,omitempty"` 38 | } 39 | 40 | // SriovFecNodeConfigStatus defines the observed state of SriovFecNodeConfig 41 | type SriovFecNodeConfigStatus struct { 42 | PfBbConfVersion string `json:"pfBbConfVersion,omitempty"` 43 | // Provides information about device update status 44 | Conditions []metav1.Condition `json:"conditions,omitempty"` 45 | // Provides information about FPGA inventory on the node 46 | // +operator-sdk:csv:customresourcedefinitions:type=status 47 | Inventory NodeInventory `json:"inventory,omitempty"` 48 | } 49 | 50 | // +kubebuilder:object:root=true 51 | // +kubebuilder:subresource:status 52 | // +kubebuilder:printcolumn:name="Configured",type=string,JSONPath=`.status.conditions[?(@.type=="Configured")].reason` 53 | // +kubebuilder:storageversion 54 | // +kubebuilder:resource:shortName=sfnc 55 | 56 | // SriovFecNodeConfig is the Schema for the sriovfecnodeconfigs API 57 | // +operator-sdk:csv:customresourcedefinitions:displayName="SriovFecNodeConfig",resources={{SriovFecNodeConfig,v1,node}} 58 | type SriovFecNodeConfig struct { 59 | metav1.TypeMeta `json:",inline"` 60 | metav1.ObjectMeta `json:"metadata,omitempty"` 61 | 62 | Spec SriovFecNodeConfigSpec `json:"spec,omitempty"` 63 | Status SriovFecNodeConfigStatus `json:"status,omitempty"` 64 | } 65 | 66 | // +kubebuilder:object:root=true 67 | 68 | // SriovFecNodeConfigList contains a list of SriovFecNodeConfig 69 | type SriovFecNodeConfigList struct { 70 | metav1.TypeMeta `json:",inline"` 71 | metav1.ListMeta `json:"metadata,omitempty"` 72 | Items []SriovFecNodeConfig `json:"items"` 73 | } 74 | 75 | func init() { 76 | SchemeBuilder.Register(&SriovFecNodeConfig{}, &SriovFecNodeConfigList{}) 77 | } 78 | -------------------------------------------------------------------------------- /api/sriovvrb/v1/groupversion_info.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | // Package v1 contains API Schema definitions for the vrb v1 API group 5 | // +kubebuilder:object:generate=true 6 | // +groupName=sriovvrb.intel.com 7 | package v1 8 | 9 | import ( 10 | "k8s.io/apimachinery/pkg/runtime/schema" 11 | "sigs.k8s.io/controller-runtime/pkg/scheme" 12 | ) 13 | 14 | var ( 15 | // GroupVersion is group version used to register these objects 16 | GroupVersion = schema.GroupVersion{Group: "sriovvrb.intel.com", Version: "v1"} 17 | 18 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 19 | SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} 20 | 21 | // AddToScheme adds the types in this group-version to the given scheme. 22 | AddToScheme = SchemeBuilder.AddToScheme 23 | ) 24 | -------------------------------------------------------------------------------- /api/sriovvrb/v1/helper.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package v1 5 | 6 | import ( 7 | "reflect" 8 | 9 | "k8s.io/apimachinery/pkg/api/meta" 10 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 | ) 12 | 13 | type ByPriority []SriovVrbClusterConfig 14 | 15 | func (a ByPriority) Len() int { 16 | return len(a) 17 | } 18 | 19 | func (a ByPriority) Less(i, j int) bool { 20 | if a[i].Spec.Priority != a[j].Spec.Priority { 21 | return a[i].Spec.Priority > a[j].Spec.Priority 22 | } 23 | return a[i].GetName() < a[j].GetName() 24 | } 25 | 26 | func (a ByPriority) Swap(i, j int) { 27 | a[i], a[j] = a[j], a[i] 28 | } 29 | 30 | func (s AcceleratorSelector) Matches(a SriovAccelerator) bool { 31 | return s.isVendorMatching(a) && s.isPciAddressMatching(a) && 32 | s.isPFDriverMatching(a) && s.isMaxVFsMatching(a) && s.isDeviceIDMatching(a) 33 | } 34 | 35 | func (s AcceleratorSelector) isVendorMatching(a SriovAccelerator) bool { 36 | return s.VendorID == "" || s.VendorID == a.VendorID 37 | } 38 | 39 | func (s AcceleratorSelector) isPciAddressMatching(a SriovAccelerator) bool { 40 | return s.PCIAddress == "" || s.PCIAddress == a.PCIAddress 41 | } 42 | 43 | func (s AcceleratorSelector) isPFDriverMatching(a SriovAccelerator) bool { 44 | return s.PFDriver == "" || s.PFDriver == a.PFDriver 45 | } 46 | 47 | func (s AcceleratorSelector) isMaxVFsMatching(a SriovAccelerator) bool { 48 | return s.MaxVFs == 0 || s.MaxVFs == a.MaxVFs 49 | } 50 | 51 | func (s AcceleratorSelector) isDeviceIDMatching(a SriovAccelerator) bool { 52 | return s.DeviceID == "" || s.DeviceID == a.DeviceID 53 | } 54 | 55 | func (in *SriovVrbNodeConfig) FindCondition(conditionType string) *metav1.Condition { 56 | return meta.FindStatusCondition(in.Status.Conditions, conditionType) 57 | } 58 | 59 | func isNil(v interface{}) bool { 60 | return v == nil || (reflect.ValueOf(v).Kind() == reflect.Ptr && reflect.ValueOf(v).IsNil()) 61 | } 62 | -------------------------------------------------------------------------------- /api/sriovvrb/v1/sriovvrbnodeconfig_types.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package v1 5 | 6 | import ( 7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | ) 9 | 10 | type VF struct { 11 | PCIAddress string `json:"pciAddress"` 12 | Driver string `json:"driver"` 13 | DeviceID string `json:"deviceID"` 14 | } 15 | 16 | type SriovAccelerator struct { 17 | VendorID string `json:"vendorID"` 18 | DeviceID string `json:"deviceID"` 19 | PCIAddress string `json:"pciAddress"` 20 | PFDriver string `json:"driver"` 21 | MaxVFs int `json:"maxVirtualFunctions"` 22 | VFs []VF `json:"virtualFunctions"` 23 | } 24 | 25 | type NodeInventory struct { 26 | SriovAccelerators []SriovAccelerator `json:"sriovAccelerators,omitempty"` 27 | } 28 | 29 | // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! 30 | // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. 31 | 32 | // SriovVrbNodeConfigSpec defines the desired state of SriovVrbNodeConfig 33 | type SriovVrbNodeConfigSpec struct { 34 | // List of PhysicalFunctions configs 35 | // +operator-sdk:csv:customresourcedefinitions:type=spec 36 | PhysicalFunctions []PhysicalFunctionConfigExt `json:"physicalFunctions"` 37 | 38 | // +operator-sdk:csv:customresourcedefinitions:type=spec 39 | // Skips drain process when true; default false. Should be true if operator is running on SNO 40 | DrainSkip bool `json:"drainSkip,omitempty"` 41 | } 42 | 43 | // SriovVrbNodeConfigStatus defines the observed state of SriovVrbNodeConfig 44 | type SriovVrbNodeConfigStatus struct { 45 | PfBbConfVersion string `json:"pfBbConfVersion,omitempty"` 46 | // Provides information about device update status 47 | Conditions []metav1.Condition `json:"conditions,omitempty"` 48 | // Provides information about FPGA inventory on the node 49 | // +operator-sdk:csv:customresourcedefinitions:type=status 50 | Inventory NodeInventory `json:"inventory,omitempty"` 51 | } 52 | 53 | // +kubebuilder:object:root=true 54 | // +kubebuilder:subresource:status 55 | // +kubebuilder:printcolumn:name="Configured",type=string,JSONPath=`.status.conditions[?(@.type=="Configured")].reason` 56 | // +kubebuilder:storageversion 57 | // +kubebuilder:resource:shortName=svnc 58 | 59 | // SriovVrbNodeConfig is the Schema for the SriovVrbNodeConfigs API 60 | type SriovVrbNodeConfig struct { 61 | metav1.TypeMeta `json:",inline"` 62 | metav1.ObjectMeta `json:"metadata,omitempty"` 63 | 64 | Spec SriovVrbNodeConfigSpec `json:"spec,omitempty"` 65 | Status SriovVrbNodeConfigStatus `json:"status,omitempty"` 66 | } 67 | 68 | //+kubebuilder:object:root=true 69 | 70 | // SriovVrbNodeConfigList contains a list of SriovVrbNodeConfig 71 | type SriovVrbNodeConfigList struct { 72 | metav1.TypeMeta `json:",inline"` 73 | metav1.ListMeta `json:"metadata,omitempty"` 74 | Items []SriovVrbNodeConfig `json:"items"` 75 | } 76 | 77 | func init() { 78 | SchemeBuilder.Register(&SriovVrbNodeConfig{}, &SriovVrbNodeConfigList{}) 79 | } 80 | -------------------------------------------------------------------------------- /assets/100-labeler.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: v1 5 | kind: ConfigMap 6 | metadata: 7 | name: labeler-config 8 | namespace: {{ .SRIOV_FEC_NAMESPACE }} 9 | immutable: false 10 | data: 11 | configMap: | 12 | apiVersion: v1 13 | kind: ConfigMap 14 | metadata: 15 | name: supported-accelerators 16 | namespace: {{ .SRIOV_FEC_NAMESPACE }} 17 | immutable: false 18 | data: 19 | accelerators.json: | 20 | { 21 | "VendorID": { 22 | "8086": "Intel Corporation", 23 | "1172": "Altera Corporation" 24 | }, 25 | "Class": "12", 26 | "SubClass": "00", 27 | "Devices": { 28 | "0d8f": "FPGA_5GNR", 29 | "5052": "FPGA_LTE", 30 | "0d5c": "ACC100", 31 | "57c0": "ACC200", 32 | "0b32": "" 33 | }, 34 | "NodeLabel": "fpga.intel.com/intel-accelerator-present" 35 | } 36 | accelerators_vrb.json: | 37 | { 38 | "VendorID": { 39 | "8086": "Intel Corporation" 40 | }, 41 | "Class": "12", 42 | "SubClass": "00", 43 | "Devices": { 44 | "57c0": "VRB1", 45 | "57c2": "VRB2" 46 | }, 47 | "NodeLabel": "fpga.intel.com/intel-accelerator-present" 48 | } 49 | serviceAccount: | 50 | apiVersion: v1 51 | kind: ServiceAccount 52 | metadata: 53 | name: accelerator-discovery 54 | namespace: {{ .SRIOV_FEC_NAMESPACE }} 55 | clusterRole: | 56 | apiVersion: rbac.authorization.k8s.io/v1 57 | kind: ClusterRole 58 | metadata: 59 | name: accelerator-discovery 60 | rules: 61 | - apiGroups: [""] 62 | resources: ["nodes"] 63 | verbs: ["get", "update"] 64 | clusterRoleBinding: | 65 | apiVersion: rbac.authorization.k8s.io/v1 66 | kind: ClusterRoleBinding 67 | metadata: 68 | name: accelerator-discovery 69 | roleRef: 70 | apiGroup: rbac.authorization.k8s.io 71 | kind: ClusterRole 72 | name: accelerator-discovery 73 | {{ if eq (.SRIOV_FEC_GENERIC_K8S|ToLower) `false` }} 74 | namespace: {{ .SRIOV_FEC_NAMESPACE }} 75 | {{ end }} 76 | subjects: 77 | - kind: ServiceAccount 78 | name: accelerator-discovery 79 | namespace: {{ .SRIOV_FEC_NAMESPACE }} 80 | {{ if eq (.SRIOV_FEC_GENERIC_K8S|ToLower) `false` }} 81 | userNames: 82 | - system:serviceaccount:{{ .SRIOV_FEC_NAMESPACE }}:accelerator-discovery 83 | {{ end }} 84 | daemonSet: | 85 | apiVersion: apps/v1 86 | kind: DaemonSet 87 | metadata: 88 | labels: 89 | app: accelerator-discovery 90 | name: accelerator-discovery 91 | namespace: {{ .SRIOV_FEC_NAMESPACE }} 92 | spec: 93 | minReadySeconds: 10 94 | selector: 95 | matchLabels: 96 | app: accelerator-discovery 97 | template: 98 | metadata: 99 | labels: 100 | app: accelerator-discovery 101 | name: accelerator-discovery 102 | spec: 103 | serviceAccount: accelerator-discovery 104 | serviceAccountName: accelerator-discovery 105 | containers: 106 | - image: {{ .SRIOV_FEC_LABELER_IMAGE }} 107 | imagePullPolicy: IfNotPresent 108 | name: accelerator-discovery 109 | securityContext: 110 | readOnlyRootFilesystem: true 111 | volumeMounts: 112 | - name: config-volume 113 | mountPath: "/labeler-workspace/config" 114 | readOnly: true 115 | env: 116 | - name: NODENAME 117 | valueFrom: 118 | fieldRef: 119 | fieldPath: spec.nodeName 120 | volumes: 121 | - name: config-volume 122 | configMap: 123 | name: supported-accelerators 124 | items: 125 | - key: accelerators.json 126 | path: accelerators.json 127 | - key: accelerators_vrb.json 128 | path: accelerators_vrb.json 129 | -------------------------------------------------------------------------------- /cmd/labeler/main.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package main 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | "os" 10 | 11 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 12 | 13 | "github.com/intel/sriov-fec-operator/pkg/common/utils" 14 | clientset "k8s.io/client-go/kubernetes" 15 | "k8s.io/client-go/rest" 16 | ) 17 | 18 | const ( 19 | configPath = "/labeler-workspace/config/accelerators.json" 20 | vrbconfigPath = "/labeler-workspace/config/accelerators_vrb.json" 21 | ) 22 | 23 | var getInclusterConfigFunc = rest.InClusterConfig 24 | 25 | func setNodeLabel(nodeName, label string, removeLabel bool) error { 26 | cfg, err := getInclusterConfigFunc() 27 | if err != nil { 28 | return fmt.Errorf("failed to get cluster config: %v", err.Error()) 29 | } 30 | cli, err := clientset.NewForConfig(cfg) 31 | if err != nil { 32 | return fmt.Errorf("failed to initialize clientset: %v", err.Error()) 33 | } 34 | 35 | node, err := cli.CoreV1().Nodes().Get(context.Background(), nodeName, metav1.GetOptions{}) 36 | if err != nil { 37 | return fmt.Errorf("failed to get the node object: %v", err) 38 | } 39 | nodeLabels := node.GetLabels() 40 | if removeLabel { 41 | delete(nodeLabels, label) 42 | } else { 43 | nodeLabels[label] = "" 44 | 45 | } 46 | node.SetLabels(nodeLabels) 47 | _, err = cli.CoreV1().Nodes().Update(context.Background(), node, metav1.UpdateOptions{}) 48 | if err != nil { 49 | return fmt.Errorf("failed to update the node object: %v", err) 50 | } 51 | return nil 52 | } 53 | 54 | func acceleratorDiscovery(cfgPath string, vrbCfgPath string) error { 55 | 56 | fecAccFound, fecNodeLabel, err1 := utils.FindAccelerator(cfgPath) 57 | vrbAccFound, vrbNodeLabel, err2 := utils.FindAccelerator(vrbCfgPath) 58 | 59 | if err1 != nil && err2 != nil { 60 | return fmt.Errorf("failed to find accelerator: %v %v", err1, err2) 61 | } 62 | nodeName := os.Getenv("NODENAME") 63 | if nodeName == "" { 64 | return fmt.Errorf("NODENAME environment variable is empty") 65 | } 66 | 67 | nodeLabel := "" 68 | if fecAccFound { 69 | nodeLabel = fecNodeLabel 70 | } else if vrbAccFound { 71 | nodeLabel = vrbNodeLabel 72 | } 73 | 74 | return setNodeLabel(nodeName, nodeLabel, !(fecAccFound || vrbAccFound)) 75 | } 76 | 77 | func main() { 78 | if err := acceleratorDiscovery(configPath, vrbconfigPath); err != nil { 79 | fmt.Printf("Accelerator discovery failed: %v\n", err) 80 | os.Exit(1) 81 | } 82 | fmt.Printf("Accelerator discovery finished successfully\n") 83 | os.Exit(0) 84 | } 85 | -------------------------------------------------------------------------------- /cmd/labeler/testdata/invalid.json: -------------------------------------------------------------------------------- 1 | invalid_json 2 | -------------------------------------------------------------------------------- /cmd/labeler/testdata/valid.json: -------------------------------------------------------------------------------- 1 | { 2 | "VendorID": {"0000": "test", 3 | "0001": "test1" 4 | }, 5 | "Class": "00", 6 | "SubClass": "00", 7 | "Devices": { 8 | "test": "test" 9 | }, 10 | "NodeLabel": "LABEL" 11 | } 12 | -------------------------------------------------------------------------------- /config/certmanager/certificate.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # The following manifests contain a self-signed issuer CR and a certificate CR. 5 | # More document can be found at https://docs.cert-manager.io 6 | # WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. 7 | apiVersion: cert-manager.io/v1 8 | kind: Issuer 9 | metadata: 10 | name: selfsigned-issuer 11 | namespace: system 12 | spec: 13 | selfSigned: {} 14 | --- 15 | apiVersion: cert-manager.io/v1 16 | kind: Certificate 17 | metadata: 18 | name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml 19 | namespace: system 20 | spec: 21 | # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize 22 | dnsNames: 23 | - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc 24 | - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local 25 | issuerRef: 26 | kind: Issuer 27 | name: selfsigned-issuer 28 | secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize 29 | -------------------------------------------------------------------------------- /config/certmanager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | resources: 5 | - certificate.yaml 6 | 7 | configurations: 8 | - kustomizeconfig.yaml 9 | -------------------------------------------------------------------------------- /config/certmanager/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # This configuration is for teaching kustomize how to update name ref and var substitution 5 | nameReference: 6 | - kind: Issuer 7 | group: cert-manager.io 8 | fieldSpecs: 9 | - kind: Certificate 10 | group: cert-manager.io 11 | path: spec/issuerRef/name 12 | 13 | varReference: 14 | - kind: Certificate 15 | group: cert-manager.io 16 | path: spec/commonName 17 | - kind: Certificate 18 | group: cert-manager.io 19 | path: spec/dnsNames 20 | -------------------------------------------------------------------------------- /config/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # This kustomization.yaml is not intended to be run by itself, 5 | # since it depends on service name and namespace that are out of this kustomize package. 6 | # It should be run by config/default 7 | resources: 8 | - bases/sriovfec.intel.com_sriovfecclusterconfigs.yaml 9 | - bases/sriovfec.intel.com_sriovfecnodeconfigs.yaml 10 | - bases/sriovvrb.intel.com_sriovvrbclusterconfigs.yaml 11 | - bases/sriovvrb.intel.com_sriovvrbnodeconfigs.yaml 12 | # +kubebuilder:scaffold:crdkustomizeresource 13 | 14 | patchesStrategicMerge: 15 | # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. 16 | # patches here are for enabling the conversion webhook for each CRD 17 | #- patches/webhook_in_sriovfecclusterconfigs.yaml 18 | #- patches/webhook_in_sriovfecnodeconfigs.yaml 19 | #- patches/webhook_in_sriovvrb_sriovvrbclusterconfigs.yaml 20 | #- patches/webhook_in_sriovvrb_sriovvrbnodeconfigs.yaml 21 | # +kubebuilder:scaffold:crdkustomizewebhookpatch 22 | 23 | # [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. 24 | # patches here are for enabling the CA injection for each CRD 25 | #- patches/cainjection_in_sriovfecclusterconfigs.yaml 26 | #- patches/cainjection_in_sriovfecnodeconfigs.yaml 27 | #- patches/cainjection_in_sriovvrb_sriovvrbclusterconfigs.yaml 28 | #- patches/cainjection_in_sriovvrb_sriovvrbnodeconfigs.yaml 29 | # +kubebuilder:scaffold:crdkustomizecainjectionpatch 30 | 31 | # the following config is for teaching kustomize how to do kustomization for CRDs. 32 | configurations: 33 | - kustomizeconfig.yaml 34 | -------------------------------------------------------------------------------- /config/crd/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # This file is for teaching kustomize how to substitute name and namespace reference in CRD 5 | nameReference: 6 | - kind: Service 7 | version: v1 8 | fieldSpecs: 9 | - kind: CustomResourceDefinition 10 | version: v1 11 | group: apiextensions.k8s.io 12 | path: spec/conversion/webhook/clientConfig/service/name 13 | 14 | namespace: 15 | - kind: CustomResourceDefinition 16 | version: v1 17 | group: apiextensions.k8s.io 18 | path: spec/conversion/webhook/clientConfig/service/namespace 19 | create: false 20 | 21 | varReference: 22 | - path: metadata/annotations 23 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_sriovfecclusterconfigs.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # The following patch adds a directive for certmanager to inject CA into the CRD 5 | apiVersion: apiextensions.k8s.io/v1 6 | kind: CustomResourceDefinition 7 | metadata: 8 | annotations: 9 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 10 | name: sriovfecclusterconfigs.sriovfec.intel.com 11 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_sriovfecnodeconfigs.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # The following patch adds a directive for certmanager to inject CA into the CRD 5 | apiVersion: apiextensions.k8s.io/v1 6 | kind: CustomResourceDefinition 7 | metadata: 8 | annotations: 9 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 10 | name: sriovfecnodeconfigs.sriovfec.intel.com 11 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_sriovvrb_sriovvrbclusterconfigs.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # The following patch adds a directive for certmanager to inject CA into the CRD 5 | apiVersion: apiextensions.k8s.io/v1 6 | kind: CustomResourceDefinition 7 | metadata: 8 | annotations: 9 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 10 | name: sriovvrbclusterconfigs.sriovvrb.intel.com 11 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_sriovvrb_sriovvrbnodeconfigs.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # The following patch adds a directive for certmanager to inject CA into the CRD 5 | apiVersion: apiextensions.k8s.io/v1 6 | kind: CustomResourceDefinition 7 | metadata: 8 | annotations: 9 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 10 | name: sriovvrbnodeconfigs.sriovvrb.intel.com 11 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_sriovfecclusterconfigs.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # The following patch enables a conversion webhook for the CRD 5 | apiVersion: apiextensions.k8s.io/v1 6 | kind: CustomResourceDefinition 7 | metadata: 8 | name: sriovfecclusterconfigs.sriovfec.intel.com 9 | spec: 10 | conversion: 11 | strategy: Webhook 12 | webhook: 13 | clientConfig: 14 | service: 15 | namespace: system 16 | name: webhook-service 17 | path: /convert 18 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_sriovfecnodeconfigs.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # The following patch enables a conversion webhook for the CRD 5 | apiVersion: apiextensions.k8s.io/v1 6 | kind: CustomResourceDefinition 7 | metadata: 8 | name: sriovfecnodeconfigs.sriovfec.intel.com 9 | spec: 10 | conversion: 11 | strategy: Webhook 12 | webhook: 13 | clientConfig: 14 | service: 15 | namespace: system 16 | name: webhook-service 17 | path: /convert 18 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_sriovvrb_sriovvrbclusterconfigs.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # The following patch enables a conversion webhook for the CRD 5 | apiVersion: apiextensions.k8s.io/v1 6 | kind: CustomResourceDefinition 7 | metadata: 8 | name: sriovvrbclusterconfigs.sriovvrb.intel.com 9 | spec: 10 | conversion: 11 | strategy: Webhook 12 | webhook: 13 | clientConfig: 14 | service: 15 | namespace: system 16 | name: webhook-service 17 | path: /convert 18 | conversionReviewVersions: 19 | - v1 20 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_sriovvrb_sriovvrbnodeconfigs.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # The following patch enables a conversion webhook for the CRD 5 | apiVersion: apiextensions.k8s.io/v1 6 | kind: CustomResourceDefinition 7 | metadata: 8 | name: sriovvrbnodeconfigs.sriovvrb.intel.com 9 | spec: 10 | conversion: 11 | strategy: Webhook 12 | webhook: 13 | clientConfig: 14 | service: 15 | namespace: system 16 | name: webhook-service 17 | path: /convert 18 | conversionReviewVersions: 19 | - v1 20 | -------------------------------------------------------------------------------- /config/default/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # Adds namespace to all resources. 5 | namespace: sriov-fec-system 6 | 7 | # Value of this field is prepended to the 8 | # names of all resources, e.g. a deployment named 9 | # "wordpress" becomes "alices-wordpress". 10 | # Note that it should also match with the prefix (text before '-') of the namespace 11 | # field above. 12 | namePrefix: sriov-fec- 13 | 14 | # Labels to add to all resources and selectors. 15 | #commonLabels: 16 | # someName: someValue 17 | 18 | bases: 19 | - ../crd 20 | - ../rbac 21 | - ../manager 22 | # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in 23 | # crd/kustomization.yaml 24 | - ../webhook 25 | # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. 26 | #- ../certmanager 27 | # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. 28 | #- ../prometheus 29 | 30 | patchesStrategicMerge: 31 | # Protect the /metrics endpoint by putting it behind auth. 32 | # If you want your controller-manager to expose the /metrics 33 | # endpoint w/o any authn/z, please comment the following line. 34 | - manager_auth_proxy_patch.yaml 35 | 36 | # Mount the controller config file for loading manager configurations 37 | # through a ComponentConfig type 38 | #- manager_config_patch.yaml 39 | 40 | # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in 41 | # crd/kustomization.yaml 42 | #- manager_webhook_patch.yaml 43 | 44 | # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 45 | # Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. 46 | # 'CERTMANAGER' needs to be enabled to use ca injection 47 | #- webhookcainjection_patch.yaml 48 | 49 | # the following config is for teaching kustomize how to do var substitution 50 | vars: 51 | # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. 52 | #- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR 53 | # objref: 54 | # kind: Certificate 55 | # group: cert-manager.io 56 | # version: v1 57 | # name: serving-cert # this name should match the one in certificate.yaml 58 | # fieldref: 59 | # fieldpath: metadata.namespace 60 | #- name: CERTIFICATE_NAME 61 | # objref: 62 | # kind: Certificate 63 | # group: cert-manager.io 64 | # version: v1 65 | # name: serving-cert # this name should match the one in certificate.yaml 66 | #- name: SERVICE_NAMESPACE # namespace of the service 67 | # objref: 68 | # kind: Service 69 | # version: v1 70 | # name: webhook-service 71 | # fieldref: 72 | # fieldpath: metadata.namespace 73 | #- name: SERVICE_NAME 74 | # objref: 75 | # kind: Service 76 | # version: v1 77 | # name: webhook-service 78 | -------------------------------------------------------------------------------- /config/default/manager_auth_proxy_patch.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # This patch inject a sidecar container which is a HTTP proxy for the 5 | # controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. 6 | apiVersion: apps/v1 7 | kind: Deployment 8 | metadata: 9 | name: controller-manager 10 | namespace: system 11 | spec: 12 | template: 13 | spec: 14 | containers: 15 | - name: kube-rbac-proxy 16 | image: $KUBE_RBAC_PROXY_IMAGE 17 | securityContext: 18 | allowPrivilegeEscalation: false 19 | runAsNonRoot: true 20 | args: 21 | - "--secure-listen-address=0.0.0.0:8443" 22 | - "--upstream=http://127.0.0.1:8080/" 23 | - "--logtostderr=true" 24 | - "--v=0" 25 | ports: 26 | - containerPort: 8443 27 | protocol: TCP 28 | name: https 29 | resources: 30 | limits: 31 | cpu: 500m 32 | memory: 128Mi 33 | requests: 34 | cpu: 5m 35 | memory: 64Mi 36 | - name: manager 37 | securityContext: 38 | allowPrivilegeEscalation: false 39 | runAsNonRoot: true 40 | args: 41 | - "--health-probe-bind-address=:8081" 42 | - "--metrics-bind-address=127.0.0.1:8080" 43 | - "--leader-elect" 44 | -------------------------------------------------------------------------------- /config/default/manager_config_patch.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: apps/v1 5 | kind: Deployment 6 | metadata: 7 | name: controller-manager 8 | namespace: system 9 | spec: 10 | template: 11 | spec: 12 | containers: 13 | - name: manager 14 | securityContext: 15 | allowPrivilegeEscalation: false 16 | runAsNonRoot: true 17 | args: 18 | - "--config=controller_manager_config.yaml" 19 | volumeMounts: 20 | - name: manager-config 21 | mountPath: /controller_manager_config.yaml 22 | subPath: controller_manager_config.yaml 23 | volumes: 24 | - name: manager-config 25 | configMap: 26 | name: manager-config 27 | -------------------------------------------------------------------------------- /config/default/manager_webhook_patch.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: apps/v1 5 | kind: Deployment 6 | metadata: 7 | name: controller-manager 8 | namespace: system 9 | spec: 10 | template: 11 | spec: 12 | containers: 13 | - name: manager 14 | securityContext: 15 | allowPrivilegeEscalation: false 16 | runAsNonRoot: true 17 | readOnlyRootFilesystem: true 18 | ports: 19 | - containerPort: 9443 20 | name: webhook-server 21 | protocol: TCP 22 | volumeMounts: 23 | - mountPath: /tmp/k8s-webhook-server/serving-certs 24 | name: cert 25 | readOnly: true 26 | volumes: 27 | - name: cert 28 | secret: 29 | defaultMode: 420 30 | secretName: webhook-server-cert 31 | -------------------------------------------------------------------------------- /config/default/webhookcainjection_patch.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # This patch add annotation to admission webhook config and 5 | # the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. 6 | apiVersion: admissionregistration.k8s.io/v1 7 | kind: MutatingWebhookConfiguration 8 | metadata: 9 | name: mutating-webhook-configuration 10 | annotations: 11 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 12 | --- 13 | apiVersion: admissionregistration.k8s.io/v1 14 | kind: ValidatingWebhookConfiguration 15 | metadata: 16 | name: validating-webhook-configuration 17 | annotations: 18 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 19 | -------------------------------------------------------------------------------- /config/manager/controller_manager_config.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 5 | kind: ControllerManagerConfig 6 | health: 7 | healthProbeBindAddress: :8081 8 | metrics: 9 | bindAddress: 127.0.0.1:8080 10 | webhook: 11 | port: 9443 12 | leaderElection: 13 | leaderElect: true 14 | resourceName: bab0ab5c.intel.com 15 | -------------------------------------------------------------------------------- /config/manager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | resources: 5 | - manager.yaml 6 | 7 | generatorOptions: 8 | disableNameSuffixHash: true 9 | 10 | configMapGenerator: 11 | - files: 12 | - controller_manager_config.yaml 13 | name: manager-config 14 | apiVersion: kustomize.config.k8s.io/v1beta1 15 | kind: Kustomization 16 | images: 17 | - name: sriov-fec-operator 18 | newName: registry.connect.redhat.com/intel/sriov-fec-operator 19 | newTag: v2.3.0 20 | -------------------------------------------------------------------------------- /config/manifests/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | resources: 5 | - ../default 6 | - ../samples 7 | - ../scorecard 8 | 9 | # [WEBHOOK] To enable webhooks, uncomment all the sections with [WEBHOOK] prefix. 10 | # Do NOT uncomment sections with prefix [CERTMANAGER], as OLM does not support cert-manager. 11 | # These patches remove the unnecessary "cert" volume and its manager container volumeMount. 12 | #patchesJson6902: 13 | #- target: 14 | # group: apps 15 | # version: v1 16 | # kind: Deployment 17 | # name: controller-manager 18 | # namespace: system 19 | # patch: |- 20 | # # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs. 21 | # # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment. 22 | # - op: remove 23 | # path: /spec/template/spec/containers/1/volumeMounts/0 24 | # # Remove the "cert" volume, since OLM will create and mount a set of certs. 25 | # # Update the indices in this path if adding or removing volumes in the manager's Deployment. 26 | # - op: remove 27 | # path: /spec/template/spec/volumes/0 28 | -------------------------------------------------------------------------------- /config/prometheus/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | resources: 5 | - monitor.yaml 6 | -------------------------------------------------------------------------------- /config/prometheus/monitor.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | 5 | # Prometheus Monitor Service (Metrics) 6 | apiVersion: monitoring.coreos.com/v1 7 | kind: ServiceMonitor 8 | metadata: 9 | labels: 10 | control-plane: controller-manager 11 | name: controller-manager-metrics-monitor 12 | namespace: system 13 | spec: 14 | endpoints: 15 | - path: /metrics 16 | port: https 17 | scheme: https 18 | bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token 19 | tlsConfig: 20 | insecureSkipVerify: true 21 | selector: 22 | matchLabels: 23 | control-plane: controller-manager 24 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_client_clusterrole.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: rbac.authorization.k8s.io/v1 5 | kind: ClusterRole 6 | metadata: 7 | name: metrics-reader 8 | rules: 9 | - nonResourceURLs: ["/metrics"] 10 | verbs: ["get"] 11 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_role.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: rbac.authorization.k8s.io/v1 5 | kind: ClusterRole 6 | metadata: 7 | name: proxy-role 8 | rules: 9 | - apiGroups: ["authentication.k8s.io"] 10 | resources: 11 | - tokenreviews 12 | verbs: ["create"] 13 | - apiGroups: ["authorization.k8s.io"] 14 | resources: 15 | - subjectaccessreviews 16 | verbs: ["create"] 17 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_role_binding.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: rbac.authorization.k8s.io/v1 5 | kind: ClusterRoleBinding 6 | metadata: 7 | name: proxy-rolebinding 8 | roleRef: 9 | apiGroup: rbac.authorization.k8s.io 10 | kind: ClusterRole 11 | name: proxy-role 12 | subjects: 13 | - kind: ServiceAccount 14 | name: controller-manager 15 | namespace: system 16 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_service.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: v1 5 | kind: Service 6 | metadata: 7 | labels: 8 | control-plane: controller-manager 9 | name: controller-manager-metrics-service 10 | namespace: system 11 | spec: 12 | ports: 13 | - name: https 14 | port: 8443 15 | targetPort: https 16 | selector: 17 | control-plane: controller-manager 18 | -------------------------------------------------------------------------------- /config/rbac/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | resources: 5 | - role.yaml 6 | - role_binding.yaml 7 | - leader_election_role.yaml 8 | - leader_election_role_binding.yaml 9 | # Comment the following 4 lines if you want to disable 10 | # the auth proxy (https://github.com/brancz/kube-rbac-proxy) 11 | # which protects your /metrics endpoint. 12 | - auth_proxy_service.yaml 13 | - auth_proxy_role.yaml 14 | - auth_proxy_role_binding.yaml 15 | - auth_proxy_client_clusterrole.yaml 16 | -------------------------------------------------------------------------------- /config/rbac/leader_election_role.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # permissions to do leader election. 5 | apiVersion: rbac.authorization.k8s.io/v1 6 | kind: Role 7 | metadata: 8 | name: leader-election-role 9 | rules: 10 | - apiGroups: 11 | - "" 12 | resources: 13 | - configmaps 14 | verbs: 15 | - get 16 | - list 17 | - watch 18 | - create 19 | - update 20 | - patch 21 | - delete 22 | - apiGroups: 23 | - coordination.k8s.io 24 | resources: 25 | - leases 26 | verbs: 27 | - get 28 | - list 29 | - watch 30 | - create 31 | - update 32 | - patch 33 | - delete 34 | - apiGroups: 35 | - "" 36 | resources: 37 | - events 38 | verbs: 39 | - create 40 | - patch 41 | -------------------------------------------------------------------------------- /config/rbac/leader_election_role_binding.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: rbac.authorization.k8s.io/v1 5 | kind: RoleBinding 6 | metadata: 7 | name: leader-election-rolebinding 8 | roleRef: 9 | apiGroup: rbac.authorization.k8s.io 10 | kind: Role 11 | name: leader-election-role 12 | subjects: 13 | - kind: ServiceAccount 14 | name: controller-manager 15 | namespace: system 16 | -------------------------------------------------------------------------------- /config/rbac/role.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | --- 4 | apiVersion: rbac.authorization.k8s.io/v1 5 | kind: ClusterRole 6 | metadata: 7 | creationTimestamp: null 8 | name: manager-role 9 | rules: 10 | - apiGroups: 11 | - "" 12 | resources: 13 | - configmaps 14 | - secrets 15 | - serviceaccounts 16 | verbs: 17 | - 'get' 18 | - 'create' 19 | - 'list' 20 | - 'update' 21 | - apiGroups: 22 | - "" 23 | resources: 24 | - nodes 25 | verbs: 26 | - list 27 | - watch 28 | - apiGroups: 29 | - apps 30 | resources: 31 | - daemonsets 32 | - deployments 33 | - deployments/finalizers 34 | verbs: 35 | - 'get' 36 | - 'create' 37 | - 'list' 38 | - 'update' 39 | - apiGroups: 40 | - rbac.authorization.k8s.io 41 | resources: 42 | - clusterrolebindings 43 | - clusterroles 44 | - rolebindings 45 | - roles 46 | verbs: 47 | - 'get' 48 | - 'create' 49 | - 'list' 50 | - 'update' 51 | - apiGroups: 52 | - security.openshift.io 53 | resources: 54 | - securitycontextconstraints 55 | verbs: 56 | - '*' 57 | - apiGroups: 58 | - sriovfec.intel.com 59 | resources: 60 | - sriovfecclusterconfigs 61 | verbs: 62 | - create 63 | - delete 64 | - get 65 | - list 66 | - patch 67 | - update 68 | - watch 69 | - apiGroups: 70 | - sriovfec.intel.com 71 | resources: 72 | - sriovfecclusterconfigs/status 73 | verbs: 74 | - get 75 | - patch 76 | - update 77 | - apiGroups: 78 | - sriovfec.intel.com 79 | resources: 80 | - sriovfecnodeconfigs 81 | verbs: 82 | - create 83 | - delete 84 | - get 85 | - list 86 | - patch 87 | - update 88 | - watch 89 | - apiGroups: 90 | - sriovfec.intel.com 91 | resources: 92 | - sriovfecnodeconfigs/status 93 | verbs: 94 | - get 95 | - patch 96 | - update 97 | - apiGroups: 98 | - sriovvrb.intel.com 99 | resources: 100 | - sriovvrbclusterconfigs 101 | verbs: 102 | - create 103 | - delete 104 | - get 105 | - list 106 | - patch 107 | - update 108 | - watch 109 | - apiGroups: 110 | - sriovvrb.intel.com 111 | resources: 112 | - sriovvrbclusterconfigs/status 113 | verbs: 114 | - get 115 | - patch 116 | - update 117 | - apiGroups: 118 | - sriovvrb.intel.com 119 | resources: 120 | - sriovvrbnodeconfigs 121 | verbs: 122 | - create 123 | - delete 124 | - get 125 | - list 126 | - patch 127 | - update 128 | - watch 129 | - apiGroups: 130 | - sriovvrb.intel.com 131 | resources: 132 | - sriovvrbnodeconfigs/status 133 | verbs: 134 | - get 135 | - patch 136 | - update 137 | - apiGroups: 138 | - sriovvrb.intel.com 139 | resources: 140 | - sriovvrbnodeconfigs/status 141 | verbs: 142 | - get 143 | - patch 144 | - update 145 | -------------------------------------------------------------------------------- /config/rbac/role_binding.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: rbac.authorization.k8s.io/v1 5 | kind: ClusterRoleBinding 6 | metadata: 7 | name: manager-rolebinding 8 | roleRef: 9 | apiGroup: rbac.authorization.k8s.io 10 | kind: ClusterRole 11 | name: manager-role 12 | subjects: 13 | - kind: ServiceAccount 14 | name: controller-manager 15 | namespace: system 16 | -------------------------------------------------------------------------------- /config/rbac/sriovfecclusterconfig_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # permissions for end users to edit sriovfecclusterconfigs. 5 | apiVersion: rbac.authorization.k8s.io/v1 6 | kind: ClusterRole 7 | metadata: 8 | name: sriovfecclusterconfig-editor-role 9 | rules: 10 | - apiGroups: 11 | - sriovfec.intel.com 12 | resources: 13 | - sriovfecclusterconfigs 14 | verbs: 15 | - create 16 | - delete 17 | - get 18 | - list 19 | - patch 20 | - update 21 | - watch 22 | - apiGroups: 23 | - sriovfec.intel.com 24 | resources: 25 | - sriovfecclusterconfigs/status 26 | verbs: 27 | - get 28 | -------------------------------------------------------------------------------- /config/rbac/sriovfecclusterconfig_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # permissions for end users to view sriovfecclusterconfigs. 5 | apiVersion: rbac.authorization.k8s.io/v1 6 | kind: ClusterRole 7 | metadata: 8 | name: sriovfecclusterconfig-viewer-role 9 | rules: 10 | - apiGroups: 11 | - sriovfec.intel.com 12 | resources: 13 | - sriovfecclusterconfigs 14 | verbs: 15 | - get 16 | - list 17 | - watch 18 | - apiGroups: 19 | - sriovfec.intel.com 20 | resources: 21 | - sriovfecclusterconfigs/status 22 | verbs: 23 | - get 24 | -------------------------------------------------------------------------------- /config/rbac/sriovfecnodeconfig_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # permissions for end users to edit sriovfecnodeconfigs. 5 | apiVersion: rbac.authorization.k8s.io/v1 6 | kind: ClusterRole 7 | metadata: 8 | name: sriovfecnodeconfig-editor-role 9 | rules: 10 | - apiGroups: 11 | - sriovfec.intel.com 12 | resources: 13 | - sriovfecnodeconfigs 14 | verbs: 15 | - create 16 | - delete 17 | - get 18 | - list 19 | - patch 20 | - update 21 | - watch 22 | - apiGroups: 23 | - sriovfec.intel.com 24 | resources: 25 | - sriovfecnodeconfigs/status 26 | verbs: 27 | - get 28 | -------------------------------------------------------------------------------- /config/rbac/sriovfecnodeconfig_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # permissions for end users to view sriovfecnodeconfigs. 5 | apiVersion: rbac.authorization.k8s.io/v1 6 | kind: ClusterRole 7 | metadata: 8 | name: sriovfecnodeconfig-viewer-role 9 | rules: 10 | - apiGroups: 11 | - sriovfec.intel.com 12 | resources: 13 | - sriovfecnodeconfigs 14 | verbs: 15 | - get 16 | - list 17 | - watch 18 | - apiGroups: 19 | - sriovfec.intel.com 20 | resources: 21 | - sriovfecnodeconfigs/status 22 | verbs: 23 | - get 24 | -------------------------------------------------------------------------------- /config/rbac/sriovvrb_sriovvrbclusterconfig_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # permissions for end users to edit sriovvrbclusterconfigs. 5 | apiVersion: rbac.authorization.k8s.io/v1 6 | kind: ClusterRole 7 | metadata: 8 | name: sriovvrbclusterconfig-editor-role 9 | rules: 10 | - apiGroups: 11 | - sriovvrb.intel.com 12 | resources: 13 | - sriovvrbclusterconfigs 14 | verbs: 15 | - create 16 | - delete 17 | - get 18 | - list 19 | - patch 20 | - update 21 | - watch 22 | - apiGroups: 23 | - sriovvrb.intel.com 24 | resources: 25 | - sriovvrbclusterconfigs/status 26 | verbs: 27 | - get 28 | -------------------------------------------------------------------------------- /config/rbac/sriovvrb_sriovvrbclusterconfig_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # permissions for end users to view sriovvrbclusterconfigs. 5 | apiVersion: rbac.authorization.k8s.io/v1 6 | kind: ClusterRole 7 | metadata: 8 | name: sriovvrbclusterconfig-viewer-role 9 | rules: 10 | - apiGroups: 11 | - sriovvrb.intel.com 12 | resources: 13 | - sriovvrbclusterconfigs 14 | verbs: 15 | - get 16 | - list 17 | - watch 18 | - apiGroups: 19 | - sriovvrb.intel.com 20 | resources: 21 | - sriovvrbclusterconfigs/status 22 | verbs: 23 | - get 24 | -------------------------------------------------------------------------------- /config/rbac/sriovvrb_sriovvrbnodeconfig_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # permissions for end users to edit sriovvrbnodeconfigs. 5 | apiVersion: rbac.authorization.k8s.io/v1 6 | kind: ClusterRole 7 | metadata: 8 | name: sriovvrbnodeconfig-editor-role 9 | rules: 10 | - apiGroups: 11 | - sriovvrb.intel.com 12 | resources: 13 | - sriovvrbnodeconfigs 14 | verbs: 15 | - create 16 | - delete 17 | - get 18 | - list 19 | - patch 20 | - update 21 | - watch 22 | - apiGroups: 23 | - sriovvrb.intel.com 24 | resources: 25 | - sriovvrbnodeconfigs/status 26 | verbs: 27 | - get 28 | -------------------------------------------------------------------------------- /config/rbac/sriovvrb_sriovvrbnodeconfig_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # permissions for end users to view sriovvrbnodeconfigs. 5 | apiVersion: rbac.authorization.k8s.io/v1 6 | kind: ClusterRole 7 | metadata: 8 | name: sriovvrbnodeconfig-viewer-role 9 | rules: 10 | - apiGroups: 11 | - sriovvrb.intel.com 12 | resources: 13 | - sriovvrbnodeconfigs 14 | verbs: 15 | - get 16 | - list 17 | - watch 18 | - apiGroups: 19 | - sriovvrb.intel.com 20 | resources: 21 | - sriovvrbnodeconfigs/status 22 | verbs: 23 | - get 24 | -------------------------------------------------------------------------------- /config/samples/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | ## Append samples you want in your CSV to this file as resources ## 5 | resources: 6 | - sriovfec_v2_sriovfecclusterconfig_n3000.yaml 7 | - sriovfec_v2_sriovfecclusterconfig_acc100.yaml 8 | - sriovfec_v2_sriovfecnodeconfig_n3000.yaml 9 | - sriovfec_v2_sriovfecnodeconfig_acc100.yaml 10 | - sriovvrb_v1_sriovvrbclusterconfig.yaml 11 | - sriovvrb_v1_sriovvrbnodeconfig.yaml 12 | # +kubebuilder:scaffold:manifestskustomizesamples 13 | -------------------------------------------------------------------------------- /config/samples/sriovfec_v2_sriovfecclusterconfig_acc100.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: acc100SampleConfig 8 | namespace: vran-acceleration-operators 9 | spec: 10 | priority: 100 11 | drainSkip: false 12 | # nodeSelector and all its key-value pairs are optional 13 | nodeSelector: 14 | expectedLabel1: "valueOfExpectedLabel1" 15 | expectedLabelN: "valueOfExpectedLabelN" 16 | # acceleratorSelector and all its fields are optional 17 | acceleratorSelector: 18 | vendorID: "someVendor" 19 | deviceID: "someDevice" 20 | pciAddress: "somePciAddress" 21 | driver: "someDriver" 22 | maxVirtualFunctions: 2 23 | physicalFunction: 24 | pfDriver: "pci-pf-stub" 25 | vfDriver: "vfio-pci" 26 | vfAmount: 2 27 | bbDevConfig: 28 | acc100: 29 | # Programming mode: 0 = VF Programming, 1 = PF Programming 30 | pfMode: true 31 | numVfBundles: 16 32 | maxQueueSize: 1024 33 | uplink4G: 34 | numQueueGroups: 0 35 | numAqsPerGroups: 16 36 | aqDepthLog2: 4 37 | downlink4G: 38 | numQueueGroups: 0 39 | numAqsPerGroups: 16 40 | aqDepthLog2: 4 41 | uplink5G: 42 | numQueueGroups: 4 43 | numAqsPerGroups: 16 44 | aqDepthLog2: 4 45 | downlink5G: 46 | numQueueGroups: 4 47 | numAqsPerGroups: 16 48 | aqDepthLog2: 4 49 | -------------------------------------------------------------------------------- /config/samples/sriovfec_v2_sriovfecclusterconfig_n3000.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: n3000SampleConfig 8 | namespace: vran-acceleration-operators 9 | spec: 10 | drainSkip: false 11 | priority: 100 12 | # nodeSelector and all its key-value pairs are optional 13 | nodeSelector: 14 | expectedLabel1: "valueOfExpectedLabel1" 15 | expectedLabelN: "valueOfExpectedLabelN" 16 | # acceleratorSelector and all its fields are optional 17 | acceleratorSelector: 18 | vendorID: "someVendor" 19 | deviceID: "someDevice" 20 | pciAddress: "somePciAddress" 21 | driver: "someDriver" 22 | maxVirtualFunctions: 2 23 | physicalFunction: 24 | pfDriver: "pci-pf-stub" 25 | vfDriver: "vfio-pci" 26 | vfAmount: 2 27 | bbDevConfig: 28 | n3000: 29 | # Network Type: either "FPGA_5GNR" or "FPGA_LTE" 30 | networkType: "FPGA_5GNR" 31 | # Programming mode: 0 = VF Programming, 1 = PF Programming 32 | pfMode: true 33 | flrTimeout: 610 34 | downlink: 35 | bandwidth: 3 36 | loadBalance: 128 37 | queues: 38 | vf0: 16 39 | vf1: 16 40 | vf2: 0 41 | vf3: 0 42 | vf4: 0 43 | vf5: 0 44 | vf6: 0 45 | vf7: 0 46 | uplink: 47 | bandwidth: 3 48 | loadBalance: 128 49 | queues: 50 | vf0: 16 51 | vf1: 16 52 | vf2: 0 53 | vf3: 0 54 | vf4: 0 55 | vf5: 0 56 | vf6: 0 57 | vf7: 0 58 | -------------------------------------------------------------------------------- /config/samples/sriovfec_v2_sriovfecnodeconfig_acc100.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecNodeConfig 6 | metadata: 7 | name: acc100-worker 8 | namespace: vran-acceleration-operators 9 | spec: 10 | drainSkip: false 11 | physicalFunctions: 12 | - pci_addr: "somePciAddress" 13 | pf_driver: "pci-pf-stub" 14 | vf_driver: "vfio-pci" 15 | vf_amount: 2 16 | bbDevConfig: 17 | acc100: 18 | # Programming mode: 0 = VF Programming, 1 = PF Programming 19 | pfMode: true 20 | numVfBundles: 16 21 | maxQueueSize: 1024 22 | uplink4G: 23 | numQueueGroups: 0 24 | numAqsPerGroups: 16 25 | aqDepthLog2: 4 26 | downlink4G: 27 | numQueueGroups: 0 28 | numAqsPerGroups: 16 29 | aqDepthLog2: 4 30 | uplink5G: 31 | numQueueGroups: 4 32 | numAqsPerGroups: 16 33 | aqDepthLog2: 4 34 | downlink5G: 35 | numQueueGroups: 4 36 | numAqsPerGroups: 16 37 | aqDepthLog2: 4 38 | -------------------------------------------------------------------------------- /config/samples/sriovfec_v2_sriovfecnodeconfig_n3000.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecNodeConfig 6 | metadata: 7 | name: n3000-worker 8 | namespace: vran-acceleration-operators 9 | spec: 10 | drainSkip: false 11 | physicalFunctions: 12 | - pci_addr: "somePciAddress" 13 | pf_driver: "pci-pf-stub" 14 | vf_driver: "vfio-pci" 15 | vf_amount: 2 16 | bbDevConfig: 17 | n3000: 18 | # Network Type: either "FPGA_5GNR" or "FPGA_LTE" 19 | networkType: "FPGA_5GNR" 20 | # Programming mode: 0 = VF Programming, 1 = PF Programming 21 | pfMode: true 22 | flrTimeout: 610 23 | downlink: 24 | bandwidth: 3 25 | loadBalance: 128 26 | queues: 27 | vf0: 16 28 | vf1: 16 29 | vf2: 0 30 | vf3: 0 31 | vf4: 0 32 | vf5: 0 33 | vf6: 0 34 | vf7: 0 35 | uplink: 36 | bandwidth: 3 37 | loadBalance: 128 38 | queues: 39 | vf0: 16 40 | vf1: 16 41 | vf2: 0 42 | vf3: 0 43 | vf4: 0 44 | vf5: 0 45 | vf6: 0 46 | vf7: 0 47 | -------------------------------------------------------------------------------- /config/samples/sriovvrb_v1_sriovvrbclusterconfig.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbclusterconfig 6 | metadata: 7 | name: vrb1SampleConfig 8 | namespace: vran-acceleration-operators 9 | spec: 10 | acceleratorSelector: 11 | pciAddress: somePciAddress 12 | nodeSelector: 13 | kubernetes.io/hostname: nodename 14 | physicalFunction: 15 | bbDevConfig: 16 | vrb1: 17 | downlink4G: 18 | aqDepthLog2: 4 19 | numAqsPerGroups: 16 20 | numQueueGroups: 0 21 | downlink5G: 22 | aqDepthLog2: 4 23 | numAqsPerGroups: 16 24 | numQueueGroups: 4 25 | maxQueueSize: 1024 26 | numVfBundles: 4 27 | pfMode: false 28 | qfft: 29 | aqDepthLog2: 4 30 | numAqsPerGroups: 16 31 | numQueueGroups: 4 32 | uplink4G: 33 | aqDepthLog2: 4 34 | numAqsPerGroups: 16 35 | numQueueGroups: 0 36 | uplink5G: 37 | aqDepthLog2: 4 38 | numAqsPerGroups: 16 39 | numQueueGroups: 4 40 | pfbbConf: 41 | pfbbUrl: "somepfbbUrl" 42 | pfbbChecksum: "relatedChecksum" 43 | fftLut: 44 | fftUrl: somefftUrl 45 | fftChecksum: "relatedChecksum" 46 | pfDriver: vfio-pci 47 | vfAmount: 4 48 | vfDriver: vfio-pci 49 | priority: 1 50 | drainSkip: true 51 | 52 | -------------------------------------------------------------------------------- /config/samples/sriovvrb_v1_sriovvrbnodeconfig.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbnodeconfig 6 | metadata: 7 | name: vrb1-worker 8 | namespace: vran-acceleration-operators 9 | spec: 10 | drainSkip: true 11 | physicalFunctions: 12 | - bbDevConfig: 13 | vrb1: 14 | downlink4G: 15 | aqDepthLog2: 4 16 | numAqsPerGroups: 16 17 | numQueueGroups: 0 18 | downlink5G: 19 | aqDepthLog2: 4 20 | numAqsPerGroups: 16 21 | numQueueGroups: 4 22 | fftLut: 23 | fftChecksum: relatedChecksum 24 | fftUrl: somefftUrl 25 | maxQueueSize: 1024 26 | numVfBundles: 4 27 | pfbbConf: 28 | pfbbChecksum: relatedChecksum 29 | pfbbUrl: somepfbbUrl 30 | qfft: 31 | aqDepthLog2: 4 32 | numAqsPerGroups: 16 33 | numQueueGroups: 4 34 | uplink4G: 35 | aqDepthLog2: 4 36 | numAqsPerGroups: 16 37 | numQueueGroups: 0 38 | uplink5G: 39 | aqDepthLog2: 4 40 | numAqsPerGroups: 16 41 | numQueueGroups: 4 42 | pciAddress: somePciAddress 43 | pfDriver: vfio-pci 44 | vfAmount: 4 45 | vfDriver: vfio-pci 46 | -------------------------------------------------------------------------------- /config/scorecard/bases/config.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: scorecard.operatorframework.io/v1alpha3 5 | kind: Configuration 6 | metadata: 7 | name: config 8 | stages: 9 | - parallel: true 10 | tests: [] 11 | -------------------------------------------------------------------------------- /config/scorecard/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | resources: 5 | - bases/config.yaml 6 | patchesJson6902: 7 | - path: patches/basic.config.yaml 8 | target: 9 | group: scorecard.operatorframework.io 10 | version: v1alpha3 11 | kind: Configuration 12 | name: config 13 | - path: patches/olm.config.yaml 14 | target: 15 | group: scorecard.operatorframework.io 16 | version: v1alpha3 17 | kind: Configuration 18 | name: config 19 | # +kubebuilder:scaffold:patchesJson6902 20 | -------------------------------------------------------------------------------- /config/scorecard/patches/basic.config.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | - op: add 5 | path: /stages/0/tests/- 6 | value: 7 | entrypoint: 8 | - scorecard-test 9 | - basic-check-spec 10 | image: quay.io/operator-framework/scorecard-test:v1.9.0 11 | labels: 12 | suite: basic 13 | test: basic-check-spec-test 14 | -------------------------------------------------------------------------------- /config/scorecard/patches/olm.config.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | - op: add 5 | path: /stages/0/tests/- 6 | value: 7 | entrypoint: 8 | - scorecard-test 9 | - olm-bundle-validation 10 | image: quay.io/operator-framework/scorecard-test:v1.9.0 11 | labels: 12 | suite: olm 13 | test: olm-bundle-validation-test 14 | - op: add 15 | path: /stages/0/tests/- 16 | value: 17 | entrypoint: 18 | - scorecard-test 19 | - olm-crds-have-validation 20 | image: quay.io/operator-framework/scorecard-test:v1.9.0 21 | labels: 22 | suite: olm 23 | test: olm-crds-have-validation-test 24 | - op: add 25 | path: /stages/0/tests/- 26 | value: 27 | entrypoint: 28 | - scorecard-test 29 | - olm-crds-have-resources 30 | image: quay.io/operator-framework/scorecard-test:v1.9.0 31 | labels: 32 | suite: olm 33 | test: olm-crds-have-resources-test 34 | - op: add 35 | path: /stages/0/tests/- 36 | value: 37 | entrypoint: 38 | - scorecard-test 39 | - olm-spec-descriptors 40 | image: quay.io/operator-framework/scorecard-test:v1.9.0 41 | labels: 42 | suite: olm 43 | test: olm-spec-descriptors-test 44 | - op: add 45 | path: /stages/0/tests/- 46 | value: 47 | entrypoint: 48 | - scorecard-test 49 | - olm-status-descriptors 50 | image: quay.io/operator-framework/scorecard-test:v1.9.0 51 | labels: 52 | suite: olm 53 | test: olm-status-descriptors-test 54 | -------------------------------------------------------------------------------- /config/webhook/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | resources: 5 | - manifests.yaml 6 | - service.yaml 7 | 8 | configurations: 9 | - kustomizeconfig.yaml 10 | -------------------------------------------------------------------------------- /config/webhook/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | # the following config is for teaching kustomize where to look at when substituting vars. 5 | # It requires kustomize v2.1.0 or newer to work properly. 6 | nameReference: 7 | - kind: Service 8 | version: v1 9 | fieldSpecs: 10 | - kind: MutatingWebhookConfiguration 11 | group: admissionregistration.k8s.io 12 | path: webhooks/clientConfig/service/name 13 | - kind: ValidatingWebhookConfiguration 14 | group: admissionregistration.k8s.io 15 | path: webhooks/clientConfig/service/name 16 | 17 | namespace: 18 | - kind: MutatingWebhookConfiguration 19 | group: admissionregistration.k8s.io 20 | path: webhooks/clientConfig/service/namespace 21 | create: true 22 | - kind: ValidatingWebhookConfiguration 23 | group: admissionregistration.k8s.io 24 | path: webhooks/clientConfig/service/namespace 25 | create: true 26 | 27 | varReference: 28 | - path: metadata/annotations 29 | -------------------------------------------------------------------------------- /config/webhook/manifests.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | --- 4 | apiVersion: admissionregistration.k8s.io/v1 5 | kind: ValidatingWebhookConfiguration 6 | metadata: 7 | creationTimestamp: null 8 | name: validating-webhook-configuration 9 | webhooks: 10 | - admissionReviewVersions: 11 | - v1 12 | clientConfig: 13 | service: 14 | name: webhook-service 15 | namespace: system 16 | path: /validate-sriovfec-intel-com-v2-sriovfecclusterconfig 17 | failurePolicy: Fail 18 | name: vsriovfecclusterconfig.kb.io 19 | rules: 20 | - apiGroups: 21 | - sriovfec.intel.com 22 | apiVersions: 23 | - v2 24 | operations: 25 | - CREATE 26 | - UPDATE 27 | resources: 28 | - sriovfecclusterconfigs 29 | sideEffects: None 30 | -------------------------------------------------------------------------------- /config/webhook/service.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | 5 | apiVersion: v1 6 | kind: Service 7 | metadata: 8 | name: webhook-service 9 | namespace: system 10 | spec: 11 | ports: 12 | - port: 443 13 | protocol: TCP 14 | targetPort: 9443 15 | selector: 16 | control-plane: controller-manager 17 | -------------------------------------------------------------------------------- /controllers/sriovfec/suite_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | /* 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | package sriovfec 20 | 21 | import ( 22 | "context" 23 | "path/filepath" 24 | "testing" 25 | 26 | "github.com/go-logr/logr" 27 | "github.com/intel/sriov-fec-operator/pkg/common/utils" 28 | 29 | sriovfecv2 "github.com/intel/sriov-fec-operator/api/sriovfec/v2" 30 | . "github.com/onsi/ginkgo" 31 | . "github.com/onsi/gomega" 32 | "k8s.io/client-go/kubernetes/scheme" 33 | "sigs.k8s.io/controller-runtime/pkg/client" 34 | "sigs.k8s.io/controller-runtime/pkg/envtest" 35 | "sigs.k8s.io/controller-runtime/pkg/envtest/printer" 36 | logf "sigs.k8s.io/controller-runtime/pkg/log" 37 | // +kubebuilder:scaffold:imports 38 | ) 39 | 40 | // These tests use Ginkgo (BDD-style Go testing framework). Refer to 41 | // http://onsi.github.io/ginkgo/ to learn more about Ginkgo. 42 | 43 | var k8sClient client.Client 44 | var testEnv *envtest.Environment 45 | var ctx context.Context 46 | var cancel context.CancelFunc 47 | 48 | func TestAPIs(t *testing.T) { 49 | RegisterFailHandler(Fail) 50 | 51 | RunSpecsWithDefaultAndCustomReporters(t, 52 | "Controller Suite", 53 | []Reporter{printer.NewlineReporter{}}) 54 | } 55 | 56 | var _ = BeforeSuite(func(done Done) { 57 | logf.SetLogger(logr.New(utils.NewLogWrapper())) 58 | ctx, cancel = context.WithCancel(context.TODO()) 59 | By("bootstrapping test environment") 60 | testEnv = &envtest.Environment{ 61 | CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, 62 | } 63 | 64 | cfg, err := testEnv.Start() 65 | Expect(err).NotTo(HaveOccurred()) 66 | Expect(cfg).NotTo(BeNil()) 67 | 68 | err = sriovfecv2.AddToScheme(scheme.Scheme) 69 | Expect(err).NotTo(HaveOccurred()) 70 | 71 | // +kubebuilder:scaffold:scheme 72 | 73 | k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) 74 | Expect(err).NotTo(HaveOccurred()) 75 | Expect(k8sClient).NotTo(BeNil()) 76 | close(done) 77 | }, 60) 78 | 79 | var _ = AfterSuite(func() { 80 | cancel() 81 | By("tearing down the test environment") 82 | err := testEnv.Stop() 83 | Expect(err).NotTo(HaveOccurred()) 84 | }) 85 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/correct/acc100_no_maxqueuesize.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: 18 | acc100: 19 | pfMode: false 20 | numVfBundles: 2 21 | uplink4G: 22 | numQueueGroups: 1 23 | numAqsPerGroups: 1 24 | aqDepthLog2: 1 25 | downlink4G: 26 | numQueueGroups: 1 27 | numAqsPerGroups: 1 28 | aqDepthLog2: 1 29 | uplink5G: 30 | numQueueGroups: 1 31 | numAqsPerGroups: 1 32 | aqDepthLog2: 1 33 | downlink5G: 34 | numQueueGroups: 1 35 | numAqsPerGroups: 1 36 | aqDepthLog2: 1 37 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/correct/acc100_no_pfmode.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: 18 | acc100: 19 | numVfBundles: 2 20 | maxQueueSize: 1024 21 | uplink4G: 22 | numQueueGroups: 1 23 | numAqsPerGroups: 1 24 | aqDepthLog2: 1 25 | downlink4G: 26 | numQueueGroups: 1 27 | numAqsPerGroups: 1 28 | aqDepthLog2: 1 29 | uplink5G: 30 | numQueueGroups: 1 31 | numAqsPerGroups: 1 32 | aqDepthLog2: 1 33 | downlink5G: 34 | numQueueGroups: 1 35 | numAqsPerGroups: 1 36 | aqDepthLog2: 1 37 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/correct/acc100_pfmode_equals_false.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: 18 | acc100: 19 | pfMode: false 20 | numVfBundles: 2 21 | maxQueueSize: 1024 22 | uplink4G: 23 | numQueueGroups: 1 24 | numAqsPerGroups: 1 25 | aqDepthLog2: 1 26 | downlink4G: 27 | numQueueGroups: 1 28 | numAqsPerGroups: 1 29 | aqDepthLog2: 1 30 | uplink5G: 31 | numQueueGroups: 1 32 | numAqsPerGroups: 1 33 | aqDepthLog2: 1 34 | downlink5G: 35 | numQueueGroups: 1 36 | numAqsPerGroups: 1 37 | aqDepthLog2: 1 38 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/correct/label_and_device_id.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: {} 18 | priority: 100 19 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/correct/labels_and_device_id.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | bar: foo 12 | acceleratorSelector: 13 | deviceID: anyDevice 14 | physicalFunction: 15 | pfDriver: pci-pf-stub 16 | vfDriver: vfDriver 17 | vfAmount: 2 18 | bbDevConfig: {} 19 | priority: 100 20 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/correct/labels_no_accelerator.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | bar: foo 12 | physicalFunction: 13 | pfDriver: pci-pf-stub 14 | vfDriver: vfDriver 15 | vfAmount: 2 16 | bbDevConfig: {} 17 | priority: 100 18 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/correct/missing_priority.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: {} 18 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/correct/n3000_no_pfmode.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: 18 | n3000: 19 | networkType: FPGA_5GNR 20 | flrTimeout: 610 21 | downlink: 22 | bandwidth: 3 23 | loadBalance: 128 24 | queues: 25 | vf0: 16 26 | vf1: 16 27 | vf2: 0 28 | vf3: 0 29 | vf4: 0 30 | vf5: 0 31 | vf6: 0 32 | vf7: 0 33 | uplink: 34 | bandwidth: 3 35 | loadBalance: 128 36 | queues: 37 | vf0: 16 38 | vf1: 16 39 | vf2: 0 40 | vf3: 0 41 | vf4: 0 42 | vf5: 0 43 | vf6: 0 44 | vf7: 0 45 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/correct/n3000_pfmode_equals_false.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: 18 | n3000: 19 | pfMode: false 20 | networkType: FPGA_5GNR 21 | flrTimeout: 610 22 | downlink: 23 | bandwidth: 3 24 | loadBalance: 128 25 | queues: 26 | vf0: 16 27 | vf1: 16 28 | vf2: 0 29 | vf3: 0 30 | vf4: 0 31 | vf5: 0 32 | vf6: 0 33 | vf7: 0 34 | uplink: 35 | bandwidth: 3 36 | loadBalance: 128 37 | queues: 38 | vf0: 16 39 | vf1: 16 40 | vf2: 0 41 | vf3: 0 42 | vf4: 0 43 | vf5: 0 44 | vf6: 0 45 | vf7: 0 46 | 47 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/correct/no_labels_and_no_accelerator.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | physicalFunction: 10 | pfDriver: pci-pf-stub 11 | vfDriver: vfDriver 12 | vfAmount: 2 13 | bbDevConfig: {} 14 | priority: 100 15 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/correct/no_labels_and_only_device_id.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | acceleratorSelector: 10 | deviceID: anyDevice 11 | physicalFunction: 12 | pfDriver: pci-pf-stub 13 | vfDriver: vfDriver 14 | vfAmount: 2 15 | bbDevConfig: {} 16 | priority: 100 17 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/correct/no_labels_and_only_driver.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | acceleratorSelector: 10 | driver: pci-pf-stub 11 | physicalFunction: 12 | pfDriver: pci-pf-stub 13 | vfDriver: vfDriver 14 | vfAmount: 2 15 | bbDevConfig: {} 16 | priority: 100 17 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/correct/no_labels_and_only_max_vfs.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | acceleratorSelector: 10 | maxVirtualFunctions: 4 11 | physicalFunction: 12 | pfDriver: pci-pf-stub 13 | vfDriver: vfDriver 14 | vfAmount: 2 15 | bbDevConfig: {} 16 | priority: 100 17 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/correct/no_labels_and_only_pci_addr.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | acceleratorSelector: 10 | pciAddress: 0000:20:00.0 11 | physicalFunction: 12 | pfDriver: pci-pf-stub 13 | vfDriver: vfDriver 14 | vfAmount: 2 15 | bbDevConfig: {} 16 | priority: 100 17 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/correct/no_labels_and_only_vendor_id#1.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | acceleratorSelector: 10 | deviceID: anyDevice 11 | physicalFunction: 12 | pfDriver: pci-pf-stub 13 | vfDriver: vfDriver 14 | vfAmount: 2 15 | bbDevConfig: {} 16 | priority: 100 17 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/correct/no_labels_and_only_vendor_id#2.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: {} 10 | acceleratorSelector: 11 | deviceID: anyDevice 12 | physicalFunction: 13 | pfDriver: pci-pf-stub 14 | vfDriver: vfDriver 15 | vfAmount: 2 16 | bbDevConfig: {} 17 | priority: 100 18 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/incorrect/acc100_drainSkip_wrong_value.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: 18 | acc100: 19 | pfMode: false 20 | numVfBundles: 2 21 | maxQueueSize: 1024 22 | uplink4G: 23 | numQueueGroups: 1 24 | numAqsPerGroups: 1 25 | aqDepthLog2: 1 26 | downlink4G: 27 | numQueueGroups: 1 28 | numAqsPerGroups: 1 29 | aqDepthLog2: 1 30 | uplink5G: 31 | numQueueGroups: 1 32 | numAqsPerGroups: 1 33 | aqDepthLog2: 1 34 | downlink5G: 35 | numQueueGroups: 1 36 | numAqsPerGroups: 1 37 | aqDepthLog2: 1 38 | drainSkip: ture -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/incorrect/acc100_pfmode_equals_true.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: 18 | acc100: 19 | # this one is prohibited 20 | pfMode: true 21 | numVfBundles: 2 22 | maxQueueSize: 1024 23 | uplink4G: 24 | numQueueGroups: 1 25 | numAqsPerGroups: 1 26 | aqDepthLog2: 1 27 | downlink4G: 28 | numQueueGroups: 1 29 | numAqsPerGroups: 1 30 | aqDepthLog2: 1 31 | uplink5G: 32 | numQueueGroups: 1 33 | numAqsPerGroups: 1 34 | aqDepthLog2: 1 35 | downlink5G: 36 | numQueueGroups: 1 37 | numAqsPerGroups: 1 38 | aqDepthLog2: 1 39 | -------------------------------------------------------------------------------- /controllers/sriovfec/testdata/clusterconfig/incorrect/n3000_pfmode_equals_true.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovfec.intel.com/v2 5 | kind: SriovFecClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: 18 | n3000: 19 | # this one is prohibited 20 | pfMode: true 21 | networkType: FPGA_5GNR 22 | flrTimeout: 610 23 | downlink: 24 | bandwidth: 3 25 | loadBalance: 128 26 | queues: 27 | vf0: 16 28 | vf1: 16 29 | vf2: 0 30 | vf3: 0 31 | vf4: 0 32 | vf5: 0 33 | vf6: 0 34 | vf7: 0 35 | uplink: 36 | bandwidth: 3 37 | loadBalance: 128 38 | queues: 39 | vf0: 16 40 | vf1: 16 41 | vf2: 0 42 | vf3: 0 43 | vf4: 0 44 | vf5: 0 45 | vf6: 0 46 | vf7: 0 47 | -------------------------------------------------------------------------------- /controllers/sriovvrb/suite_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | /* 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | */ 18 | 19 | package sriovvrb 20 | 21 | import ( 22 | "context" 23 | "path/filepath" 24 | "testing" 25 | 26 | "github.com/go-logr/logr" 27 | "github.com/intel/sriov-fec-operator/pkg/common/utils" 28 | 29 | vrbv1 "github.com/intel/sriov-fec-operator/api/sriovvrb/v1" 30 | . "github.com/onsi/ginkgo" 31 | . "github.com/onsi/gomega" 32 | "k8s.io/client-go/kubernetes/scheme" 33 | "sigs.k8s.io/controller-runtime/pkg/client" 34 | "sigs.k8s.io/controller-runtime/pkg/envtest" 35 | "sigs.k8s.io/controller-runtime/pkg/envtest/printer" 36 | logf "sigs.k8s.io/controller-runtime/pkg/log" 37 | // +kubebuilder:scaffold:imports 38 | ) 39 | 40 | // These tests use Ginkgo (BDD-style Go testing framework). Refer to 41 | // http://onsi.github.io/ginkgo/ to learn more about Ginkgo. 42 | 43 | var k8sClient client.Client 44 | var testEnv *envtest.Environment 45 | var ctx context.Context 46 | var cancel context.CancelFunc 47 | 48 | func TestAPIs(t *testing.T) { 49 | RegisterFailHandler(Fail) 50 | 51 | RunSpecsWithDefaultAndCustomReporters(t, 52 | "Controller Suite", 53 | []Reporter{printer.NewlineReporter{}}) 54 | } 55 | 56 | var _ = BeforeSuite(func(done Done) { 57 | logf.SetLogger(logr.New(utils.NewLogWrapper())) 58 | ctx, cancel = context.WithCancel(context.TODO()) 59 | By("bootstrapping test environment") 60 | testEnv = &envtest.Environment{ 61 | CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, 62 | } 63 | 64 | cfg, err := testEnv.Start() 65 | Expect(err).NotTo(HaveOccurred()) 66 | Expect(cfg).NotTo(BeNil()) 67 | 68 | err = vrbv1.AddToScheme(scheme.Scheme) 69 | Expect(err).NotTo(HaveOccurred()) 70 | 71 | // +kubebuilder:scaffold:scheme 72 | 73 | k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) 74 | Expect(err).NotTo(HaveOccurred()) 75 | Expect(k8sClient).NotTo(BeNil()) 76 | close(done) 77 | }, 60) 78 | 79 | var _ = AfterSuite(func() { 80 | cancel() 81 | By("tearing down the test environment") 82 | err := testEnv.Stop() 83 | Expect(err).NotTo(HaveOccurred()) 84 | }) 85 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/correct/label_and_device_id.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: {} 18 | priority: 100 19 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/correct/labels_and_device_id.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | bar: foo 12 | acceleratorSelector: 13 | deviceID: anyDevice 14 | physicalFunction: 15 | pfDriver: pci-pf-stub 16 | vfDriver: vfDriver 17 | vfAmount: 2 18 | bbDevConfig: {} 19 | priority: 100 20 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/correct/labels_no_accelerator.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | bar: foo 12 | physicalFunction: 13 | pfDriver: pci-pf-stub 14 | vfDriver: vfDriver 15 | vfAmount: 2 16 | bbDevConfig: {} 17 | priority: 100 18 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/correct/missing_priority.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: {} 18 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/correct/no_labels_and_no_accelerator.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | physicalFunction: 10 | pfDriver: pci-pf-stub 11 | vfDriver: vfDriver 12 | vfAmount: 2 13 | bbDevConfig: {} 14 | priority: 100 15 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/correct/no_labels_and_only_device_id.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | acceleratorSelector: 10 | deviceID: anyDevice 11 | physicalFunction: 12 | pfDriver: pci-pf-stub 13 | vfDriver: vfDriver 14 | vfAmount: 2 15 | bbDevConfig: {} 16 | priority: 100 17 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/correct/no_labels_and_only_driver.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | acceleratorSelector: 10 | driver: pci-pf-stub 11 | physicalFunction: 12 | pfDriver: pci-pf-stub 13 | vfDriver: vfDriver 14 | vfAmount: 2 15 | bbDevConfig: {} 16 | priority: 100 17 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/correct/no_labels_and_only_max_vfs.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | acceleratorSelector: 10 | maxVirtualFunctions: 4 11 | physicalFunction: 12 | pfDriver: pci-pf-stub 13 | vfDriver: vfDriver 14 | vfAmount: 2 15 | bbDevConfig: {} 16 | priority: 100 17 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/correct/no_labels_and_only_pci_addr.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | acceleratorSelector: 10 | pciAddress: 0000:20:00.0 11 | physicalFunction: 12 | pfDriver: pci-pf-stub 13 | vfDriver: vfDriver 14 | vfAmount: 2 15 | bbDevConfig: {} 16 | priority: 100 17 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/correct/no_labels_and_only_vendor_id#1.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | acceleratorSelector: 10 | deviceID: anyDevice 11 | physicalFunction: 12 | pfDriver: pci-pf-stub 13 | vfDriver: vfDriver 14 | vfAmount: 2 15 | bbDevConfig: {} 16 | priority: 100 17 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/correct/no_labels_and_only_vendor_id#2.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: {} 10 | acceleratorSelector: 11 | deviceID: anyDevice 12 | physicalFunction: 13 | pfDriver: pci-pf-stub 14 | vfDriver: vfDriver 15 | vfAmount: 2 16 | bbDevConfig: {} 17 | priority: 100 18 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/correct/vrb1_no_maxqueuesize.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: 18 | vrb1: 19 | pfMode: false 20 | numVfBundles: 2 21 | uplink4G: 22 | numQueueGroups: 1 23 | numAqsPerGroups: 1 24 | aqDepthLog2: 1 25 | downlink4G: 26 | numQueueGroups: 1 27 | numAqsPerGroups: 1 28 | aqDepthLog2: 1 29 | uplink5G: 30 | numQueueGroups: 1 31 | numAqsPerGroups: 1 32 | aqDepthLog2: 1 33 | downlink5G: 34 | numQueueGroups: 1 35 | numAqsPerGroups: 1 36 | aqDepthLog2: 1 37 | qfft: 38 | numQueueGroups: 1 39 | numAqsPerGroups: 1 40 | aqDepthLog2: 1 41 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/correct/vrb1_no_pfmode.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: 18 | vrb1: 19 | maxQueueSize: 1024 20 | numVfBundles: 2 21 | uplink4G: 22 | numQueueGroups: 1 23 | numAqsPerGroups: 1 24 | aqDepthLog2: 1 25 | downlink4G: 26 | numQueueGroups: 1 27 | numAqsPerGroups: 1 28 | aqDepthLog2: 1 29 | uplink5G: 30 | numQueueGroups: 1 31 | numAqsPerGroups: 1 32 | aqDepthLog2: 1 33 | downlink5G: 34 | numQueueGroups: 1 35 | numAqsPerGroups: 1 36 | aqDepthLog2: 1 37 | qfft: 38 | numQueueGroups: 1 39 | numAqsPerGroups: 1 40 | aqDepthLog2: 1 41 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/correct/vrb1_pfmode_equals_false.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: 18 | vrb1: 19 | pfMode: false 20 | maxQueueSize: 1024 21 | numVfBundles: 2 22 | uplink4G: 23 | numQueueGroups: 1 24 | numAqsPerGroups: 1 25 | aqDepthLog2: 1 26 | downlink4G: 27 | numQueueGroups: 1 28 | numAqsPerGroups: 1 29 | aqDepthLog2: 1 30 | uplink5G: 31 | numQueueGroups: 1 32 | numAqsPerGroups: 1 33 | aqDepthLog2: 1 34 | downlink5G: 35 | numQueueGroups: 1 36 | numAqsPerGroups: 1 37 | aqDepthLog2: 1 38 | qfft: 39 | numQueueGroups: 1 40 | numAqsPerGroups: 1 41 | aqDepthLog2: 1 42 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/correct/vrb2_no_maxqueuesize.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: 18 | vrb2: 19 | pfMode: false 20 | numVfBundles: 2 21 | uplink4G: 22 | numQueueGroups: 1 23 | numAqsPerGroups: 1 24 | aqDepthLog2: 1 25 | downlink4G: 26 | numQueueGroups: 1 27 | numAqsPerGroups: 1 28 | aqDepthLog2: 1 29 | uplink5G: 30 | numQueueGroups: 1 31 | numAqsPerGroups: 1 32 | aqDepthLog2: 1 33 | downlink5G: 34 | numQueueGroups: 1 35 | numAqsPerGroups: 1 36 | aqDepthLog2: 1 37 | qfft: 38 | numQueueGroups: 1 39 | numAqsPerGroups: 1 40 | aqDepthLog2: 1 41 | qmld: 42 | numQueueGroups: 1 43 | numAqsPerGroups: 1 44 | aqDepthLog2: 1 45 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/correct/vrb2_no_pfmode.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: 18 | vrb2: 19 | maxQueueSize: 1024 20 | numVfBundles: 2 21 | uplink4G: 22 | numQueueGroups: 1 23 | numAqsPerGroups: 1 24 | aqDepthLog2: 1 25 | downlink4G: 26 | numQueueGroups: 1 27 | numAqsPerGroups: 1 28 | aqDepthLog2: 1 29 | uplink5G: 30 | numQueueGroups: 1 31 | numAqsPerGroups: 1 32 | aqDepthLog2: 1 33 | downlink5G: 34 | numQueueGroups: 1 35 | numAqsPerGroups: 1 36 | aqDepthLog2: 1 37 | qfft: 38 | numQueueGroups: 1 39 | numAqsPerGroups: 1 40 | aqDepthLog2: 1 41 | qmld: 42 | numQueueGroups: 1 43 | numAqsPerGroups: 1 44 | aqDepthLog2: 1 45 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/correct/vrb2_pfmode_equals_false.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: 18 | vrb2: 19 | pfMode: false 20 | maxQueueSize: 1024 21 | numVfBundles: 2 22 | uplink4G: 23 | numQueueGroups: 1 24 | numAqsPerGroups: 1 25 | aqDepthLog2: 1 26 | downlink4G: 27 | numQueueGroups: 1 28 | numAqsPerGroups: 1 29 | aqDepthLog2: 1 30 | uplink5G: 31 | numQueueGroups: 1 32 | numAqsPerGroups: 1 33 | aqDepthLog2: 1 34 | downlink5G: 35 | numQueueGroups: 1 36 | numAqsPerGroups: 1 37 | aqDepthLog2: 1 38 | qfft: 39 | numQueueGroups: 1 40 | numAqsPerGroups: 1 41 | aqDepthLog2: 1 42 | qmld: 43 | numQueueGroups: 1 44 | numAqsPerGroups: 1 45 | aqDepthLog2: 1 46 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/incorrect/vrb1_drainSkip_wrong_value.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | drainSkip: ture 10 | nodeSelector: 11 | foo: bar 12 | acceleratorSelector: 13 | deviceID: anyDevice 14 | physicalFunction: 15 | pfDriver: pci-pf-stub 16 | vfDriver: vfDriver 17 | vfAmount: 2 18 | bbDevConfig: 19 | vrb1: 20 | pfMode: false 21 | maxQueueSize: 1024 22 | numVfBundles: 2 23 | uplink4G: 24 | numQueueGroups: 1 25 | numAqsPerGroups: 1 26 | aqDepthLog2: 1 27 | downlink4G: 28 | numQueueGroups: 1 29 | numAqsPerGroups: 1 30 | aqDepthLog2: 1 31 | uplink5G: 32 | numQueueGroups: 1 33 | numAqsPerGroups: 1 34 | aqDepthLog2: 1 35 | downlink5G: 36 | numQueueGroups: 1 37 | numAqsPerGroups: 1 38 | aqDepthLog2: 1 39 | qfft: 40 | numQueueGroups: 1 41 | numAqsPerGroups: 1 42 | aqDepthLog2: 1 43 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/incorrect/vrb1_pfmode_equals_true.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: 18 | vrb1: 19 | pfMode: true 20 | maxQueueSize: 1024 21 | numVfBundles: 2 22 | uplink4G: 23 | numQueueGroups: 1 24 | numAqsPerGroups: 1 25 | aqDepthLog2: 1 26 | downlink4G: 27 | numQueueGroups: 1 28 | numAqsPerGroups: 1 29 | aqDepthLog2: 1 30 | uplink5G: 31 | numQueueGroups: 1 32 | numAqsPerGroups: 1 33 | aqDepthLog2: 1 34 | downlink5G: 35 | numQueueGroups: 1 36 | numAqsPerGroups: 1 37 | aqDepthLog2: 1 38 | qfft: 39 | numQueueGroups: 1 40 | numAqsPerGroups: 1 41 | aqDepthLog2: 1 42 | -------------------------------------------------------------------------------- /controllers/sriovvrb/testdata/clusterconfig/incorrect/vrb2_pfmode_equals_true.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: sriovvrb.intel.com/v1 5 | kind: SriovVrbClusterConfig 6 | metadata: 7 | name: config 8 | spec: 9 | nodeSelector: 10 | foo: bar 11 | acceleratorSelector: 12 | deviceID: anyDevice 13 | physicalFunction: 14 | pfDriver: pci-pf-stub 15 | vfDriver: vfDriver 16 | vfAmount: 2 17 | bbDevConfig: 18 | vrb2: 19 | pfMode: true 20 | maxQueueSize: 1024 21 | numVfBundles: 2 22 | uplink4G: 23 | numQueueGroups: 1 24 | numAqsPerGroups: 1 25 | aqDepthLog2: 1 26 | downlink4G: 27 | numQueueGroups: 1 28 | numAqsPerGroups: 1 29 | aqDepthLog2: 1 30 | uplink5G: 31 | numQueueGroups: 1 32 | numAqsPerGroups: 1 33 | aqDepthLog2: 1 34 | downlink5G: 35 | numQueueGroups: 1 36 | numAqsPerGroups: 1 37 | aqDepthLog2: 1 38 | qfft: 39 | numQueueGroups: 1 40 | numAqsPerGroups: 1 41 | aqDepthLog2: 1 42 | qmld: 43 | numQueueGroups: 1 44 | numAqsPerGroups: 1 45 | aqDepthLog2: 1 46 | -------------------------------------------------------------------------------- /copyright.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: Apache-2.0 3 | # Copyright (c) 2020-2025 Intel Corporation 4 | 5 | FOLDER=${FOLDER:-.} 6 | COPYRIGHT_FILE=${COPYRIGHT_FILE:-COPYRIGHT} 7 | copyright=$(cat "$COPYRIGHT_FILE") 8 | 9 | 10 | while read -r file; 11 | do 12 | if ! grep -q "${copyright}" "$file" 13 | then 14 | echo "$file" 15 | cat "$COPYRIGHT_FILE" "$file" >"$file".new && mv "$file".new "$file" 16 | fi 17 | done < <(find "${FOLDER}" -name '*.yaml') 18 | -------------------------------------------------------------------------------- /gather_sriovfec_logs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # SPDX-License-Identifier: Apache-2.0 3 | # Copyright (c) 2020-2025 Intel Corporation 4 | 5 | K8S_BIN="${1:-oc}" 6 | NAMESPACE="${2:-vran-acceleration-operators}" 7 | SRIOV_FEC_CLUSTER_CONFIG="sfcc" 8 | SRIOV_FEC_NODE_CONFIG="sfnc" 9 | SRIOV_VRB_CLUSTER_CONFIG="svcc" 10 | SRIOV_VRB_NODE_CONFIG="svnc" 11 | DIR=sriov-fec-$(hostname)-$(date) 12 | 13 | mkdir -p "${DIR}" 14 | cd "${DIR}" || exit 15 | 16 | "${K8S_BIN}" version > "${K8S_BIN}"_version 17 | "${K8S_BIN}" get csv -n "${NAMESPACE}" > csv_in_namespace 18 | 19 | # nodes 20 | echo "Getting information about nodes" 21 | "${K8S_BIN}" get nodes -o wide -n "${NAMESPACE}" > nodes_in_namespace 22 | mkdir -p nodes 23 | nodes=$("${K8S_BIN}" get nodes -o custom-columns=NAME:.metadata.name --no-headers=true) 24 | # shellcheck disable=SC2068 25 | for node in ${nodes[@]}; do 26 | "${K8S_BIN}" describe node "${node}" > nodes/"${node}" 27 | "${K8S_BIN}" get node "${node}" -o yaml > nodes/"${node}".yaml 28 | done 29 | 30 | # pods 31 | echo "Getting information about pods in ${NAMESPACE}" 32 | "${K8S_BIN}" get all -n "${NAMESPACE}" -o wide > resources_in_namespace 33 | mkdir -p pods 34 | pods=$("${K8S_BIN}" -n "${NAMESPACE}" get pods -o custom-columns=NAME:.metadata.name --no-headers=true) 35 | # shellcheck disable=SC2068 36 | for pod in ${pods[@]}; do 37 | "${K8S_BIN}" -n "${NAMESPACE}" logs --all-containers=true "${pod}" > pods/"${pod}".log 38 | "${K8S_BIN}" -n "${NAMESPACE}" get pod "${pod}" -o yaml > pods/"${pod}".yaml 39 | done 40 | 41 | # SriovFecClusterConfig 42 | echo "Getting information about SriovFecClusterConfigs in ${NAMESPACE}" 43 | mkdir -p sriovfecclusterConfigs 44 | "${K8S_BIN}" get "${SRIOV_FEC_CLUSTER_CONFIG}" -n "${NAMESPACE}" > sriov_fec_cluster_configs_in_namespace 45 | sriovfecclusterConfigs=$("${K8S_BIN}" -n "${NAMESPACE}" get "${SRIOV_FEC_CLUSTER_CONFIG}" --ignore-not-found=true -o custom-columns=NAME:.metadata.name --no-headers=true) 46 | # shellcheck disable=SC2068 47 | for sriovfecclusterConfig in ${sriovfecclusterConfigs[@]}; do 48 | "${K8S_BIN}" -n "${NAMESPACE}" describe "${SRIOV_FEC_CLUSTER_CONFIG}" "${sriovfecclusterConfig}" > sriovfecclusterConfigs/"${sriovfecclusterConfig}" 49 | "${K8S_BIN}" -n "${NAMESPACE}" get "${SRIOV_FEC_CLUSTER_CONFIG}" "${sriovfecclusterConfig}" -o yaml > sriovfecclusterConfigs/"${sriovfecclusterConfig}".yaml 50 | done 51 | 52 | # SriovVrbClusterConfig 53 | echo "Getting information about SriovVrbClusterConfigs in ${NAMESPACE}" 54 | mkdir -p sriovvrbclusterConfigs 55 | "${K8S_BIN}" get "${SRIOV_VRB_CLUSTER_CONFIG}" -n "${NAMESPACE}" > sriov_vrb_cluster_configs_in_namespace 56 | sriovvrbclusterConfigs=$("${K8S_BIN}" -n "${NAMESPACE}" get "${SRIOV_VRB_CLUSTER_CONFIG}" --ignore-not-found=true -o custom-columns=NAME:.metadata.name --no-headers=true) 57 | # shellcheck disable=SC2068 58 | for sriovvrbclusterConfig in ${sriovvrbclusterConfigs[@]}; do 59 | "${K8S_BIN}" -n "${NAMESPACE}" describe "${SRIOV_VRB_CLUSTER_CONFIG}" "${sriovvrbclusterConfig}" > sriovvrbclusterConfigs/"${sriovvrbclusterConfig}" 60 | "${K8S_BIN}" -n "${NAMESPACE}" get "${SRIOV_VRB_CLUSTER_CONFIG}" "${sriovvrbclusterConfig}" -o yaml > sriovvrbclusterConfigs/"${sriovvrbclusterConfig}".yaml 61 | done 62 | 63 | # SriovFecNodeConfig 64 | echo "Getting information about SriovFecNodeConfigs in ${NAMESPACE}" 65 | mkdir -p sriovfecnodeConfigs 66 | "${K8S_BIN}" get "${SRIOV_FEC_NODE_CONFIG}" -n "${NAMESPACE}" > sriov_fec_node_configs_in_namespace 67 | sriovfecnodeConfigs=$("${K8S_BIN}" -n "${NAMESPACE}" get "${SRIOV_FEC_NODE_CONFIG}" --ignore-not-found=true -o custom-columns=NAME:.metadata.name --no-headers=true) 68 | # shellcheck disable=SC2068 69 | for sriovfecnodeConfig in ${sriovfecnodeConfigs[@]}; do 70 | "${K8S_BIN}" -n "${NAMESPACE}" describe "${SRIOV_FEC_NODE_CONFIG}" "${sriovfecnodeConfig}" > sriovfecnodeConfigs/"${sriovfecnodeConfig}" 71 | "${K8S_BIN}" -n "${NAMESPACE}" get "${SRIOV_FEC_NODE_CONFIG}" "${sriovfecnodeConfig}" -o yaml > sriovfecnodeConfigs/"${sriovfecnodeConfig}".yaml 72 | done 73 | 74 | # SriovVrbNodeConfig 75 | echo "Getting information about SriovVrbNodeConfigs in ${NAMESPACE}" 76 | mkdir -p sriovvrbnodeConfigs 77 | "${K8S_BIN}" get "${SRIOV_VRB_NODE_CONFIG}" -n "${NAMESPACE}" > sriov_vrb_node_configs_in_namespace 78 | sriovvrbnodeConfigs=$("${K8S_BIN}" -n "${NAMESPACE}" get "${SRIOV_VRB_NODE_CONFIG}" --ignore-not-found=true -o custom-columns=NAME:.metadata.name --no-headers=true) 79 | # shellcheck disable=SC2068 80 | for sriovvrbnodeConfig in ${sriovvrbnodeConfigs[@]}; do 81 | "${K8S_BIN}" -n "${NAMESPACE}" describe "${SRIOV_VRB_NODE_CONFIG}" "${sriovvrbnodeConfig}" > sriovvrbnodeConfigs/"${sriovvrbnodeConfig}" 82 | "${K8S_BIN}" -n "${NAMESPACE}" get "${SRIOV_VRB_NODE_CONFIG}" "${sriovvrbnodeConfig}" -o yaml > sriovvrbnodeConfigs/"${sriovvrbnodeConfig}".yaml 83 | done 84 | 85 | # system configuration logs 86 | echo "Getting information about system configurations in ${NAMESPACE}" 87 | mkdir -p systemLogs 88 | pods=$("${K8S_BIN}" -n "${NAMESPACE}" get pods -o custom-columns=NAME:.metadata.name --no-headers=true | grep sriov-fec-daemonset) 89 | # shellcheck disable=SC2068 90 | for pod in ${pods[@]}; do 91 | nodeName=$("${K8S_BIN}" -n "${NAMESPACE}" get pod "${pod}" -o custom-columns=NODE:.spec.nodeName --no-headers=true) 92 | "${K8S_BIN}" -n "${NAMESPACE}" exec -it "${pod}" -- bash -c "chroot / lspci -vvv" > systemLogs/lspci-"${nodeName}".log 93 | telemetryFiles=$("${K8S_BIN}" -n "${NAMESPACE}" exec -it "${pod}" -- bash -c "ls -f -A1 /var/log/"|grep pf_bb_cfg| tr -d '\r') 94 | for telemetryFiles in ${telemetryFiles[@]}; do 95 | "${K8S_BIN}" -n "${NAMESPACE}" exec -it "${pod}" -- bash -c "cat /var/log/${telemetryFiles}" > systemLogs/"${nodeName}"-"${telemetryFiles}" 96 | done 97 | done 98 | 99 | cd ../ 100 | tar -zcvf sriov-fec.logs.tar.gz "${DIR}" 101 | echo "Please attach 'sriov-fec.logs.tar.gz' to bug report. If you had to apply some configs and deleted them to reproduce issue, attach them as well." 102 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/intel/sriov-fec-operator 2 | 3 | go 1.23.4 4 | toolchain go1.24.1 5 | 6 | require ( 7 | github.com/elliotchance/orderedmap/v2 v2.2.0 8 | github.com/go-logr/logr v1.2.3 9 | github.com/google/gofuzz v1.2.0 10 | github.com/google/uuid v1.3.0 11 | github.com/hpcloud/tail v1.0.0 12 | github.com/jaypipes/ghw v0.9.0 13 | github.com/k8snetworkplumbingwg/sriov-network-device-plugin v0.0.0-20220614121156-6fff085aed91 14 | github.com/onsi/ginkgo v1.16.5 15 | github.com/onsi/gomega v1.24.1 16 | github.com/openshift/api v0.0.0-20221123130830-0dea1780a599 17 | github.com/pkg/errors v0.9.1 18 | github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.61.1 19 | github.com/prometheus/client_golang v1.14.0 20 | github.com/sirupsen/logrus v1.9.0 21 | gopkg.in/ini.v1 v1.67.0 22 | k8s.io/api v0.25.4 23 | k8s.io/apimachinery v0.25.4 24 | k8s.io/client-go v0.25.4 25 | k8s.io/kubectl v0.25.4 26 | k8s.io/utils v0.0.0-20221108210102-8e77b1f39fe2 27 | sigs.k8s.io/controller-runtime v0.13.1 28 | ) 29 | 30 | require ( 31 | cloud.google.com/go v0.97.0 // indirect 32 | github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect 33 | github.com/MakeNowJust/heredoc v1.0.0 // indirect 34 | github.com/Mellanox/sriovnet v1.0.3 // indirect 35 | github.com/PuerkitoBio/purell v1.1.1 // indirect 36 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect 37 | github.com/StackExchange/wmi v1.2.1 // indirect 38 | github.com/beorn7/perks v1.0.1 // indirect 39 | github.com/cespare/xxhash/v2 v2.1.2 // indirect 40 | github.com/chai2010/gettext-go v1.0.2 // indirect 41 | github.com/davecgh/go-spew v1.1.1 // indirect 42 | github.com/emicklei/go-restful/v3 v3.12.1 // indirect 43 | github.com/evanphx/json-patch v4.12.0+incompatible // indirect 44 | github.com/evanphx/json-patch/v5 v5.6.0 // indirect 45 | github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect 46 | github.com/fsnotify/fsnotify v1.5.4 // indirect 47 | github.com/ghodss/yaml v1.0.0 // indirect 48 | github.com/go-errors/errors v1.0.1 // indirect 49 | github.com/go-ole/go-ole v1.2.6 // indirect 50 | github.com/go-openapi/jsonpointer v0.19.5 // indirect 51 | github.com/go-openapi/jsonreference v0.19.5 // indirect 52 | github.com/go-openapi/swag v0.19.14 // indirect 53 | github.com/gogo/protobuf v1.3.2 // indirect 54 | github.com/golang/glog v1.2.4 // indirect 55 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect 56 | github.com/golang/protobuf v1.5.2 // indirect 57 | github.com/google/btree v1.0.1 // indirect 58 | github.com/google/gnostic v0.5.7-v3refs // indirect 59 | github.com/google/go-cmp v0.6.0 // indirect 60 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect 61 | github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect 62 | github.com/imdario/mergo v0.3.12 // indirect 63 | github.com/inconshreveable/mousetrap v1.0.0 // indirect 64 | github.com/jaypipes/pcidb v1.0.0 // indirect 65 | github.com/josharian/intern v1.0.0 // indirect 66 | github.com/json-iterator/go v1.1.12 // indirect 67 | github.com/k8snetworkplumbingwg/govdpa v0.1.3 // indirect 68 | github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect 69 | github.com/mailru/easyjson v0.7.6 // indirect 70 | github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect 71 | github.com/mitchellh/go-homedir v1.1.0 // indirect 72 | github.com/mitchellh/go-wordwrap v1.0.0 // indirect 73 | github.com/moby/spdystream v0.2.0 // indirect 74 | github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect 75 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 76 | github.com/modern-go/reflect2 v1.0.2 // indirect 77 | github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect 78 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 79 | github.com/nxadm/tail v1.4.8 // indirect 80 | github.com/onsi/ginkgo/v2 v2.5.1 // indirect 81 | github.com/peterbourgon/diskv v2.0.1+incompatible // indirect 82 | github.com/pmezard/go-difflib v1.0.0 // indirect 83 | github.com/prometheus/client_model v0.3.0 // indirect 84 | github.com/prometheus/common v0.37.0 // indirect 85 | github.com/prometheus/procfs v0.8.0 // indirect 86 | github.com/russross/blackfriday v1.5.2 // indirect 87 | github.com/spf13/afero v1.4.1 // indirect 88 | github.com/spf13/cobra v1.4.0 // indirect 89 | github.com/spf13/pflag v1.0.5 // indirect 90 | github.com/stretchr/objx v0.4.0 // indirect 91 | github.com/stretchr/testify v1.8.0 // indirect 92 | github.com/vishvananda/netlink v1.1.1-0.20211101163509-b10eb8fe5cf6 // indirect 93 | github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae // indirect 94 | github.com/xlab/treeprint v1.1.0 // indirect 95 | go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect 96 | golang.org/x/net v0.38.0 // indirect 97 | golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect 98 | golang.org/x/sys v0.31.0 // indirect 99 | golang.org/x/term v0.30.0 // indirect 100 | golang.org/x/text v0.23.0 // indirect 101 | golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect 102 | gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect 103 | google.golang.org/appengine v1.6.7 // indirect 104 | google.golang.org/protobuf v1.33.0 // indirect 105 | gopkg.in/fsnotify.v1 v1.4.7 // indirect 106 | gopkg.in/inf.v0 v0.9.1 // indirect 107 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect 108 | gopkg.in/yaml.v2 v2.4.0 // indirect 109 | gopkg.in/yaml.v3 v3.0.1 // indirect 110 | howett.net/plist v1.0.0 // indirect 111 | k8s.io/apiextensions-apiserver v0.25.4 // indirect 112 | k8s.io/cli-runtime v0.25.4 // indirect 113 | k8s.io/component-base v0.25.4 // indirect 114 | k8s.io/klog/v2 v2.80.1 // indirect 115 | k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect 116 | sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect 117 | sigs.k8s.io/kustomize/api v0.12.1 // indirect 118 | sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect 119 | sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect 120 | sigs.k8s.io/yaml v1.3.0 // indirect 121 | ) 122 | -------------------------------------------------------------------------------- /hack/boilerplate.go.txt: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | -------------------------------------------------------------------------------- /misc/src/README.md: -------------------------------------------------------------------------------- 1 | 5 | # List of 3rd party source code packages used in SRIOV-FEC Operator: 6 | 7 | ## kmod 8 | Source code: https://github.com/kmod-project/kmod/archive/refs/tags/v28.tar.gz 9 | License: LGPL-v2.1 10 | 11 | ## pciutils 12 | Source code: https://github.com/pciutils/pciutils/archive/refs/tags/v3.7.0.tar.gz 13 | License: GPL-v2.0 14 | 15 | ## procps-ng 16 | Source code: https://gitlab.com/procps-ng/procps/-/archive/v3.3.17/procps-v3.3.17.tar.gz 17 | License: GPL-v2.0 18 | -------------------------------------------------------------------------------- /misc/src/kmod-28.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/sriov-fec-operator/1268dcbe1ee19f9941d54105918ff67dd5acbcf0/misc/src/kmod-28.tar.gz -------------------------------------------------------------------------------- /misc/src/pciutils-3.7.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/sriov-fec-operator/1268dcbe1ee19f9941d54105918ff67dd5acbcf0/misc/src/pciutils-3.7.0.tar.gz -------------------------------------------------------------------------------- /misc/src/procps-v3.3.17.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/sriov-fec-operator/1268dcbe1ee19f9941d54105918ff67dd5acbcf0/misc/src/procps-v3.3.17.tar.gz -------------------------------------------------------------------------------- /pkg/common/assets/suite_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package assets 5 | 6 | import ( 7 | "context" 8 | "github.com/go-logr/logr" 9 | "github.com/intel/sriov-fec-operator/pkg/common/utils" 10 | corev1 "k8s.io/api/core/v1" 11 | "k8s.io/utils/pointer" 12 | "os" 13 | "path/filepath" 14 | "testing" 15 | 16 | . "github.com/onsi/ginkgo" 17 | . "github.com/onsi/gomega" 18 | "sigs.k8s.io/controller-runtime/pkg/envtest/printer" 19 | 20 | appsv1 "k8s.io/api/apps/v1" 21 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 | "k8s.io/client-go/kubernetes/scheme" 23 | "k8s.io/client-go/rest" 24 | "sigs.k8s.io/controller-runtime/pkg/client" 25 | "sigs.k8s.io/controller-runtime/pkg/envtest" 26 | logf "sigs.k8s.io/controller-runtime/pkg/log" 27 | // +kubebuilder:scaffold:imports 28 | ) 29 | 30 | var ( 31 | cfg *rest.Config 32 | k8sClient client.Client 33 | fakeOwner metav1.Object 34 | 35 | testEnv *envtest.Environment 36 | 37 | fakeConfigMapName string 38 | fakeAssetFile string 39 | 40 | tolerationKey = "key" 41 | tolerationOperator = corev1.TolerationOperator("Exists") 42 | tolerationEffect = corev1.TaintEffect("NoSchedule") 43 | ) 44 | 45 | func TestAPIs(t *testing.T) { 46 | RegisterFailHandler(Fail) 47 | 48 | RunSpecsWithDefaultAndCustomReporters(t, 49 | "N3000 assets Suite", 50 | []Reporter{printer.NewlineReporter{}}) 51 | } 52 | 53 | var _ = BeforeSuite(func(done Done) { 54 | var err error 55 | logf.SetLogger(logr.New(utils.NewLogWrapper())) 56 | 57 | fakeAssetFile = "test/101-fake-labeler.yaml" 58 | fakeConfigMapName = "fake-config" 59 | 60 | By("bootstrapping test environment") 61 | testEnv = &envtest.Environment{ 62 | CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, 63 | } 64 | 65 | cfg, err = testEnv.Start() 66 | Expect(err).ToNot(HaveOccurred()) 67 | Expect(cfg).ToNot(BeNil()) 68 | 69 | // +kubebuilder:scaffold:scheme 70 | 71 | k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) 72 | Expect(err).ToNot(HaveOccurred()) 73 | Expect(k8sClient).ToNot(BeNil()) 74 | 75 | fakeOwner = &appsv1.Deployment{} 76 | fakeOwner.SetUID("123") 77 | fakeOwner.SetName("123") 78 | 79 | name := "sriov-fec-controller-manager" 80 | err = os.Setenv("NAME", name+"-123-234") 81 | Expect(err).To(Succeed()) 82 | 83 | deploymentforTests := &appsv1.Deployment{ 84 | ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: "default"}, 85 | Spec: appsv1.DeploymentSpec{ 86 | Replicas: pointer.Int32(0), 87 | Selector: &metav1.LabelSelector{ 88 | MatchLabels: map[string]string{"test": "test"}, 89 | }, 90 | Template: corev1.PodTemplateSpec{ 91 | Spec: corev1.PodSpec{ 92 | Tolerations: []corev1.Toleration{{ 93 | Key: tolerationKey, 94 | Operator: tolerationOperator, 95 | Effect: tolerationEffect, 96 | }}, 97 | 98 | Containers: []corev1.Container{{ 99 | Name: "test-container", 100 | Image: "test-container", 101 | }}, 102 | }, 103 | ObjectMeta: metav1.ObjectMeta{ 104 | Labels: map[string]string{"test": "test"}, 105 | }, 106 | }, 107 | Strategy: appsv1.DeploymentStrategy{}, 108 | MinReadySeconds: 0, 109 | RevisionHistoryLimit: nil, 110 | Paused: false, 111 | ProgressDeadlineSeconds: nil, 112 | }, 113 | } 114 | err = k8sClient.Create(context.TODO(), deploymentforTests) 115 | Expect(err).To(Succeed()) 116 | 117 | close(done) 118 | }, 60) 119 | 120 | var _ = AfterSuite(func() { 121 | By("tearing down the test environment") 122 | err := testEnv.Stop() 123 | Expect(err).ToNot(HaveOccurred()) 124 | }) 125 | -------------------------------------------------------------------------------- /pkg/common/assets/test/101-fake-labeler.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | 4 | apiVersion: v1 5 | kind: ConfigMap 6 | metadata: 7 | name: daemon-config 8 | namespace: default 9 | immutable: false 10 | data: 11 | namespace: | 12 | apiVersion: v1 13 | kind: Namespace 14 | metadata: 15 | name: vran-acceleration-operators 16 | serviceAccount: | 17 | apiVersion: v1 18 | kind: ServiceAccount 19 | metadata: 20 | name: accelerator-discovery 21 | namespace: vran-acceleration-operators 22 | clusterRole: | 23 | apiVersion: rbac.authorization.k8s.io/v1 24 | kind: ClusterRole 25 | metadata: 26 | name: accelerator-discovery 27 | rules: 28 | - apiGroups: [""] 29 | resources: ["nodes"] 30 | verbs: ["get", "update"] 31 | clusterRoleBinding: | 32 | apiVersion: rbac.authorization.k8s.io/v1 33 | kind: ClusterRoleBinding 34 | metadata: 35 | name: accelerator-discovery 36 | roleRef: 37 | apiGroup: rbac.authorization.k8s.io 38 | kind: ClusterRole 39 | name: accelerator-discovery 40 | namespace: vran-acceleration-operators 41 | subjects: 42 | - kind: ServiceAccount 43 | name: accelerator-discovery 44 | namespace: vran-acceleration-operators 45 | userNames: 46 | - system:serviceaccount:vran-acceleration-operators:accelerator-discovery 47 | configMap: | 48 | apiVersion: v1 49 | kind: ConfigMap 50 | metadata: 51 | name: n3000-labeler-config 52 | namespace: vran-acceleration-operators 53 | data: 54 | accelerators.json: | 55 | { 56 | "VendorID": "8086", 57 | "Class": "12", 58 | "SubClass": "00", 59 | "Devices": { 60 | "0d8f": "FPGA_5GNR", 61 | "5052": "FPGA_LTE", 62 | "0b32": "" 63 | }, 64 | "NodeLabel": "fpga.intel.com/intel-accelerator-present" 65 | } 66 | accelerators_vrb.json: | 67 | { 68 | "VendorID": { 69 | "8086": "Intel Corporation" 70 | }, 71 | "Class": "12", 72 | "SubClass": "00", 73 | "Devices": { 74 | "57c0": "VRB1" 75 | }, 76 | "NodeLabel": "fpga.intel.com/intel-accelerator-present" 77 | } 78 | daemonSet: | 79 | apiVersion: apps/v1 80 | kind: DaemonSet 81 | metadata: 82 | labels: 83 | app: accelerator-discovery 84 | name: accelerator-discovery 85 | namespace: vran-acceleration-operators 86 | spec: 87 | minReadySeconds: 10 88 | selector: 89 | matchLabels: 90 | app: accelerator-discovery 91 | template: 92 | metadata: 93 | labels: 94 | app: accelerator-discovery 95 | name: accelerator-discovery 96 | spec: 97 | serviceAccount: accelerator-discovery 98 | serviceAccountName: accelerator-discovery 99 | containers: 100 | - image: "N3000_LABELER_IMAGE-123" 101 | name: accelerator-discovery 102 | securityContext: 103 | readOnlyRootFilesystem: true 104 | volumeMounts: 105 | - name: config-volume 106 | mountPath: "/labeler-workspace/config" 107 | readOnly: true 108 | env: 109 | - name: NODENAME 110 | valueFrom: 111 | fieldRef: 112 | fieldPath: spec.nodeName 113 | volumes: 114 | - name: config-volume 115 | configMap: 116 | name: n3000-labeler-config 117 | items: 118 | - key: accelerators.json 119 | path: accelerators.json 120 | - key: accelerators_vrb.json 121 | path: accelerators_vrb.json 122 | -------------------------------------------------------------------------------- /pkg/common/drainhelper/suite_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package drainhelper 5 | 6 | import ( 7 | "github.com/go-logr/logr" 8 | "github.com/intel/sriov-fec-operator/pkg/common/utils" 9 | "path/filepath" 10 | "testing" 11 | 12 | . "github.com/onsi/ginkgo" 13 | . "github.com/onsi/gomega" 14 | "sigs.k8s.io/controller-runtime/pkg/envtest/printer" 15 | 16 | "k8s.io/client-go/kubernetes/scheme" 17 | "k8s.io/client-go/rest" 18 | "sigs.k8s.io/controller-runtime/pkg/client" 19 | "sigs.k8s.io/controller-runtime/pkg/envtest" 20 | logf "sigs.k8s.io/controller-runtime/pkg/log" 21 | // +kubebuilder:scaffold:imports 22 | ) 23 | 24 | var cfg *rest.Config 25 | var k8sClient client.Client 26 | var testEnv *envtest.Environment 27 | 28 | func TestAPIs(t *testing.T) { 29 | RegisterFailHandler(Fail) 30 | 31 | RunSpecsWithDefaultAndCustomReporters(t, 32 | "drainhelper Suite", 33 | []Reporter{printer.NewlineReporter{}}) 34 | } 35 | 36 | var _ = BeforeSuite(func() { 37 | var err error 38 | logf.SetLogger(logr.New(utils.NewLogWrapper())) 39 | 40 | By("bootstrapping test environment") 41 | testEnv = &envtest.Environment{ 42 | CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, 43 | } 44 | 45 | cfg, err = testEnv.Start() 46 | Expect(err).ToNot(HaveOccurred()) 47 | Expect(cfg).ToNot(BeNil()) 48 | 49 | // +kubebuilder:scaffold:scheme 50 | 51 | k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) 52 | Expect(err).ToNot(HaveOccurred()) 53 | Expect(k8sClient).ToNot(BeNil()) 54 | 55 | }, 60) 56 | 57 | var _ = AfterSuite(func() { 58 | By("tearing down the test environment") 59 | err := testEnv.Stop() 60 | Expect(err).ToNot(HaveOccurred()) 61 | }) 62 | -------------------------------------------------------------------------------- /pkg/common/utils/logger_wrapper.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package utils 5 | 6 | import ( 7 | "github.com/go-logr/logr" 8 | "github.com/sirupsen/logrus" 9 | ) 10 | 11 | type logrusWrapper struct { 12 | log *logrus.Logger 13 | lastEntry *logrus.Entry 14 | } 15 | 16 | // Init implements logr.LogSink 17 | func (l *logrusWrapper) Init(info logr.RuntimeInfo) { 18 | } 19 | 20 | func (l *logrusWrapper) Enabled(level int) bool { 21 | return true 22 | } 23 | 24 | func (l *logrusWrapper) Info(level int, msg string, keysAndValues ...interface{}) { 25 | if l.lastEntry != nil { 26 | l.lastEntry.WithFields(l.parseFields(keysAndValues)).Info(msg) 27 | l.lastEntry = nil 28 | } else { 29 | logrus.WithFields(l.parseFields(keysAndValues)).Info(msg) 30 | } 31 | } 32 | 33 | func (l *logrusWrapper) Error(err error, msg string, keysAndValues ...interface{}) { 34 | if l.lastEntry != nil { 35 | l.lastEntry.WithError(err).WithFields(l.parseFields(keysAndValues)).Error(msg) 36 | l.lastEntry = nil 37 | } else { 38 | logrus.WithError(err).WithFields(l.parseFields(keysAndValues)).Error(msg) 39 | } 40 | } 41 | 42 | func (l *logrusWrapper) V(level int) logr.LogSink { 43 | return l 44 | } 45 | 46 | func (l *logrusWrapper) WithValues(keysAndValues ...interface{}) logr.LogSink { 47 | entry := l.getEntry() 48 | entry.WithFields(l.parseFields(keysAndValues)) 49 | l.lastEntry = entry 50 | return l 51 | } 52 | 53 | func (l *logrusWrapper) parseFields(keysAndValues []interface{}) logrus.Fields { 54 | res := logrus.Fields{} 55 | for i := 0; i+1 < len(keysAndValues); i += 2 { 56 | key, ok := keysAndValues[i].(string) 57 | if ok { 58 | res[key] = keysAndValues[i+1] 59 | } 60 | } 61 | return res 62 | } 63 | 64 | func (l *logrusWrapper) getEntry() *logrus.Entry { 65 | if l.lastEntry != nil { 66 | return l.lastEntry 67 | } 68 | return logrus.NewEntry(l.log) 69 | } 70 | 71 | func (l *logrusWrapper) WithName(name string) logr.LogSink { 72 | entry := l.getEntry() 73 | l.lastEntry = entry.WithField("name", name) 74 | return l 75 | } 76 | 77 | func NewLogger() *logrus.Logger { 78 | log := logrus.New() 79 | log.SetReportCaller(true) 80 | log.SetFormatter(&logrus.JSONFormatter{}) 81 | return log 82 | } 83 | 84 | func NewLogWrapper() *logrusWrapper { 85 | return &logrusWrapper{ 86 | log: NewLogger(), 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /pkg/common/utils/slices.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package utils 5 | 6 | func Filter[T any](slice []T, filter func(T) bool) []T { 7 | var n []T 8 | for _, e := range slice { 9 | if filter(e) { 10 | n = append(n, e) 11 | } 12 | } 13 | return n 14 | } 15 | -------------------------------------------------------------------------------- /pkg/common/utils/testdata/invalid.json: -------------------------------------------------------------------------------- 1 | invalid_json 2 | -------------------------------------------------------------------------------- /pkg/common/utils/testdata/valid.json: -------------------------------------------------------------------------------- 1 | { 2 | "VendorID": {"0000": "test", 3 | "0001": "test1" 4 | }, 5 | "Class": "00", 6 | "SubClass": "00", 7 | "Devices": { 8 | "test": "test" 9 | }, 10 | "NodeLabel": "LABEL" 11 | } 12 | -------------------------------------------------------------------------------- /pkg/common/utils/utils.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package utils 5 | 6 | import ( 7 | "context" 8 | "encoding/json" 9 | "fmt" 10 | "os" 11 | "path/filepath" 12 | "strings" 13 | 14 | "github.com/go-logr/logr" 15 | "github.com/jaypipes/ghw" 16 | corev1 "k8s.io/api/core/v1" 17 | "sigs.k8s.io/controller-runtime/pkg/client" 18 | ) 19 | 20 | type AcceleratorDiscoveryConfig struct { 21 | VendorID map[string]string 22 | Class string 23 | SubClass string 24 | Devices map[string]string 25 | NodeLabel string 26 | } 27 | 28 | const ( 29 | ConfigFileSizeLimitInBytes = 10485760 // 10 MB 30 | SriovPrefix = "SRIOV_FEC_" 31 | PciPfStubDash = "pci-pf-stub" 32 | PciPfStubUnderscore = "pci_pf_stub" 33 | VfioPci = "vfio-pci" 34 | VfioPciUnderscore = "vfio_pci" 35 | IgbUio = "igb_uio" 36 | ) 37 | 38 | func LoadDiscoveryConfig(cfgPath string) (AcceleratorDiscoveryConfig, error) { 39 | var cfg AcceleratorDiscoveryConfig 40 | file, err := os.Open(filepath.Clean(cfgPath)) 41 | if err != nil { 42 | return cfg, fmt.Errorf("failed to open config: %v", err) 43 | } 44 | defer file.Close() 45 | 46 | // get file stat 47 | stat, err := file.Stat() 48 | if err != nil { 49 | return cfg, fmt.Errorf("failed to get file stat: %v", err) 50 | } 51 | 52 | // check file size 53 | if stat.Size() > ConfigFileSizeLimitInBytes { 54 | return cfg, fmt.Errorf("config file size %d, exceeds limit %d bytes", 55 | stat.Size(), ConfigFileSizeLimitInBytes) 56 | } 57 | 58 | cfgData := make([]byte, stat.Size()) 59 | bytesRead, err := file.Read(cfgData) 60 | if err != nil || int64(bytesRead) != stat.Size() { 61 | return cfg, fmt.Errorf("unable to read config: %s", filepath.Clean(cfgPath)) 62 | } 63 | 64 | if err = json.Unmarshal(cfgData, &cfg); err != nil { 65 | return cfg, fmt.Errorf("failed to unmarshal config: %v", err) 66 | } 67 | return cfg, nil 68 | } 69 | 70 | func SetOsEnvIfNotSet(key, value string, logger logr.Logger) error { 71 | if osValue := os.Getenv(key); osValue != "" { 72 | logger.Info("skipping ENV because it is already set", "key", key, "value", osValue) 73 | return nil 74 | } 75 | logger.Info("setting ENV var", "key", key, "value", value) 76 | return os.Setenv(key, value) 77 | } 78 | 79 | func IsSingleNodeCluster(c client.Client) (bool, error) { 80 | nodeList := &corev1.NodeList{} 81 | err := c.List(context.TODO(), nodeList) 82 | if err != nil { 83 | return false, err 84 | } 85 | if len(nodeList.Items) == 1 { 86 | return true, nil 87 | } 88 | return false, nil 89 | } 90 | 91 | var GetPCIDevices = func() ([]*ghw.PCIDevice, error) { 92 | pci, err := ghw.PCI() 93 | if err != nil { 94 | return nil, fmt.Errorf("failed to get PCI info: %v", err) 95 | } 96 | 97 | devices := pci.ListDevices() 98 | if len(devices) == 0 { 99 | return nil, fmt.Errorf("got 0 devices") 100 | } 101 | return devices, nil 102 | } 103 | 104 | func FindAccelerator(cfgPath string) (bool, string, error) { 105 | 106 | cfg, err := LoadDiscoveryConfig(cfgPath) 107 | if err != nil { 108 | return false, "", fmt.Errorf("failed to load config: %v", err) 109 | } 110 | 111 | devices, err := GetPCIDevices() 112 | if err != nil { 113 | return false, "", fmt.Errorf("failed to get PCI devices: %v", err) 114 | } 115 | 116 | for _, device := range devices { 117 | _, exist := cfg.VendorID[device.Vendor.ID] 118 | if !(exist && 119 | device.Class.ID == cfg.Class && 120 | device.Subclass.ID == cfg.SubClass) { 121 | continue 122 | } 123 | 124 | if _, ok := cfg.Devices[device.Product.ID]; ok { 125 | fmt.Printf("[%s]Accelerator found %v\n", cfgPath, device) 126 | return true, cfg.NodeLabel, nil 127 | } 128 | } 129 | return false, "", nil 130 | } 131 | 132 | // Function to find all VFs associated with a given PF PCI address 133 | func FindVFs(pfPCIAddress string) ([]string, error) { 134 | // Path to the PF's SR-IOV directory in sysfs 135 | sriovPath := fmt.Sprintf("/sys/bus/pci/devices/%s/virtfn*", pfPCIAddress) 136 | 137 | // Find all symbolic links matching the virtfn* pattern 138 | vfLinks, err := filepath.Glob(sriovPath) 139 | if err != nil { 140 | return nil, err 141 | } 142 | 143 | vfAddresses := make([]string, 0, len(vfLinks)) 144 | for _, vfLink := range vfLinks { 145 | // Read the target of the symbolic link to get the VF PCI address 146 | vfTarget, err := os.Readlink(vfLink) 147 | if err != nil { 148 | return nil, err 149 | } 150 | 151 | // Extract the VF PCI address from the target path 152 | vfAddress := filepath.Base(vfTarget) 153 | vfAddresses = append(vfAddresses, vfAddress) 154 | } 155 | 156 | return vfAddresses, nil 157 | } 158 | 159 | func GetVFDeviceID(pfPCIAddress string) (string, error) { 160 | // Path to the PF's SR-IOV VF device ID file in sysfs 161 | deviceIDPath := fmt.Sprintf("/sys/bus/pci/devices/%s/sriov_vf_device", pfPCIAddress) 162 | 163 | // Read the device ID from the file 164 | deviceID, err := os.ReadFile(deviceIDPath) 165 | if err != nil { 166 | return "", err 167 | } 168 | 169 | return strings.ToLower(strings.TrimSpace(string(deviceID))), nil 170 | } 171 | -------------------------------------------------------------------------------- /pkg/common/utils/utils_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | package utils 4 | 5 | import ( 6 | "github.com/go-logr/logr" 7 | "os" 8 | "testing" 9 | 10 | . "github.com/onsi/ginkgo" 11 | . "github.com/onsi/gomega" 12 | ) 13 | 14 | func TestMain(t *testing.T) { 15 | RegisterFailHandler(Fail) 16 | RunSpecs(t, "Main suite") 17 | } 18 | 19 | var _ = Describe("Utils", func() { 20 | var _ = Describe("LoadDiscoveryConfig", func() { 21 | var _ = It("will fail if the file does not exist", func() { 22 | cfg, err := LoadDiscoveryConfig("notExistingFile.json") 23 | Expect(err).To(HaveOccurred()) 24 | Expect(cfg).To(Equal(AcceleratorDiscoveryConfig{})) 25 | }) 26 | var _ = It("will fail if the file is not json", func() { 27 | cfg, err := LoadDiscoveryConfig("testdata/invalid.json") 28 | Expect(err).To(HaveOccurred()) 29 | Expect(cfg).To(Equal(AcceleratorDiscoveryConfig{})) 30 | }) 31 | var _ = It("will load the valid config successfully", func() { 32 | cfg, err := LoadDiscoveryConfig("testdata/valid.json") 33 | Expect(err).ToNot(HaveOccurred()) 34 | Expect(cfg).To(Equal(AcceleratorDiscoveryConfig{ 35 | VendorID: map[string]string{"0000": "test", "0001": "test1"}, 36 | Class: "00", 37 | SubClass: "00", 38 | Devices: map[string]string{"test": "test"}, 39 | NodeLabel: "LABEL", 40 | })) 41 | }) 42 | }) 43 | }) 44 | 45 | var _ = Describe("Utils", func() { 46 | var _ = Describe("SetOsEnvIfNotSet", func() { 47 | var _ = It("should set ENV if variable is not set", func() { 48 | key := "key" 49 | value := "value" 50 | Expect(os.Getenv(key)).To(Equal("")) 51 | 52 | err := SetOsEnvIfNotSet(key, value, logr.Discard()) 53 | 54 | Expect(err).To(Succeed()) 55 | Expect(os.Getenv(key)).To(Equal(value)) 56 | }) 57 | 58 | var _ = It("should not set ENV if variable is already set", func() { 59 | key := "key" 60 | value := "value" 61 | Expect(os.Setenv(key, value)).To(Succeed()) 62 | Expect(os.Getenv(key)).To(Equal(value)) 63 | 64 | err := SetOsEnvIfNotSet(key, "value that should be omitted", logr.Discard()) 65 | 66 | Expect(err).To(Succeed()) 67 | Expect(os.Getenv(key)).To(Equal(value)) 68 | }) 69 | }) 70 | }) 71 | -------------------------------------------------------------------------------- /pkg/daemon/common.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package daemon 5 | 6 | import ( 7 | "errors" 8 | "os/exec" 9 | 10 | "github.com/sirupsen/logrus" 11 | ) 12 | 13 | func execCmd(args []string, log *logrus.Logger) (string, error) { 14 | return execAndSuppress(args, log, func(error) bool { 15 | return false 16 | }) 17 | } 18 | 19 | func execAndSuppress(args []string, log *logrus.Logger, suppressError func(e error) bool) (string, error) { 20 | var cmd *exec.Cmd 21 | if len(args) == 0 { 22 | log.Error("provided cmd is empty") 23 | return "", errors.New("cmd is empty") 24 | } 25 | 26 | if len(args) == 1 { 27 | cmd = exec.Command(args[0]) 28 | } else { 29 | cmd = exec.Command(args[0], args[1:]...) 30 | } 31 | 32 | log.WithFields(logrus.Fields{ 33 | "cmd": cmd.Path, 34 | "args": cmd.Args, 35 | }).Info("executing command") 36 | 37 | out, err := cmd.Output() 38 | if err != nil { 39 | if suppressError(err) { 40 | log.WithField("cmd", args).WithError(err).Info("ignoring error") 41 | } else { 42 | log.WithField("cmd", args).WithField("output", string(out)).WithError(err).Error("failed to execute command") 43 | return string(out), err 44 | } 45 | } 46 | 47 | output := string(out) 48 | log.WithField("output", output).Info("commands output") 49 | return output, nil 50 | } 51 | -------------------------------------------------------------------------------- /pkg/daemon/common_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package daemon 5 | 6 | import ( 7 | "github.com/intel/sriov-fec-operator/pkg/common/utils" 8 | . "github.com/onsi/ginkgo" 9 | . "github.com/onsi/gomega" 10 | ) 11 | 12 | var _ = Describe("common", func() { 13 | log = utils.NewLogger() 14 | var _ = Context("execCmd", func() { 15 | var _ = It("will return error when args is empty ", func() { 16 | _, err := execCmd([]string{}, log) 17 | Expect(err).To(HaveOccurred()) 18 | }) 19 | var _ = It("will return error when exec doesn't exist ", func() { 20 | _, err := execCmd([]string{"dummyExecFile"}, log) 21 | Expect(err).To(HaveOccurred()) 22 | }) 23 | var _ = It("will call exec ", func() { 24 | _, err := execCmd([]string{"ls"}, log) 25 | Expect(err).ToNot(HaveOccurred()) 26 | }) 27 | }) 28 | }) 29 | -------------------------------------------------------------------------------- /pkg/daemon/daemon.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package daemon 5 | 6 | import ( 7 | "context" 8 | "errors" 9 | "fmt" 10 | "io/fs" 11 | "os" 12 | "strconv" 13 | "strings" 14 | "time" 15 | 16 | "github.com/sirupsen/logrus" 17 | corev1 "k8s.io/api/core/v1" 18 | "k8s.io/apimachinery/pkg/runtime" 19 | "k8s.io/client-go/rest" 20 | "sigs.k8s.io/controller-runtime/pkg/healthz" 21 | "sigs.k8s.io/controller-runtime/pkg/manager" 22 | 23 | ctrl "sigs.k8s.io/controller-runtime" 24 | ) 25 | 26 | type ConfigurationConditionReason string 27 | 28 | const ( 29 | ConditionConfigured string = "Configured" 30 | ConfigurationInProgress ConfigurationConditionReason = "InProgress" 31 | ConfigurationFailed ConfigurationConditionReason = "Failed" 32 | ConfigurationNotRequested ConfigurationConditionReason = "NotRequested" 33 | ConfigurationSucceeded ConfigurationConditionReason = "Succeeded" 34 | ) 35 | 36 | var ( 37 | resyncPeriod = time.Minute 38 | procCmdlineFilePath = "/proc/cmdline" 39 | sysLockdownFilePath = "/sys/kernel/security/lockdown" 40 | kernelParams = []string{"intel_iommu=on", "iommu=pt"} 41 | ) 42 | 43 | type DrainAndExecute func(configurer func(ctx context.Context) bool, drain bool) error 44 | 45 | type RestartDevicePluginFunction func() error 46 | 47 | func pfBbConfigProcIsDead(log *logrus.Logger, pciAddr string) bool { 48 | defaultLogLevel := log.GetLevel() 49 | if defaultLogLevel == logrus.InfoLevel { 50 | log.SetLevel(logrus.WarnLevel) 51 | } 52 | stdout, err := execCmd([]string{ 53 | "pgrep", 54 | "--count", 55 | "--full", 56 | fmt.Sprintf("pf_bb_config.*%s", pciAddr), 57 | }, log) 58 | log.SetLevel(defaultLogLevel) 59 | if err != nil { 60 | log.WithError(err).Error("failed to determine status of pf-bb-config daemon") 61 | return true 62 | } 63 | matchingProcCount, err := strconv.Atoi(stdout[0:1]) // Stdout contains characters like '\n', so we are removing them 64 | if err != nil { 65 | log.WithError(err).Error("failed to convert 'pgrep' output to int") 66 | return true 67 | } 68 | return matchingProcCount == 0 69 | } 70 | 71 | func isReady(p corev1.Pod) bool { 72 | for _, condition := range p.Status.Conditions { 73 | if condition.Type == corev1.PodReady && p.Status.Phase == corev1.PodRunning { 74 | return true 75 | } 76 | } 77 | return false 78 | } 79 | 80 | func CreateManager(config *rest.Config, scheme *runtime.Scheme, namespace string, metricsPort int, healthProbePort int, log *logrus.Logger) (manager.Manager, error) { 81 | mgr, err := ctrl.NewManager(config, ctrl.Options{ 82 | Scheme: scheme, 83 | MetricsBindAddress: ":" + strconv.Itoa(metricsPort), 84 | LeaderElection: false, 85 | Namespace: namespace, 86 | HealthProbeBindAddress: ":" + strconv.Itoa(healthProbePort), 87 | }) 88 | if err != nil { 89 | return nil, err 90 | } 91 | 92 | if err := mgr.AddHealthzCheck("health", healthz.Ping); err != nil { 93 | log.WithError(err).Error("unable to set up health check") 94 | return nil, err 95 | } 96 | if err := mgr.AddReadyzCheck("check", healthz.Ping); err != nil { 97 | log.WithError(err).Error("unable to set up ready check") 98 | return nil, err 99 | } 100 | return mgr, nil 101 | } 102 | 103 | func moduleParameterIsEnabled(moduleName, parameter string) error { 104 | value, err := os.ReadFile("/sys/module/" + moduleName + "/parameters/" + parameter) 105 | if err != nil { 106 | if errors.Is(err, fs.ErrNotExist) { 107 | // module is not loaded - we will automatically append required parameter during modprobe 108 | return nil 109 | } else { 110 | return fmt.Errorf("failed to check parameter %v for %v module - %v", parameter, moduleName, err) 111 | } 112 | } 113 | if strings.Contains(strings.ToLower(string(value)), "n") { 114 | return fmt.Errorf("%v is loaded and doesn't have %v set", moduleName, parameter) 115 | } 116 | return nil 117 | } 118 | 119 | func validateOrdinalKernelParams(cmdline string) error { 120 | for _, param := range kernelParams { 121 | if !strings.Contains(cmdline, param) { 122 | return fmt.Errorf("missing kernel param(%s)", param) 123 | } 124 | } 125 | return nil 126 | } 127 | -------------------------------------------------------------------------------- /pkg/daemon/device_plugin_controller.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package daemon 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | "time" 10 | 11 | "github.com/pkg/errors" 12 | "github.com/sirupsen/logrus" 13 | corev1 "k8s.io/api/core/v1" 14 | "k8s.io/apimachinery/pkg/types" 15 | "k8s.io/apimachinery/pkg/util/wait" 16 | "sigs.k8s.io/controller-runtime/pkg/client" 17 | ) 18 | 19 | func NewDevicePluginController(c client.Client, log *logrus.Logger, nnr types.NamespacedName) *DevicePluginController { 20 | return &DevicePluginController{ 21 | Client: c, 22 | log: log, 23 | nodeNameRef: nnr, 24 | } 25 | } 26 | 27 | type DevicePluginController struct { 28 | client.Client 29 | log *logrus.Logger 30 | nodeNameRef types.NamespacedName 31 | } 32 | 33 | func (d *DevicePluginController) RestartDevicePlugin() error { 34 | pods := &corev1.PodList{} 35 | err := d.List(context.TODO(), pods, 36 | client.InNamespace(d.nodeNameRef.Namespace), 37 | &client.MatchingLabels{"app": "sriov-device-plugin-daemonset"}) 38 | 39 | if err != nil { 40 | return errors.Wrap(err, "failed to get pods") 41 | } 42 | if len(pods.Items) == 0 { 43 | d.log.Info("there is no running instance of device plugin, nothing to restart") 44 | } 45 | 46 | for i := range pods.Items { 47 | if pods.Items[i].Spec.NodeName != d.nodeNameRef.Name { 48 | continue 49 | } 50 | if err := d.Delete(context.TODO(), &pods.Items[i], &client.DeleteOptions{}); err != nil { 51 | return errors.Wrap(err, "failed to delete sriov-device-plugin-daemonset pod") 52 | } 53 | backoff := wait.Backoff{Steps: 300, Duration: 1 * time.Second, Factor: 1} 54 | err = wait.ExponentialBackoff(backoff, d.waitForDevicePluginRestart(pods.Items[i].Name)) 55 | if err == wait.ErrWaitTimeout { 56 | return fmt.Errorf("failed to restart sriov-device-plugin within specified time") 57 | } 58 | return err 59 | } 60 | 61 | return nil 62 | } 63 | 64 | func (d *DevicePluginController) waitForDevicePluginRestart(oldPodName string) func() (bool, error) { 65 | return func() (bool, error) { 66 | pods := &corev1.PodList{} 67 | 68 | err := d.List(context.TODO(), pods, 69 | client.InNamespace(d.nodeNameRef.Namespace), 70 | &client.MatchingLabels{"app": "sriov-device-plugin-daemonset"}) 71 | if err != nil { 72 | d.log.WithError(err).Error("failed to list pods for sriov-device-plugin") 73 | return false, err 74 | } 75 | 76 | for _, pod := range pods.Items { 77 | if pod.Spec.NodeName == d.nodeNameRef.Name && pod.Name != oldPodName && isReady(pod) { 78 | d.log.Info("device-plugin is running") 79 | return true, nil 80 | } 81 | 82 | } 83 | return false, nil 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /pkg/daemon/inventory.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package daemon 5 | 6 | import ( 7 | "errors" 8 | "strings" 9 | 10 | commonUtils "github.com/intel/sriov-fec-operator/pkg/common/utils" 11 | "github.com/jaypipes/ghw/pkg/pci" 12 | "github.com/sirupsen/logrus" 13 | 14 | sriovv2 "github.com/intel/sriov-fec-operator/api/sriovfec/v2" 15 | vrbv1 "github.com/intel/sriov-fec-operator/api/sriovvrb/v1" 16 | "github.com/jaypipes/ghw" 17 | "github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/utils" 18 | ) 19 | 20 | func getVFDeviceInfo(log *logrus.Logger, pciInfo *ghw.PCIInfo, pfAddress, vfAddress string) (string, string) { 21 | 22 | driver, err := utils.GetDriverName(vfAddress) 23 | if err != nil { 24 | driver = "" 25 | log.WithFields(logrus.Fields{ 26 | "pci": vfAddress, 27 | "pf": pfAddress, 28 | "reason": err.Error(), 29 | }).Info("failed to get driver name for VF") 30 | } 31 | 32 | deviceID := "" 33 | if vfDeviceInfo := pciInfo.GetDevice(vfAddress); vfDeviceInfo == nil { 34 | log.WithField("pci", vfAddress).Info("failed to get device info for vf") 35 | } else { 36 | deviceID = vfDeviceInfo.Product.ID 37 | } 38 | 39 | return driver, deviceID 40 | } 41 | 42 | func GetSriovInventory(log *logrus.Logger) (*sriovv2.NodeInventory, error) { 43 | pciInfo, err := ghw.PCI() 44 | if err != nil { 45 | log.WithError(err).Error("failed to get PCI info") 46 | return nil, err 47 | } 48 | 49 | devices := pciInfo.ListDevices() 50 | if len(devices) == 0 { 51 | log.Info("got 0 pci devices") 52 | err := errors.New("pci.ListDevices() returned 0 devices") 53 | return nil, err 54 | } 55 | 56 | accelerators := &sriovv2.NodeInventory{ 57 | SriovAccelerators: []sriovv2.SriovAccelerator{}, 58 | } 59 | 60 | for _, device := range commonUtils.Filter(devices, isKnownDevice) { 61 | if !utils.IsSriovPF(device.Address) { 62 | log.WithField("pci", device.Address).Info("ignoring non SriovPF capable device") 63 | continue 64 | } 65 | 66 | driver, err := utils.GetDriverName(device.Address) 67 | if err != nil { 68 | driver = "" 69 | if strings.Contains(err.Error(), "no such file or directory") { 70 | log.WithField("pci", device.Address).WithField("reason", err.Error()).Debug("driver link does not exist for device") 71 | } else { 72 | log.WithField("pci", device.Address).WithField("reason", err.Error()).Info("unable to get driver for device") 73 | } 74 | } 75 | 76 | acc := sriovv2.SriovAccelerator{ 77 | VendorID: device.Vendor.ID, 78 | DeviceID: device.Product.ID, 79 | PCIAddress: device.Address, 80 | PFDriver: driver, 81 | MaxVFs: utils.GetSriovVFcapacity(device.Address), 82 | VFs: []sriovv2.VF{}, 83 | } 84 | 85 | vfs, err := utils.GetVFList(device.Address) 86 | if err != nil { 87 | log.WithError(err).WithField("pci", device.Address).Error("failed to get list of VFs for device") 88 | } 89 | 90 | for _, vf := range vfs { 91 | vfInfo := sriovv2.VF{ 92 | PCIAddress: vf, 93 | } 94 | 95 | vfInfo.Driver, vfInfo.DeviceID = getVFDeviceInfo(log, pciInfo, device.Address, vf) 96 | 97 | acc.VFs = append(acc.VFs, vfInfo) 98 | } 99 | 100 | accelerators.SriovAccelerators = append(accelerators.SriovAccelerators, acc) 101 | } 102 | 103 | return accelerators, nil 104 | } 105 | 106 | func VrbGetSriovInventory(log *logrus.Logger) (*vrbv1.NodeInventory, error) { 107 | pciInfo, err := ghw.PCI() 108 | if err != nil { 109 | log.WithError(err).Error("failed to get PCI info") 110 | return nil, err 111 | } 112 | 113 | devices := pciInfo.ListDevices() 114 | if len(devices) == 0 { 115 | log.Info("got 0 pci devices") 116 | err := errors.New("pci.ListDevices() returned 0 devices") 117 | return nil, err 118 | } 119 | 120 | accelerators := &vrbv1.NodeInventory{ 121 | SriovAccelerators: []vrbv1.SriovAccelerator{}, 122 | } 123 | 124 | for _, device := range commonUtils.Filter(devices, VrbisKnownDevice) { 125 | if !utils.IsSriovPF(device.Address) { 126 | log.WithField("pci", device.Address).Info("ignoring non SriovPF capable device") 127 | continue 128 | } 129 | 130 | driver, err := utils.GetDriverName(device.Address) 131 | if err != nil { 132 | driver = "" 133 | if strings.Contains(err.Error(), "no such file or directory") { 134 | log.WithField("pci", device.Address).WithField("reason", err.Error()).Debug("driver link does not exist for device") 135 | } else { 136 | log.WithField("pci", device.Address).WithField("reason", err.Error()).Info("unable to get driver for device") 137 | } 138 | } 139 | 140 | acc := vrbv1.SriovAccelerator{ 141 | VendorID: device.Vendor.ID, 142 | DeviceID: device.Product.ID, 143 | PCIAddress: device.Address, 144 | PFDriver: driver, 145 | MaxVFs: utils.GetSriovVFcapacity(device.Address), 146 | VFs: []vrbv1.VF{}, 147 | } 148 | 149 | vfs, err := utils.GetVFList(device.Address) 150 | if err != nil { 151 | log.WithError(err).WithField("pci", device.Address).Error("failed to get list of VFs for device") 152 | } 153 | 154 | for _, vf := range vfs { 155 | vfInfo := vrbv1.VF{ 156 | PCIAddress: vf, 157 | } 158 | 159 | vfInfo.Driver, vfInfo.DeviceID = getVFDeviceInfo(log, pciInfo, device.Address, vf) 160 | 161 | acc.VFs = append(acc.VFs, vfInfo) 162 | } 163 | 164 | accelerators.SriovAccelerators = append(accelerators.SriovAccelerators, acc) 165 | } 166 | 167 | return accelerators, nil 168 | } 169 | 170 | func isKnownDevice(device *pci.Device) bool { 171 | _, hasKnownVendor := supportedAccelerators.VendorID[device.Vendor.ID] 172 | _, hasKnownDeviceID := supportedAccelerators.Devices[device.Product.ID] 173 | 174 | return hasKnownVendor && 175 | hasKnownDeviceID && 176 | device.Class.ID == supportedAccelerators.Class && 177 | device.Subclass.ID == supportedAccelerators.SubClass 178 | } 179 | 180 | func VrbisKnownDevice(device *pci.Device) bool { 181 | _, hasKnownVendor := VrbsupportedAccelerators.VendorID[device.Vendor.ID] 182 | _, hasKnownDeviceID := VrbsupportedAccelerators.Devices[device.Product.ID] 183 | 184 | return hasKnownVendor && 185 | hasKnownDeviceID && 186 | device.Class.ID == VrbsupportedAccelerators.Class && 187 | device.Subclass.ID == VrbsupportedAccelerators.SubClass 188 | } 189 | -------------------------------------------------------------------------------- /pkg/daemon/inventory_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package daemon 5 | 6 | import ( 7 | . "github.com/onsi/ginkgo" 8 | . "github.com/onsi/gomega" 9 | "github.com/sirupsen/logrus" 10 | ) 11 | 12 | var _ = Describe("SriovInventoryTest", func() { 13 | log := logrus.New() 14 | var _ = Context("GetSriovInventory", func() { 15 | var _ = It("will return error when config is nil ", func() { 16 | _, err := GetSriovInventory(log) 17 | Expect(err).ToNot(HaveOccurred()) 18 | }) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /pkg/daemon/package_config.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package daemon 5 | 6 | import "github.com/intel/sriov-fec-operator/pkg/common/utils" 7 | 8 | var log = utils.NewLogger() 9 | -------------------------------------------------------------------------------- /pkg/daemon/pf_bb_config_cli_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package daemon 5 | 6 | import ( 7 | "fmt" 8 | "net" 9 | "os" 10 | 11 | "github.com/intel/sriov-fec-operator/pkg/common/utils" 12 | . "github.com/onsi/ginkgo" 13 | . "github.com/onsi/gomega" 14 | ) 15 | 16 | const missingEndStr = ` 17 | Tue Oct 10 18:35:48 2023:INFO:Read 0x00C84060 0x00003030 18 | 19 | Tue Oct 10 18:35:48 2023:INFO:` 20 | 21 | const mmReadLog = ` 22 | Tue Oct 10 18:35:48 2023:INFO:Read 0x00C84060 0x00003030 23 | 24 | Tue Oct 10 18:35:48 2023:INFO:-- End of Response --` 25 | 26 | var _ = Describe("sendCmd", func() { 27 | var cmd = []byte{0x09, 0x00} 28 | It("socket doesn't exists", func() { 29 | err := sendCmd("0000:ff:ff.0", cmd, utils.NewLogger()) 30 | Expect(err).To(MatchError("dial unix /tmp/pf_bb_config.0000:ff:ff.0.sock: connect: no such file or directory")) 31 | }) 32 | 33 | It("socket exists and responds correctly", func() { 34 | pciAddr := "1111:11:23.1" 35 | listener, err := net.Listen("unix", fmt.Sprintf("/tmp/pf_bb_config.%v.sock", pciAddr)) 36 | Expect(err).To(BeNil()) 37 | defer listener.Close() 38 | 39 | err = sendCmd(pciAddr, cmd, utils.NewLogger()) 40 | Expect(err).To(BeNil()) 41 | }) 42 | }) 43 | 44 | var _ = Describe("resetMode", func() { 45 | It("missing reset mode argument", func() { 46 | _, err := resetMode([]string{}) 47 | Expect(err).To(MatchError("error: missing argument for command reset_mode")) 48 | }) 49 | 50 | It("invalid reset mode", func() { 51 | _, err := resetMode([]string{"dummy_mode"}) 52 | Expect(err).To(MatchError("error: invalid reset_mode value")) 53 | }) 54 | 55 | It("valid pf_flr reset mode", func() { 56 | _, err := resetMode([]string{"pf_flr"}) 57 | Expect(err).To(BeNil()) 58 | }) 59 | 60 | It("valid cluster_reset reset mode", func() { 61 | _, err := resetMode([]string{"cluster_reset"}) 62 | Expect(err).To(BeNil()) 63 | }) 64 | }) 65 | 66 | var _ = Describe("autoReset", func() { 67 | It("missing auto reset argument", func() { 68 | _, err := autoReset([]string{}) 69 | Expect(err).To(MatchError("error: missing argument for command auto_reset")) 70 | }) 71 | 72 | It("invalid auto reset mode", func() { 73 | _, err := autoReset([]string{"foo"}) 74 | Expect(err).To(MatchError("error: invalid auto_reset value")) 75 | }) 76 | 77 | It("valid auto_reset on", func() { 78 | _, err := autoReset([]string{"on"}) 79 | Expect(err).To(BeNil()) 80 | }) 81 | 82 | It("valid auto_reset off", func() { 83 | _, err := autoReset([]string{"off"}) 84 | Expect(err).To(BeNil()) 85 | }) 86 | }) 87 | 88 | var _ = Describe("regDump", func() { 89 | It("missing register dump argument", func() { 90 | _, err := regDump([]string{}) 91 | Expect(err).To(MatchError("error: missing argument for reg_dump")) 92 | }) 93 | 94 | It("invalid fec device", func() { 95 | _, err := regDump([]string{"5052"}) 96 | Expect(err).To(MatchError("error: invalid device for reg_dump")) 97 | }) 98 | 99 | It("valid ACC100 fec device", func() { 100 | _, err := regDump([]string{"0d5c"}) 101 | Expect(err).To(BeNil()) 102 | }) 103 | 104 | It("valid VRB1 fec device", func() { 105 | _, err := regDump([]string{"57c0"}) 106 | Expect(err).To(BeNil()) 107 | }) 108 | 109 | It("valid VRB2 fec device", func() { 110 | _, err := regDump([]string{"57c2"}) 111 | Expect(err).To(BeNil()) 112 | }) 113 | }) 114 | 115 | var _ = Describe("mmRead", func() { 116 | It("missing read address", func() { 117 | _, err := mmRead([]string{}) 118 | Expect(err).To(MatchError("error: missing register address for mm_read")) 119 | }) 120 | 121 | It("read incomplete register address", func() { 122 | _, err := mmRead([]string{"0x"}) 123 | Expect(err).To(MatchError("error: invalid input for register address")) 124 | }) 125 | 126 | It("read non hex register address", func() { 127 | _, err := mmRead([]string{"123456"}) 128 | Expect(err).To(MatchError("error: dump address must be HEX")) 129 | }) 130 | 131 | It("invalid hex value for register address", func() { 132 | _, err := mmRead([]string{"0xAVX512"}) 133 | Expect(err).To(MatchError("error: failed to convert address string to uint")) 134 | }) 135 | }) 136 | 137 | var _ = Describe("pollLogFile", func() { 138 | It("file doesn't exists", func() { 139 | pciAddr := "2222:22:22.2" 140 | filePath := "/var/log/pf_bb_cfg_2222:22:22.2_response.log" 141 | searchStr := "" 142 | file, err := pollLogFile(pciAddr, filePath, searchStr, utils.NewLogger()) 143 | Expect(file).To(BeNil()) 144 | Expect(err).To(MatchError("open /var/log/pf_bb_cfg_2222:22:22.2_response.log: no such file or directory")) 145 | }) 146 | 147 | It("file exists but it is empty", func() { 148 | pciAddr := "4321:11:23.1" 149 | filePath := fmt.Sprintf("/var/log/pf_bb_cfg_%v_response.log", pciAddr) 150 | searchStr := "-- End of Response --" 151 | 152 | fileHandler, err := os.Create(filePath) 153 | Expect(err).To(BeNil()) 154 | defer fileHandler.Close() 155 | 156 | file, err := pollLogFile(pciAddr, filePath, searchStr, utils.NewLogger()) 157 | Expect(file).To(BeNil()) 158 | Expect(err).To(MatchError("timed out waiting for the condition")) 159 | }) 160 | 161 | It("file exists but search string missing", func() { 162 | pciAddr := "4444:11:23.1" 163 | filePath := fmt.Sprintf("/var/log/pf_bb_cfg_%v_response.log", pciAddr) 164 | searchStr := "-- End of Response --" 165 | 166 | fileHandler, err := os.Create(filePath) 167 | Expect(err).To(BeNil()) 168 | defer fileHandler.Close() 169 | _, err = fileHandler.Write([]byte(missingEndStr)) 170 | Expect(err).To(BeNil()) 171 | 172 | file, err := pollLogFile(pciAddr, filePath, searchStr, utils.NewLogger()) 173 | Expect(file).To(BeNil()) 174 | Expect(err).To(MatchError("timed out waiting for the condition")) 175 | }) 176 | 177 | It("file exists and contains search string", func() { 178 | pciAddr := "4444:11:23.1" 179 | filePath := fmt.Sprintf("/var/log/pf_bb_cfg_%v_response.log", pciAddr) 180 | searchStr := "-- End of Response --" 181 | 182 | fileHandler, err := os.Create(filePath) 183 | Expect(err).To(BeNil()) 184 | defer fileHandler.Close() 185 | _, err = fileHandler.Write([]byte(mmReadLog)) 186 | Expect(err).To(BeNil()) 187 | 188 | file, err := pollLogFile(pciAddr, filePath, searchStr, utils.NewLogger()) 189 | Expect(file).To(BeEquivalentTo(mmReadLog)) 190 | Expect(err).To(BeNil()) 191 | }) 192 | }) 193 | -------------------------------------------------------------------------------- /pkg/daemon/suite_test.go: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // Copyright (c) 2020-2025 Intel Corporation 3 | 4 | package daemon 5 | 6 | import ( 7 | "github.com/go-logr/logr" 8 | "github.com/intel/sriov-fec-operator/pkg/common/utils" 9 | "github.com/sirupsen/logrus" 10 | "os" 11 | "testing" 12 | 13 | . "github.com/onsi/ginkgo" 14 | . "github.com/onsi/gomega" 15 | "sigs.k8s.io/controller-runtime/pkg/envtest/printer" 16 | logf "sigs.k8s.io/controller-runtime/pkg/log" 17 | // +kubebuilder:scaffold:imports 18 | ) 19 | 20 | // These tests use Ginkgo (BDD-style Go testing framework). Refer to 21 | // http://onsi.github.io/ginkgo/ to learn more about Ginkgo. 22 | 23 | var ( 24 | testTmpFolder string 25 | ) 26 | 27 | func TestAPIs(t *testing.T) { 28 | log = logrus.New() 29 | RegisterFailHandler(Fail) 30 | 31 | RunSpecsWithDefaultAndCustomReporters(t, 32 | "Controller Suite", 33 | []Reporter{printer.NewlineReporter{}}) 34 | } 35 | 36 | var _ = BeforeSuite(func() { 37 | logf.SetLogger(logr.New(utils.NewLogWrapper())) 38 | var err error 39 | testTmpFolder, err = os.MkdirTemp("/tmp", "bbdevconfig_test") 40 | Expect(err).ShouldNot(HaveOccurred()) 41 | }, 60) 42 | 43 | var _ = AfterSuite(func() { 44 | err := os.RemoveAll(testTmpFolder) 45 | Expect(err).ShouldNot(HaveOccurred()) 46 | }) 47 | -------------------------------------------------------------------------------- /pkg/daemon/testdata/accelerators.json: -------------------------------------------------------------------------------- 1 | { 2 | "VendorID": { 3 | "8086": "Intel Corporation", 4 | "1172": "Altera Corporation" 5 | }, 6 | "Class": "12", 7 | "SubClass": "00", 8 | "Devices": { 9 | "0d8f": "FPGA_5GNR", 10 | "5052": "FPGA_LTE", 11 | "0d5c": "ACC100", 12 | "0b32": "" 13 | }, 14 | "NodeLabel": "fpga.intel.com/intel-accelerator-present" 15 | } 16 | -------------------------------------------------------------------------------- /pkg/daemon/testdata/accelerators_vrb.json: -------------------------------------------------------------------------------- 1 | { 2 | "VendorID": { 3 | "8086": "Intel Corporation" 4 | }, 5 | "Class": "12", 6 | "SubClass": "00", 7 | "Devices": { 8 | "57c0": "VRB1" 9 | }, 10 | "NodeLabel": "fpga.intel.com/intel-accelerator-present" 11 | } -------------------------------------------------------------------------------- /pkg/daemon/testdata/archives/sample-archive/inner-dir/inner-file-1: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | -------------------------------------------------------------------------------- /pkg/daemon/testdata/archives/sample-archive/outer-file-1: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | -------------------------------------------------------------------------------- /pkg/daemon/testdata/archives/sample-archive/outer-file-2: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | -------------------------------------------------------------------------------- /pkg/daemon/testdata/bbdevconfig_test1.cfg: -------------------------------------------------------------------------------- 1 | [MODE] 2 | pf_mode_en = 1 3 | 4 | [UL] 5 | bandwidth = 8 6 | load_balance = 128 7 | vfqmap = 15,13,11,9,14,3,5,7 8 | 9 | [DL] 10 | bandwidth = 6 11 | load_balance = 64 12 | vfqmap = 16,8,4,2,6,1,0,0 13 | 14 | [FLR] 15 | flr_time_out = 21 16 | -------------------------------------------------------------------------------- /pkg/daemon/testdata/bbdevconfig_test2.cfg: -------------------------------------------------------------------------------- 1 | [MODE] 2 | pf_mode_en = 1 3 | 4 | [VFBUNDLES] 5 | num_vf_bundles = 16 6 | 7 | [MAXQSIZE] 8 | max_queue_size = 1024 9 | 10 | [QUL4G] 11 | num_qgroups = 2 12 | num_aqs_per_groups = 16 13 | aq_depth_log2 = 4 14 | 15 | [QDL4G] 16 | num_qgroups = 2 17 | num_aqs_per_groups = 16 18 | aq_depth_log2 = 4 19 | 20 | [QUL5G] 21 | num_qgroups = 2 22 | num_aqs_per_groups = 16 23 | aq_depth_log2 = 4 24 | 25 | [QDL5G] 26 | num_qgroups = 2 27 | num_aqs_per_groups = 16 28 | aq_depth_log2 = 4 29 | -------------------------------------------------------------------------------- /pkg/daemon/testdata/centos_os_release: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | NAME="CentOS Linux" 4 | VERSION="7 (Core)" 5 | ID="centos" 6 | ID_LIKE="rhel fedora" 7 | VERSION_ID="7" 8 | PRETTY_NAME="CentOS Linux 7 (Core)" 9 | ANSI_COLOR="0;31" 10 | CPE_NAME="cpe:/o:centos:centos:7" 11 | HOME_URL="https://www.centos.org/" 12 | BUG_REPORT_URL="https://bugs.centos.org/" 13 | 14 | CENTOS_MANTISBT_PROJECT="CentOS-7" 15 | CENTOS_MANTISBT_PROJECT_VERSION="7" 16 | REDHAT_SUPPORT_PRODUCT="centos" 17 | REDHAT_SUPPORT_PRODUCT_VERSION="7" 18 | -------------------------------------------------------------------------------- /pkg/daemon/testdata/cmdline_test: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | intel_iommu=on 4 | iommu=pt 5 | -------------------------------------------------------------------------------- /pkg/daemon/testdata/cmdline_test_missing_param: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | intel_iommu=off 4 | iommu=pt 5 | -------------------------------------------------------------------------------- /pkg/daemon/testdata/node_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "sriov_fec_node_config": { 3 | "metadata": { 4 | "name": "worker", 5 | "namespace": "default" 6 | }, 7 | "spec": { 8 | "physicalFunctions": [ 9 | { 10 | "pciAddress": "0000:14:00.1", 11 | "pfDriver": "igb_uio", 12 | "vfDriver": "v", 13 | "vfAmount": 5, 14 | "bbDevConfig": { 15 | "n3000": { 16 | "networkType": "FPGA_LTE", 17 | "pfMode": false, 18 | "flrTimeout": 10, 19 | "downlink": { 20 | "bandwidth": 3, 21 | "loadBalance": 3, 22 | "queues": { 23 | "vf1": 1, 24 | "vf2": 2, 25 | "vf3": 3, 26 | "vf4": 4, 27 | "vf5": 5, 28 | "vf6": 6, 29 | "vf7": 7 30 | } 31 | }, 32 | "uplink": { 33 | "bandwidth": 2, 34 | "loadBalance": 2, 35 | "queues": { 36 | "vf1": 1, 37 | "vf2": 2, 38 | "vf3": 3, 39 | "vf4": 4, 40 | "vf5": 5, 41 | "vf6": 6, 42 | "vf7": 7 43 | } 44 | } 45 | } 46 | } 47 | } 48 | ] 49 | }, 50 | "status": { 51 | "inventory": { 52 | "sriovAccelerators": [ 53 | { 54 | "vendorID": "1", 55 | "deviceID": "0d8f", 56 | "pciAddress": "0000:14:00.1", 57 | "driver": "D3", 58 | "maxVirtualFunctions": 1, 59 | "virtualFunctions": [ 60 | { 61 | "pciAddress": "0000:14:00.1", 62 | "driver": "D3", 63 | "deviceID": "0d8f" 64 | } 65 | ] 66 | } 67 | ] 68 | } 69 | } 70 | }, 71 | "node": { 72 | "metadata": { 73 | "name": "worker", 74 | "labels": { 75 | "fpga.intel.com/intel-accelerator-present": "" 76 | } 77 | } 78 | }, 79 | "sriov_device_plugin_pod": { 80 | "metadata": { 81 | "name": "sriov-device-plugin", 82 | "namespace": "default", 83 | "labels": { 84 | "app": "sriov-device-plugin-daemonset" 85 | } 86 | }, 87 | "spec": { 88 | "nodeName": "worker", 89 | "containers": [ 90 | { 91 | "name": "sriov-device-plugin-container", 92 | "image": "image" 93 | } 94 | ] 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /pkg/daemon/testdata/rhcos_os_release: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | NAME="Red Hat Enterprise Linux CoreOS" 4 | VERSION="4.5" 5 | VERSION_ID="4.5" 6 | OPENSHIFT_VERSION="4.5" 7 | RHEL_VERSION="8.2" 8 | PRETTY_NAME="Red Hat Enterprise Linux CoreOS 4.5 (Ootpa)" 9 | ID="rhcos" 10 | ID_LIKE="rhel fedora" 11 | ANSI_COLOR="0;31" 12 | HOME_URL="https://www.redhat.com/" 13 | BUG_REPORT_URL="https://bugzilla.redhat.com/" 14 | REDHAT_BUGZILLA_PRODUCT="OpenShift Container Platform" 15 | REDHAT_BUGZILLA_PRODUCT_VERSION="4.5" 16 | REDHAT_SUPPORT_PRODUCT="OpenShift Container Platform" 17 | REDHAT_SUPPORT_PRODUCT_VERSION="4.5" 18 | OSTREE_VERSION='46.82.202006152120-0' 19 | -------------------------------------------------------------------------------- /pkg/daemon/testdata/rhel_os_release: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | NAME="Red Hat Enterprise Linux" 4 | VERSION="8.2 (Ootpa)" 5 | ID="rhel" 6 | ID_LIKE="fedora" 7 | VERSION_ID="8.2" 8 | PLATFORM_ID="platform:el8" 9 | PRETTY_NAME="Red Hat Enterprise Linux 8.2 (Ootpa)" 10 | ANSI_COLOR="0;31" 11 | CPE_NAME="cpe:/o:redhat:enterprise_linux:8.2:GA" 12 | HOME_URL="https://www.redhat.com/" 13 | BUG_REPORT_URL="https://bugzilla.redhat.com/" 14 | 15 | REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 8" 16 | REDHAT_BUGZILLA_PRODUCT_VERSION=8.2 17 | REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux" 18 | REDHAT_SUPPORT_PRODUCT_VERSION="8.2" 19 | -------------------------------------------------------------------------------- /pkg/daemon/testdata/unknown_os_release: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # Copyright (c) 2020-2025 Intel Corporation 3 | ID="unknown" 4 | -------------------------------------------------------------------------------- /spec/images/acc100-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/sriov-fec-operator/1268dcbe1ee19f9941d54105918ff67dd5acbcf0/spec/images/acc100-diagram.png -------------------------------------------------------------------------------- /spec/images/sriov_fec_operator_acc100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/sriov-fec-operator/1268dcbe1ee19f9941d54105918ff67dd5acbcf0/spec/images/sriov_fec_operator_acc100.png -------------------------------------------------------------------------------- /spec/openshift-deployment.md: -------------------------------------------------------------------------------- 1 | ## SPDX-License-Identifier: Apache-2.0 2 | ## Copyright (c) 2020-2025 Intel Corporation 3 | 4 | ## Technical Requirements and Dependencies 5 | 6 | The SRIOV-FEC Operator for Wireless FEC Accelerators has the following requirements: 7 | 8 | - [Intel® vRAN Dedicated Accelerator ACC100](https://builders.intel.com/docs/networkbuilders/intel-vran-dedicated-accelerator-acc100-product-brief.pdf) 9 | - [OpenShift 4.10.x](https://docs.openshift.com/container-platform/4.10/release_notes/ocp-4-10-release-notes.html) 10 | - RT Kernel configured with [Performance Addon Operator](https://access.redhat.com/documentation/en-us/openshift_container_platform/4.6/html/scalability_and_performance/cnf-performance-addon-operator-for-low-latency-nodes). 11 | - sriov-fec:2.3.0 comes with initial support of `vfio-pci` driver for ACC100. Configurations leveraging `vfio-pci` require following kernel parameters: 12 | - vfio_pci.enable_sriov=1 13 | - vfio_pci.disable_idle_d3=1 14 | - BIOS with enabled settings "Intel® Virtualization Technology for Directed I/O" (VT-d), "Single Root I/O Virtualization" (SR-IOV) and "Input–Output Memory Management Unit" (IOMMU) 15 | 16 | ### Install the Bundle 17 | 18 | To install the SRIOV-FEC Operator for Wireless FEC Accelerators operator bundle perform the following steps: 19 | 20 | Create the project: 21 | ```shell 22 | [user@ctrl1 /home]# oc new-project vran-acceleration-operators 23 | ``` 24 | Execute following commands on cluster: 25 | 26 | Create an operator group and the subscriptions (all the commands are run in the `vran-acceleration-operators` namespace): 27 | 28 | ```shell 29 | [user@ctrl1 /home]# cat <> #DDDDDD { 10 | 11 | class SriovFecClusterConfigList{ 12 | metav1.TypeMeta 13 | metav1.ListMeta 14 | Items []SriovFecClusterConfig 15 | } 16 | 17 | class SriovFecClusterConfig{ 18 | metav1.TypeMeta 19 | metav1.ObjectMeta 20 | 21 | Spec SriovFecClusterConfigSpec 22 | Status SriovFecClusterConfigStatus 23 | } 24 | 25 | class SriovFecClusterConfigSpec { 26 | NodeSelector map[string]string 27 | 28 | AcceleratorSelector SriovAcceleratorSelector 29 | 30 | PhysicalFunction PhysicalFunctionConfig 31 | 32 | // Higher priority policies can override lower ones. 33 | Priority int 34 | 35 | DrainSkip bool 36 | } 37 | 38 | class SriovAcceleratorSelector { 39 | VendorID string 40 | DeviceID string 41 | PCIAddress string 42 | Driver string 43 | MaxVFs int 44 | } 45 | 46 | class SriovFecClusterConfigStatus { 47 | SyncStatus SyncStatus 48 | LastSyncError string 49 | } 50 | 51 | enum SyncStatus { 52 | InProgress 53 | Succeeded 54 | Ignored 55 | Failed 56 | } 57 | } 58 | 59 | package NodeConfig <> #DDDDDD { 60 | 61 | class SriovFecNodeConfigList { 62 | metav1.TypeMeta 63 | metav1.ListMeta 64 | Items []SriovFecNodeConfig 65 | } 66 | 67 | class SriovFecNodeConfig { 68 | metav1.TypeMeta 69 | metav1.ObjectMeta 70 | Spec SriovFecNodeConfigSpec 71 | Status SriovFecNodeConfigStatus 72 | } 73 | 74 | class SriovFecNodeConfigStatus { 75 | Conditions []metav1.Condition 76 | Inventory NodeInventory 77 | } 78 | 79 | class NodeInventory { 80 | SriovAccelerators []SriovAccelerator 81 | } 82 | 83 | class SriovAccelerator { 84 | VendorID string 85 | DeviceID string 86 | PCIAddress string 87 | Driver string 88 | MaxVFs int 89 | VFs []VF 90 | } 91 | 92 | class VF { 93 | PCIAddress string 94 | Driver string 95 | DeviceID string 96 | } 97 | 98 | class SriovFecNodeConfigSpec { 99 | PhysicalFunctions []PhysicalFunctionExtConfig 100 | DrainSkip bool 101 | } 102 | 103 | class PhysicalFunctionExtConfig { 104 | PCIAddress string 105 | } 106 | } 107 | 108 | package common <> { 109 | class PhysicalFunctionConfig { 110 | PFDriver string 111 | VFDriver string 112 | VFAmount int 113 | BBDevConfig BBDevConfig 114 | } 115 | 116 | class BBDevConfig { 117 | ACC100 *ACC100BBDevConfig 118 | ACC200 *ACC200BBDevConfig 119 | } 120 | 121 | class ACC100BBDevConfig { 122 | PFMode bool 123 | NumVfBundles int 124 | MaxQueueSize int 125 | Uplink4G QueueGroupConfig 126 | Downlink4G QueueGroupConfig 127 | Uplink5G QueueGroupConfig 128 | Downlink5G QueueGroupConfig 129 | } 130 | 131 | class ACC200BBDevConfig { 132 | PFMode bool 133 | NumVfBundles int 134 | MaxQueueSize int 135 | Uplink4G QueueGroupConfig 136 | Downlink4G QueueGroupConfig 137 | Uplink5G QueueGroupConfig 138 | Downlink5G QueueGroupConfig 139 | QFFT QueueGroupConfig 140 | } 141 | 142 | class QueueGroupConfig { 143 | NumQueueGroups 144 | NumAqsPerGroups 145 | AqDepthLog2 int 146 | } 147 | } 148 | 149 | 150 | 151 | PhysicalFunctionConfig --> BBDevConfig 152 | BBDevConfig --> ACC100BBDevConfig 153 | BBDevConfig --> ACC200BBDevConfig 154 | ACC100BBDevConfig -- QueueGroupConfig 155 | ACC200BBDevConfig -- QueueGroupConfig 156 | PhysicalFunctionConfig <|---- PhysicalFunctionExtConfig 157 | PhysicalFunctionConfig <--- SriovFecClusterConfigSpec 158 | SriovFecClusterConfigSpec --> SriovAcceleratorSelector 159 | SriovFecClusterConfigList *-- SriovFecClusterConfig 160 | SriovFecClusterConfig --> SriovFecClusterConfigStatus 161 | SriovFecClusterConfig --> SriovFecClusterConfigSpec 162 | SriovFecClusterConfigStatus --> SyncStatus 163 | SriovAccelerator *-- VF 164 | SriovFecNodeConfigList *-- SriovFecNodeConfig 165 | SriovFecNodeConfig --> SriovFecNodeConfigStatus 166 | SriovFecNodeConfig --> SriovFecNodeConfigSpec 167 | SriovFecNodeConfigStatus --> NodeInventory 168 | NodeInventory *-- SriovAccelerator 169 | SriovFecNodeConfigSpec *-- PhysicalFunctionExtConfig 170 | 171 | 172 | @enduml 173 | -------------------------------------------------------------------------------- /spec/vran-accelerators-supported-by-operator.md: -------------------------------------------------------------------------------- 1 | ```text 2 | SPDX-License-Identifier: Apache-2.0 3 | Copyright (c) 2020-2025 Intel Corporation 4 | ``` 5 | 6 | # Intel's vRAN accelerators supported by SRIOV-FEC Operator on OpenShift 7 | 8 | - [Overview](#overview) 9 | - [Intel® vRAN Dedicated Accelerator ACC100](#intel-vran-dedicated-accelerator-acc100) 10 | - [Intel® vRAN Dedicated Accelerator ACC100 FlexRAN Host Interface Overview](#intel-vran-dedicated-accelerator-acc100-flexran-host-interface-overview) 11 | - [SRIOV-FEC Operator for Intel® vRAN Dedicated Accelerator ACC100](#sriov-fec-operator-for-intel-vran-dedicated-accelerator-acc100) 12 | - [Intel® ACC200 vRAN Dedicated Accelerator](#intel-vran-dedicated-accelerator-acc200) 13 | 14 | ## Overview 15 | 16 | This document details the Intel's vRAN accelerator devices/hardware supported by the [SRIOV-FEC Operator for Wireless FEC Accelerators](https://github.com/intel/sriov-fec-operator/blob/master/spec/openshift-sriov-fec-operator.md) in Red Hat's OpenShift Container Platform. 17 | 18 | ## Intel® vRAN Dedicated Accelerator ACC100 19 | 20 | Intel® vRAN Dedicated Accelerator ACC100 plays a key role in accelerating 4G and 5G Virtualized Radio Access Networks (vRAN) workloads, which in turn increases the overall compute capacity of a commercial, off-the-shelf platform. 21 | 22 | Intel® vRAN Dedicated Accelerator ACC100 provides the following features: 23 | 24 | - LDPC FEC processing for 3GPP 5G: 25 | - LDPC encoder/decoder 26 | - Code block CRC generation/checking 27 | - Rate matching/de-matching 28 | - HARQ buffer management 29 | - Turbo FEC processing for 3GPP 4G: 30 | - Turbo encoder/decoder 31 | - Code block CRC generation/checking 32 | - Rate matching/de-matching 33 | - Scalable to required system configuration 34 | - Hardware DMA support 35 | - Performance monitoring 36 | - Load balancing supported by the hardware queue manager (QMGR) 37 | - Interface through the DPDK BBDev library and APIs 38 | 39 | Intel® vRAN Dedicated Accelerator ACC100 benefits include: 40 | - Reduced platform power, E2E latency and Intel® CPU core count requirements as well as increase in cell capacity than existing programmable accelerator 41 | - Accelerates both 4G and 5G data concurrently 42 | - Lowers development cost using commercial off the shelf (COTS) servers 43 | - Accommodates space-constrained implementations via a low-profile PCIe* card form factor 44 | - Enables a variety of flexible FlexRAN deployments from small cell to macro to Massive 45 | MIMO networks 46 | - Supports extended temperature for the most challenging of RAN deployment scenarios 47 | 48 | For more information, see product brief in [Intel® vRAN Dedicated Accelerator ACC100](https://builders.intel.com/docs/networkbuilders/intel-vran-dedicated-accelerator-acc100-product-brief.pdf). 49 | 50 | ### Intel® vRAN Dedicated Accelerator ACC100 FlexRAN Host Interface Overview 51 | 52 | FlexRAN is a reference layer 1 pipeline of 4G eNb and 5G gNb on Intel® architecture. The FlexRAN reference pipeline consists of an L1 pipeline, optimized L1 processing modules, BBU pooling framework, cloud and cloud-native deployment support, and accelerator support for hardware offload. Intel® vRAN Dedicated Accelerator ACC100 card is used by FlexRAN to offload FEC (Forward Error Correction) for 4G and 5G. 53 | 54 | Intel® vRAN Dedicated Accelerator ACC100 card used in the FlexRAN solution exposes the following physical functions to the CPU host: 55 | - One FEC interface that can be used of 4G or 5G FEC acceleration 56 | - The LTE FEC IP components have turbo encoder/turbo decoder and rate matching/de-matching 57 | - The 5GNR FEC IP components have low-density parity-check (LDPC) Encoder / LDPC Decoder, rate matching/de-matching, and UL HARQ combining 58 | 59 | ![Intel® vRAN Dedicated Accelerator ACC100 support](images/acc100-diagram.png) 60 | 61 | ### SRIOV-FEC Operator for Intel® vRAN Dedicated Accelerator ACC100 62 | 63 | The role of the operator for the Intel® vRAN Dedicated Accelerator ACC100 card is to orchestrate and manage the resources/devices exposed by the card within the OpenShift cluster. The operator is a state machine which will configure the resources and then monitor them and act autonomously based on the user interaction. 64 | The operator design for Intel® vRAN Dedicated Accelerator ACC100 consist of: 65 | 66 | * [SRIOV-FEC Operator for Wireless FEC Accelerators](https://github.com/intel/sriov-fec-operator/blob/master/spec/sriov-fec-operator.md) 67 | 68 | # Intel® ACC200 vRAN Dedicated Accelerator 69 | 70 | The Intel® vRAN Dedicated Accelerator ACC200 peripheral enables cost-effective 4G and 5G next-generation virtualized Radio Access Network (vRAN) solutions integrated on Sapphire Rapids Edge Enhanced Processor (SPR-EE) Intel® 7 based Xeon® multi-core server processor. 71 | 72 | The ACC200 includes a 5G Low Density Parity Check (LDPC) encoder/decoder, rate match/dematch, Hybrid Automatic Repeat Request (HARQ) with access to DDR memory for buffer management, a 4G Turbo encoder/decoder, a Fast Fourier Transform (FFT) block providing DFT/iDFT processing offload for the 5G Sounding Reference Signal (SRS), a Queue Manager (QMGR), and a DMA subsystem. There is no dedicated on-card memory for HARQ, this is using coherent memory on the CPU side. 73 | --------------------------------------------------------------------------------