├── .github ├── ISSUE_TEMPLATE │ ├── cicd.yaml │ ├── minor_issue.yaml │ ├── report_a_bug.yaml │ └── request_a_feature.yaml ├── cspell.json ├── license_check.ini ├── pylintrc └── workflows │ ├── contributor-list.yaml │ ├── pr-doclint.yaml │ ├── pr-license-check.yaml │ ├── pr-node-check.yaml │ ├── pr-python-check.yaml │ └── pr-shell-check.yaml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── MAINTAINERS.md ├── README.md ├── SECURITY.md ├── cnap ├── core │ ├── __init__.py │ ├── crypto │ │ ├── __init__.py │ │ ├── qat.py │ │ ├── qat_params.py │ │ └── zip.py │ ├── engines │ │ ├── __init__.py │ │ └── tensorflow_engine.py │ ├── eventlog.py │ ├── filedb.py │ ├── frame.py │ ├── generated │ │ └── core │ │ │ └── protobuf │ │ │ └── frame_pb2.py │ ├── infereng.py │ ├── inferqueue.py │ ├── keybroker.py │ ├── metrics.py │ ├── model.py │ ├── modelprovider.py │ ├── pipeline.py │ ├── processors │ │ ├── __init__.py │ │ ├── category_list.py │ │ ├── postprocessor.py │ │ └── preprocessor.py │ ├── protobuf │ │ └── frame.proto │ ├── rtdb.py │ ├── stream.py │ └── streambroker.py ├── requirements-test.txt ├── requirements.txt ├── ui │ ├── .gitignore │ ├── .npmrc │ ├── README.md │ ├── index.html │ ├── package.json │ ├── public │ │ ├── CNAME │ │ ├── element-plus-logo-small.svg │ │ └── favicon.svg │ ├── src │ │ ├── App.vue │ │ ├── api │ │ │ ├── frame.d.ts │ │ │ ├── frame.js │ │ │ └── ppdb_api.ts │ │ ├── assets │ │ │ ├── carbon_footprint.png │ │ │ ├── cnap_logo.png │ │ │ ├── diverse_frameworks.png │ │ │ ├── pipeline_cloud_native_design.png │ │ │ ├── sample-video.png │ │ │ └── trusted_pipeline.png │ │ ├── components.d.ts │ │ ├── components │ │ │ ├── AppFooter.vue │ │ │ ├── AppHeader.vue │ │ │ ├── DetailView.vue │ │ │ └── StreamView.vue │ │ ├── composables │ │ │ ├── dark.ts │ │ │ └── index.ts │ │ ├── env.d.ts │ │ ├── main.ts │ │ ├── proto │ │ ├── router.ts │ │ ├── store │ │ │ └── index.ts │ │ ├── styles │ │ │ ├── element │ │ │ │ ├── dark.scss │ │ │ │ └── index.scss │ │ │ └── index.scss │ │ └── views │ │ │ ├── Dashboard.vue │ │ │ ├── Grafana.vue │ │ │ ├── Overview.vue │ │ │ └── Pipelines.vue │ ├── tsconfig.json │ └── vite.config.ts └── userv │ ├── __init__.py │ ├── inference.py │ ├── pipeline_server.py │ ├── streaming.py │ ├── uapp.py │ └── websocket_server.py ├── container ├── cnap-inference │ └── Dockerfile ├── cnap-ppdb │ └── Dockerfile ├── cnap-redis │ ├── Dockerfile │ ├── patches │ │ ├── idxd-reset.patch │ │ ├── idxd.h │ │ ├── redis_dto.patch │ │ └── test_runner_disable_shared_queues.patch │ └── redis.conf ├── cnap-spa │ └── Dockerfile ├── cnap-streaming │ └── Dockerfile └── cnap-wss │ └── Dockerfile ├── docs ├── How_to_Protect_AI_Models_in_Cloud_Native_Environments.md ├── KEDA.md ├── cnap-uses.png ├── cnap_arch.png ├── enable_dsa_offloading.md ├── enable_qat_offloading.md ├── resources │ ├── images │ │ └── class_uml │ │ │ ├── engines │ │ │ └── tensorflowengine.png │ │ │ ├── filedb.png │ │ │ ├── frame.png │ │ │ ├── infereng.png │ │ │ ├── inferqueue.png │ │ │ ├── model.png │ │ │ ├── pipeline.png │ │ │ ├── processors │ │ │ ├── postprocessor.png │ │ │ └── preprocessor.png │ │ │ ├── rtdb.png │ │ │ ├── stream.png │ │ │ └── streambroker.png │ └── pumls │ │ ├── engines │ │ └── tensorflowengine.puml │ │ ├── filedb.puml │ │ ├── frame.puml │ │ ├── infereng.puml │ │ ├── inferqueue.puml │ │ ├── model.puml │ │ ├── pipeline.puml │ │ ├── processors │ │ ├── postprocessor.puml │ │ └── preprocessor.puml │ │ ├── rtdb.puml │ │ ├── stream.puml │ │ ├── streambroker.puml │ │ └── style.puml └── secure-model-design.png ├── helm ├── inference │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── service.yaml │ │ └── servicemonitor.yaml │ └── values.yaml ├── pipelineapi │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── service.yaml │ │ └── tests │ │ │ └── test-connection.yaml │ └── values.yaml ├── redis-exporter │ ├── .helmignore │ ├── Chart.yaml │ ├── dashboards │ │ └── grafana_prometheus_redis_dashboard.json │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── configmap.yaml │ │ ├── deployment.yaml │ │ ├── service.yaml │ │ ├── servicemonitor.yaml │ │ └── tests │ │ │ └── test-connection.yaml │ └── values.yaml ├── redis │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── configmap.yaml │ │ ├── deployment.yaml │ │ ├── service.yaml │ │ └── tests │ │ │ └── test-connection.yaml │ └── values.yaml ├── stream │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ └── deployment.yaml │ └── values.yaml ├── ui │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ └── service.yaml │ └── values.yaml └── websocket │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── deployment.yaml │ ├── service.yaml │ └── tests │ │ └── test-connection.yaml │ └── values.yaml ├── k8s-manifests ├── grafana │ ├── configmaps │ │ ├── cnap-inference-dashboard-cm.yaml │ │ ├── grafana-config-cm.yaml │ │ └── keda-dashboard-cm.yaml │ ├── dashboards │ │ ├── cnap-inference.json │ │ └── keda.json │ └── patches │ │ └── grafana-patch.yaml ├── keda │ ├── infer_scale.yaml │ └── keda-service-monitor.yaml ├── plugin │ └── dsa │ │ └── config_dsa │ │ ├── configs │ │ ├── 1e1w-d.conf │ │ ├── 1e1w-s.conf │ │ ├── 4e1w-d.conf │ │ ├── 4e4w-d.conf │ │ └── 4e8w-d.conf │ │ └── setup_dsa.sh └── prometheus │ └── ClusterRole-All.yaml ├── tests ├── __init__.py ├── core │ ├── __init__.py │ ├── conftest.py │ ├── test_filedb.py │ ├── test_frame.py │ ├── test_infereng.py │ ├── test_inferqueue.py │ ├── test_metrics.py │ ├── test_model.py │ ├── test_pipeline.py │ ├── test_rtdb.py │ ├── test_stream.py │ └── test_streambroker.py └── userv │ ├── __init__.py │ ├── test_inference.py │ ├── test_pipeline_server.py │ ├── test_streaming.py │ ├── test_uapp.py │ └── test_websocket_server.py └── tools ├── common.sh ├── docker_image_manager.sh ├── helm_manager.sh ├── prerequisites └── k8s-setup.sh └── video_downloader.sh /.github/ISSUE_TEMPLATE/cicd.yaml: -------------------------------------------------------------------------------- 1 | name: CI/CD Issue 2 | description: Report an issue related to Continuous Integration or Continuous Deployment 3 | labels: kind/cicd 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | **We appreciate your contribution to improving our CI/CD processes.** 9 | Please provide detailed information to help us understand and address the issue efficiently. 10 | 11 | - type: textarea 12 | id: issue-summary 13 | attributes: 14 | label: Issue Summary 15 | description: | 16 | Briefly summarize the CI/CD issue you are experiencing. 17 | placeholder: "A concise overview of the issue..." 18 | validations: 19 | required: true 20 | 21 | - type: textarea 22 | id: issue-description 23 | attributes: 24 | label: Detailed Description 25 | description: | 26 | Provide a detailed description of the issue. Include what you were trying to accomplish and where the process failed. 27 | placeholder: "Detailed information about the issue, including specific errors or failures..." 28 | validations: 29 | required: true 30 | 31 | - type: textarea 32 | id: steps-to-reproduce 33 | attributes: 34 | label: Steps to Reproduce 35 | description: | 36 | List the steps to reproduce the issue. Be as specific as possible. 37 | placeholder: "Step-by-step instructions to reproduce the issue..." 38 | validations: 39 | required: true 40 | 41 | - type: textarea 42 | id: ci-cd-environment 43 | attributes: 44 | label: CI/CD Environment 45 | description: | 46 | Describe the CI/CD environment where the issue occurred (e.g., tools, versions, configurations). 47 | placeholder: "Details about the CI/CD environment..." 48 | validations: 49 | required: true 50 | 51 | - type: textarea 52 | id: logs-output 53 | attributes: 54 | label: Logs and Output 55 | description: | 56 | Provide any relevant logs or output data that can help diagnose the issue. 57 | placeholder: "Logs, console output, error messages..." 58 | validations: 59 | required: false 60 | 61 | - type: textarea 62 | id: additional-info 63 | attributes: 64 | label: Additional Information 65 | description: | 66 | Any other information that might be helpful, such as attempted solutions or workarounds. 67 | placeholder: "Any other useful information..." 68 | validations: 69 | required: false 70 | 71 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/minor_issue.yaml: -------------------------------------------------------------------------------- 1 | name: Minor Issue 2 | description: Report a minor issue or suggest a small fix 3 | labels: kind/small-fix 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | **Thank you for contributing to the cloud-native-ai-pipeline!** 9 | For small fixes or minor issues, please provide the following details to help us understand and address your concern promptly. 10 | 11 | - type: textarea 12 | id: description 13 | attributes: 14 | label: Description 15 | description: | 16 | Briefly describe the small fix or minor issue. 17 | placeholder: "A concise description of the issue or fix..." 18 | validations: 19 | required: true 20 | 21 | 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/report_a_bug.yaml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Create a bug report to help improve cloud-native-ai-pipeline 3 | labels: kind/bug 4 | body: 5 | - type: textarea 6 | id: problem 7 | attributes: 8 | label: What happened? 9 | description: | 10 | Please provide as much info as possible. Not doing so may result in your bug not being addressed in a timely manner. 11 | If this matter is security related, please disclose it privately via our security contact. 12 | validations: 13 | required: true 14 | 15 | - type: textarea 16 | id: expected 17 | attributes: 18 | label: What did you expect to happen? 19 | validations: 20 | required: true 21 | 22 | - type: textarea 23 | id: repro 24 | attributes: 25 | label: How can we reproduce it (as minimally and precisely as possible)? 26 | validations: 27 | required: true 28 | 29 | - type: textarea 30 | id: additional 31 | attributes: 32 | label: Anything else we need to know? 33 | 34 | - type: textarea 35 | id: pipelineVersion 36 | attributes: 37 | label: Cloud-Native AI Pipeline version commit 38 | value: | 39 | 40 | 41 | ```console 42 | # Provide version details here 43 | ``` 44 | 45 | 46 | validations: 47 | required: true 48 | 49 | - type: textarea 50 | id: kubernetesVersion 51 | attributes: 52 | label: Kubernetes version 53 | value: | 54 | 55 | 56 | # Specify cloud provider or indicate if it's a bare metal deployment 57 | 58 | 59 | validations: 60 | required: true 61 | 62 | - type: textarea 63 | id: osVersion 64 | attributes: 65 | label: OS version 66 | value: | 67 | 68 | 69 | ```console 70 | $ cat /etc/os-release 71 | # paste output here 72 | $ uname -a 73 | # paste output here 74 | ``` 75 | 76 | 77 | validations: 78 | required: true 79 | 80 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/request_a_feature.yaml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Propose a new feature or enhancement for the cloud-native-ai-pipeline 3 | labels: kind/feature 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | **Thank you for your interest in improving the cloud-native-ai-pipeline!** 9 | We value your contributions and ideas. Please take a moment to share detailed information about your feature request. This helps us understand your vision and evaluate its potential impact. 10 | 11 | - type: textarea 12 | id: feature-summary 13 | attributes: 14 | label: Feature Summary 15 | description: | 16 | Provide a brief summary of the feature or enhancement you are proposing. 17 | placeholder: "A concise summary of the feature..." 18 | validations: 19 | required: true 20 | 21 | - type: textarea 22 | id: feature-detail 23 | attributes: 24 | label: Detailed Description 25 | description: | 26 | Elaborate on your feature idea. Include specific requirements, benefits, and any potential challenges. 27 | placeholder: "In-depth details about the feature, including any specific requirements..." 28 | validations: 29 | required: true 30 | 31 | - type: textarea 32 | id: motivation 33 | attributes: 34 | label: Motivation and Context 35 | description: | 36 | Explain the problem or need that this feature addresses. How does it benefit the users and the project? 37 | placeholder: "The problem or need the feature addresses..." 38 | validations: 39 | required: true 40 | 41 | - type: textarea 42 | id: use-cases 43 | attributes: 44 | label: Use Cases 45 | description: | 46 | Describe potential use cases for this feature. How would it be used and by whom? 47 | placeholder: "Examples of how the feature could be used..." 48 | validations: 49 | required: false 50 | 51 | - type: textarea 52 | id: alternatives 53 | attributes: 54 | label: Alternatives and Considerations 55 | description: | 56 | Have you considered any alternative solutions or features? Please share your thoughts on them. 57 | placeholder: "Alternative solutions or features considered..." 58 | validations: 59 | required: false 60 | 61 | - type: textarea 62 | id: additional-info 63 | attributes: 64 | label: Additional Information 65 | description: | 66 | Provide any other information or screenshots that could be helpful in understanding your request. 67 | placeholder: "Any other information or visual aids..." 68 | validations: 69 | required: false 70 | 71 | -------------------------------------------------------------------------------- /.github/cspell.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2", 3 | "ignorepaths": [ 4 | ".github/", 5 | ".git/" 6 | ], 7 | "ignorewords": [], 8 | "useGitignore": true, 9 | "language": "en", 10 | "import": [], 11 | "dictionarydefinitions": [], 12 | "dictionaries": [], 13 | "words": [ 14 | "cnap", 15 | "Dockerfile" 16 | "pipelineapi" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /.github/license_check.ini: -------------------------------------------------------------------------------- 1 | # Authorized and unauthorized licenses in LOWER CASE 2 | [Licenses] 3 | authorized_licenses: 4 | 3-clause bsd 5 | apache 6 | apache 2.0 7 | apache software 8 | apache software license 9 | apache-2.0 10 | bsd 11 | bsd license 12 | new bsd 13 | new bsd license 14 | simplified bsd 15 | gnu lesser general public license v3 or later (lgplv3+) 16 | gnu lgpl 17 | isc license 18 | isc license (iscl) 19 | lgpl with exceptions or zpl 20 | mit 21 | mit license 22 | mozilla public license 2.0 (mpl 2.0) 23 | python software foundation 24 | python software foundation license 25 | zpl 2.1 26 | 27 | unauthorized_licenses: 28 | gpl v3 29 | -------------------------------------------------------------------------------- /.github/workflows/contributor-list.yaml: -------------------------------------------------------------------------------- 1 | name: Add contributors 2 | on: 3 | workflow_dispatch: 4 | 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | contrib-readme-job: 10 | runs-on: ubuntu-latest 11 | name: A job to automate contrib in readme 12 | steps: 13 | - name: Contribute List 14 | uses: akhilmhdh/contributors-readme-action@v2.3.6 15 | env: 16 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 17 | -------------------------------------------------------------------------------- /.github/workflows/pr-doclint.yaml: -------------------------------------------------------------------------------- 1 | name: Document Scan 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - '**/*.md' 9 | pull_request: 10 | paths: 11 | - '**/*.md' 12 | workflow_dispatch: 13 | 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | scan_doc: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@v3 22 | - uses: streetsidesoftware/cspell-action@v2 23 | with: 24 | files: | 25 | **/*.md 26 | *.md 27 | config: .github/cspell.json 28 | verbose: true 29 | incremental_files_only: false 30 | -------------------------------------------------------------------------------- /.github/workflows/pr-license-check.yaml: -------------------------------------------------------------------------------- 1 | name: License Scan 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - 'cnap/**/requirements.txt' 9 | - 'cnap/**/requirements-test.txt' 10 | pull_request: 11 | paths: 12 | - 'cnap/**/requirements.txt' 13 | - 'cnap/**/requirements-test.txt' 14 | workflow_dispatch: 15 | 16 | permissions: 17 | contents: read 18 | 19 | jobs: 20 | codescan: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v3 24 | 25 | - uses: actions/setup-python@v4 26 | 27 | - name: Check License 28 | run: | 29 | set -ex 30 | python3 -m pip install --upgrade pip 31 | python3 -m pip install liccheck 32 | 33 | license_files=$(find -type f -name "requirements*.txt") 34 | if [[ -n "$license_files" ]]; then 35 | for f in $license_files; do 36 | python3 -m pip install -r $f 37 | liccheck -s .github/license_check.ini -r $f 38 | done 39 | else 40 | echo "No license files found." 41 | fi 42 | -------------------------------------------------------------------------------- /.github/workflows/pr-node-check.yaml: -------------------------------------------------------------------------------- 1 | name: UI Node Code Scan 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - 'cnap/ui/**' 9 | pull_request: 10 | paths: 11 | - 'cnap/ui/**' 12 | workflow_dispatch: 13 | 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | codescan: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Cleanup workspace for the job (self hosted only) 22 | run: | 23 | sudo rm -fr * 24 | 25 | - uses: actions/checkout@v3 26 | 27 | - name: Setup Node 28 | uses: actions/setup-node@v3 29 | with: 30 | node-version: "18" 31 | 32 | - name: Install Dependencies 33 | run: | 34 | cd cnap/ui/ 35 | npm install --registry=https://registry.npmmirror.com 36 | 37 | - name: Type Check 38 | run: | 39 | cd cnap/ui/ 40 | npm run typecheck 41 | -------------------------------------------------------------------------------- /.github/workflows/pr-python-check.yaml: -------------------------------------------------------------------------------- 1 | name: Python Code Scan 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - 'cnap/**/*.py' 9 | - 'tests/**/*.py' 10 | pull_request: 11 | paths: 12 | - 'cnap/**/*.py' 13 | - 'tests/**/*.py' 14 | workflow_dispatch: 15 | 16 | permissions: 17 | contents: read 18 | 19 | jobs: 20 | codescan: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v3 24 | 25 | - uses: actions/setup-python@v4 26 | 27 | - name: Install dependencies 28 | run: | 29 | python3 -m pip install --upgrade pip 30 | python3 -m pip install pylint pydocstyle 31 | python3 -m pip install -r ./cnap/requirements.txt 32 | python3 -m pip install -r ./cnap/requirements-test.txt 33 | sudo apt update 34 | sudo apt install redis 35 | 36 | - name: Analyze python code 37 | run: | 38 | set -ex 39 | export PYTHONPATH=$PWD/cnap:$PYTHONPATH 40 | python_files=$(find ./cnap -name "*.py" -print) 41 | if [[ -n "$python_files" ]]; then 42 | echo "$python_files" | xargs -n 1 python3 -m pylint --rcfile=.github/pylintrc 43 | echo "$python_files" | xargs -n 1 python3 -m pydocstyle --convention=google 44 | else 45 | echo "No python files found." 46 | fi 47 | 48 | - name: Analyze python test code 49 | run: | 50 | set -ex 51 | export PYTHONPATH=$PWD/cnap:$PYTHONPATH 52 | test_files=$(find ./tests -name "*.py" -print) 53 | if [[ -n "$test_files" ]]; then 54 | echo "$test_files" | xargs -n 1 python3 -m pylint --rcfile=.github/pylintrc 55 | else 56 | echo "No python test files found." 57 | fi 58 | 59 | - name: Run unit tests 60 | run: | 61 | set -ex 62 | export PYTHONPATH=$PWD/cnap:$PYTHONPATH 63 | python3 -m pytest --cov=cnap tests 64 | 65 | - name: Display detailed coverage report 66 | run: | 67 | coverage report -m 68 | -------------------------------------------------------------------------------- /.github/workflows/pr-shell-check.yaml: -------------------------------------------------------------------------------- 1 | name: Shell Code Scan 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - '**/*.sh' 9 | pull_request: 10 | paths: 11 | - '**/*.sh' 12 | workflow_dispatch: 13 | 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | codescan: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@v3 22 | - name: Run ShellCheck 23 | uses: ludeeus/action-shellcheck@master 24 | env: 25 | SHELLCHECK_OPTS: -e SC1091 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.pyd 3 | __pycache__/ 4 | dictionary.dic 5 | node_modules/ 6 | .coverage 7 | 8 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing guide 2 | 3 | ## Commit guidelines 4 | 5 | ### Subject line content 6 | 7 | The subject line of a commit should explain what files or topic in the project 8 | is being modified as well as the overall change that is being made. 9 | 10 | For example, if the overall documentation format is being changed to meet a new 11 | standard, a good subject line would be as follows: 12 | 13 | ``` 14 | documentation: rework to fit standard X 15 | ``` 16 | 17 | Another example, if a specific documentation file is being changed to fix 18 | spelling errors, a good subject line would be as follows: 19 | 20 | ``` 21 | documentation/some-file.md: fix spelling errors 22 | ``` 23 | 24 | ### Subject line format 25 | 26 | The subject line should be no longer than 72 characters. Past this it will wrap 27 | when reading via a standard sized terminal. If the changes cannot be summarized 28 | in that length then the commit is likely better split into multiple commits. 29 | 30 | The `topic: summary of what changed` format is preferred but will not be 31 | enforced. As long as it includes the topic and a summary of what changed it is 32 | acceptable. 33 | 34 | ### Body content 35 | 36 | The body of the commit should explain the why the commit is needed or wanted. 37 | 38 | The body may also give more detail on what is being changed or how it is being 39 | changed. 40 | 41 | With simple and obvious commits this is not always necessary and the body of the 42 | commit may be omitted. 43 | 44 | ### Body format 45 | 46 | Body text should usually not go past 72 characters per line. This is not a hard 47 | rule and can be broken where appropriate. For example, if error text is included 48 | in the commit body and is longer than 72 characters, it does not need to be 49 | broken into shorter lines. 50 | -------------------------------------------------------------------------------- /MAINTAINERS.md: -------------------------------------------------------------------------------- 1 | # MAINTAINERS 2 | 3 | ## Introduction 4 | 5 | This document lists the maintainers of Cloud Native AI Pipeline (CNAP), their roles, and their areas of responsibility. Maintainers are key contributors who are responsible for driving the project forward, ensuring its health, and supporting the community. 6 | 7 | ## Current Maintainers 8 | 9 | ### [Lu, Ken] 10 | 11 | - **GitHub Handle**: @kenplusplus 12 | 13 | - **Role**: Maintainer 14 | 15 | ### [Yao, Le] 16 | 17 | - **GitHub Handle**: @leyao-daily 18 | 19 | - **Role**: Maintainer 20 | 21 | ### [Hu, Longyin] 22 | 23 | - **GitHub Handle**: @Hulongyin 24 | 25 | - **Role**: Maintainer 26 | 27 | ### [Dong, Xiaocheng] 28 | 29 | - **GitHub Handle**: @dongx1x 30 | 31 | - **Role**: Maintainer 32 | 33 | ## Becoming a Maintainer 34 | 35 | ### Criteria for Becoming a Maintainer 36 | 37 | - Consistent contributions to the project (code, documentation, etc.) 38 | - Active participation in code reviews and discussions 39 | - Demonstrated understanding of the project's goals and technical aspects 40 | 41 | ### Process for Becoming a Maintainer 42 | 43 | - Current maintainers nominate new maintainers based on the above criteria. 44 | - A majority of current maintainers must approve the nomination. 45 | - New maintainers are formally announced and added to this document. 46 | 47 | ## Maintainer Responsibilities 48 | 49 | ### Code Reviews and Merging 50 | 51 | - Ensure that contributions align with the project's standards and goals. 52 | - Provide timely and constructive feedback on pull requests. 53 | 54 | ### Issue and Discussion Moderation 55 | 56 | - Respond to and manage issues and discussions in a respectful and timely manner. 57 | - Facilitate community engagement and collaboration. 58 | 59 | ### Release Management 60 | 61 | - Coordinate and oversee the release process, including versioning and release notes. 62 | 63 | ### Community Engagement 64 | 65 | - Act as an ambassador for the project, engaging with the community and promoting the project's growth and reputation. 66 | 67 | ## Stepping Down as a Maintainer 68 | 69 | - If a maintainer chooses to step down, they should inform the other maintainers with as much notice as possible. 70 | - Responsibilities will be reassigned, and the `MAINTAINERS.md` file will be updated accordingly. 71 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | Intel is committed to rapidly addressing security vulnerabilities affecting our customers and providing clear guidance on the solution, impact, severity and mitigation. 3 | 4 | ## Reporting a Vulnerability 5 | 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). 6 | -------------------------------------------------------------------------------- /cnap/core/__init__.py: -------------------------------------------------------------------------------- 1 | """The core package. 2 | 3 | This package contains the core components of CNAP, including the 4 | implementations of engines, processors, stream brokers, etc. 5 | """ 6 | -------------------------------------------------------------------------------- /cnap/core/crypto/__init__.py: -------------------------------------------------------------------------------- 1 | """The core.crypto package. 2 | 3 | This package contains the implementations of compression and decompression, 4 | which are used to process the frame. 5 | """ 6 | -------------------------------------------------------------------------------- /cnap/core/crypto/zip.py: -------------------------------------------------------------------------------- 1 | """A Zip module. 2 | 3 | This module provides a class to compress/decompress of frames. 4 | 5 | Classes: 6 | ZipBase: An abstract base class for creating custom zip implementations. 7 | CPUZip: A concrete class implementing compress and decompress frame with CPU. 8 | """ 9 | import gzip 10 | import time 11 | import logging 12 | from abc import ABC, abstractmethod 13 | LOG = logging.getLogger(__name__) 14 | 15 | class ZipBase(ABC): 16 | """An Abstract base class for creating custom zip implementations. 17 | 18 | This class serves as a blueprint for subclass that need to implement `compress` 19 | and `decompress` method for different accelerators. 20 | """ 21 | 22 | def __init__(self): 23 | """Initialize a ZipBase object.""" 24 | 25 | def __del__(self): 26 | """Destroy a ZipBase object.""" 27 | 28 | @abstractmethod 29 | def compress(self, src: bytes) -> bytes: 30 | """Compress. 31 | 32 | The method is to compress frame. 33 | 34 | Args: 35 | src (bytes): Frame that need to be compressed. 36 | 37 | Returns: 38 | bytes: Compressed Frame. 39 | 40 | Raises: 41 | NotImplementedError: If the subclasses don't implement the method. 42 | OverflowError: If compression integer overflow occurs. 43 | ValueError: If the compression input length is invalid. 44 | RuntimeError: If any error occurs during compression. 45 | """ 46 | raise NotImplementedError("Subclasses should implement connect() method.") 47 | 48 | @abstractmethod 49 | def decompress(self, src: bytes) -> bytes: 50 | """Decompress. 51 | 52 | The method is to decompress frame. 53 | 54 | Args: 55 | src (bytes): Frame that need to be decompressed. 56 | 57 | Returns: 58 | bytes: Decompressed Frame. 59 | 60 | Raises: 61 | NotImplementedError: If the subclasses don't implement the method. 62 | RuntimeError: If any error occurs during decompression 63 | """ 64 | raise NotImplementedError("Subclasses should implement connect() method.") 65 | 66 | 67 | class CPUZip(ZipBase): 68 | """A class that use CPU to compress and decompress.""" 69 | 70 | def __init__(self): 71 | """Initialize a CPUZip object.""" 72 | 73 | def __del__(self): 74 | """Destroy a CPUZip object.""" 75 | 76 | def compress(self, src: bytes) -> bytes: 77 | """See base class.""" 78 | start_time = time.time() 79 | #use gzip to compress 80 | dst =gzip.compress(src) 81 | 82 | end_time= time.time() 83 | time_cost = end_time -start_time 84 | LOG.debug("compress %d bytes in %d bytes, cost %fs", len(src), len(dst), time_cost) 85 | return dst 86 | 87 | def decompress(self, src: bytes) -> bytes: 88 | """See base class.""" 89 | start_time = time.time() 90 | #use gzip to decompress 91 | dst =gzip.decompress(src) 92 | 93 | end_time= time.time() 94 | time_cost = end_time - start_time 95 | LOG.debug("decompress %d bytes in %d bytes, cost %fs", len(src), len(dst), time_cost) 96 | return dst 97 | -------------------------------------------------------------------------------- /cnap/core/engines/__init__.py: -------------------------------------------------------------------------------- 1 | """The core.engines package. 2 | 3 | This package contains the implementations of engines, which are used 4 | to run the model inference. 5 | """ 6 | -------------------------------------------------------------------------------- /cnap/core/eventlog.py: -------------------------------------------------------------------------------- 1 | """A EventLog module. 2 | 3 | This module provides functions related to event log processing. The event log can be fetched by 4 | Confidential Cloud-Native Primitives (CCNP), and is defined according to several tcg supported event 5 | log formats defined in TCG_PCClient Spec, Canonical Eventlog Spec, etc. 6 | 7 | CCNP: https://github.com/cc-api/confidential-cloud-native-primitives 8 | TCG_PCClient Spec: 9 | https://trustedcomputinggroup.org/wp-content/uploads/TCG_PCClientSpecPlat_TPM_2p0_1p04_pub.pdf 10 | Canonical Eventlog Spec: 11 | https://trustedcomputinggroup.org/wp-content/uploads/TCG_IWG_CEL_v1_r0p41_pub.pdf 12 | 13 | Functions: 14 | replay_event_log: Replay event logs by IMR index. 15 | verify_event_log: Verify event log by comparing IMR value from CCNP fetching and replayed from 16 | event log. 17 | """ 18 | import logging 19 | import base64 20 | from hashlib import sha1, sha256, sha384, sha512 21 | 22 | from ccnp import CcnpSdk 23 | from cctrusted_base.tcg import TcgAlgorithmRegistry 24 | 25 | LOG = logging.getLogger(__name__) 26 | 27 | IMR_VERIFY_COUNT = 3 28 | 29 | def replay_event_log(event_logs) -> dict: 30 | """Replay event logs by Integrated Measurement Register (IMR) index. 31 | 32 | Args: 33 | event_logs: Event logs fetched by CCNP. 34 | 35 | Returns: 36 | dict: A dictionary containing the replay result displayed by IMR index and hash algorithm. 37 | Layer 1 key of the dict is the IMR index, the value is another dict which using the hash 38 | algorithm as the key and the replayed measurement as value. 39 | Sample value: 40 | { 0: { 12: }} 41 | """ 42 | measurement_dict = {} 43 | for event_log in event_logs: 44 | # pylint: disable-next=consider-iterating-dictionary 45 | if event_log.reg_idx not in measurement_dict.keys(): 46 | measurement_dict[event_log.reg_idx] = {} 47 | 48 | alg_id = event_log.alg_id.algo_id 49 | # Check algorithm type and prepare for replay 50 | if alg_id == TcgAlgorithmRegistry.TPM_ALG_SHA1: 51 | algo = sha1() 52 | elif alg_id == TcgAlgorithmRegistry.TPM_ALG_SHA384: 53 | algo = sha384() 54 | elif alg_id == TcgAlgorithmRegistry.TPM_ALG_SHA256: 55 | algo = sha256() 56 | elif alg_id == TcgAlgorithmRegistry.TPM_ALG_SHA512: 57 | algo = sha512() 58 | else: 59 | LOG.error("Unsupported hash algorithm %d", alg_id) 60 | continue 61 | 62 | # Initialize value if alg_id not found in dict 63 | if alg_id not in measurement_dict[event_log.reg_idx].keys(): 64 | measurement_dict[event_log.reg_idx][alg_id] = bytearray( 65 | event_log.alg_id.digest_size) 66 | 67 | # Do replay and update the result into dict 68 | digest = list(map(int, event_log.digest.strip('[]').split(' '))) 69 | # pylint: disable-next=consider-using-f-string 70 | digest_hex = ''.join('{:02x}'.format(i) for i in digest) 71 | algo.update(measurement_dict[event_log.reg_idx][alg_id] + bytes.fromhex(digest_hex)) 72 | measurement_dict[event_log.reg_idx][alg_id] = algo.digest() 73 | 74 | return measurement_dict 75 | 76 | def verify_event_log(measurement_dict: dict) -> bool: 77 | """Verify event log by comparing IMR value from CCNP fetching and replayed via event log. 78 | 79 | IMR: Integrated Measurement Register. 80 | 81 | Args: 82 | measurement_dict (dict): The event logs replay result displayed by IMR index and hash 83 | algorithm. 84 | 85 | Returns: 86 | bool: True if event log verify success, False if event log verify failed. 87 | """ 88 | LOG.info("Verify IMR measurement value and replayed value from event logs") 89 | for index in range(IMR_VERIFY_COUNT): 90 | # Fectch IMR measurement 91 | LOG.info("Fetch measurements in IMR[%d]", index) 92 | imr_measurement = base64.b64decode(CcnpSdk.inst().get_cc_measurement( 93 | [index, 12])) 94 | LOG.info("IMR[%d](measurement): %s", index, imr_measurement.hash.hex()) 95 | 96 | # Get IMR value from replayed event log 97 | if index not in measurement_dict or measurement_dict[index] == {}: 98 | LOG.error("IMR[%d] verify failed, the replayed value from event logs doesn't exist", 99 | index) 100 | return False 101 | for value in measurement_dict[index].values(): 102 | imr_replayed = value 103 | break 104 | 105 | LOG.info("IMR[%d](replayed): %s", index, imr_replayed.hash.hex()) 106 | if imr_measurement == imr_replayed: 107 | LOG.info("IMR[%d] passed the verification.", index) 108 | else: 109 | LOG.error("IMR[%d] did not pass the verification.", index) 110 | return False 111 | 112 | return True 113 | -------------------------------------------------------------------------------- /cnap/core/filedb.py: -------------------------------------------------------------------------------- 1 | """A FileDatabase module. 2 | 3 | This module provides an object-oriented design for a file database to load video files. 4 | 5 | Classes: 6 | FileDatabase: An abstract base class for creating custom filedatabase implementations. 7 | LocalFileDatabase: A concrete class implementing the FileDatabase for local file operations. 8 | """ 9 | 10 | import os 11 | import logging 12 | from abc import ABC, abstractmethod 13 | 14 | LOG = logging.getLogger(__name__) 15 | 16 | class FileDatabase(ABC): 17 | """An abstract base class for creating custom file database implementations. 18 | 19 | This class serves as a blueprint for subclasses that need to implement 20 | the `get_file` method for different types of file databases. 21 | """ 22 | 23 | @abstractmethod 24 | def __init__(self): # pragma: no cover 25 | """Initialize the FileDatabase object.""" 26 | 27 | @abstractmethod 28 | def get_file(self, filename: str) -> str: # pragma: no cover 29 | """Abstract method for getting a file from the file database. 30 | 31 | This method is expected to retrieve a file from the file database and return 32 | the local path for the file. 33 | 34 | Args: 35 | filename (str): The name of the file to get. 36 | 37 | Returns: 38 | str: The local path for the file. 39 | 40 | Raises: 41 | NotImplementedError: if the subclass does not implement this method. 42 | """ 43 | raise NotImplementedError("Subclasses should implement get_file() method.") 44 | 45 | class LocalFileDatabase(FileDatabase): 46 | """A concrete class implementing the FileDatabase for local file operations. 47 | 48 | This class uses local filesystem to implement the `get_file` method 49 | defined in the `FileDatabase` abstract base class. 50 | 51 | Attributes: 52 | _root_dir (str): The root directory path for local file operations. 53 | """ 54 | 55 | def __init__(self, root_dir: str): 56 | """Initializes the LocalFileDatabase with a given root directory. 57 | 58 | This constructor initializes the LocalFileDatabase with a given root directory 59 | for local file operations. 60 | 61 | Args: 62 | root_dir (str): The root directory path for local file operations. 63 | """ 64 | self._root_dir = os.path.abspath(root_dir) 65 | 66 | def get_file(self, filename: str) -> str: 67 | """Gets the local path for a file. 68 | 69 | This method uses the root directory to find the given file and returns 70 | its local path. 71 | 72 | Args: 73 | filename (str): The name of the file to get. 74 | 75 | Returns: 76 | str: The local path for the file. 77 | 78 | Raises: 79 | FileNotFoundError: If the root_dir is invalid or failed to find the given file. 80 | """ 81 | if not os.path.exists(self._root_dir): 82 | LOG.error("Invalid root directory for local file database.") 83 | raise FileNotFoundError("Invalid root directory for local file database.") 84 | 85 | filepath = os.path.join(self._root_dir, filename) 86 | if not os.path.exists(filepath): 87 | LOG.error("Failed to find the given file %s at %s", 88 | filename, self._root_dir) 89 | raise FileNotFoundError(f"Failed to find the given file {filename} at {self._root_dir}") 90 | return filepath 91 | -------------------------------------------------------------------------------- /cnap/core/generated/core/protobuf/frame_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # source: core/protobuf/frame.proto 4 | """Generated protocol buffer code.""" 5 | from google.protobuf import descriptor as _descriptor 6 | from google.protobuf import descriptor_pool as _descriptor_pool 7 | from google.protobuf import symbol_database as _symbol_database 8 | from google.protobuf.internal import builder as _builder 9 | # @@protoc_insertion_point(imports) 10 | 11 | _sym_db = _symbol_database.Default() 12 | 13 | 14 | 15 | 16 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19\x63ore/protobuf/frame.proto\"\xa5\x01\n\x0c\x46rameMessage\x12\x13\n\x0bpipeline_id\x18\x01 \x01(\t\x12\x10\n\x08sequence\x18\x02 \x01(\x03\x12\x0b\n\x03raw\x18\x03 \x01(\x0c\x12\x0e\n\x06ts_new\x18\x04 \x01(\x01\x12\x12\n\nraw_height\x18\x05 \x01(\x05\x12\x11\n\traw_width\x18\x06 \x01(\x05\x12\x14\n\x0craw_channels\x18\x07 \x01(\x05\x12\x14\n\x0cts_infer_end\x18\x08 \x01(\x01\x62\x06proto3') 17 | 18 | _globals = globals() 19 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) 20 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'core.protobuf.frame_pb2', _globals) 21 | if _descriptor._USE_C_DESCRIPTORS == False: 22 | DESCRIPTOR._options = None 23 | _globals['_FRAMEMESSAGE']._serialized_start=30 24 | _globals['_FRAMEMESSAGE']._serialized_end=195 25 | # @@protoc_insertion_point(module_scope) 26 | -------------------------------------------------------------------------------- /cnap/core/processors/__init__.py: -------------------------------------------------------------------------------- 1 | """The core.processors package. 2 | 3 | This package contains the implementations of processors, which are used 4 | to process the output from model inference. 5 | """ 6 | -------------------------------------------------------------------------------- /cnap/core/processors/category_list.py: -------------------------------------------------------------------------------- 1 | """A dictionary object representing the drawing category list. 2 | 3 | This dictionary object maps the category ID to the category name. 4 | """ 5 | 6 | CategoryList = { 7 | 1: 'person', 8 | 2: 'bicycle', 9 | 3: 'car', 10 | 4: 'motorcycle', 11 | 5: 'airplane', 12 | 6: 'bus', 13 | 7: 'train', 14 | 8: 'truck', 15 | 9: 'boat', 16 | 10: 'traffic light', 17 | 11: 'fire hydrant', 18 | 13: 'stop sign', 19 | 14: 'parking meter', 20 | 15: 'bench', 21 | 16: 'bird', 22 | 17: 'cat', 23 | 18: 'dog', 24 | 19: 'horse', 25 | 20: 'sheep', 26 | 21: 'cow', 27 | 22: 'elephant', 28 | 23: 'bear', 29 | 24: 'zebra', 30 | 25: 'giraffe', 31 | 27: 'backpack', 32 | 28: 'umbrella', 33 | 31: 'handbag', 34 | 32: 'tie', 35 | 33: 'suitcase', 36 | 34: 'frisbee', 37 | 35: 'skis', 38 | 36: 'snowboard', 39 | 37: 'sports ball', 40 | 38: 'kite', 41 | 39: 'baseball bat', 42 | 40: 'baseball glove', 43 | 41: 'skateboard', 44 | 42: 'surfboard', 45 | 43: 'tennis racket', 46 | 44: 'bottle', 47 | 46: 'wine glass', 48 | 47: 'cup', 49 | 48: 'fork', 50 | 49: 'knife', 51 | 50: 'spoon', 52 | 51: 'bowl', 53 | 52: 'banana', 54 | 53: 'apple', 55 | 54: 'sandwich', 56 | 55: 'orange', 57 | 56: 'broccoli', 58 | 57: 'carrot', 59 | 58: 'hot dog', 60 | 59: 'pizza', 61 | 60: 'donut', 62 | 61: 'cake', 63 | 62: 'chair', 64 | 63: 'couch', 65 | 64: 'potted plant', 66 | 65: 'bed', 67 | 67: 'dining table', 68 | 70: 'toilet', 69 | 72: 'tv', 70 | 73: 'laptop', 71 | 74: 'mouse', 72 | 75: 'remote', 73 | 76: 'keyboard', 74 | 77: 'cell phone', 75 | 78: 'microwave', 76 | 79: 'oven', 77 | 80: 'toaster', 78 | 81: 'sink', 79 | 82: 'refrigerator', 80 | 84: 'book', 81 | 85: 'clock', 82 | 86: 'vase', 83 | 87: 'scissors', 84 | 88: 'teddy bear', 85 | 89: 'hair drier', 86 | 90: 'toothbrush' 87 | } 88 | -------------------------------------------------------------------------------- /cnap/core/processors/preprocessor.py: -------------------------------------------------------------------------------- 1 | """A Preprocessor module. 2 | 3 | This module provides an object-oriented design for preprocessing the input data 4 | for machine learning models. 5 | 6 | Classes: 7 | Preprocessor: An abstract base class for creating custom preprocessoring implementations. 8 | """ 9 | 10 | from abc import ABC, abstractmethod 11 | import numpy as np 12 | 13 | class Preprocessor(ABC): 14 | """An abstract base class for creating custom preprocessoring implementations. 15 | 16 | This class serves as a blueprint for subclasses that need to implement 17 | `preprocess` method for different types of preprocessing tasks. 18 | """ 19 | 20 | @abstractmethod 21 | def preprocess(self, frame: np.ndarray) -> np.ndarray: 22 | """Preprocess the input frame before feeding it to the model. 23 | 24 | Args: 25 | frame (np.ndarray): An np.ndarray object representing the input frame. 26 | 27 | Returns: 28 | np.ndarray: An np.ndarray object representing the preprocessed frame. 29 | 30 | Raises: 31 | NotImplementedError: If the subclasses don't implement the method. 32 | """ 33 | raise NotImplementedError("Subclasses should implement the preprocess() method.") 34 | -------------------------------------------------------------------------------- /cnap/core/protobuf/frame.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | message FrameMessage { 4 | string pipeline_id = 1; 5 | int64 sequence = 2; 6 | bytes raw = 3; 7 | double ts_new = 4; 8 | int32 raw_height = 5; 9 | int32 raw_width = 6; 10 | int32 raw_channels = 7; 11 | double ts_infer_end = 8; 12 | } 13 | -------------------------------------------------------------------------------- /cnap/requirements-test.txt: -------------------------------------------------------------------------------- 1 | docker 2 | pytest 3 | pytest-cov 4 | pytest-httpserver 5 | pytest-redis 6 | -------------------------------------------------------------------------------- /cnap/requirements.txt: -------------------------------------------------------------------------------- 1 | ccnp 2 | cctrusted_base 3 | Flask==3.0.0 4 | Flask-Cors==4.0.2 5 | kafka-python==2.0.2 6 | numpy==1.26.2 7 | opencv-python==4.8.1.78 8 | prometheus-client==0.18.0 9 | protobuf==4.23.4 10 | redis==5.0.1 11 | requests==2.32.0 12 | tensorflow==2.15.0 13 | websockets==12.0 14 | -------------------------------------------------------------------------------- /cnap/ui/.gitignore: -------------------------------------------------------------------------------- 1 | .vite-ssg-temp 2 | 3 | node_modules 4 | .DS_Store 5 | dist 6 | dist-ssr 7 | *.local 8 | 9 | # lock 10 | yarn.lock 11 | package-lock.json 12 | pnpm-lock.yaml 13 | 14 | *.log 15 | -------------------------------------------------------------------------------- /cnap/ui/.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | strict-peer-dependencies=false 3 | -------------------------------------------------------------------------------- /cnap/ui/README.md: -------------------------------------------------------------------------------- 1 | # Cloud Native AI Inference Pipeline 2 | 3 | ## Project setup 4 | 5 | ```bash 6 | npm install --registry=https://registry.npmmirror.com 7 | ``` 8 | 9 | ### Compiles and hot-reloads for development 10 | 11 | ```bash 12 | npm run dev 13 | ``` 14 | 15 | ### Compiles and minifies for production 16 | 17 | ```bash 18 | npm run build 19 | ``` 20 | -------------------------------------------------------------------------------- /cnap/ui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Cloud-Native AI Pipeline 8 | 9 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /cnap/ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cloud-native-ai-pipeline", 3 | "private": true, 4 | "version": "0.1.0", 5 | "scripts": { 6 | "dev": "npm run proto:generate && vite --host", 7 | "build": "npm run proto:generate && vite build", 8 | "generate": "npm run proto:generate && vite-ssg build", 9 | "preview": "npm run proto:generate && vite preview", 10 | "typecheck": "vue-tsc --noEmit", 11 | "proto:generate": "npx pbjs -t static-module -w es6 -o src/api/frame.js src/proto/frame.proto && npx pbts -o src/api/frame.d.ts src/api/frame.js" 12 | }, 13 | "dependencies": { 14 | "@types/axios": "^0.14.0", 15 | "@types/cors": "^2.8.16", 16 | "@types/express": "^4.17.21", 17 | "axios": "^1.6.2", 18 | "cors": "^2.8.5", 19 | "echarts": "^5.4.3", 20 | "element-plus": "^2.4.2", 21 | "eslint": "^8.54.0", 22 | "express": "^4.18.2", 23 | "nodemon": "^3.0.1", 24 | "npm": "^10.2.4", 25 | "uuid": "^9.0.1", 26 | "vue": "^3.3.8", 27 | "vue-router": "^4.2.5", 28 | "vue3-echarts": "^1.1.0", 29 | "vuex": "^4.1.0" 30 | }, 31 | "devDependencies": { 32 | "@iconify-json/ep": "^1.1.12", 33 | "@types/node": "^20.9.2", 34 | "@types/uuid": "^9.0.7", 35 | "@vitejs/plugin-vue": "^4.5.0", 36 | "less": "^4.2.0", 37 | "long": "^5.2.3", 38 | "protobufjs": "^7.2.5", 39 | "protobufjs-cli": "^1.1.2", 40 | "sass": "^1.69.5", 41 | "ts-node": "^10.9.1", 42 | "typescript": "^5.2.2", 43 | "unocss": "^0.57.6", 44 | "unplugin-vue-components": "^0.25.2", 45 | "vite": "^5.0.0", 46 | "vite-ssg": "^0.23.5", 47 | "vue-tsc": "1.8.22" 48 | }, 49 | "license": "MIT", 50 | "type": "module" 51 | } 52 | -------------------------------------------------------------------------------- /cnap/ui/public/CNAME: -------------------------------------------------------------------------------- 1 | cnap.pandora.intel.com 2 | -------------------------------------------------------------------------------- /cnap/ui/src/App.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 23 | 24 | 34 | -------------------------------------------------------------------------------- /cnap/ui/src/api/frame.d.ts: -------------------------------------------------------------------------------- 1 | import * as $protobuf from "protobufjs"; 2 | import Long = require("long"); 3 | /** Properties of a FrameMessage. */ 4 | export interface IFrameMessage { 5 | 6 | /** FrameMessage pipelineId */ 7 | pipelineId?: (string|null); 8 | 9 | /** FrameMessage sequence */ 10 | sequence?: (number|Long|null); 11 | 12 | /** FrameMessage raw */ 13 | raw?: (Uint8Array|null); 14 | 15 | /** FrameMessage tsNew */ 16 | tsNew?: (number|null); 17 | 18 | /** FrameMessage rawHeight */ 19 | rawHeight?: (number|null); 20 | 21 | /** FrameMessage rawWidth */ 22 | rawWidth?: (number|null); 23 | 24 | /** FrameMessage rawChannels */ 25 | rawChannels?: (number|null); 26 | 27 | /** FrameMessage tsInferEnd */ 28 | tsInferEnd?: (number|null); 29 | } 30 | 31 | /** Represents a FrameMessage. */ 32 | export class FrameMessage implements IFrameMessage { 33 | 34 | /** 35 | * Constructs a new FrameMessage. 36 | * @param [properties] Properties to set 37 | */ 38 | constructor(properties?: IFrameMessage); 39 | 40 | /** FrameMessage pipelineId. */ 41 | public pipelineId: string; 42 | 43 | /** FrameMessage sequence. */ 44 | public sequence: (number|Long); 45 | 46 | /** FrameMessage raw. */ 47 | public raw: Uint8Array; 48 | 49 | /** FrameMessage tsNew. */ 50 | public tsNew: number; 51 | 52 | /** FrameMessage rawHeight. */ 53 | public rawHeight: number; 54 | 55 | /** FrameMessage rawWidth. */ 56 | public rawWidth: number; 57 | 58 | /** FrameMessage rawChannels. */ 59 | public rawChannels: number; 60 | 61 | /** FrameMessage tsInferEnd. */ 62 | public tsInferEnd: number; 63 | 64 | /** 65 | * Creates a new FrameMessage instance using the specified properties. 66 | * @param [properties] Properties to set 67 | * @returns FrameMessage instance 68 | */ 69 | public static create(properties?: IFrameMessage): FrameMessage; 70 | 71 | /** 72 | * Encodes the specified FrameMessage message. Does not implicitly {@link FrameMessage.verify|verify} messages. 73 | * @param message FrameMessage message or plain object to encode 74 | * @param [writer] Writer to encode to 75 | * @returns Writer 76 | */ 77 | public static encode(message: IFrameMessage, writer?: $protobuf.Writer): $protobuf.Writer; 78 | 79 | /** 80 | * Encodes the specified FrameMessage message, length delimited. Does not implicitly {@link FrameMessage.verify|verify} messages. 81 | * @param message FrameMessage message or plain object to encode 82 | * @param [writer] Writer to encode to 83 | * @returns Writer 84 | */ 85 | public static encodeDelimited(message: IFrameMessage, writer?: $protobuf.Writer): $protobuf.Writer; 86 | 87 | /** 88 | * Decodes a FrameMessage message from the specified reader or buffer. 89 | * @param reader Reader or buffer to decode from 90 | * @param [length] Message length if known beforehand 91 | * @returns FrameMessage 92 | * @throws {Error} If the payload is not a reader or valid buffer 93 | * @throws {$protobuf.util.ProtocolError} If required fields are missing 94 | */ 95 | public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): FrameMessage; 96 | 97 | /** 98 | * Decodes a FrameMessage message from the specified reader or buffer, length delimited. 99 | * @param reader Reader or buffer to decode from 100 | * @returns FrameMessage 101 | * @throws {Error} If the payload is not a reader or valid buffer 102 | * @throws {$protobuf.util.ProtocolError} If required fields are missing 103 | */ 104 | public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): FrameMessage; 105 | 106 | /** 107 | * Verifies a FrameMessage message. 108 | * @param message Plain object to verify 109 | * @returns `null` if valid, otherwise the reason why it is not 110 | */ 111 | public static verify(message: { [k: string]: any }): (string|null); 112 | 113 | /** 114 | * Creates a FrameMessage message from a plain object. Also converts values to their respective internal types. 115 | * @param object Plain object 116 | * @returns FrameMessage 117 | */ 118 | public static fromObject(object: { [k: string]: any }): FrameMessage; 119 | 120 | /** 121 | * Creates a plain object from a FrameMessage message. Also converts values to other types if specified. 122 | * @param message FrameMessage 123 | * @param [options] Conversion options 124 | * @returns Plain object 125 | */ 126 | public static toObject(message: FrameMessage, options?: $protobuf.IConversionOptions): { [k: string]: any }; 127 | 128 | /** 129 | * Converts this FrameMessage to JSON. 130 | * @returns JSON object 131 | */ 132 | public toJSON(): { [k: string]: any }; 133 | 134 | /** 135 | * Gets the default type url for FrameMessage 136 | * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") 137 | * @returns The default type url 138 | */ 139 | public static getTypeUrl(typeUrlPrefix?: string): string; 140 | } 141 | -------------------------------------------------------------------------------- /cnap/ui/src/api/ppdb_api.ts: -------------------------------------------------------------------------------- 1 | 2 | export interface Pipeline { 3 | pipeline_id: string; 4 | model_name: string; 5 | stream_name: string; 6 | input_fps: number; 7 | infer_fps: number; 8 | }; 9 | -------------------------------------------------------------------------------- /cnap/ui/src/assets/carbon_footprint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/cnap/ui/src/assets/carbon_footprint.png -------------------------------------------------------------------------------- /cnap/ui/src/assets/cnap_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/cnap/ui/src/assets/cnap_logo.png -------------------------------------------------------------------------------- /cnap/ui/src/assets/diverse_frameworks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/cnap/ui/src/assets/diverse_frameworks.png -------------------------------------------------------------------------------- /cnap/ui/src/assets/pipeline_cloud_native_design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/cnap/ui/src/assets/pipeline_cloud_native_design.png -------------------------------------------------------------------------------- /cnap/ui/src/assets/sample-video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/cnap/ui/src/assets/sample-video.png -------------------------------------------------------------------------------- /cnap/ui/src/assets/trusted_pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/cnap/ui/src/assets/trusted_pipeline.png -------------------------------------------------------------------------------- /cnap/ui/src/components.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* prettier-ignore */ 3 | // @ts-nocheck 4 | // Generated by unplugin-vue-components 5 | // Read more: https://github.com/vuejs/core/pull/3399 6 | import '@vue/runtime-core' 7 | 8 | export {} 9 | 10 | declare module '@vue/runtime-core' { 11 | export interface GlobalComponents { 12 | AppFooter: typeof import('./components/AppFooter.vue')['default'] 13 | AppHeader: typeof import('./components/AppHeader.vue')['default'] 14 | DetailView: typeof import('./components/DetailView.vue')['default'] 15 | ElButton: typeof import('element-plus/es')['ElButton'] 16 | ElCard: typeof import('element-plus/es')['ElCard'] 17 | ElCarousel: typeof import('element-plus/es')['ElCarousel'] 18 | ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem'] 19 | ElCol: typeof import('element-plus/es')['ElCol'] 20 | ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider'] 21 | ElDialog: typeof import('element-plus/es')['ElDialog'] 22 | ElForm: typeof import('element-plus/es')['ElForm'] 23 | ElFormItem: typeof import('element-plus/es')['ElFormItem'] 24 | ElImage: typeof import('element-plus/es')['ElImage'] 25 | ElInput: typeof import('element-plus/es')['ElInput'] 26 | ElMenu: typeof import('element-plus/es')['ElMenu'] 27 | ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] 28 | ElRow: typeof import('element-plus/es')['ElRow'] 29 | ElText: typeof import('element-plus/es')['ElText'] 30 | RouterLink: typeof import('vue-router')['RouterLink'] 31 | RouterView: typeof import('vue-router')['RouterView'] 32 | StreamView: typeof import('./components/StreamView.vue')['default'] 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /cnap/ui/src/components/AppFooter.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | Created by Intel/SATG/SSE/Cloud Stack Solution Team 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 36 | -------------------------------------------------------------------------------- /cnap/ui/src/components/AppHeader.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | Overview 7 | 8 | 9 | Dashboard 10 | 11 | 12 | Pipelines 13 | 14 | 15 | Grafana 16 | 17 | 18 | 19 | Cloud-Native AI Pipeline 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | Cancel 41 | 42 | Confirm 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 75 | 76 | 87 | -------------------------------------------------------------------------------- /cnap/ui/src/components/StreamView.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ streamTitle }} 6 | 7 | 8 | 9 | 10 | 11 | 12 | 96 | 97 | 114 | -------------------------------------------------------------------------------- /cnap/ui/src/composables/dark.ts: -------------------------------------------------------------------------------- 1 | import { useDark, useToggle } from "@vueuse/core"; 2 | 3 | export const isDark = useDark(); 4 | export const toggleDark = useToggle(isDark); 5 | -------------------------------------------------------------------------------- /cnap/ui/src/composables/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./dark"; 2 | -------------------------------------------------------------------------------- /cnap/ui/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module "*.vue" { 4 | import { DefineComponent } from "vue"; 5 | // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types 6 | const component: DefineComponent<{}, {}, any>; 7 | export default component; 8 | } 9 | -------------------------------------------------------------------------------- /cnap/ui/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from "vue"; 2 | import App from "./App.vue"; 3 | import router from "./router"; 4 | import { initStore } from "./store"; 5 | 6 | // import "~/styles/element/index.scss"; 7 | 8 | // import ElementPlus from "element-plus"; 9 | // import all element css, uncommented next line 10 | // import "element-plus/dist/index.css"; 11 | 12 | // or use cdn, uncomment cdn link in `index.html` 13 | 14 | import "~/styles/index.scss"; 15 | import "uno.css"; 16 | 17 | // If you want to use ElMessage, import it. 18 | import "element-plus/theme-chalk/src/message.scss"; 19 | 20 | const app = createApp(App); 21 | initStore(app); 22 | // app.use(ElementPlus); 23 | app.use(router); 24 | app.mount("#app"); 25 | app.config.performance = true; 26 | -------------------------------------------------------------------------------- /cnap/ui/src/proto: -------------------------------------------------------------------------------- 1 | ../../core/protobuf/ -------------------------------------------------------------------------------- /cnap/ui/src/router.ts: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHistory } from 'vue-router' 2 | import Overview from './views/Overview.vue' 3 | 4 | export default createRouter({ 5 | history: createWebHistory(), 6 | routes: [ 7 | { 8 | path: '/', 9 | component: Overview, 10 | }, 11 | { 12 | path: '/dashboard', 13 | component: () => import('./views/Dashboard.vue'), 14 | }, 15 | { 16 | path: '/pipelines', 17 | component: () => import('./views/Pipelines.vue'), 18 | }, 19 | { 20 | path: '/grafana', 21 | component: () => import('./views/Grafana.vue'), 22 | }, 23 | ], 24 | }) 25 | -------------------------------------------------------------------------------- /cnap/ui/src/store/index.ts: -------------------------------------------------------------------------------- 1 | import { createStore } from 'vuex' 2 | import { App } from 'vue' 3 | import { Pipeline } from '../api/ppdb_api'; 4 | 5 | const store = createStore<{pipelines:Pipeline[], stream_urls:string[], now_time:string, 6 | pipeline_db_server:string, websocket_server:string, grafana_server:string}>({ 7 | state() { 8 | return { 9 | pipelines: [], 10 | stream_urls: [], 11 | now_time: "", 12 | // To prevent accidentally leaking env variables to the client, only variables prefixed 13 | // with `VITE_` are exposed to Vite-processed code. 14 | pipeline_db_server: 'http://' + get_env('VITE_PPDB_SERVER_HOST', window.location.hostname) 15 | + ':' + get_env('VITE_PPDB_SERVER_PORT', 31500) + '/events', 16 | websocket_server: 'ws://' + get_env('VITE_WS_SERVER_HOST', window.location.hostname) 17 | + ':' + get_env('VITE_WS_SERVER_PORT', 31611), 18 | grafana_server: 'http://' + get_env('VITE_GRAFANA_SERVER_HOST', window.location.hostname 19 | + ':' + get_env('VITE_GRAFANA_SERVER_PORT', 32000)) 20 | } 21 | }, 22 | mutations: { 23 | updatePipelines(state, payload) { 24 | state.pipelines = payload.pipelines 25 | state.stream_urls = payload.urls 26 | state.now_time = payload.now_time 27 | state.pipeline_db_server = payload.db_server 28 | state.websocket_server = payload.ws_server 29 | state.grafana_server = payload.gf_server 30 | }, 31 | cleanPipelines(state, payload) { 32 | state.pipelines = [] 33 | state.stream_urls = [] 34 | state.now_time = "" 35 | state.pipeline_db_server = payload.db_server 36 | state.websocket_server = payload.ws_server 37 | state.grafana_server = payload.gf_server 38 | } 39 | }, 40 | }); 41 | 42 | export const initStore = (app: App) => { 43 | app.use(store); 44 | } 45 | 46 | let eventSource: EventSource | null = null; 47 | let retries = 0; 48 | 49 | export const refreshPipeline = async (pipeline_db_url:string=store.state.pipeline_db_server, 50 | ws_server_url:string=store.state.websocket_server, 51 | gf_server_url:string=store.state.grafana_server) => { 52 | 53 | if (eventSource) { 54 | eventSource.close(); 55 | } 56 | console.log("SSE: Refresh pipeline from", pipeline_db_url); 57 | eventSource = new EventSource(pipeline_db_url); 58 | 59 | eventSource.onmessage = (event) => { 60 | const data = JSON.parse(event.data); 61 | let urls = []; 62 | for (let pipeline of data) { 63 | urls.push(ws_server_url + "/" + pipeline.pipeline_id); 64 | } 65 | 66 | let date = new Date(Date.parse(new Date().toString())); 67 | let now_time = format_time(date); 68 | 69 | store.commit('updatePipelines', { 70 | 'db_server': pipeline_db_url, 71 | 'ws_server': ws_server_url, 72 | 'gf_server': gf_server_url, 73 | 'pipelines': data, 74 | 'urls': urls, 75 | 'now_time': now_time 76 | }); 77 | 78 | retries = 0; 79 | }; 80 | 81 | eventSource.onerror = (error) => { 82 | console.error('EventSource failed:', error); 83 | store.commit('cleanPipelines', { 84 | 'db_server': pipeline_db_url, 85 | 'ws_server': ws_server_url, 86 | 'gf_server': gf_server_url 87 | }); 88 | 89 | let delay = Math.min(30, (Math.pow(2, retries) - 1)) * 1000; // Exponential backoff capped at 30 seconds 90 | retries++; 91 | 92 | setTimeout(() => { 93 | refreshPipeline(); 94 | }, delay); 95 | }; 96 | } 97 | 98 | export const closeEventSource = () => { 99 | if (eventSource) { 100 | eventSource.close(); 101 | eventSource = null; 102 | } 103 | } 104 | 105 | function format_time(date: Date) { 106 | const padZero = (num: number) => num < 10 ? `0${num}` : num.toString(); 107 | const hour = padZero(date.getHours()); 108 | const minute = padZero(date.getMinutes()); 109 | const second = padZero(date.getSeconds()); 110 | return `${hour}:${minute}:${second}`; 111 | } 112 | 113 | function get_env(key:string, default_vaule:any = null) { 114 | let value = import.meta.env[key]; 115 | if (value == null) { 116 | console.log("Cloud not find the key %s in environment, use default value %s", 117 | key, String(default_vaule)); 118 | return default_vaule; 119 | } 120 | return value; 121 | } 122 | -------------------------------------------------------------------------------- /cnap/ui/src/styles/element/dark.scss: -------------------------------------------------------------------------------- 1 | // only scss variables 2 | 3 | $--colors: ( 4 | "primary": ( 5 | "base": #589ef8, 6 | ), 7 | ); 8 | 9 | @forward "element-plus/theme-chalk/src/dark/var.scss" with ( 10 | $colors: $--colors 11 | ); 12 | -------------------------------------------------------------------------------- /cnap/ui/src/styles/element/index.scss: -------------------------------------------------------------------------------- 1 | $--colors: ( 2 | "primary": ( 3 | "base": green, 4 | ), 5 | "success": ( 6 | "base": #21ba45, 7 | ), 8 | "warning": ( 9 | "base": #f2711c, 10 | ), 11 | "danger": ( 12 | "base": #db2828, 13 | ), 14 | "error": ( 15 | "base": #db2828, 16 | ), 17 | "info": ( 18 | "base": #42b8dd, 19 | ), 20 | ); 21 | 22 | // we can add this to custom namespace, default is 'el' 23 | @forward "element-plus/theme-chalk/src/mixins/config.scss" with ( 24 | $namespace: "ep" 25 | ); 26 | 27 | // You should use them in scss, because we calculate it by sass. 28 | // comment next lines to use default color 29 | @forward "element-plus/theme-chalk/src/common/var.scss" with ( 30 | // do not use same name, it will override. 31 | $colors: $--colors, 32 | $button-padding-horizontal: ("default": 50px) 33 | ); 34 | 35 | // if you want to import all 36 | // @use "element-plus/theme-chalk/src/index.scss" as *; 37 | 38 | // You can comment it to hide debug info. 39 | // @debug $--colors; 40 | 41 | // custom dark variables 42 | @use "./dark.scss"; 43 | -------------------------------------------------------------------------------- /cnap/ui/src/styles/index.scss: -------------------------------------------------------------------------------- 1 | // import dark theme 2 | @use "element-plus/theme-chalk/src/dark/css-vars.scss" as *; 3 | 4 | // :root { 5 | // --ep-color-primary: red; 6 | // } 7 | 8 | body { 9 | font-family: "Verdana", "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", 10 | "Microsoft YaHei", "微软雅黑", Arial, sans-serif; 11 | -webkit-font-smoothing: antialiased; 12 | -moz-osx-font-smoothing: grayscale; 13 | margin: 0; 14 | } 15 | 16 | a { 17 | color: var(--ep-color-primary); 18 | } 19 | 20 | code { 21 | border-radius: 2px; 22 | padding: 2px 4px; 23 | background-color: var(--ep-color-primary-light-9); 24 | color: var(--ep-color-primary); 25 | } 26 | -------------------------------------------------------------------------------- /cnap/ui/src/views/Dashboard.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | {{ store.state.pipelines[index]['pipeline_id'] }} 14 | 15 | 16 | 17 | 18 | 19 | No pipeline found from database server 20 | 21 | {{ store.state.pipeline_db_server }} 22 | 23 | 24 | 25 | 26 | 43 | 44 | 82 | -------------------------------------------------------------------------------- /cnap/ui/src/views/Grafana.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 25 | -------------------------------------------------------------------------------- /cnap/ui/src/views/Overview.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | Cloud Native Design for Micro/Macro Bench 7 | 13 | 14 | 15 | Carbon Footprint for Kubernetes 16 | 22 | 23 | 24 | Trusted Design to Protect input and Model 25 | 31 | 32 | 33 | Landing on Diverse Cloud Native Framework 34 | 40 | 41 | 42 | 43 | 44 | 45 | 51 | 52 | 58 | -------------------------------------------------------------------------------- /cnap/ui/src/views/Pipelines.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 16 | 17 | 18 | 19 | 20 | 21 | No pipeline found from database server 22 | 23 | {{ store.state.pipeline_db_server }} 24 | 25 | 26 | 27 | 28 | 44 | 45 | 67 | -------------------------------------------------------------------------------- /cnap/ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "target": "esnext", 5 | "useDefineForClassFields": true, 6 | "module": "esnext", 7 | "moduleResolution": "node", 8 | "strict": true, 9 | "jsx": "preserve", 10 | "sourceMap": true, 11 | "resolveJsonModule": true, 12 | "esModuleInterop": true, 13 | "lib": ["esnext", "dom"], 14 | "paths": { 15 | "~/*": ["src/*"] 16 | }, 17 | "skipLibCheck": true, 18 | "noImplicitThis": false 19 | }, 20 | "vueCompilerOptions": { 21 | "target": 3, 22 | "jsxTemplates": true 23 | }, 24 | "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], 25 | "exclude": [ 26 | "node_modules/vue3-echarts/index.ts" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /cnap/ui/vite.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import { defineConfig } from 'vite' 3 | import vue from '@vitejs/plugin-vue' 4 | 5 | import Components from 'unplugin-vue-components/vite' 6 | import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' 7 | 8 | import Unocss from 'unocss/vite' 9 | import { 10 | presetAttributify, 11 | presetIcons, 12 | presetUno, 13 | transformerDirectives, 14 | transformerVariantGroup, 15 | } from 'unocss' 16 | 17 | const pathSrc = path.resolve(__dirname, 'src') 18 | 19 | // https://vitejs.dev/config/ 20 | export default defineConfig({ 21 | resolve: { 22 | alias: { 23 | '~/': `${pathSrc}/`, 24 | }, 25 | }, 26 | css: { 27 | preprocessorOptions: { 28 | scss: { 29 | additionalData: `@use "~/styles/element/index.scss" as *;`, 30 | }, 31 | }, 32 | }, 33 | plugins: [ 34 | vue(), 35 | Components({ 36 | // allow auto load markdown components under `./src/components/` 37 | extensions: ['vue', 'md'], 38 | // allow auto import and register components used in markdown 39 | include: [/\.vue$/, /\.vue\?vue/, /\.md$/], 40 | resolvers: [ 41 | ElementPlusResolver({ 42 | importStyle: 'sass', 43 | }), 44 | ], 45 | dts: 'src/components.d.ts', 46 | }), 47 | 48 | // https://github.com/antfu/unocss 49 | // see unocss.config.ts for config 50 | Unocss({ 51 | presets: [ 52 | presetUno(), 53 | presetAttributify(), 54 | presetIcons({ 55 | scale: 1.2, 56 | warn: true, 57 | }), 58 | ], 59 | transformers: [ 60 | transformerDirectives(), 61 | transformerVariantGroup(), 62 | ] 63 | }), 64 | ], 65 | build: { 66 | chunkSizeWarningLimit: 2000, 67 | rollupOptions: { 68 | output: { 69 | manualChunks(id) { 70 | if (id.includes('node_modules')) { 71 | return id.toString().split('node_modules/')[1].split('/')[0].toString(); 72 | } 73 | } 74 | } 75 | } 76 | } 77 | }) 78 | -------------------------------------------------------------------------------- /cnap/userv/__init__.py: -------------------------------------------------------------------------------- 1 | """The user micro service. 2 | 3 | The package contains the user micro service, which is responsible for 4 | handling user requests and responses. 5 | """ 6 | -------------------------------------------------------------------------------- /container/cnap-inference/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 as builder 2 | 3 | ARG DEBIAN_FRONTEND=noninteractive 4 | ARG QAT_DRIVER_RELEASE="QAT20.L.1.0.50-00003" 5 | ARG QAT_DRIVER_SHA256="41b45f936dc870299a00dffeeb1818774de1a3791d8fbb4365a5074a22f20017" 6 | ARG QATZIP_URL=https://github.com/intel/QATzip 7 | ARG QATZIP_VERSION="v1.1.2" 8 | 9 | RUN apt-get update && \ 10 | apt-get install -y --no-install-recommends libudev-dev build-essential make gcc g++ nasm \ 11 | pkg-config libssl-dev zlib1g-dev wget ca-certificates git yasm autoconf cmake libtool \ 12 | libboost-all-dev openssl haproxy liblz4-tool liblz4-dev && \ 13 | rm -rf /var/lib/apt/lists/* 14 | 15 | # QAT driver 16 | WORKDIR /home/project/QAT 17 | 18 | RUN wget https://downloadmirror.intel.com/783270/$QAT_DRIVER_RELEASE.tar.gz && \ 19 | echo "$QAT_DRIVER_SHA256 $QAT_DRIVER_RELEASE.tar.gz" | sha256sum -c - && \ 20 | tar -zxvf $QAT_DRIVER_RELEASE.tar.gz -C . && \ 21 | sed -i -e 's/cmn_ko$//' -e 's/lac_kernel$//' quickassist/Makefile && \ 22 | KERNEL_SOURCE_ROOT=/tmp ./configure --disable-param-check --prefix=/usr && \ 23 | make quickassist-all adf-ctl-all && \ 24 | install -m 755 build/libqat_s.so /usr/lib/ && \ 25 | install -m 755 build/libusdm_drv_s.so /usr/lib/ && \ 26 | install -m 755 build/adf_ctl /usr/bin/ 27 | 28 | # QATzip 29 | WORKDIR /home/project 30 | 31 | RUN git clone -b $QATZIP_VERSION $QATZIP_URL && \ 32 | cd QATzip && \ 33 | export ICP_ROOT=/home/project/QAT && \ 34 | export QZ_ROOT=/home/project/QATzip && \ 35 | ./autogen.sh && \ 36 | ./configure --with-ICP_ROOT=$ICP_ROOT --prefix=/usr && \ 37 | make install 38 | 39 | FROM intel/oneapi-aikit:2023.1.1-devel-ubuntu22.04 AS runner 40 | 41 | RUN useradd --create-home appuser 42 | 43 | ARG DEBIAN_FRONTEND=noninteractive 44 | 45 | RUN apt-get update && \ 46 | apt-get install -y --no-install-recommends libopencv-dev && \ 47 | apt-get autoremove -y && apt-get clean && rm -rf /var/lib/apt/lists/* 48 | 49 | ARG pip_mirror 50 | 51 | COPY ./cnap /cnap 52 | 53 | COPY --from=builder /usr/lib/libqat* /usr/lib/libusdm_drv_s.so /usr/lib 54 | 55 | COPY --from=builder /usr/bin/adf_ctl /usr/bin/qzip /usr/bin 56 | 57 | RUN chown -R appuser:appuser /cnap 58 | 59 | ENV PYTHONPATH="/cnap:${PYTHONPATH}" 60 | 61 | RUN /opt/intel/oneapi/tensorflow/latest/bin/pip install ${pip_mirror} \ 62 | --upgrade --no-cache-dir pip \ 63 | && /opt/intel/oneapi/tensorflow/latest/bin/pip install ${pip_mirror} \ 64 | --no-cache-dir redis>=4.3.0 kafka-python websockets opencv-python prometheus_client \ 65 | ccnp requests 66 | 67 | RUN date > /build-date.cnap-inference.txt 68 | 69 | EXPOSE 8000 70 | 71 | USER appuser 72 | 73 | CMD ["/opt/intel/oneapi/tensorflow/latest/bin/python", "/cnap/userv/inference.py"] 74 | -------------------------------------------------------------------------------- /container/cnap-ppdb/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.10-slim 2 | 3 | RUN useradd --create-home appuser 4 | 5 | COPY ./cnap /cnap 6 | 7 | RUN chown -R appuser:appuser /cnap 8 | 9 | ENV PYTHONPATH="/cnap:${PYTHONPATH}" 10 | 11 | ARG pip_mirror 12 | 13 | RUN pip3 install ${pip_mirror} --upgrade --no-cache-dir pip && \ 14 | pip3 install ${pip_mirror} --no-cache-dir flask flask_cors redis 15 | 16 | RUN date > /build-date.cnap-ppdb.txt 17 | 18 | EXPOSE 5000 19 | 20 | USER appuser 21 | 22 | CMD ["python", "/cnap/userv/pipeline_server.py"] 23 | -------------------------------------------------------------------------------- /container/cnap-redis/Dockerfile: -------------------------------------------------------------------------------- 1 | # base-OS-image for build 2 | ARG OS_VER=20.04 3 | ARG OS_IMAGE=ubuntu 4 | FROM ${OS_IMAGE}:${OS_VER} AS baseimage 5 | 6 | RUN apt-get update && DEBIAN_FRONTEND="noninteractive" TZ="America/Los_Angeles" apt-get install -y build-essential git cmake autoconf libtool pkg-config uuid-dev numactl libevent-dev asciidoc libjson-c-dev gdb curl libz-dev libssl-dev 7 | 8 | # accel for DSA 9 | ARG ACCEL_CONFIG_VERSION="4.0" 10 | ARG ACCEL_CONFIG_DOWNLOAD_URL="https://github.com/intel/idxd-config/archive/accel-config-v$ACCEL_CONFIG_VERSION.tar.gz" 11 | ARG ACCEL_CONFIG_SHA256="6d9bce40d797a87508ce5c5a5b71bb2bdc1cb544848925ed2c4c37b46a1252ce" 12 | 13 | RUN /bin/bash -c set -o pipefail && curl -fsSL "$ACCEL_CONFIG_DOWNLOAD_URL" -o accel-config.tar.gz && echo "$ACCEL_CONFIG_SHA256 accel-config.tar.gz" | sha256sum -c - && tar -xzf accel-config.tar.gz 14 | COPY container/cnap-redis/patches/*.patch / 15 | RUN cd idxd-config-accel-config-v$ACCEL_CONFIG_VERSION && \ 16 | patch -p1 < ../idxd-reset.patch && \ 17 | patch -p1 < ../test_runner_disable_shared_queues.patch && \ 18 | ./git-version-gen && \ 19 | autoreconf -i && \ 20 | ./configure -q --libdir=/usr/lib64 --enable-test=yes --disable-docs && \ 21 | make install 22 | 23 | # DTO 24 | ARG DTO_VERSION="1.0" 25 | ARG DTO_URL="https://github.com/intel/DTO/archive/refs/tags/v$DTO_VERSION.tar.gz" 26 | 27 | RUN curl -fsSL "$DTO_URL" -o dto.tar.gz && tar -xzf dto.tar.gz 28 | COPY container/cnap-redis/patches/idxd.h /usr/local/include/linux/ 29 | RUN cd DTO-$DTO_VERSION && \ 30 | make libdto && make install && \ 31 | cp lib* / 32 | 33 | # Redis 34 | ARG REDIS_VERSION="7.2.0" 35 | ARG REDIS_URL="https://github.com/redis/redis/archive/refs/tags/$REDIS_VERSION.tar.gz" 36 | RUN curl -fsSL "$REDIS_URL" -o redis.tar.gz && tar -xzf redis.tar.gz 37 | RUN cd redis-$REDIS_VERSION && \ 38 | make && \ 39 | cp src/redis-server /redis-server-orig && \ 40 | cp src/redis-cli /redis-cli && \ 41 | patch -p1 < ../redis_dto.patch && \ 42 | make clean && make && \ 43 | cp src/redis-server /redis-server-dto 44 | 45 | # target image with binaries and libraries 46 | FROM ${OS_IMAGE}:${OS_VER} AS redis 47 | 48 | RUN groupadd -r nonroot && useradd -r -g nonroot nonroot 49 | 50 | COPY --from=baseimage /usr/lib64/libaccel* /lib/x86_64-linux-gnu/ 51 | COPY --from=baseimage /libdto.so.1.0 /lib/x86_64-linux-gnu/ 52 | 53 | WORKDIR /opt 54 | RUN mkdir bin 55 | WORKDIR /opt/bin 56 | 57 | COPY --from=baseimage /usr/local/bin /opt/bin 58 | COPY container/cnap-redis/redis.conf /etc/redis.conf 59 | 60 | WORKDIR /opt 61 | RUN mkdir redis 62 | WORKDIR /opt/redis 63 | 64 | COPY --from=baseimage /redis-server* /opt/redis/ 65 | COPY --from=baseimage /redis-cli /usr/local/bin/ 66 | 67 | RUN ldconfig 68 | 69 | USER nonroot 70 | 71 | -------------------------------------------------------------------------------- /container/cnap-redis/patches/idxd-reset.patch: -------------------------------------------------------------------------------- 1 | From 07e1137a71021dc02df98b942a260b70ff852ca5 Mon Sep 17 00:00:00 2001 2 | From: Oleg Zhurakivskyy 3 | Date: Tue, 3 May 2022 15:28:05 +0300 4 | Subject: [PATCH] idxd: Ignore reset device error 5 | 6 | Signed-off-by: Oleg Zhurakivskyy 7 | --- 8 | accfg/lib/libaccfg.c | 2 +- 9 | 1 file changed, 1 insertion(+), 1 deletion(-) 10 | 11 | diff --git a/accfg/lib/libaccfg.c b/accfg/lib/libaccfg.c 12 | index be3be69..32eb71f 100644 13 | --- a/accfg/lib/libaccfg.c 14 | +++ b/accfg/lib/libaccfg.c 15 | @@ -636,7 +636,7 @@ static void *add_device(void *parent, int id, const char *ctl_base, 16 | 17 | rc = accfg_set_param(ctx, dfd, "cmd_status", "1", 1); 18 | /* older drivers don't support writing to cmd_status */ 19 | - if (rc && rc != -EACCES) { 20 | + if (rc && rc != -EACCES && rc != -EROFS) { 21 | err(ctx, "Failed resetting cmd status %d\n", rc); 22 | close(dfd); 23 | goto err_device; 24 | -- 25 | 2.36.1 26 | 27 | -------------------------------------------------------------------------------- /container/cnap-redis/patches/redis_dto.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/Makefile b/src/Makefile 2 | index ecbd2753d..3f42351d7 100644 3 | --- a/src/Makefile 4 | +++ b/src/Makefile 5 | @@ -25,6 +25,7 @@ ifeq ($(OPTIMIZATION),-O3) 6 | endif 7 | REDIS_LDFLAGS+=-O3 -flto 8 | endif 9 | +LDFLAGS+=-ldto 10 | DEPENDENCY_TARGETS=hiredis linenoise lua hdr_histogram fpconv 11 | NODEPS:=clean distclean 12 | 13 | @@ -218,6 +219,8 @@ endif 14 | endif 15 | endif 16 | 17 | +FINAL_LIBS+=-ldto 18 | + 19 | ifdef OPENSSL_PREFIX 20 | OPENSSL_CFLAGS=-I$(OPENSSL_PREFIX)/include 21 | OPENSSL_LDFLAGS=-L$(OPENSSL_PREFIX)/lib 22 | -------------------------------------------------------------------------------- /container/cnap-spa/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18-slim 2 | 3 | RUN useradd --create-home appuser 4 | 5 | COPY ./cnap /cnap 6 | 7 | RUN chown -R appuser:appuser /cnap && \ 8 | date > /build-date.cnap-spa.txt 9 | 10 | USER appuser 11 | 12 | WORKDIR /cnap/ui/ 13 | 14 | RUN npm install --registry=https://registry.npmmirror.com 15 | 16 | EXPOSE 5173 17 | 18 | CMD ["npm", "run", "dev"] 19 | -------------------------------------------------------------------------------- /container/cnap-streaming/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 as builder 2 | 3 | ARG DEBIAN_FRONTEND=noninteractive 4 | ARG QAT_DRIVER_RELEASE="QAT20.L.1.0.50-00003" 5 | ARG QAT_DRIVER_SHA256="41b45f936dc870299a00dffeeb1818774de1a3791d8fbb4365a5074a22f20017" 6 | ARG QATZIP_URL=https://github.com/intel/QATzip 7 | ARG QATZIP_VERSION="v1.1.2" 8 | 9 | RUN apt-get update && \ 10 | apt-get install -y --no-install-recommends libudev-dev build-essential make gcc g++ nasm \ 11 | pkg-config libssl-dev zlib1g-dev wget ca-certificates git yasm autoconf cmake libtool \ 12 | libboost-all-dev openssl haproxy liblz4-tool liblz4-dev && \ 13 | rm -rf /var/lib/apt/lists/* 14 | 15 | # QAT driver 16 | WORKDIR /home/project/QAT 17 | 18 | RUN wget https://downloadmirror.intel.com/783270/$QAT_DRIVER_RELEASE.tar.gz && \ 19 | echo "$QAT_DRIVER_SHA256 $QAT_DRIVER_RELEASE.tar.gz" | sha256sum -c -&& \ 20 | tar -zxvf $QAT_DRIVER_RELEASE.tar.gz -C . && \ 21 | sed -i -e 's/cmn_ko$//' -e 's/lac_kernel$//' quickassist/Makefile && \ 22 | KERNEL_SOURCE_ROOT=/tmp ./configure --disable-param-check --prefix=/usr && \ 23 | make quickassist-all adf-ctl-all && \ 24 | install -m 755 build/libqat_s.so /usr/lib/ && \ 25 | install -m 755 build/libusdm_drv_s.so /usr/lib/ && \ 26 | install -m 755 build/adf_ctl /usr/bin/ 27 | 28 | # QATzip 29 | WORKDIR /home/project 30 | 31 | RUN git clone -b $QATZIP_VERSION $QATZIP_URL && \ 32 | cd QATzip && \ 33 | export ICP_ROOT=/home/project/QAT && \ 34 | export QZ_ROOT=/home/project/QATzip && \ 35 | ./autogen.sh && \ 36 | ./configure --with-ICP_ROOT=$ICP_ROOT --prefix=/usr && \ 37 | make install 38 | 39 | FROM ubuntu:22.04 AS downloader 40 | 41 | COPY ./tools /tools 42 | 43 | ARG DEBIAN_FRONTEND=noninteractive 44 | 45 | RUN apt-get update && \ 46 | apt-get install -y --no-install-recommends unzip wget ca-certificates && \ 47 | rm -rf /var/lib/apt/lists/* 48 | 49 | RUN ./tools/video_downloader.sh 50 | 51 | FROM python:3.10-slim AS runner 52 | 53 | RUN useradd --create-home appuser 54 | 55 | COPY ./cnap /cnap 56 | 57 | COPY --from=downloader /sample-videos /demo/sample-videos 58 | 59 | COPY --from=builder /usr/lib/libqat* /usr/lib/libusdm_drv_s.so /usr/lib 60 | 61 | COPY --from=builder /usr/bin/adf_ctl /usr/bin/qzip /usr/bin 62 | 63 | RUN chown -R appuser:appuser /cnap /demo 64 | 65 | ENV PYTHONPATH="/cnap:${PYTHONPATH}" 66 | 67 | ARG DEBIAN_FRONTEND=noninteractive 68 | 69 | RUN apt-get update && \ 70 | apt-get install -y --no-install-recommends libgl1-mesa-glx libglib2.0-0 && \ 71 | rm -rf /var/lib/apt/lists/* 72 | 73 | ARG pip_mirror 74 | 75 | RUN pip3 install ${pip_mirror} --upgrade --no-cache-dir pip && \ 76 | pip3 install ${pip_mirror} --no-cache-dir redis numpy opencv-python kafka-python protobuf 77 | 78 | RUN date > /build-date.cnap-streaming.txt 79 | 80 | USER appuser 81 | 82 | CMD ["python", "/cnap/userv/streaming.py"] 83 | -------------------------------------------------------------------------------- /container/cnap-wss/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.10-slim 2 | 3 | RUN useradd --create-home appuser 4 | 5 | COPY ./cnap /cnap 6 | 7 | RUN chown -R appuser:appuser /cnap 8 | 9 | ENV PYTHONPATH="/cnap:${PYTHONPATH}" 10 | 11 | ARG pip_mirror 12 | 13 | RUN pip3 install ${pip_mirror} --upgrade --no-cache-dir pip && \ 14 | pip3 install ${pip_mirror} --no-cache-dir websockets redis>=4.3.0 15 | 16 | RUN date > /build-date.cnap-wss.txt 17 | 18 | EXPOSE 31611 19 | 20 | USER appuser 21 | 22 | CMD ["python", "/cnap/userv/websocket_server.py"] 23 | -------------------------------------------------------------------------------- /docs/KEDA.md: -------------------------------------------------------------------------------- 1 | # KEDA Integration Documentation 2 | 3 | This document delineates the integration of Kubernetes Event-driven Autoscaling (KEDA) within the Cloud Native AI Pipeline, specifically focusing on augmenting the scalability of the Horizontal Pod Autoscaler (HPA) and Vertical Pod Autoscaler (VPA) which are imperative for optimizing resource allocation in cloud-native settings. 4 | 5 | ## Table of Contents 6 | 7 | - [Overview](#overview) 8 | - [Installation](#installation) 9 | - [Configuration](#configuration) 10 | - [Usage](#usage) 11 | - [Resources](#resources) 12 | 13 | ## Overview 14 | 15 | KEDA, acting as an operator, synergizes with the Cloud Native AI Pipeline to bolster the scalability of HPA and VPA, ensuring efficient resource allocation and optimized performance in response to real-time workload demands. 16 | 17 | ## Installation 18 | 19 | ### Prerequisites 20 | 21 | - Kubernetes cluster 22 | - Helm 3 23 | 24 | ### Steps 25 | 26 | 1. Install KEDA using Helm: 27 | ```bash 28 | helm repo add kedacore https://kedacore.github.io/charts 29 | helm repo update 30 | helm install keda kedacore/keda --namespace keda 31 | ``` 32 | 33 | ## Configuration 34 | 35 | Configure the scalers and triggers in accordance with the project requirements to fine-tune the autoscaling behavior. 36 | 37 | 1. Define the ScaledObject or ScaledJob custom resource: 38 | 39 | ```yaml 40 | apiVersion: keda.sh/v1alpha1 41 | kind: ScaledObject 42 | metadata: 43 | name: example-scaledobject 44 | spec: 45 | scaleTargetRef: 46 | name: example-deployment 47 | triggers: 48 | - type: example-trigger 49 | metadata: 50 | # trigger-specific configuration 51 | ``` 52 | 53 | ## Usage 54 | 55 | Utilize KEDA to orchestrate the autoscaling of HPA and VPA within the project, ensuring real-time scalability in response to workload dynamics. 56 | 57 | ### Monitor the autoscaling behavior: 58 | 59 | ```bash 60 | kubectl get hpa 61 | ``` 62 | 63 | Or you can just deploy grafana dashboard for KEDA in grafana and directly monitor the autoscaling behavior. 64 | 65 | ## Resources 66 | 67 | - [KEDA Official Documentation](https://keda.sh/docs/) 68 | - Additional resources and references pertinent to the Cloud Native AI Pipeline and KEDA integration. 69 | -------------------------------------------------------------------------------- /docs/cnap-uses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/docs/cnap-uses.png -------------------------------------------------------------------------------- /docs/cnap_arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/docs/cnap_arch.png -------------------------------------------------------------------------------- /docs/enable_dsa_offloading.md: -------------------------------------------------------------------------------- 1 | # Redis Memory Operation Offload with DSA 2 | 3 | Accelerate memory copy & move operation in Redis with Intel® [DTO](https://github.com/intel/DTO#intel-dsa-transparent-offload-library)(DSA Transparent Offload Library), a shared library for applications to transparently use DSA. 4 | 5 | ## Prerequisites 6 | 7 | Intel® DSA(Data streaming accelerator), [Specification](https://www.intel.com/content/www/us/en/content-details/671116/intel-data-streaming-accelerator-architecture-specification.html?wapkw=data%20streaming%20accelerator%20specification), 8 | DSA is a high-performance data copy and transformation accelerator that is integrated in 4th Gen Intel(R) Xeon(R) Scalable Processor(Sapphire Rapids) and later. 9 | 10 | You need firstly follow DSA [accel-config](https://github.com/intel/idxd-config) to build and install it. 11 | 12 | ## How to use 13 | 14 | ### 1. Build Redis & DSA image 15 | 16 | You can skip this step if you have already done it before. 17 | 18 | ``` 19 | $ ./tools/docker_image_manager.sh -a build -c cnap-redis -r 20 | ``` 21 | 22 | 23 | ### 2. Enable DSA in host 24 | 25 | Configure DSA: 26 | 27 | - Make sure you have installed [accel-config](https://github.com/intel/idxd-config) library and tools before doing this step 28 | ``` 29 | $ cd k8s-manifests/plugin/dsa/config_dsa 30 | $ ./setup_dsa.sh configs/1e1w-s.conf 31 | ``` 32 | 33 | Run test to verfiy: 34 | 35 | - To run dsa_test for single mode, run dsa_test_batch for batch mode 36 | ``` 37 | $ cd build/bin 38 | $ ./dsa_test -w 0 -l 4096 -o 3 39 | $ ./dsa_test_batch -w 0 -l 4096 -c 16 40 | ``` 41 | 42 | ### 3. Setup [DSA Device Plugin](https://github.com/intel/intel-device-plugins-for-kubernetes#dsa-device-plugin) 43 | 44 | The DSA plugin discovers DSA work queues and presents them as a node resources. 45 | 46 | ``` 47 | $ kubectl apply -k 'https://github.com/intel/intel-device-plugins-for-kubernetes/deployments/dsa_plugin?ref=main' 48 | daemonset.apps/intel-dsa-plugin created 49 | ``` 50 | 51 | Verify DSA device plugin: 52 | ``` 53 | $ kubectl get nodes -o go-template='{{range .items}}{{.metadata.name}}{{"\n"}}{{range $k,$v:=.status.allocatable}}{{" "}}{{$k}}{{": "}}{{$v}}{{"\n"}}{{end}}{{end}}' | grep '^\([^ ]\)\|\( dsa\)' 54 | master 55 | dsa.intel.com/wq-user-shared: 8 56 | node1 57 | dsa.intel.com/wq-user-shared: 20 58 | ``` 59 | 60 | ### 4. Enable Redis offload with DSA 61 | 62 | We have integrated Redis offloading with DSA in CNAP, you can modify the helm/redis/values.yaml to enable DSA: 63 | 64 | ``` 65 | dsa: 66 | enabled: true 67 | wqnumbers: 2 68 | ``` 69 | 70 | To enable Redis offloading with DSA in other user scenarios, you can update Redis deployment yaml file directly as below: 71 | ``` 72 | image: 73 | command: ["/opt/redis/redis-server-dto"] 74 | resources: 75 | limits: 76 | dsa.intel.com/wq-user-shared: 77 | ``` 78 | 79 | ### 5. Deployment 80 | 81 | Same deployment command as original with your image registry 82 | 83 | ``` 84 | $ ./tools/helm_manager.sh -i -r -g 85 | # To uninstall all charts 86 | # ./tools/helm_manager.sh -u 87 | ``` 88 | 89 | -------------------------------------------------------------------------------- /docs/enable_qat_offloading.md: -------------------------------------------------------------------------------- 1 | # QAT Integration Documentation 2 | 3 | This document delineates the integration of Intel® QuickAssist Technology ([Intel® QAT](https://www.intel.com/content/www/us/en/developer/topic-technology/open/quick-assist-technology/overview.html)) within the Cloud Native AI Pipeline. Using Intel® QAT in Cloud Native AI Pipeline to accelerate the compression and decompression of image frames can improve peformance and power efficiency. 4 | 5 | ## Table of Contents 6 | 7 | - [Overview](#overview) 8 | - [Install QAT As Non-root User on host](#install-qat-as-non-root-user-on-host) 9 | - [Setup QAT Device Plugin](#setup-qat-device-plugin) 10 | - [Configuration for Containerd](#configuration-for-containerd) 11 | - [Configuration in Cloud Native AI Pipeline](#configuration-in-cloud-native-ai-pipeline) 12 | - [Resources](#resources) 13 | 14 | ## Overview 15 | 16 | [Intel® QAT](https://www.intel.com/content/www/us/en/developer/topic-technology/open/quick-assist-technology/overview.html) offloads computationally intensive symmetric and asymmetric cryptography and data compression/decompression operations from the CPU, relieving the CPU from these demanding tasks. This reallocation of computational resources allows the CPU to perform other tasks more efficiently, potentially enhancing overall system performance, efficiency, and power across various use cases. 17 | 18 | ## Install QAT As Non-root User on host 19 | 20 | Please refer to https://www.intel.com/content/www/us/en/content-details/632506/intel-quickassist-technology-intel-qat-software-for-linux-getting-started-guide-hardware-version-2-0.html section "3.8 Running Applications as Non-Root User". 21 | 22 | ## Setup QAT Device Plugin 23 | 24 | Please refer to https://github.com/intel/intel-device-plugins-for-kubernetes/blob/main/cmd/qat_plugin/README.md. 25 | 26 | ## Configuration for Containerd 27 | 28 | Configure LimitMEMLOCK for containerd: 29 | ```bash 30 | sudo systemctl edit containerd 31 | 32 | # Add this text 33 | [Service] 34 | LimitMEMLOCK=infinity 35 | 36 | sudo systemctl daemon-reload 37 | sudo systemctl restart containerd 38 | ``` 39 | 40 | ## Configuration in Cloud Native AI Pipeline 41 | 42 | Add QAT resources in [streaming service](../helm/stream/values.yaml#L30) and [inference service](../helm/inference/values.yaml#L34): 43 | ``` 44 | resources: 45 | limits: 46 | qat.intel.com/cy0_dc1: 1 47 | ``` 48 | 49 | In order to compress and decompress image frame using QAT in Cloud Native AI Pipeline, the env need to be added in [streaming service](../helm/stream/values.yaml#L52) and [inference service](../helm/inference/values.yaml#L56): 50 | ``` 51 | - name: ZIP_ENABLE 52 | value: true 53 | - name: ZIP_TOOL 54 | value: QAT 55 | ``` 56 | 57 | ## Resources 58 | 59 | - [Intel® QuickAssist Technology (Intel® QAT)](https://www.intel.com/content/www/us/en/developer/topic-technology/open/quick-assist-technology/overview.html) 60 | - [Intel® Device Plugin for Kubernetes](https://github.com/intel/intel-device-plugins-for-kubernetes) 61 | -------------------------------------------------------------------------------- /docs/resources/images/class_uml/engines/tensorflowengine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/docs/resources/images/class_uml/engines/tensorflowengine.png -------------------------------------------------------------------------------- /docs/resources/images/class_uml/filedb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/docs/resources/images/class_uml/filedb.png -------------------------------------------------------------------------------- /docs/resources/images/class_uml/frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/docs/resources/images/class_uml/frame.png -------------------------------------------------------------------------------- /docs/resources/images/class_uml/infereng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/docs/resources/images/class_uml/infereng.png -------------------------------------------------------------------------------- /docs/resources/images/class_uml/inferqueue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/docs/resources/images/class_uml/inferqueue.png -------------------------------------------------------------------------------- /docs/resources/images/class_uml/model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/docs/resources/images/class_uml/model.png -------------------------------------------------------------------------------- /docs/resources/images/class_uml/pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/docs/resources/images/class_uml/pipeline.png -------------------------------------------------------------------------------- /docs/resources/images/class_uml/processors/postprocessor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/docs/resources/images/class_uml/processors/postprocessor.png -------------------------------------------------------------------------------- /docs/resources/images/class_uml/processors/preprocessor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/docs/resources/images/class_uml/processors/preprocessor.png -------------------------------------------------------------------------------- /docs/resources/images/class_uml/rtdb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/docs/resources/images/class_uml/rtdb.png -------------------------------------------------------------------------------- /docs/resources/images/class_uml/stream.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/docs/resources/images/class_uml/stream.png -------------------------------------------------------------------------------- /docs/resources/images/class_uml/streambroker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/docs/resources/images/class_uml/streambroker.png -------------------------------------------------------------------------------- /docs/resources/pumls/engines/tensorflowengine.puml: -------------------------------------------------------------------------------- 1 | @startuml TensorFlowEngine 2 | 3 | !includeurl ../style.puml 4 | 5 | package "TensorFlowEngine" { 6 | 7 | class TFModelConfig { 8 | - _path: str 9 | - _dtype: str 10 | - _device: str 11 | - _target: str 12 | - _output_layer: list 13 | - _drawing: dict 14 | --- 15 | + path: str (property) 16 | + dtype: str (property) 17 | + device: str (property) 18 | + target: str (property) 19 | + output_layer: list (property) 20 | + drawing: dict (property) 21 | } 22 | 23 | class TensorFlowPreprocessor { 24 | - _input_size: Tuple[int, int] 25 | - _dtype: str 26 | --- 27 | + __init__(input_size: Tuple[int, int], dtype: str) 28 | + preprocess(frame: np.ndarray): np.ndarray 29 | } 30 | 31 | class TensorFlowPostprocessor { 32 | - _postprocessor: Postprocessor 33 | --- 34 | - _select_postprocessor(target: str, drawing: dict): Postprocessor 35 | + __init__(target: str, drawing: dict) 36 | + postprocess(frame: np.ndarray, outputs: dict): np.ndarray 37 | } 38 | 39 | class TensorFlowEngine { 40 | - _model_path: str 41 | - _dtype: str 42 | - _target: str 43 | - _drawing: dict 44 | - _output_layer: list 45 | - _input_size: Tuple[int, int] 46 | - _model: any 47 | - _session: any 48 | - _preprocessor: TensorFlowPreprocessor 49 | - _postprocessor: TensorFlowPostprocessor 50 | --- 51 | - _load_model(): None 52 | - _load_frozen_graph_model(): None 53 | - _load_saved_model(): None 54 | - _configure_optimizer(): None 55 | - _configure_environment(): None 56 | + __init__(config: TFModelConfig) 57 | + verify(): bool 58 | + preprocess(frame: np.ndarray): np.ndarray 59 | + _predict(preprocessed_frame: np.ndarray): np.ndarray 60 | + postprocess(frame: np.ndarray, outputs: dict): np.ndarray 61 | + input_size: Tuple[int, int] (property) 62 | } 63 | 64 | TFModelConfig <-- TensorFlowEngine 65 | TensorFlowPreprocessor <-- TensorFlowEngine 66 | TensorFlowPostprocessor <-- TensorFlowEngine 67 | 68 | } 69 | 70 | @enduml 71 | -------------------------------------------------------------------------------- /docs/resources/pumls/filedb.puml: -------------------------------------------------------------------------------- 1 | @startuml FileDatabase 2 | 3 | !includeurl ./style.puml 4 | 5 | package "FileDatabase" { 6 | 7 | abstract class FileDatabase<> { 8 | + {abstract} get_file(filename: str): str 9 | } 10 | 11 | class LocalFileDatabase { 12 | - _root_dir: str 13 | --- 14 | + __init__(root_dir: str) 15 | + get_file(filename: str): str 16 | } 17 | 18 | LocalFileDatabase --|> FileDatabase: Inheritance 19 | } 20 | 21 | @enduml 22 | -------------------------------------------------------------------------------- /docs/resources/pumls/frame.puml: -------------------------------------------------------------------------------- 1 | @startuml Frame 2 | 3 | !includeurl ./style.puml 4 | 5 | package "Frame" { 6 | 7 | abstract class FrameCipherBase<> { 8 | + {abstract} encrypt() 9 | + {abstract} decrypt() 10 | } 11 | 12 | class QATFrameCipher { 13 | + encrypt() 14 | + decrypt() 15 | } 16 | 17 | class Frame { 18 | - _provider: StreamProvider 19 | - _pipeline_id: str 20 | - _sequence: int 21 | - _raw: np.ndarray 22 | - _ts_new: float 23 | - _ts_infer_end: float 24 | + {static} last_sequence: int 25 | -- 26 | + pipeline_id(): str (property) 27 | + sequence(): int (property) 28 | + timestamp_new_frame(): float (property) 29 | + timestamp_infer_end(): float (property) 30 | + raw(): np.ndarray (property) 31 | + pipeline_id(new_str: str) (setter) 32 | + timestamp_new_frame(timestamp: float) (setter) 33 | + timestamp_infer_end(timestamp: float) (setter) 34 | + raw(raw_frame: np.ndarray) (setter) 35 | + __init__(provider: StreamProvider, pipeline_id: str, sequence: int, raw: np.ndarray) 36 | + {static} get_sequence(): int 37 | + to_blob(): bytes 38 | + {static} from_blob(blob: bytes): Frame 39 | + normalize(target_size: Tuple[int, int])) 40 | + encrypt(actor: FrameCipherBase) 41 | + decrypt(actor: FrameCipherBase) 42 | -- 43 | } 44 | 45 | FrameCipherBase <|-- QATFrameCipher 46 | Frame o-- FrameCipherBase: encryption/decryption 47 | } 48 | 49 | @enduml 50 | -------------------------------------------------------------------------------- /docs/resources/pumls/infereng.puml: -------------------------------------------------------------------------------- 1 | @startuml InferenceEngine 2 | 3 | !includeurl ./style.puml 4 | 5 | package "InferenceEngine" { 6 | 7 | class InferenceInfo { 8 | - _device: str 9 | - _model_id: str 10 | - _id: str 11 | - _queue_topic: str 12 | - _input_size: Tuple[int, int] 13 | --- 14 | + __init__(device: str, model_id: str) 15 | + id: str (property) 16 | + input_size: Tuple[int, int] (property) 17 | + device: str (property) 18 | + model_id: str (property) 19 | + queue_topic: str (property) 20 | + id(new_str: str) (setter) 21 | + queue_topic(new_queue_topic: str) (setter) 22 | + __iter__(): Iterator[Tuple[str, Any]] 23 | } 24 | 25 | class InferEngineManager { 26 | - _db: RuntimeDatabaseBase 27 | + {static} _instance: InferEngineManager 28 | --- 29 | + __init__(db: RuntimeDatabaseBase) 30 | + search_engine(framework: str, target: str, device: str, model_name: str, model_version: str): Optional[InferenceInfo] 31 | + register_engine(infer_info: InferenceInfo, model_info: ModelInfo) 32 | + unregister_engine(infer_info_id: str) 33 | } 34 | 35 | abstract class InferenceEngine<> { 36 | + {abstract} verify(): bool 37 | + {abstract} preprocess(frame: np.ndarray): np.ndarray 38 | + predict(frame: np.ndarray): Tuple[np.ndarray, float] 39 | + {abstract} postprocess(frame: np.ndarray, outputs: dict): np.ndarray 40 | + {abstract} _predict(preprocessed_frame: np.ndarray): dict 41 | } 42 | 43 | InferEngineManager "1" -- "0..*" InferenceInfo 44 | } 45 | 46 | @enduml 47 | -------------------------------------------------------------------------------- /docs/resources/pumls/inferqueue.puml: -------------------------------------------------------------------------------- 1 | @startuml InferqQueue 2 | 3 | !includeurl ./style.puml 4 | 5 | package "InferqQueue" { 6 | 7 | abstract class InferQueueClientBase<> { 8 | - _buffer_len: int 9 | --- 10 | + __init__() 11 | + {abstract} connect(host: str, port: int) 12 | + {abstract} publish_frame(topic: str, frame: Frame) 13 | + {abstract} get_frame(topic: str): Frame 14 | + {abstract} drop(topic: str): int 15 | + buffer_len(): int (property) 16 | + buffer_len(new_buffer_len: int) (setter) 17 | + {abstract} infer_queue_available(topic: str): bool 18 | + {abstract} register_infer_queue(topic: str) 19 | + {abstract} unregister_infer_queue(topic: str) 20 | } 21 | 22 | class RedisInferQueueClient { 23 | - _conn: redis. 24 | --- 25 | + __init__() 26 | + connect(host: str, port: int) 27 | + publish_frame(topic: str, frame: Frame) 28 | + get_frame(topic: str): Frame 29 | + drop(topic: str): int 30 | + infer_queue_available(topic: str): bool 31 | + register_infer_queue(topic: str) 32 | + unregister_infer_queue(topic: str) 33 | } 34 | 35 | class KafkaInferQueueClient { 36 | - _conn: KafkaProducer 37 | --- 38 | + __init__() 39 | + connect(host: str, port: int) 40 | + publish_frame(topic: str, frame: Frame) 41 | + get_frame(topic: str): Frame 42 | + drop(topic: str): int 43 | + infer_queue_available(topic: str): bool 44 | + register_infer_queue(topic: str) 45 | + unregister_infer_queue(topic: str) 46 | } 47 | 48 | InferQueueClientBase <|-- RedisInferQueueClient 49 | InferQueueClientBase <|-- KafkaInferQueueClient 50 | 51 | } 52 | 53 | @enduml 54 | -------------------------------------------------------------------------------- /docs/resources/pumls/model.puml: -------------------------------------------------------------------------------- 1 | @startuml Model 2 | 3 | !includeurl ./style.puml 4 | 5 | package "Model" { 6 | 7 | class ModelMetrics { 8 | - _accuracy: float 9 | - _precision: float 10 | - _recall: float 11 | - _f1_score: float 12 | - _loss: float 13 | --- 14 | + __init__(accuracy: float, precision: float, recall: float, f1_score: float, loss: float) 15 | + accuracy(): float (property) 16 | + precision(): float (property) 17 | + recall(): float (property) 18 | + f1_score(): float (property) 19 | + loss(): float (property) 20 | + __iter__(): Iterator[Tuple[str, Any]] 21 | } 22 | 23 | class ModelDetails { 24 | - _name: str 25 | - _version: str 26 | - _framework: str 27 | - _target: str 28 | - _dtype: str 29 | --- 30 | + __init__(name: str, version: str, framework: str, target: str, dtype: str) 31 | + name(): str (property) 32 | + version(): str (property) 33 | + framework(): str (property) 34 | + target(): str (property) 35 | + dtype(): str (property) 36 | + __iter__(): Iterator[Tuple[str, Any]] 37 | } 38 | 39 | class ModelInfo { 40 | - _id: uuid.UUID 41 | - _details: ModelDetails 42 | - _uploaded_date: datetime 43 | - _metrics: ModelMetrics 44 | --- 45 | + __init__(details: ModelDetails, uploaded_date: datetime, metrics: ModelMetrics) 46 | + id(): str (property) 47 | + details(): ModelDetails (property) 48 | + uploaded_date(): datetime (property) 49 | + metrics(): ModelMetrics (property) 50 | + id(new_str: str) (setter) 51 | + __iter__(): Iterator[Tuple[str, Any]] 52 | } 53 | 54 | class Model { 55 | - _model_info: ModelInfo 56 | - _model_binary: bytes 57 | --- 58 | + __init__(model_info: ModelInfo, model_binary: bytes) 59 | + model_info(): ModelInfo (property) 60 | + model_binary(): bytes (property) 61 | + __iter__(): Iterator[Tuple[str, Any]] 62 | } 63 | 64 | ModelInfo -- ModelMetrics : has > 65 | ModelInfo -- ModelDetails : has > 66 | Model -- ModelInfo : has > 67 | 68 | } 69 | 70 | @enduml 71 | -------------------------------------------------------------------------------- /docs/resources/pumls/pipeline.puml: -------------------------------------------------------------------------------- 1 | @startuml Pipeline 2 | 3 | !includeurl ./style.puml 4 | 5 | package "Pipeline" { 6 | 7 | class Pipeline { 8 | - _id: str 9 | - _provider: StreamProvider 10 | - _info_engine_info: InferenceInfo 11 | --- 12 | + __init__(provider: StreamProvider, info_engine_info: InferenceInfo) 13 | + id(): str (property) 14 | + id(new_id: str) (setter) 15 | + __iter__(): Iterator[Tuple[str, Dict[str, Any]]] 16 | } 17 | 18 | class PipelineManager { 19 | - _db: RuntimeDatabaseBase 20 | --- 21 | + __init__(db: RuntimeDatabaseBase) 22 | + register_pipeline(pipeline_obj: Pipeline) 23 | + unregister_pipeline(pipeline_id: str) 24 | } 25 | 26 | PipelineManager -- Pipeline : manages > 27 | 28 | } 29 | 30 | @enduml 31 | -------------------------------------------------------------------------------- /docs/resources/pumls/processors/postprocessor.puml: -------------------------------------------------------------------------------- 1 | @startuml PostProcessor 2 | 3 | !includeurl ../style.puml 4 | 5 | package "PostProcessor" { 6 | 7 | abstract class Postprocessor<> { 8 | + {abstract} postprocess(frame: np.ndarray, outputs: dict): np.ndarray 9 | } 10 | 11 | class ObjectDetectionPostprocessor { 12 | - _drawing: dict 13 | --- 14 | + __init__(drawing: dict) 15 | + postprocess(frame: np.ndarray, outputs: dict): np.ndarray 16 | } 17 | 18 | class FaceRecognitionPostprocessor { 19 | - _drawing: dict 20 | --- 21 | + __init__(drawing: dict) 22 | + postprocess(frame: np.ndarray, outputs: dict): np.ndarray 23 | } 24 | 25 | Postprocessor <|-- ObjectDetectionPostprocessor 26 | Postprocessor <|-- FaceRecognitionPostprocessor 27 | 28 | } 29 | 30 | @enduml 31 | -------------------------------------------------------------------------------- /docs/resources/pumls/processors/preprocessor.puml: -------------------------------------------------------------------------------- 1 | @startuml PreProcessor 2 | 3 | !includeurl ../style.puml 4 | 5 | package "PreProcessor" { 6 | 7 | abstract class Preprocessor<> { 8 | + {abstract} preprocess(frame: np.ndarray): np.ndarray 9 | } 10 | 11 | } 12 | 13 | @enduml 14 | -------------------------------------------------------------------------------- /docs/resources/pumls/rtdb.puml: -------------------------------------------------------------------------------- 1 | @startuml RuntimeDatabase 2 | 3 | !includeurl ./style.puml 4 | 5 | package "RuntimeDatabase" { 6 | 7 | abstract class RuntimeDatabaseBase<> { 8 | + {abstract} connect() 9 | + {abstract} save_table_object_dict(table: str, obj: str, d: dict) 10 | + {abstract} get_table_object_dict(table: str, obj: str): dict 11 | + {abstract} get_all_table_objects_dict(table: str): dict 12 | + {abstract} check_table_object_exist(table: str, obj: str): bool 13 | + {abstract} del_table_object(table: str, obj: str) 14 | } 15 | 16 | class RedisDB { 17 | - _conn: redis.Redis 18 | --- 19 | + __init__() 20 | + connect(host: str, port: int, db: int) 21 | + save_table_object_dict(table: str, obj: str, d: dict) 22 | + get_table_object_dict(table: str, obj: str): dict 23 | + get_all_table_objects_dict(table: str): dict 24 | + check_table_object_exist(table: str, obj: str): bool 25 | + del_table_object(table: str, obj: str) 26 | } 27 | 28 | RedisDB --|> RuntimeDatabaseBase 29 | 30 | } 31 | 32 | @enduml 33 | -------------------------------------------------------------------------------- /docs/resources/pumls/stream.puml: -------------------------------------------------------------------------------- 1 | @startuml Stream 2 | 3 | !includeurl ./style.puml 4 | 5 | package "Stream" { 6 | 7 | abstract class StreamProvider<> { 8 | - _name: str 9 | - _pathname: str 10 | - _raw_size: Tuple[int, int] 11 | - _raw_fps: int 12 | - _seq: int 13 | - _target_fps: int 14 | --- 15 | + __init__(name: str, pathname: str) 16 | + name(): str (property) 17 | + pathname(): str (property) 18 | + raw_size(): Tuple[int, int] (property) 19 | + raw_fps(): int (property) 20 | + target_fps(): int (property) 21 | + target_fps(new_val) (setter) 22 | + {abstract} verify(): bool 23 | + {abstract} read_raw_frame(): numpy.ndarray 24 | + {abstract} open() 25 | + {abstract} close() 26 | 27 | } 28 | 29 | class CameraSource { 30 | - _device_obj: any 31 | --- 32 | - _dev_num(): int 33 | + __init__(name:str, pathname: str) 34 | + verify(): bool 35 | + read_raw_frame(): numpy.ndarray 36 | + open() 37 | + close() 38 | } 39 | 40 | class FileSource { 41 | - _file_db: FileDatabase 42 | - _file_object: any 43 | - _file_path: str 44 | - _frame_counter: int 45 | - _max_frame: int 46 | --- 47 | + __init__(name: str, pathname: str) 48 | + verify(): bool 49 | + open() 50 | + close() 51 | + read_raw_frame(): numpy.ndarray 52 | + file_db(): FileDatabase (property) 53 | + file_db(new_val: FileDatabase) (setter) 54 | + target_fps(): int (property) 55 | } 56 | 57 | class StreamProcessor { 58 | - _provider: StreamProvider 59 | --- 60 | + __init__(provider: StreamProvider) 61 | + provider: StreamProvider (property) 62 | + prepare() 63 | } 64 | 65 | CameraSource --|> StreamProvider: Inheritance 66 | FileSource --|> StreamProvider: Inheritance 67 | StreamProcessor -- StreamProvider 68 | } 69 | 70 | @enduml 71 | -------------------------------------------------------------------------------- /docs/resources/pumls/streambroker.puml: -------------------------------------------------------------------------------- 1 | @startuml StreamBroker 2 | 3 | !includeurl ./style.puml 4 | 5 | package "StreamBroker" { 6 | 7 | abstract class StreamBrokerClientBase<> { 8 | + {abstract} connect(host: str, port: int) 9 | + {abstract} publish_frame(topic: str, frame: Frame) 10 | } 11 | 12 | class RedisStreamBrokerClient { 13 | - _conn: redis.Redis 14 | --- 15 | + __init__() 16 | + connect(host: str, port: int): bool 17 | + publish_frame(topic: str, frame: Frame) 18 | } 19 | 20 | class KafkaStreamBrokerClient { 21 | - _conn: kafka.KafkaProducer 22 | --- 23 | + __init__() 24 | + connect(host: str, port: int): bool 25 | + publish_frame(topic: str, frame: Frame) 26 | } 27 | 28 | RedisStreamBrokerClient --|> StreamBrokerClientBase 29 | KafkaStreamBrokerClient --|> StreamBrokerClientBase 30 | 31 | } 32 | 33 | @enduml 34 | -------------------------------------------------------------------------------- /docs/resources/pumls/style.puml: -------------------------------------------------------------------------------- 1 | @startuml Style 2 | 3 | skinparam defaultFontName Helvetica 4 | skinparam defaultFontSize 12 5 | skinparam defaultFontColor #333333 6 | 7 | skinparam class { 8 | BackgroundColor<> #8CC152 9 | BackgroundColor<> #FFFFFF 10 | BorderColor<> #9E9E9E 11 | BorderColor<> #333333 12 | borderThickness 1.5 13 | shadowing true 14 | Padding 5 15 | roundCorner 10 16 | } 17 | 18 | skinparam package { 19 | backgroundColor #F5F5F5 20 | borderColor #333333 21 | borderThickness 2 22 | fontStyle Bold 23 | fontSize 14 24 | roundCorner 25 25 | shadowing true 26 | padding 10 27 | } 28 | 29 | skinparam arrow { 30 | color #333333 31 | thickness 1.5 32 | fontStyle Bold 33 | fontSize 12 34 | shadowing true 35 | } 36 | 37 | @enduml 38 | -------------------------------------------------------------------------------- /docs/secure-model-design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/cloud-native-ai-pipeline/f51cc5a3b0c9463570042ebd6d750da74dd49fd3/docs/secure-model-design.png -------------------------------------------------------------------------------- /helm/inference/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/inference/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: inference 3 | description: A Helm chart for inference service of CNAP 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.1 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "" 25 | -------------------------------------------------------------------------------- /helm/inference/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | The inference service deployed. 2 | -------------------------------------------------------------------------------- /helm/inference/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "inference.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "inference.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "inference.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "inference.labels" -}} 37 | helm.sh/chart: {{ include "inference.chart" . }} 38 | {{ include "inference.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "inference.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "inference.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "inference.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "inference.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /helm/inference/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "inference.fullname" . }} 5 | labels: 6 | {{- include "inference.labels" . | nindent 4 }} 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | {{- include "inference.selectorLabels" . | nindent 6 }} 12 | template: 13 | metadata: 14 | {{- with .Values.podAnnotations }} 15 | annotations: 16 | {{- toYaml . | nindent 8 }} 17 | {{- end }} 18 | labels: 19 | {{- include "inference.selectorLabels" . | nindent 8 }} 20 | spec: 21 | {{- with .Values.imagePullSecrets }} 22 | imagePullSecrets: 23 | {{- toYaml . | nindent 8 }} 24 | {{- end }} 25 | securityContext: 26 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 27 | containers: 28 | - name: {{ .Chart.Name }} 29 | securityContext: 30 | {{- toYaml .Values.securityContext | nindent 12 }} 31 | image: "{{ .Values.image.repository }}/cnap-inference:{{ .Values.image.tag | default .Chart.AppVersion }}" 32 | imagePullPolicy: {{ .Values.image.pullPolicy }} 33 | env: 34 | {{- toYaml .Values.env | nindent 10 }} 35 | ports: 36 | - name: http 37 | containerPort: {{ .Values.service.port }} 38 | protocol: TCP 39 | resources: 40 | {{- toYaml .Values.resources | nindent 12 }} 41 | initContainers: 42 | - name: init-{{ .Chart.Name }} 43 | image: busybox:1.28 44 | command: 45 | - 'sh' 46 | - '-c' 47 | - | 48 | check_redis() { 49 | echo -e "PING\r\n" | nc -w 1 {{ .Values.redis.service }} {{ .Values.redis.port }} \ 50 | | grep -q "+PONG" 51 | } 52 | 53 | until check_redis 54 | do 55 | echo "waiting for {{ .Values.redis.service }}" 56 | sleep 2 57 | done 58 | {{- with .Values.nodeSelector }} 59 | nodeSelector: 60 | {{- toYaml . | nindent 8 }} 61 | {{- end }} 62 | {{- with .Values.affinity }} 63 | affinity: 64 | {{- toYaml . | nindent 8 }} 65 | {{- end }} 66 | {{- with .Values.tolerations }} 67 | tolerations: 68 | {{- toYaml . | nindent 8 }} 69 | {{- end }} 70 | -------------------------------------------------------------------------------- /helm/inference/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "inference.fullname" . }}-service 5 | labels: 6 | {{- include "inference.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | targetPort: http 12 | protocol: TCP 13 | name: http 14 | selector: 15 | {{- include "inference.selectorLabels" . | nindent 4 }} 16 | -------------------------------------------------------------------------------- /helm/inference/templates/servicemonitor.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: ServiceMonitor 3 | metadata: 4 | name: {{ include "inference.fullname" . }} 5 | labels: 6 | {{- include "inference.labels" . | nindent 4 }} 7 | spec: 8 | selector: 9 | matchLabels: 10 | {{- include "inference.selectorLabels" . | nindent 6 }} 11 | endpoints: 12 | - port: http 13 | interval: 15s 14 | -------------------------------------------------------------------------------- /helm/inference/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for inference. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: 9 | pullPolicy: IfNotPresent 10 | # Overrides the image tag whose default is the chart appVersion. 11 | tag: "" 12 | 13 | imagePullSecrets: [] 14 | nameOverride: "" 15 | fullnameOverride: "" 16 | 17 | podAnnotations: {} 18 | 19 | podSecurityContext: {} 20 | # fsGroup: 2000 21 | 22 | securityContext: {} 23 | # capabilities: 24 | # drop: 25 | # - ALL 26 | # readOnlyRootFilesystem: true 27 | # runAsNonRoot: true 28 | # runAsUser: 1000 29 | 30 | service: 31 | type: ClusterIP 32 | port: 8000 33 | 34 | resources: {} 35 | # We usually recommend not to specify default resources and to leave this as a conscious 36 | # choice for the user. This also increases chances charts run on environments with little 37 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 38 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 39 | # limits: 40 | # cpu: 100m 41 | # memory: 128Mi 42 | # requests: 43 | # cpu: 100m 44 | # memory: 128Mi 45 | 46 | nodeSelector: {} 47 | 48 | tolerations: [] 49 | 50 | affinity: {} 51 | 52 | redis: 53 | service: "redis-service" 54 | port: 6379 55 | 56 | env: 57 | - name: RUNTIME_DB_TYPE 58 | value: "redis" 59 | - name: REDIS_HOST 60 | value: "redis-service" 61 | - name: QUEUE_TYPE 62 | value: "redis" 63 | - name: QUEUE_HOST 64 | value: "redis-service" 65 | - name: BROKER_TYPE 66 | value: "redis" 67 | - name: BROKER_HOST 68 | value: "redis-service" 69 | - name: INFER_MODEL_PROVIDER 70 | value: "simple" 71 | - name: INFER_MODEL_INFO_URL 72 | value: "" 73 | - name: INFER_MODEL_ID 74 | value: "" 75 | - name: INFER_DEVICE 76 | value: "cpu" 77 | - name: OMP_NUM_THREADS 78 | value: "1" 79 | - name: TF_NUM_INTEROP_THREADS 80 | value: "'1'" 81 | - name: TF_NUM_INTRAOP_THREADS 82 | value: "'1'" 83 | - name: KMP_AFFINITY 84 | value: "granularity=fine,verbose,compact,1,0" 85 | 86 | -------------------------------------------------------------------------------- /helm/pipelineapi/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/pipelineapi/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: pipelineapi 3 | description: A Helm chart for pipeline runtime database RESTful api service 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.1 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "" 25 | -------------------------------------------------------------------------------- /helm/pipelineapi/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | Deployed pipeline runtime database RESTful api service, you can run `helm test {{ include "pipelineapi.fullname" . }}` to test if the deployment succeeded. 2 | -------------------------------------------------------------------------------- /helm/pipelineapi/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "pipelineapi.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "pipelineapi.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "pipelineapi.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "pipelineapi.labels" -}} 37 | helm.sh/chart: {{ include "pipelineapi.chart" . }} 38 | {{ include "pipelineapi.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "pipelineapi.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "pipelineapi.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "pipelineapi.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "pipelineapi.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /helm/pipelineapi/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "pipelineapi.fullname" . }} 5 | labels: 6 | {{- include "pipelineapi.labels" . | nindent 4 }} 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | {{- include "pipelineapi.selectorLabels" . | nindent 6 }} 12 | template: 13 | metadata: 14 | {{- with .Values.podAnnotations }} 15 | annotations: 16 | {{- toYaml . | nindent 8 }} 17 | {{- end }} 18 | labels: 19 | {{- include "pipelineapi.selectorLabels" . | nindent 8 }} 20 | spec: 21 | {{- with .Values.imagePullSecrets }} 22 | imagePullSecrets: 23 | {{- toYaml . | nindent 8 }} 24 | {{- end }} 25 | securityContext: 26 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 27 | containers: 28 | - name: {{ .Chart.Name }} 29 | securityContext: 30 | {{- toYaml .Values.securityContext | nindent 12 }} 31 | image: "{{ .Values.image.repository }}/cnap-ppdb:{{ .Values.image.tag | default .Chart.AppVersion }}" 32 | imagePullPolicy: {{ .Values.image.pullPolicy }} 33 | env: 34 | {{- toYaml .Values.env | nindent 10 }} 35 | ports: 36 | - name: http 37 | containerPort: {{ .Values.service.port }} 38 | protocol: TCP 39 | livenessProbe: 40 | httpGet: 41 | path: /healthz 42 | port: http 43 | initialDelaySeconds: 5 44 | timeoutSeconds: 5 45 | readinessProbe: 46 | httpGet: 47 | path: /healthz 48 | port: http 49 | initialDelaySeconds: 5 50 | timeoutSeconds: 5 51 | resources: 52 | {{- toYaml .Values.resources | nindent 12 }} 53 | initContainers: 54 | - name: init-{{ .Chart.Name }} 55 | image: busybox:1.28 56 | command: 57 | - 'sh' 58 | - '-c' 59 | - | 60 | check_redis() { 61 | echo -e "PING\r\n" | nc -w 1 {{ .Values.redis.service }} {{ .Values.redis.port }} \ 62 | | grep -q "+PONG" 63 | } 64 | 65 | until check_redis 66 | do 67 | echo "waiting for {{ .Values.redis.service }}" 68 | sleep 2 69 | done 70 | {{- with .Values.nodeSelector }} 71 | nodeSelector: 72 | {{- toYaml . | nindent 8 }} 73 | {{- end }} 74 | {{- with .Values.affinity }} 75 | affinity: 76 | {{- toYaml . | nindent 8 }} 77 | {{- end }} 78 | {{- with .Values.tolerations }} 79 | tolerations: 80 | {{- toYaml . | nindent 8 }} 81 | {{- end }} 82 | -------------------------------------------------------------------------------- /helm/pipelineapi/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "pipelineapi.fullname" . }}-service 5 | labels: 6 | {{- include "pipelineapi.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | targetPort: http 12 | nodePort: {{ .Values.service.nodePort }} 13 | protocol: TCP 14 | name: http 15 | selector: 16 | {{- include "pipelineapi.selectorLabels" . | nindent 4 }} 17 | -------------------------------------------------------------------------------- /helm/pipelineapi/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "pipelineapi.fullname" . }}-test-connection" 5 | labels: 6 | {{- include "pipelineapi.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test 9 | spec: 10 | containers: 11 | - name: wget 12 | image: busybox:1.28 13 | command: ['wget'] 14 | args: ['{{ include "pipelineapi.fullname" . }}-service:{{ .Values.service.port }}/healthz'] 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /helm/pipelineapi/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for pipelineapi. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: 9 | pullPolicy: IfNotPresent 10 | # Overrides the image tag whose default is the chart appVersion. 11 | tag: "" 12 | 13 | imagePullSecrets: [] 14 | nameOverride: "" 15 | fullnameOverride: "" 16 | 17 | podAnnotations: {} 18 | 19 | podSecurityContext: {} 20 | # fsGroup: 2000 21 | 22 | securityContext: {} 23 | # capabilities: 24 | # drop: 25 | # - ALL 26 | # readOnlyRootFilesystem: true 27 | # runAsNonRoot: true 28 | # runAsUser: 1000 29 | 30 | service: 31 | type: NodePort 32 | port: 5000 33 | nodePort: 31500 34 | 35 | resources: {} 36 | # We usually recommend not to specify default resources and to leave this as a conscious 37 | # choice for the user. This also increases chances charts run on environments with little 38 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 39 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 40 | # limits: 41 | # cpu: 100m 42 | # memory: 128Mi 43 | # requests: 44 | # cpu: 100m 45 | # memory: 128Mi 46 | 47 | nodeSelector: {} 48 | 49 | tolerations: [] 50 | 51 | affinity: {} 52 | 53 | redis: 54 | service: "redis-service" 55 | port: 6379 56 | 57 | env: 58 | - name: RUNTIME_DB_TYPE 59 | value: "redis" 60 | - name: REDIS_HOST 61 | value: "redis-service" 62 | -------------------------------------------------------------------------------- /helm/redis-exporter/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/redis-exporter/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: redis-exporter 3 | description: A Helm chart deploy the redis exporter of CNAP 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.1 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "v1.51.0" 25 | -------------------------------------------------------------------------------- /helm/redis-exporter/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | The redis-exporter deployed, you can run `helm test {{ include "redis-exporter.fullname" . }}` to test if the deployment succeeded. 2 | -------------------------------------------------------------------------------- /helm/redis-exporter/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "redis-exporter.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "redis-exporter.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "redis-exporter.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "redis-exporter.labels" -}} 37 | helm.sh/chart: {{ include "redis-exporter.chart" . }} 38 | {{ include "redis-exporter.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "redis-exporter.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "redis-exporter.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "redis-exporter.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "redis-exporter.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /helm/redis-exporter/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: grafana-{{ include "redis-exporter.fullname" . }}-dashboard 5 | namespace: {{ .Values.grafana.namespace }} 6 | labels: 7 | {{- toYaml .Values.grafana.dashboard_labels | nindent 4 }} 8 | data: 9 | {{ (.Files.Glob "dashboards/*.json").AsConfig | indent 2 }} 10 | -------------------------------------------------------------------------------- /helm/redis-exporter/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "redis-exporter.fullname" . }} 5 | labels: 6 | {{- include "redis-exporter.labels" . | nindent 4 }} 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | {{- include "redis-exporter.selectorLabels" . | nindent 6 }} 12 | template: 13 | metadata: 14 | {{- with .Values.podAnnotations }} 15 | annotations: 16 | {{- toYaml . | nindent 8 }} 17 | {{- end }} 18 | labels: 19 | {{- include "redis-exporter.selectorLabels" . | nindent 8 }} 20 | spec: 21 | {{- with .Values.imagePullSecrets }} 22 | imagePullSecrets: 23 | {{- toYaml . | nindent 8 }} 24 | {{- end }} 25 | securityContext: 26 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 27 | containers: 28 | - name: {{ .Chart.Name }} 29 | securityContext: 30 | {{- toYaml .Values.securityContext | nindent 12 }} 31 | image: "{{ .Values.redisExpertor.repository }}/redis_exporter:{{ .Values.redisExpertor.tag | default .Chart.AppVersion }}" 32 | imagePullPolicy: {{ .Values.redisExpertor.pullPolicy }} 33 | env: 34 | - name: REDIS_ADDR 35 | value: {{ .Values.redis.service }}:{{ .Values.redis.port }} 36 | ports: 37 | - name: http 38 | containerPort: {{ .Values.service.port }} 39 | protocol: TCP 40 | livenessProbe: 41 | httpGet: 42 | path: / 43 | port: http 44 | readinessProbe: 45 | httpGet: 46 | path: / 47 | port: http 48 | resources: 49 | {{- toYaml .Values.resources | nindent 12 }} 50 | initContainers: 51 | - name: init-{{ .Chart.Name }} 52 | image: busybox:1.28 53 | command: 54 | - 'sh' 55 | - '-c' 56 | - | 57 | check_redis() { 58 | echo -e "PING\r\n" | nc -w 1 {{ .Values.redis.service }} {{ .Values.redis.port }} \ 59 | | grep -q "+PONG" 60 | } 61 | 62 | until check_redis 63 | do 64 | echo "waiting for {{ .Values.redis.service }}" 65 | sleep 2 66 | done 67 | {{- with .Values.nodeSelector }} 68 | nodeSelector: 69 | {{- toYaml . | nindent 8 }} 70 | {{- end }} 71 | {{- with .Values.affinity }} 72 | affinity: 73 | {{- toYaml . | nindent 8 }} 74 | {{- end }} 75 | {{- with .Values.tolerations }} 76 | tolerations: 77 | {{- toYaml . | nindent 8 }} 78 | {{- end }} 79 | -------------------------------------------------------------------------------- /helm/redis-exporter/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "redis-exporter.fullname" . }} 5 | labels: 6 | {{- include "redis-exporter.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | targetPort: http 12 | protocol: TCP 13 | name: http 14 | selector: 15 | {{- include "redis-exporter.selectorLabels" . | nindent 4 }} 16 | -------------------------------------------------------------------------------- /helm/redis-exporter/templates/servicemonitor.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: ServiceMonitor 3 | metadata: 4 | name: {{ include "redis-exporter.fullname" . }} 5 | labels: 6 | {{- include "redis-exporter.labels" . | nindent 4 }} 7 | spec: 8 | selector: 9 | matchLabels: 10 | {{- include "redis-exporter.selectorLabels" . | nindent 6 }} 11 | endpoints: 12 | - port: http 13 | interval: 15s 14 | -------------------------------------------------------------------------------- /helm/redis-exporter/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "redis-exporter.fullname" . }}-test-connection" 5 | labels: 6 | {{- include "redis-exporter.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test 9 | spec: 10 | containers: 11 | - name: wget 12 | image: busybox:1.28 13 | command: ['wget'] 14 | args: ['{{ include "redis-exporter.fullname" . }}:{{ .Values.service.port }}'] 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /helm/redis-exporter/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for redis-exporter. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | redisExpertor: 8 | repository: docker.io/oliver006 9 | pullPolicy: IfNotPresent 10 | # Overrides the image tag whose default is the chart appVersion. 11 | tag: "v1.51.0" 12 | 13 | imagePullSecrets: [] 14 | nameOverride: "" 15 | fullnameOverride: "" 16 | 17 | podAnnotations: {} 18 | 19 | podSecurityContext: {} 20 | # fsGroup: 2000 21 | 22 | securityContext: 23 | runAsUser: 59000 24 | runAsGroup: 59000 25 | allowPrivilegeEscalation: false 26 | capabilities: 27 | drop: 28 | - ALL 29 | 30 | service: 31 | type: ClusterIP 32 | port: 9121 33 | 34 | resources: {} 35 | # We usually recommend not to specify default resources and to leave this as a conscious 36 | # choice for the user. This also increases chances charts run on environments with little 37 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 38 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 39 | # limits: 40 | # cpu: 100m 41 | # memory: 128Mi 42 | # requests: 43 | # cpu: 100m 44 | # memory: 128Mi 45 | 46 | nodeSelector: {} 47 | 48 | tolerations: [] 49 | 50 | affinity: {} 51 | 52 | redis: 53 | service: "redis-service" 54 | port: 6379 55 | 56 | grafana: 57 | namespace: monitoring 58 | dashboard_labels: 59 | grafana_dashboard: "1" 60 | -------------------------------------------------------------------------------- /helm/redis/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/redis/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: redis 3 | description: A Helm chart to deploy the redis server of CNAP 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.1 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "" 25 | -------------------------------------------------------------------------------- /helm/redis/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | Deployed Redis server, you can run `helm test {{ include "redis.fullname" . }}` to test if the deployment succeeded. 2 | -------------------------------------------------------------------------------- /helm/redis/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "redis.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "redis.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "redis.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "redis.labels" -}} 37 | helm.sh/chart: {{ include "redis.chart" . }} 38 | {{ include "redis.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "redis.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "redis.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "redis.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "redis.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /helm/redis/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: {{ include "redis.fullname" . }} 5 | data: 6 | redis.conf: 7 | {{- toYaml .Values.config | nindent 4 }} 8 | -------------------------------------------------------------------------------- /helm/redis/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "redis.fullname" . }} 5 | labels: 6 | {{- include "redis.labels" . | nindent 4 }} 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | {{- include "redis.selectorLabels" . | nindent 6 }} 12 | template: 13 | metadata: 14 | {{- with .Values.podAnnotations }} 15 | annotations: 16 | {{- toYaml . | nindent 8 }} 17 | {{- end }} 18 | labels: 19 | {{- include "redis.selectorLabels" . | nindent 8 }} 20 | spec: 21 | volumes: 22 | - name: config-volume 23 | configMap: 24 | name: {{ include "redis.fullname" . }} 25 | {{- with .Values.imagePullSecrets }} 26 | imagePullSecrets: 27 | {{- toYaml . | nindent 8 }} 28 | {{- end }} 29 | securityContext: 30 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 31 | containers: 32 | - name: {{ .Chart.Name }} 33 | {{- if .Values.dsa.enabled }} 34 | image: "{{ .Values.image.repository }}/cnap-redis:{{ .Values.image.tag | default .Chart.AppVersion }}" 35 | command: ["/opt/redis/redis-server-dto"] 36 | resources: 37 | limits: 38 | dsa.intel.com/wq-user-shared: "{{ .Values.dsa.wqnumbers }}" 39 | {{- else }} 40 | image: "docker.io/redis:7.0" 41 | command: ["redis-server"] 42 | {{- end }} 43 | args: ["/etc/redis.conf"] 44 | imagePullPolicy: {{ .Values.image.pullPolicy }} 45 | securityContext: 46 | {{- toYaml .Values.securityContext | nindent 12 }} 47 | volumeMounts: 48 | - name: config-volume 49 | mountPath: /etc/redis.conf 50 | subPath: redis.conf 51 | ports: 52 | - name: http 53 | containerPort: {{ .Values.service.port }} 54 | protocol: TCP 55 | livenessProbe: 56 | exec: 57 | command: 58 | - sh 59 | - -c 60 | - redis-cli ping 61 | initialDelaySeconds: 5 62 | timeoutSeconds: 5 63 | readinessProbe: 64 | exec: 65 | command: 66 | - sh 67 | - -c 68 | - redis-cli ping 69 | initialDelaySeconds: 5 70 | timeoutSeconds: 5 71 | {{- with .Values.nodeSelector }} 72 | nodeSelector: 73 | {{- toYaml . | nindent 8 }} 74 | {{- end }} 75 | {{- with .Values.affinity }} 76 | affinity: 77 | {{- toYaml . | nindent 8 }} 78 | {{- end }} 79 | {{- with .Values.tolerations }} 80 | tolerations: 81 | {{- toYaml . | nindent 8 }} 82 | {{- end }} 83 | -------------------------------------------------------------------------------- /helm/redis/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "redis.fullname" . }}-service 5 | labels: 6 | {{- include "redis.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | targetPort: http 12 | protocol: TCP 13 | name: http 14 | selector: 15 | {{- include "redis.selectorLabels" . | nindent 4 }} 16 | -------------------------------------------------------------------------------- /helm/redis/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "redis.fullname" . }}-test-connection" 5 | labels: 6 | {{- include "redis.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test 9 | spec: 10 | containers: 11 | - name: "{{ .Chart.Name }}-test" 12 | {{- if .Values.dsa.enabled }} 13 | image: "{{ .Values.image.repository }}/cnap-redis:{{ .Values.image.tag | default .Chart.AppVersion }}" 14 | {{- else }} 15 | image: "docker.io/redis:7.0" 16 | {{- end }} 17 | command: 18 | - sh 19 | - -c 20 | - redis-cli -h {{ include "redis.fullname" . }}-service -p {{ .Values.service.port }} info server 21 | restartPolicy: Never 22 | -------------------------------------------------------------------------------- /helm/redis/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for redis. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: 9 | pullPolicy: IfNotPresent 10 | # Overrides the image tag whose default is the chart appVersion. 11 | tag: "" 12 | 13 | imagePullSecrets: [] 14 | nameOverride: "" 15 | fullnameOverride: "" 16 | 17 | podAnnotations: {} 18 | 19 | podSecurityContext: {} 20 | # fsGroup: 2000 21 | 22 | securityContext: {} 23 | # capabilities: 24 | # drop: 25 | # - ALL 26 | # readOnlyRootFilesystem: true 27 | # runAsNonRoot: true 28 | # runAsUser: 1000 29 | 30 | service: 31 | type: ClusterIP 32 | port: 6379 33 | 34 | # move resources to redis deployment because device plugin resouce also there. 35 | # resources: {} 36 | # We usually recommend not to specify default resources and to leave this as a conscious 37 | # choice for the user. This also increases chances charts run on environments with little 38 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 39 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 40 | # limits: 41 | # cpu: 100m 42 | # memory: 128Mi 43 | # requests: 44 | # cpu: 100m 45 | # memory: 128Mi 46 | 47 | dsa: 48 | enabled: false 49 | wqnumbers: 2 50 | 51 | nodeSelector: {} 52 | 53 | tolerations: [] 54 | 55 | affinity: {} 56 | 57 | # Add config to override the default settings of redis.conf 58 | config: |- 59 | # Disable protected mode 60 | protected-mode no 61 | # Disable RDB persistence 62 | save "" 63 | -------------------------------------------------------------------------------- /helm/stream/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/stream/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: stream 3 | description: A Helm chart for streaming service of CNAP 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.1 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "" 25 | -------------------------------------------------------------------------------- /helm/stream/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | The streaming service deployed. 2 | -------------------------------------------------------------------------------- /helm/stream/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "stream.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "stream.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "stream.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "stream.labels" -}} 37 | helm.sh/chart: {{ include "stream.chart" . }} 38 | {{ include "stream.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "stream.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "stream.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "stream.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "stream.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /helm/stream/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "stream.fullname" . }} 5 | labels: 6 | {{- include "stream.labels" . | nindent 4 }} 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | {{- include "stream.selectorLabels" . | nindent 6 }} 12 | template: 13 | metadata: 14 | {{- with .Values.podAnnotations }} 15 | annotations: 16 | {{- toYaml . | nindent 8 }} 17 | {{- end }} 18 | labels: 19 | {{- include "stream.selectorLabels" . | nindent 8 }} 20 | spec: 21 | {{- with .Values.imagePullSecrets }} 22 | imagePullSecrets: 23 | {{- toYaml . | nindent 8 }} 24 | {{- end }} 25 | securityContext: 26 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 27 | containers: 28 | - name: {{ .Chart.Name }} 29 | securityContext: 30 | {{- toYaml .Values.securityContext | nindent 12 }} 31 | image: "{{ .Values.image.repository }}/cnap-streaming:{{ .Values.image.tag | default .Chart.AppVersion }}" 32 | imagePullPolicy: {{ .Values.image.pullPolicy }} 33 | env: 34 | {{- toYaml .Values.env | nindent 10 }} 35 | resources: 36 | {{- toYaml .Values.resources | nindent 12 }} 37 | initContainers: 38 | - name: init-{{ .Chart.Name }} 39 | image: busybox:1.28 40 | command: 41 | - 'sh' 42 | - '-c' 43 | - | 44 | check_redis() { 45 | echo -e "PING\r\n" | nc -w 1 {{ .Values.redis.service }} {{ .Values.redis.port }} \ 46 | | grep -q "+PONG" 47 | } 48 | 49 | until check_redis 50 | do 51 | echo "waiting for {{ .Values.redis.service }}" 52 | sleep 2 53 | done 54 | {{- with .Values.nodeSelector }} 55 | nodeSelector: 56 | {{- toYaml . | nindent 8 }} 57 | {{- end }} 58 | {{- with .Values.affinity }} 59 | affinity: 60 | {{- toYaml . | nindent 8 }} 61 | {{- end }} 62 | {{- with .Values.tolerations }} 63 | tolerations: 64 | {{- toYaml . | nindent 8 }} 65 | {{- end }} 66 | -------------------------------------------------------------------------------- /helm/stream/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for stream. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: 9 | pullPolicy: IfNotPresent 10 | # Overrides the image tag whose default is the chart appVersion. 11 | tag: "" 12 | 13 | imagePullSecrets: [] 14 | nameOverride: "" 15 | fullnameOverride: "" 16 | 17 | podAnnotations: {} 18 | 19 | podSecurityContext: {} 20 | # fsGroup: 2000 21 | 22 | securityContext: {} 23 | # capabilities: 24 | # drop: 25 | # - ALL 26 | # readOnlyRootFilesystem: true 27 | # runAsNonRoot: true 28 | # runAsUser: 1000 29 | 30 | resources: {} 31 | # We usually recommend not to specify default resources and to leave this as a conscious 32 | # choice for the user. This also increases chances charts run on environments with little 33 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 34 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 35 | # limits: 36 | # cpu: 100m 37 | # memory: 128Mi 38 | # requests: 39 | # cpu: 100m 40 | # memory: 128Mi 41 | 42 | nodeSelector: {} 43 | 44 | tolerations: [] 45 | 46 | affinity: {} 47 | 48 | redis: 49 | service: "redis-service" 50 | port: 6379 51 | 52 | env: 53 | - name: RUNTIME_DB_TYPE 54 | value: "redis" 55 | - name: REDIS_HOST 56 | value: "redis-service" 57 | - name: QUEUE_TYPE 58 | value: "redis" 59 | - name: QUEUE_HOST 60 | value: "redis-service" 61 | - name: PROVIDER_TYPE 62 | value: "file" 63 | - name: PROVIDER_NAME 64 | value: "classroom" 65 | - name: PROVIDER_PATHNAME 66 | value: "classroom.mp4" 67 | - name: INFER_FRAMEWORK 68 | value: "tensorflow" 69 | - name: INFER_TARGET 70 | value: "object-detection" 71 | - name: INFER_DEVICE 72 | value: "cpu" 73 | - name: INFER_MODEL_NAME 74 | value: "ssdmobilenet" 75 | - name: INFER_MODEL_VERSION 76 | value: "1.0" 77 | -------------------------------------------------------------------------------- /helm/ui/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/ui/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: ui 3 | description: A Helm chart for spa service of CNAP 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.1 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "" 25 | -------------------------------------------------------------------------------- /helm/ui/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | The spa service deployed, you can access the spa by visiting the `http://:{{ .Values.service.nodePort }}` in your browser. 2 | -------------------------------------------------------------------------------- /helm/ui/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "ui.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "ui.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "ui.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "ui.labels" -}} 37 | helm.sh/chart: {{ include "ui.chart" . }} 38 | {{ include "ui.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "ui.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "ui.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "ui.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "ui.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /helm/ui/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "ui.fullname" . }} 5 | labels: 6 | {{- include "ui.labels" . | nindent 4 }} 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | {{- include "ui.selectorLabels" . | nindent 6 }} 12 | template: 13 | metadata: 14 | {{- with .Values.podAnnotations }} 15 | annotations: 16 | {{- toYaml . | nindent 8 }} 17 | {{- end }} 18 | labels: 19 | {{- include "ui.selectorLabels" . | nindent 8 }} 20 | spec: 21 | {{- with .Values.imagePullSecrets }} 22 | imagePullSecrets: 23 | {{- toYaml . | nindent 8 }} 24 | {{- end }} 25 | securityContext: 26 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 27 | containers: 28 | - name: {{ .Chart.Name }} 29 | securityContext: 30 | {{- toYaml .Values.securityContext | nindent 12 }} 31 | image: "{{ .Values.image.repository }}/cnap-spa:{{ .Values.image.tag | default .Chart.AppVersion }}" 32 | imagePullPolicy: {{ .Values.image.pullPolicy }} 33 | env: 34 | {{- toYaml .Values.env | nindent 10 }} 35 | ports: 36 | - name: http 37 | containerPort: {{ .Values.service.port }} 38 | protocol: TCP 39 | livenessProbe: 40 | httpGet: 41 | path: / 42 | port: http 43 | initialDelaySeconds: 5 44 | timeoutSeconds: 5 45 | readinessProbe: 46 | httpGet: 47 | path: / 48 | port: http 49 | initialDelaySeconds: 5 50 | timeoutSeconds: 5 51 | resources: 52 | {{- toYaml .Values.resources | nindent 12 }} 53 | {{- with .Values.nodeSelector }} 54 | nodeSelector: 55 | {{- toYaml . | nindent 8 }} 56 | {{- end }} 57 | {{- with .Values.affinity }} 58 | affinity: 59 | {{- toYaml . | nindent 8 }} 60 | {{- end }} 61 | {{- with .Values.tolerations }} 62 | tolerations: 63 | {{- toYaml . | nindent 8 }} 64 | {{- end }} 65 | -------------------------------------------------------------------------------- /helm/ui/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "ui.fullname" . }}-service 5 | labels: 6 | {{- include "ui.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | targetPort: http 12 | nodePort: {{ .Values.service.nodePort }} 13 | protocol: TCP 14 | name: http 15 | selector: 16 | {{- include "ui.selectorLabels" . | nindent 4 }} 17 | -------------------------------------------------------------------------------- /helm/ui/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for ui. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: 9 | pullPolicy: IfNotPresent 10 | # Overrides the image tag whose default is the chart appVersion. 11 | tag: "" 12 | 13 | imagePullSecrets: [] 14 | nameOverride: "" 15 | fullnameOverride: "" 16 | 17 | podAnnotations: {} 18 | 19 | podSecurityContext: {} 20 | # fsGroup: 2000 21 | 22 | securityContext: {} 23 | # capabilities: 24 | # drop: 25 | # - ALL 26 | # readOnlyRootFilesystem: true 27 | # runAsNonRoot: true 28 | # runAsUser: 1000 29 | 30 | service: 31 | type: NodePort 32 | port: 5173 33 | nodePort: 31002 34 | 35 | resources: {} 36 | # We usually recommend not to specify default resources and to leave this as a conscious 37 | # choice for the user. This also increases chances charts run on environments with little 38 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 39 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 40 | # limits: 41 | # cpu: 100m 42 | # memory: 128Mi 43 | # requests: 44 | # cpu: 100m 45 | # memory: 128Mi 46 | 47 | nodeSelector: {} 48 | 49 | tolerations: [] 50 | 51 | affinity: {} 52 | 53 | env: 54 | - name: VITE_PPDB_SERVER_PORT 55 | value: "31500" 56 | -------------------------------------------------------------------------------- /helm/websocket/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/websocket/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: websocket 3 | description: A Helm chart for websocket service of CNAP 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.1 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "" 25 | -------------------------------------------------------------------------------- /helm/websocket/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | Deployed websocket server, you can run `helm test {{ include "websocket.fullname" . }}` to test if the deployment succeeded. 2 | -------------------------------------------------------------------------------- /helm/websocket/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "websocket.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "websocket.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "websocket.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "websocket.labels" -}} 37 | helm.sh/chart: {{ include "websocket.chart" . }} 38 | {{ include "websocket.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "websocket.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "websocket.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "websocket.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "websocket.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /helm/websocket/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "websocket.fullname" . }} 5 | labels: 6 | {{- include "websocket.labels" . | nindent 4 }} 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | {{- include "websocket.selectorLabels" . | nindent 6 }} 12 | template: 13 | metadata: 14 | {{- with .Values.podAnnotations }} 15 | annotations: 16 | {{- toYaml . | nindent 8 }} 17 | {{- end }} 18 | labels: 19 | {{- include "websocket.selectorLabels" . | nindent 8 }} 20 | spec: 21 | {{- with .Values.imagePullSecrets }} 22 | imagePullSecrets: 23 | {{- toYaml . | nindent 8 }} 24 | {{- end }} 25 | securityContext: 26 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 27 | containers: 28 | - name: {{ .Chart.Name }} 29 | securityContext: 30 | {{- toYaml .Values.securityContext | nindent 12 }} 31 | image: "{{ .Values.image.repository }}/cnap-wss:{{ .Values.image.tag | default .Chart.AppVersion }}" 32 | imagePullPolicy: {{ .Values.image.pullPolicy }} 33 | env: 34 | {{- toYaml .Values.env | nindent 10 }} 35 | ports: 36 | - name: http 37 | containerPort: {{ .Values.service.port }} 38 | protocol: TCP 39 | livenessProbe: 40 | httpGet: 41 | path: /healthz 42 | port: http 43 | initialDelaySeconds: 5 44 | timeoutSeconds: 5 45 | readinessProbe: 46 | httpGet: 47 | path: /healthz 48 | port: http 49 | initialDelaySeconds: 5 50 | timeoutSeconds: 5 51 | resources: 52 | {{- toYaml .Values.resources | nindent 12 }} 53 | initContainers: 54 | - name: init-{{ .Chart.Name }} 55 | image: busybox:1.28 56 | command: 57 | - 'sh' 58 | - '-c' 59 | - | 60 | check_redis() { 61 | echo -e "PING\r\n" | nc -w 1 {{ .Values.redis.service }} {{ .Values.redis.port }} \ 62 | | grep -q "+PONG" 63 | } 64 | 65 | until check_redis 66 | do 67 | echo "waiting for {{ .Values.redis.service }}" 68 | sleep 2 69 | done 70 | {{- with .Values.nodeSelector }} 71 | nodeSelector: 72 | {{- toYaml . | nindent 8 }} 73 | {{- end }} 74 | {{- with .Values.affinity }} 75 | affinity: 76 | {{- toYaml . | nindent 8 }} 77 | {{- end }} 78 | {{- with .Values.tolerations }} 79 | tolerations: 80 | {{- toYaml . | nindent 8 }} 81 | {{- end }} 82 | -------------------------------------------------------------------------------- /helm/websocket/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "websocket.fullname" . }}-service 5 | labels: 6 | {{- include "websocket.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | targetPort: http 12 | nodePort: {{ .Values.service.nodePort }} 13 | protocol: TCP 14 | name: http 15 | selector: 16 | {{- include "websocket.selectorLabels" . | nindent 4 }} 17 | -------------------------------------------------------------------------------- /helm/websocket/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "websocket.fullname" . }}-test-connection" 5 | labels: 6 | {{- include "websocket.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test 9 | spec: 10 | containers: 11 | - name: wget 12 | image: busybox:1.28 13 | command: ['wget'] 14 | args: ['{{ include "websocket.fullname" . }}-service:{{ .Values.service.port }}/healthz'] 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /helm/websocket/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for websocket. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: 9 | pullPolicy: IfNotPresent 10 | # Overrides the image tag whose default is the chart appVersion. 11 | tag: "" 12 | 13 | imagePullSecrets: [] 14 | nameOverride: "" 15 | fullnameOverride: "" 16 | 17 | podAnnotations: {} 18 | 19 | podSecurityContext: {} 20 | # fsGroup: 2000 21 | 22 | securityContext: {} 23 | # capabilities: 24 | # drop: 25 | # - ALL 26 | # readOnlyRootFilesystem: true 27 | # runAsNonRoot: true 28 | # runAsUser: 1000 29 | 30 | service: 31 | type: NodePort 32 | port: 31611 33 | nodePort: 31611 34 | 35 | resources: {} 36 | # We usually recommend not to specify default resources and to leave this as a conscious 37 | # choice for the user. This also increases chances charts run on environments with little 38 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 39 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 40 | # limits: 41 | # cpu: 100m 42 | # memory: 128Mi 43 | # requests: 44 | # cpu: 100m 45 | # memory: 128Mi 46 | 47 | nodeSelector: {} 48 | 49 | tolerations: [] 50 | 51 | affinity: {} 52 | 53 | redis: 54 | service: "redis-service" 55 | port: 6379 56 | 57 | env: 58 | - name: STREAM_BROKER_REDIS_HOST 59 | value: "redis-service" 60 | -------------------------------------------------------------------------------- /k8s-manifests/grafana/configmaps/grafana-config-cm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: grafana-config 5 | namespace: monitoring 6 | labels: 7 | app.kubernetes.io/name: grafana 8 | data: 9 | grafana.ini: | 10 | [analytics] 11 | check_for_updates = true 12 | 13 | [auth.anonymous] 14 | enabled = true 15 | 16 | [grafana_net] 17 | url = https://grafana.net 18 | 19 | [log] 20 | mode = console 21 | 22 | [paths] 23 | data = /var/lib/grafana/ 24 | logs = /var/log/grafana 25 | plugins = /var/lib/grafana/plugins 26 | provisioning = /etc/grafana/provisioning 27 | 28 | [security] 29 | allow_embedding = true 30 | 31 | [server] 32 | domain = '' 33 | -------------------------------------------------------------------------------- /k8s-manifests/grafana/patches/grafana-patch.yaml: -------------------------------------------------------------------------------- 1 | spec: 2 | template: 3 | spec: 4 | containers: 5 | - name: grafana 6 | volumeMounts: 7 | - name: grafana-config-volume 8 | mountPath: /etc/grafana/grafana.ini 9 | subPath: grafana.ini 10 | volumes: 11 | - name: grafana-config-volume 12 | configMap: 13 | name: grafana-config 14 | -------------------------------------------------------------------------------- /k8s-manifests/keda/infer_scale.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: keda.sh/v1alpha1 2 | kind: ScaledObject 3 | metadata: 4 | name: ineference-scale 5 | namespace: 6 | spec: 7 | scaleTargetRef: 8 | name: inference 9 | minReplicaCount: 1 10 | maxReplicaCount: 10 11 | pollingInterval: 5 # Optional. Default: 30 seconds 12 | cooldownPeriod: 30 # Optional. Default: 300 seconds 13 | triggers: 14 | - type: prometheus 15 | metadata: 16 | serverAddress: http:// 17 | metricName: drop_fps 18 | threshold: '10' # Define the threshold for scaling 19 | query: sum(drop_fps) by (job) 20 | 21 | -------------------------------------------------------------------------------- /k8s-manifests/keda/keda-service-monitor.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: ServiceMonitor 3 | metadata: 4 | name: keda-metrics-apiserver-monitor 5 | namespace: keda 6 | labels: 7 | app.kubernetes.io/name: keda-metrics-apiserver 8 | spec: 9 | selector: 10 | matchLabels: 11 | app.kubernetes.io/name: keda-metrics-apiserver 12 | endpoints: 13 | - port: metrics 14 | interval: 15s 15 | 16 | --- 17 | apiVersion: monitoring.coreos.com/v1 18 | kind: ServiceMonitor 19 | metadata: 20 | name: keda-operator-monitor 21 | namespace: keda 22 | labels: 23 | app.kubernetes.io/name: keda-operator 24 | spec: 25 | selector: 26 | matchLabels: 27 | app.kubernetes.io/name: keda-operator 28 | endpoints: 29 | - port: metrics 30 | interval: 15s 31 | 32 | --- 33 | apiVersion: monitoring.coreos.com/v1 34 | kind: ServiceMonitor 35 | metadata: 36 | name: keda-admission-monitor 37 | namespace: keda 38 | labels: 39 | app.kubernetes.io/component: admission-webhooks 40 | app.kubernetes.io/instance: admission-webhooks 41 | app.kubernetes.io/part-of: keda-operator 42 | spec: 43 | selector: 44 | matchLabels: 45 | app.kubernetes.io/component: admission-webhooks 46 | app.kubernetes.io/instance: admission-webhooks 47 | app.kubernetes.io/part-of: keda-operator 48 | endpoints: 49 | - port: metrics 50 | interval: 15s 51 | 52 | -------------------------------------------------------------------------------- /k8s-manifests/plugin/dsa/config_dsa/configs/1e1w-d.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "dev":"dsa0", 4 | "token_limit":0, 5 | "groups":[ 6 | { 7 | "dev":"group0.0", 8 | "tokens_reserved":0, 9 | "use_token_limit":0, 10 | "grouped_workqueues":[ 11 | { 12 | "dev":"wq0.0", 13 | "mode":"dedicated", 14 | "size":128, 15 | "group_id":0, 16 | "priority":10, 17 | "block_on_fault":0, 18 | "type":"user", 19 | "name":"app1", 20 | "threshold":15 21 | } 22 | ], 23 | "grouped_engines":[ 24 | { 25 | "dev":"engine0.0", 26 | "group_id":0 27 | } 28 | ] 29 | } 30 | ] 31 | } 32 | ] 33 | -------------------------------------------------------------------------------- /k8s-manifests/plugin/dsa/config_dsa/configs/1e1w-s.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "dev":"dsa0", 4 | "token_limit":0, 5 | "groups":[ 6 | { 7 | "dev":"group0.0", 8 | "tokens_reserved":0, 9 | "use_token_limit":0, 10 | "grouped_workqueues":[ 11 | { 12 | "dev":"wq0.0", 13 | "mode":"shared", 14 | "size":128, 15 | "group_id":0, 16 | "priority":10, 17 | "block_on_fault":0, 18 | "type":"user", 19 | "name":"app1", 20 | "threshold":128 21 | } 22 | ], 23 | "grouped_engines":[ 24 | { 25 | "dev":"engine0.0", 26 | "group_id":0 27 | } 28 | ] 29 | } 30 | ] 31 | } 32 | ] 33 | -------------------------------------------------------------------------------- /k8s-manifests/plugin/dsa/config_dsa/configs/4e1w-d.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "dev":"dsa0", 4 | "token_limit":0, 5 | "groups":[ 6 | { 7 | "dev":"group0.0", 8 | "tokens_reserved":0, 9 | "use_token_limit":0, 10 | "grouped_workqueues":[ 11 | { 12 | "dev":"wq0.0", 13 | "mode":"dedicated", 14 | "size":128, 15 | "group_id":0, 16 | "priority":10, 17 | "block_on_fault":0, 18 | "type":"user", 19 | "name":"app1", 20 | "threshold":15 21 | } 22 | ], 23 | "grouped_engines":[ 24 | { 25 | "dev":"engine0.0", 26 | "group_id":0 27 | }, 28 | { 29 | "dev":"engine0.1", 30 | "group_id":0 31 | }, 32 | { 33 | "dev":"engine0.2", 34 | "group_id":0 35 | }, 36 | { 37 | "dev":"engine0.3", 38 | "group_id":0 39 | } 40 | ] 41 | } 42 | ] 43 | } 44 | ] 45 | -------------------------------------------------------------------------------- /k8s-manifests/plugin/dsa/config_dsa/configs/4e4w-d.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "dev":"dsa0", 4 | "token_limit":0, 5 | "groups":[ 6 | { 7 | "dev":"group0.0", 8 | "tokens_reserved":0, 9 | "use_token_limit":0, 10 | "grouped_workqueues":[ 11 | { 12 | "dev":"wq0.0", 13 | "mode":"dedicated", 14 | "size":32, 15 | "group_id":0, 16 | "priority":10, 17 | "block_on_fault":0, 18 | "type":"user", 19 | "name":"app1", 20 | "threshold":15 21 | }, 22 | { 23 | "dev":"wq0.1", 24 | "mode":"dedicated", 25 | "size":32, 26 | "group_id":0, 27 | "priority":10, 28 | "block_on_fault":0, 29 | "type":"user", 30 | "name":"app2", 31 | "threshold":15 32 | }, 33 | { 34 | "dev":"wq0.2", 35 | "mode":"dedicated", 36 | "size":32, 37 | "group_id":0, 38 | "priority":10, 39 | "block_on_fault":0, 40 | "type":"user", 41 | "name":"app3", 42 | "threshold":15 43 | }, 44 | { 45 | "dev":"wq0.3", 46 | "mode":"dedicated", 47 | "size":32, 48 | "group_id":0, 49 | "priority":10, 50 | "block_on_fault":0, 51 | "type":"user", 52 | "name":"app1", 53 | "threshold":15 54 | } 55 | ], 56 | "grouped_engines":[ 57 | { 58 | "dev":"engine0.0", 59 | "group_id":0 60 | }, 61 | { 62 | "dev":"engine0.1", 63 | "group_id":0 64 | }, 65 | { 66 | "dev":"engine0.2", 67 | "group_id":0 68 | }, 69 | { 70 | "dev":"engine0.3", 71 | "group_id":0 72 | } 73 | ] 74 | } 75 | ] 76 | } 77 | ] 78 | -------------------------------------------------------------------------------- /k8s-manifests/plugin/dsa/config_dsa/configs/4e8w-d.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "dev":"dsa0", 4 | "token_limit":0, 5 | "groups":[ 6 | { 7 | "dev":"group0.0", 8 | "tokens_reserved":0, 9 | "use_token_limit":0, 10 | "grouped_workqueues":[ 11 | { 12 | "dev":"wq0.0", 13 | "mode":"dedicated", 14 | "size":16, 15 | "group_id":0, 16 | "priority":10, 17 | "block_on_fault":0, 18 | "type":"user", 19 | "name":"app1", 20 | "threshold":15 21 | }, 22 | { 23 | "dev":"wq0.1", 24 | "mode":"dedicated", 25 | "size":16, 26 | "group_id":0, 27 | "priority":10, 28 | "block_on_fault":0, 29 | "type":"user", 30 | "name":"app2", 31 | "threshold":15 32 | }, 33 | { 34 | "dev":"wq0.2", 35 | "mode":"dedicated", 36 | "size":16, 37 | "group_id":0, 38 | "priority":10, 39 | "block_on_fault":0, 40 | "type":"user", 41 | "name":"app3", 42 | "threshold":15 43 | }, 44 | { 45 | "dev":"wq0.3", 46 | "mode":"dedicated", 47 | "size":16, 48 | "group_id":0, 49 | "priority":10, 50 | "block_on_fault":0, 51 | "type":"user", 52 | "name":"app1", 53 | "threshold":15 54 | }, 55 | { 56 | "dev":"wq0.4", 57 | "mode":"dedicated", 58 | "size":16, 59 | "group_id":0, 60 | "priority":10, 61 | "block_on_fault":0, 62 | "type":"user", 63 | "name":"app2", 64 | "threshold":15 65 | }, 66 | { 67 | "dev":"wq0.5", 68 | "mode":"dedicated", 69 | "size":16, 70 | "group_id":0, 71 | "priority":10, 72 | "block_on_fault":0, 73 | "type":"user", 74 | "name":"app3", 75 | "threshold":15 76 | }, 77 | { 78 | "dev":"wq0.6", 79 | "mode":"dedicated", 80 | "size":16, 81 | "group_id":0, 82 | "priority":10, 83 | "block_on_fault":0, 84 | "type":"user", 85 | "name":"app4", 86 | "threshold":15 87 | }, 88 | { 89 | "dev":"wq0.7", 90 | "mode":"dedicated", 91 | "size":16, 92 | "group_id":0, 93 | "priority":10, 94 | "block_on_fault":0, 95 | "type":"user", 96 | "name":"app4", 97 | "threshold":15 98 | } 99 | ], 100 | "grouped_engines":[ 101 | { 102 | "dev":"engine0.0", 103 | "group_id":0 104 | }, 105 | { 106 | "dev":"engine0.1", 107 | "group_id":0 108 | }, 109 | { 110 | "dev":"engine0.2", 111 | "group_id":0 112 | }, 113 | { 114 | "dev":"engine0.3", 115 | "group_id":0 116 | } 117 | ] 118 | } 119 | ] 120 | } 121 | ] 122 | -------------------------------------------------------------------------------- /k8s-manifests/plugin/dsa/config_dsa/setup_dsa.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | shopt -s nullglob 3 | num_dsa=$(echo /sys/bus/dsa/devices/dsa* | wc -w) 4 | 5 | script=$(basename "$0") 6 | 7 | usage() { 8 | cat < 17 | HELP_USAGE 18 | exit 19 | } 20 | 21 | unbind() { 22 | 23 | case $1 in 24 | 25 | 0) 26 | for ((i = 0; i < num_dsa ; i++ )) 27 | do 28 | echo wq"$did".$i > "$WQ_DRV_PATH"/unbind 2>/dev/null && echo disabled wq"$did".$i 29 | done 30 | 31 | echo "$dname" > "$DEV_DRV_PATH"/unbind 2>/dev/null && echo disabled "$dname" 32 | ;; 33 | 34 | 1) 35 | 36 | dname=$(grep "\"dev\":\"dsa" < "$config" | cut -f2 -d: | cut -f1 -d, | sed -e s/\"//g) 37 | 38 | readarray -d a -t tmp <<< "$dname" 39 | d=$(echo -n "${tmp[1]}" | tr -d '\n') 40 | 41 | for i in {0..7} 42 | do 43 | [[ $(cat /sys/bus/dsa/devices/"$dname"/wq"$d"."$i"/state) == "enabled" ]] && sudo accel-config disable-wq "$dname"/wq"$d"."$i" 44 | done 45 | 46 | [[ $(cat /sys/bus/dsa/devices/"$dname"/state) == "enabled" ]] && sudo accel-config disable-device "$dname" 47 | ;; 48 | 49 | *) 50 | echo "unknown" 51 | ;; 52 | esac 53 | } 54 | 55 | configure() { 56 | 57 | case $1 in 58 | 59 | 0) 60 | for ((i = 0; i < num_eng ; i++ )) 61 | do 62 | echo 0 > "$DSA_CONFIG_PATH"/"$dname"/engine"$did".$i/group_id 63 | done 64 | 65 | for ((i = 0; i < num_wq ; i++ )) 66 | do 67 | [ -d "$DSA_CONFIG_PATH"/"$dname"/wq"$did".$i/ ] && wq_dir=$DSA_CONFIG_PATH/$dname/wq$did.$i/ 68 | [ -d "$DSA_CONFIG_PATH"/wq"$did".$i/ ] && wq_dir=$DSA_CONFIG_PATH/wq$did.$i/ 69 | 70 | echo 0 > "$wq_dir"/block_on_fault 71 | echo 0 > "$wq_dir"/group_id 72 | echo "$mode" > "$wq_dir"/mode 73 | echo 10 > "$wq_dir"/priority 74 | echo "$size" > "$wq_dir"/size 75 | [[ $mode == shared ]] && echo 10 > "$wq_dir"/threshold 76 | echo "user" > "$wq_dir"/type 77 | echo "app$i" > "$wq_dir"/name 78 | done 79 | ;; 80 | 81 | 1) 82 | sudo accel-config load-config -c "$config" 83 | ;; 84 | 85 | *) 86 | echo "Unknown" 87 | ;; 88 | esac 89 | } 90 | 91 | bind() { 92 | # start devices 93 | case $1 in 94 | 0) 95 | echo "$dname" > "$DEV_DRV_PATH"/bind && echo enabled "$dname" 96 | 97 | for ((i = 0; i < num_wq ; i++ )) 98 | do 99 | echo wq"$did".$i > "$WQ_DRV_PATH"/bind && echo enabled wq"$did".$i 100 | done 101 | ;; 102 | 1) 103 | sudo accel-config enable-device "$dname" 104 | 105 | for i in {0..7} 106 | do 107 | [[ $(cat /sys/bus/dsa/devices/"$dname"/wq"$d"\."$i"/size) -ne "0" ]] && sudo accel-config enable-wq "$dname"/wq"$d"\."$i" 108 | done 109 | ;; 110 | *) 111 | echo "Unknown" 112 | ;; 113 | esac 114 | } 115 | 116 | do_config_file() { 117 | 118 | config=$1 119 | unbind 1 120 | configure 1 121 | bind 1 122 | 123 | exit 124 | } 125 | 126 | do_options() { 127 | num_wq=0 128 | num_eng=4 129 | 130 | if [[ ! "$*" =~ ^\-.+ ]] 131 | then 132 | usage 133 | fi 134 | 135 | while getopts d:w:m:e: flag 136 | do 137 | case "${flag}" in 138 | d) 139 | dname=${OPTARG} 140 | did=$(echo "$dname" | awk '{print substr($0,4)}') 141 | ;; 142 | w) 143 | num_wq=${OPTARG} 144 | ;; 145 | e) 146 | num_eng=${OPTARG} 147 | ;; 148 | m) 149 | mode=${OPTARG} 150 | ;; 151 | :) 152 | usage >&2 153 | ;; 154 | *) 155 | usage >&2 156 | ;; 157 | esac 158 | done 159 | 160 | [ -d /sys/bus/dsa/devices/"$dname" ] || { echo "Invalid dev name $dname" && exit 1; } 161 | 162 | DSA_CONFIG_PATH=/sys/bus/dsa/devices 163 | DEV_DRV_PATH=/sys/bus/dsa/drivers/dsa 164 | WQ_DRV_PATH=$DEV_DRV_PATH 165 | [ -d /sys/bus/dsa/drivers/user ] && WQ_DRV_PATH=/sys/bus/dsa/drivers/user 166 | 167 | if [ "$num_wq" -ne "0" ] 168 | then 169 | [[ $mode == "d" ]] && mode=dedicated 170 | [[ $mode == "s" ]] && mode=shared 171 | [[ $mode == "" ]] && usage 172 | 173 | wq_size=$(cat /sys/bus/dsa/devices/"$dname"/max_work_queues_size) 174 | size=$(( wq_size / num_wq )) 175 | 176 | unbind 0 177 | configure 0 178 | bind 0 179 | else 180 | echo "disabling device" "$dname" 181 | unbind 0 182 | fi 183 | 184 | exit 185 | } 186 | 187 | if [ $# -eq "0" ] 188 | then 189 | usage 190 | elif [ -f "$1" ] 191 | then 192 | do_config_file "$1" 193 | else 194 | do_options "$@" 195 | fi -------------------------------------------------------------------------------- /k8s-manifests/prometheus/ClusterRole-All.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: prometheus-k8s 5 | rules: 6 | - apiGroups: 7 | - "" 8 | resources: 9 | - nodes 10 | - services 11 | - endpoints 12 | - pods 13 | verbs: ["get", "list", "watch"] 14 | - nonResourceURLs: 15 | - /metrics 16 | verbs: 17 | - get 18 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | """The tests package. 2 | 3 | This package contains the tests for the core components of CNAP, including the 4 | implementations of engines, processors, stream brokers, etc. 5 | 6 | This package also contains the tests for the userv components of CNAP, including the 7 | unit tests for the userv engine, processor, stream broker, etc. 8 | """ 9 | -------------------------------------------------------------------------------- /tests/core/__init__.py: -------------------------------------------------------------------------------- 1 | """The tests.core package. 2 | 3 | This package contains the tests for the core components of CNAP, including the 4 | implementations of engines, processors, stream brokers, etc. 5 | """ 6 | -------------------------------------------------------------------------------- /tests/core/test_filedb.py: -------------------------------------------------------------------------------- 1 | """Tests for the file database module. 2 | 3 | This module contains the tests for the file database module. 4 | 5 | Functions: 6 | test_local_file_database_get_file: Tests the get_file method of the LocalFileDatabase class. 7 | test_local_file_database_get_file_invalid_root: Tests the get_file method of the 8 | LocalFileDatabase class with an invalid root directory. 9 | test_local_file_database_get_file_not_found: Tests the get_file method of the LocalFileDatabase 10 | class with a file that does not exist. 11 | """ 12 | 13 | import pytest 14 | 15 | from cnap.core import filedb 16 | 17 | def test_local_file_database_get_file(tmp_path): 18 | """Tests the get_file method of the LocalFileDatabase class. 19 | 20 | This test checks if the get_file method correctly finds the given file and returns its local 21 | path. 22 | 23 | Args: 24 | tmp_path (LocalPath): Temporary path provided by pytest's tmp_path fixture. 25 | """ 26 | # Create a temporary file for testing 27 | filename = 'test_file.txt' 28 | file_path = tmp_path / filename 29 | file_path.write_text('Hello, world!') 30 | 31 | root_dir = str(tmp_path) 32 | db = filedb.LocalFileDatabase(root_dir) 33 | assert db.get_file(filename) == str(file_path) 34 | 35 | def test_local_file_database_get_file_invalid_root(): 36 | """Tests the get_file method of the LocalFileDatabase class with an invalid root directory.""" 37 | root_dir = '/invalid/path' 38 | db = filedb.LocalFileDatabase(root_dir) 39 | with pytest.raises(FileNotFoundError): 40 | db.get_file('filename') 41 | 42 | def test_local_file_database_get_file_not_found(tmp_path): 43 | """Tests the get_file method of the LocalFileDatabase class with a file not found.""" 44 | root_dir = str(tmp_path) 45 | db = filedb.LocalFileDatabase(root_dir) 46 | with pytest.raises(FileNotFoundError): 47 | db.get_file('non_existent_file.txt') 48 | -------------------------------------------------------------------------------- /tests/core/test_metrics.py: -------------------------------------------------------------------------------- 1 | """Tests for the metrics framework. 2 | 3 | This module contains the tests for the metrics framework. 4 | 5 | Functions: 6 | test_metrics_framework: Tests the functionality of the metrics framework. 7 | """ 8 | 9 | def test_metrics_framework(): 10 | """Tests the functionality of the metrics framework. 11 | 12 | This test checks basic operations related to metrics collection, aggregation, and reporting. 13 | """ 14 | # Add your specific tests for the metrics framework here 15 | assert True 16 | -------------------------------------------------------------------------------- /tests/core/test_stream.py: -------------------------------------------------------------------------------- 1 | """Tests for the stream module. 2 | 3 | This module contains the tests for the stream module. 4 | 5 | Functions: 6 | test_stream_handling: Tests the handling of streams. 7 | """ 8 | 9 | def test_stream_handling(): 10 | """Tests the handling of streams. 11 | 12 | This test checks basic operations related to stream manipulation and handling. 13 | """ 14 | # Add your specific tests for stream handling here 15 | assert True 16 | -------------------------------------------------------------------------------- /tests/userv/__init__.py: -------------------------------------------------------------------------------- 1 | """The tests.userv package. 2 | 3 | This package contains the tests for the userv components of CNAP, including the 4 | unit tests for the userv engine, processor, stream broker, etc. 5 | """ 6 | -------------------------------------------------------------------------------- /tests/userv/test_inference.py: -------------------------------------------------------------------------------- 1 | """Tests for the inference operations. 2 | 3 | This module contains the tests for the inference operations. 4 | 5 | Functions: 6 | test_inference_operations: Tests the basic operations related to inference. 7 | """ 8 | 9 | def test_inference_operations(): 10 | """Tests the basic operations related to inference. 11 | 12 | This test checks functionalities such as model loading, prediction, and error handling. 13 | """ 14 | # Add your specific tests for inference operations here 15 | assert True 16 | -------------------------------------------------------------------------------- /tests/userv/test_pipeline_server.py: -------------------------------------------------------------------------------- 1 | """Tests for the pipeline server. 2 | 3 | This module contains the tests for the pipeline server. 4 | 5 | Functions: 6 | test_pipeline_server_management: Tests the management of pipelines within the server. 7 | """ 8 | 9 | def test_pipeline_server_management(): 10 | """Tests the management of pipelines within the server. 11 | 12 | This test checks functionalities such as pipeline creation, modification, deletion, and 13 | execution. 14 | """ 15 | # Add your specific tests for pipeline server management here 16 | assert True 17 | -------------------------------------------------------------------------------- /tests/userv/test_streaming.py: -------------------------------------------------------------------------------- 1 | """Tests for the streaming functionalities. 2 | 3 | This module contains the tests for the streaming functionalities. 4 | 5 | Functions: 6 | test_streaming_functionality: Tests the streaming functionalities. 7 | """ 8 | 9 | def test_streaming_functionality(): 10 | """Tests the streaming functionalities. 11 | 12 | This test checks functionalities such as frame rate handling, quality control, and latency. 13 | """ 14 | # Add your specific tests for streaming functionalities here 15 | assert True 16 | -------------------------------------------------------------------------------- /tests/userv/test_uapp.py: -------------------------------------------------------------------------------- 1 | """Tests for user application functionalities. 2 | 3 | This module contains the tests for the user application functionalities. 4 | 5 | Functions: 6 | test_user_application: Tests the user application functionalities. 7 | """ 8 | 9 | def test_user_application(): 10 | """Tests the user application functionalities. 11 | 12 | This test checks functionalities related to user interactions, requests, and responses. 13 | """ 14 | # Add your specific tests for user application functionalities here 15 | assert True 16 | -------------------------------------------------------------------------------- /tests/userv/test_websocket_server.py: -------------------------------------------------------------------------------- 1 | """Tests for the WebSocket server functionalities. 2 | 3 | This module contains the tests for the WebSocket server functionalities. 4 | 5 | Functions: 6 | 7 | """ 8 | 9 | def test_websocket_server(): 10 | """Tests the WebSocket server functionalities. 11 | 12 | This test checks functionalities such as connection handling, message sending/receiving, and 13 | error management. 14 | """ 15 | # Add your specific tests for WebSocket server functionalities here 16 | assert True 17 | -------------------------------------------------------------------------------- /tools/common.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #################################################################################### 4 | # This function is used to download a file from a given URL, but only if the file 5 | # does not already exist with the correct MD5 hash. If the file does exist but the 6 | # MD5 hash is different, the existing file is deleted and a new one is downloaded. 7 | # 8 | # Usage: download_file [file_path] [download_url] [expected_md5] 9 | # 10 | # Parameters: 11 | # file_path: The path where the file should be saved. 12 | # download_url: The URL from which the file should be downloaded. 13 | # expected_md5: The expected MD5 hash of the file. If the file already exists 14 | # and its MD5 hash matches this value, the file will not be 15 | # downloaded again. 16 | # 17 | # Returns: 18 | # This function returns 1 and prints an error message in two cases: 19 | # - If the required parameters are not provided. 20 | # - If the required commands (wget and md5sum) are not available. 21 | # If the function completes successfully, it does not return any value. 22 | #################################################################################### 23 | 24 | download_file() { 25 | # Check if the required parameters are provided 26 | if [[ $# -ne 3 ]]; then 27 | printf "Usage: download_file [file_path] [download_url] [expected_md5]\n" 28 | return 1 29 | fi 30 | 31 | local file_path="$1" 32 | local download_url="$2" 33 | local expected_md5="$3" 34 | 35 | # Check if wget and md5sum commands are available 36 | if ! command -v wget > /dev/null || ! command -v md5sum > /dev/null; then 37 | printf "wget and md5sum commands are required.\n" 38 | return 1 39 | fi 40 | 41 | local need_download=1 42 | 43 | # Check if the file already exists 44 | if [[ -f $file_path ]]; then 45 | local md5sum 46 | md5sum=$(md5sum "$file_path" | grep --only-matching -m 1 '^[0-9a-f]*') 47 | 48 | # If the MD5SUM of the existing file matches the expected MD5, no need to download the file 49 | if [[ "$md5sum" == "$expected_md5" ]]; then 50 | need_download=0 51 | else 52 | printf "MD5SUM mismatch. Deleting the existing file.\n" 53 | if ! rm "$file_path"; then 54 | printf "Failed to delete the existing file. Please check the file permissions.\n" 55 | return 1 56 | fi 57 | fi 58 | fi 59 | 60 | # Download the file if needed 61 | if ((need_download)); then 62 | if wget -O "$file_path" --show-progress "$download_url"; then 63 | local new_md5sum 64 | new_md5sum=$(md5sum "$file_path" | grep --only-matching -m 1 '^[0-9a-f]*') 65 | if [[ "$new_md5sum" == "$expected_md5" ]]; then 66 | printf "Success download %s\n" "$file_path" 67 | else 68 | printf "MD5SUM mismatch after download. Please check the source file.\n" 69 | return 1 70 | fi 71 | else 72 | printf "Failed to download the file. Please check the URL and network connection.\n" 73 | return 1 74 | fi 75 | else 76 | printf "%s already exists.\n" "$file_path" 77 | fi 78 | } 79 | -------------------------------------------------------------------------------- /tools/video_downloader.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ############################################################################### 4 | # This script downloads sample videos from a GitHub repository and saves them 5 | # in the /sample-videos directory. 6 | # 7 | # The videos are licensed under the Attribution 4.0 license and can be found at 8 | # https://github.com/intel-iot-devkit/sample-videos/ 9 | ############################################################################### 10 | 11 | current_directory=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")") 12 | top_directory=$(dirname "$current_directory") 13 | 14 | # Check if common.sh file exists 15 | if [[ ! -f "${current_directory}/common.sh" ]]; then 16 | printf "common.sh file not found.\n" 17 | exit 1 18 | fi 19 | 20 | source "${current_directory}/common.sh" 21 | 22 | # Create a cache directory if it doesn't exist 23 | mkdir -p "${top_directory}/.cache" 24 | cd "${top_directory}/.cache" || exit 1 25 | 26 | # Check if unzip command is available 27 | if ! command -v unzip > /dev/null; then 28 | printf "unzip command is required.\n" 29 | exit 1 30 | fi 31 | 32 | # Download the sample videos 33 | if ! download_file sample-videos.zip \ 34 | https://github.com/intel-iot-devkit/sample-videos/archive/b8e3425998213e0b4957c20f0ed5f83411f7a802.zip \ 35 | 22d5c4974d7d6407a470958be5ecfe9a; then 36 | printf "Failed to download the sample videos.\n" 37 | exit 1 38 | fi 39 | 40 | # Unzip the sample videos if the directory doesn't exist 41 | if [[ ! -d ${top_directory}/.cache/sample-videos-b8e3425998213e0b4957c20f0ed5f83411f7a802 ]]; then 42 | if ! unzip sample-videos.zip; then 43 | printf "Failed to unzip the sample videos.\n" 44 | exit 1 45 | fi 46 | fi 47 | 48 | # Copy the sample videos to the sample-videos directory 49 | if [[ ! -d ${top_directory}/sample-videos ]]; then 50 | mkdir -p "${top_directory}/sample-videos" 51 | if ! cp --recursive "${top_directory}/.cache/sample-videos-b8e3425998213e0b4957c20f0ed5f83411f7a802/"* "${top_directory}/sample-videos/"; then 52 | printf "Failed to copy the sample videos.\n" 53 | exit 1 54 | fi 55 | fi 56 | 57 | printf "Success\n" 58 | 59 | # Clean up 60 | if ! rm -rf "${top_directory}/.cache/sample-videos-b8e3425998213e0b4957c20f0ed5f83411f7a802"; then 61 | printf "Failed to clean up the temporary directory.\n" 62 | exit 1 63 | fi 64 | --------------------------------------------------------------------------------