├── .github └── workflows │ ├── mcad-CI.yml │ ├── mcad-release.yml │ └── update-codeflare-operator.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── Makefile ├── OWNERS ├── README.md ├── cluster └── lib │ └── logging.sh ├── cmd └── kar-controllers │ ├── app │ ├── options │ │ └── options.go │ └── server.go │ └── main.go ├── config └── crd │ ├── bases │ ├── quota.codeflare.dev_quotasubtrees.yaml │ ├── workload.codeflare.dev_appwrappers.yaml │ └── workload.codeflare.dev_schedulingspecs.yaml │ └── kustomization.yaml ├── deployment └── mcad-controller │ ├── .helmignore │ ├── Chart.yaml │ ├── crds │ ├── quota.codeflare.dev_quotasubtrees.yaml │ ├── workload.codeflare.dev_appwrappers.yaml │ └── workload.codeflare.dev_schedulingspecs.yaml │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── configmap.yaml │ ├── deployment.yaml │ └── imageSecret.yaml │ └── values.yaml ├── doc ├── build │ └── build.md ├── deploy │ └── deployment.md ├── images │ ├── mcad-release.png │ ├── mcad_logo.png │ └── xqueuejob-controller.png └── usage │ ├── aw-01.yaml │ ├── aw-02.yaml │ ├── debugger │ ├── README.md │ └── launch.json.template │ ├── examples │ ├── aw-1-k8s-job1.yaml │ ├── aw-1-k8s-job2.yaml │ ├── aw-1-k8s-job3.yaml │ └── kuberay │ │ ├── config │ │ ├── aw-kuberay-glue.yaml │ │ ├── aw-raycluster-1.yaml │ │ ├── aw-raycluster.yaml │ │ └── xqueuejob-controller.yaml │ │ ├── kuberay-mcad.md │ │ └── raycluster │ │ └── ray-cluster.autoscaler.yaml │ ├── quota_management │ └── quickstart.md │ └── tutorial.md ├── go.mod ├── go.sum ├── hack ├── .golint_failures ├── boilerplate │ └── boilerplate.go.txt ├── e2e-kind-config.yaml ├── install-etcd.sh ├── lib │ ├── etcd.sh │ ├── golang.sh │ ├── init.sh │ ├── util.sh │ └── version.sh ├── make-rules │ ├── test-integration.sh │ └── test.sh ├── run-e2e-kind.sh ├── update-gofmt.sh ├── verify-gencode.sh ├── verify-gofmt.sh └── verify-golint.sh ├── pkg ├── apis │ ├── controller │ │ ├── utils │ │ │ └── utils.go │ │ └── v1beta1 │ │ │ ├── appwrapper.go │ │ │ ├── doc.go │ │ │ ├── register.go │ │ │ ├── schedulingspec.go │ │ │ └── zz_generated.deepcopy.go │ └── quotaplugins │ │ └── quotasubtree │ │ └── v1alpha1 │ │ ├── doc.go │ │ ├── register.go │ │ ├── types.go │ │ └── zz_generated.deepcopy.go ├── client │ ├── applyconfiguration │ │ ├── controller │ │ │ └── v1beta1 │ │ │ │ ├── appwrapper.go │ │ │ │ ├── appwrappercondition.go │ │ │ │ ├── appwrappergenericresource.go │ │ │ │ ├── appwrapperresourcelist.go │ │ │ │ ├── appwrapperservice.go │ │ │ │ ├── appwrapperspec.go │ │ │ │ ├── appwrapperstatus.go │ │ │ │ ├── custompodresourcetemplate.go │ │ │ │ ├── dispatchdurationspec.go │ │ │ │ ├── pendingpodspec.go │ │ │ │ ├── requeuingtemplate.go │ │ │ │ └── schedulingspectemplate.go │ │ ├── internal │ │ │ └── internal.go │ │ └── utils.go │ ├── client_factory.go │ ├── clientset │ │ └── versioned │ │ │ ├── clientset.go │ │ │ ├── fake │ │ │ ├── clientset_generated.go │ │ │ ├── doc.go │ │ │ └── register.go │ │ │ ├── scheme │ │ │ ├── doc.go │ │ │ └── register.go │ │ │ └── typed │ │ │ ├── controller │ │ │ └── v1beta1 │ │ │ │ ├── appwrapper.go │ │ │ │ ├── controller_client.go │ │ │ │ ├── doc.go │ │ │ │ ├── fake │ │ │ │ ├── doc.go │ │ │ │ ├── fake_appwrapper.go │ │ │ │ └── fake_controller_client.go │ │ │ │ └── generated_expansion.go │ │ │ └── quotasubtree │ │ │ └── v1alpha1 │ │ │ ├── doc.go │ │ │ ├── fake │ │ │ ├── doc.go │ │ │ ├── fake_quotasubtree.go │ │ │ └── fake_quotasubtree_client.go │ │ │ ├── generated_expansion.go │ │ │ ├── quotasubtree.go │ │ │ └── quotasubtree_client.go │ ├── informers │ │ └── externalversions │ │ │ ├── controller │ │ │ ├── interface.go │ │ │ └── v1beta1 │ │ │ │ ├── appwrapper.go │ │ │ │ └── interface.go │ │ │ ├── factory.go │ │ │ ├── generic.go │ │ │ ├── internalinterfaces │ │ │ └── factory_interfaces.go │ │ │ └── quotasubtree │ │ │ ├── interface.go │ │ │ └── v1alpha1 │ │ │ ├── interface.go │ │ │ └── quotasubtree.go │ └── listers │ │ ├── controller │ │ └── v1beta1 │ │ │ ├── appwrapper.go │ │ │ └── expansion_generated.go │ │ └── quotasubtree │ │ ├── v1 │ │ ├── expansion_generated.go │ │ └── quotasubtree.go │ │ └── v1alpha1 │ │ ├── expansion_generated.go │ │ └── quotasubtree.go ├── config │ ├── config.go │ └── support.go ├── controller │ ├── clusterstate │ │ ├── api │ │ │ ├── cluster_info.go │ │ │ ├── helpers.go │ │ │ ├── histogram_info.go │ │ │ ├── node_info.go │ │ │ ├── resource_info.go │ │ │ └── types.go │ │ ├── cache │ │ │ ├── cache.go │ │ │ ├── event_handlers.go │ │ │ └── interface.go │ │ └── util │ │ │ └── priority_queue.go │ ├── heap.go │ ├── maputils │ │ └── sync_map.go │ ├── metrics │ │ └── adapter │ │ │ ├── adapter.go │ │ │ └── provider │ │ │ └── provider.go │ ├── queuejob │ │ ├── heap.go │ │ ├── queuejob_controller_ex.go │ │ ├── queuejob_controller_ex_test.go │ │ ├── queuejob_suite_test.go │ │ ├── scheduling_queue.go │ │ ├── utils.go │ │ └── utils_test.go │ ├── queuejobdispatch │ │ └── queuejobagent.go │ ├── queuejobresources │ │ └── genericresource │ │ │ └── genericresource.go │ └── quota │ │ ├── quota_manager_interface.go │ │ └── quotaforestmanager │ │ ├── qm_lib_backend_with_quotasubt_mgr.go │ │ └── qm_lib_backend_with_quotasubt_mgr │ │ └── quotasubtmgr │ │ ├── event_handlers.go │ │ ├── quota_subtree_manager.go │ │ └── util │ │ └── constants.go ├── health │ ├── health.go │ └── health_test.go └── quotaplugins │ ├── quota-forest │ └── quota-manager │ │ ├── .gitignore │ │ ├── README.md │ │ ├── demos │ │ ├── forest │ │ │ └── demo.go │ │ ├── incremental │ │ │ └── demo.go │ │ ├── manager │ │ │ ├── forest │ │ │ │ └── demo.go │ │ │ └── tree │ │ │ │ └── demo.go │ │ ├── tree │ │ │ └── demo.go │ │ ├── undo │ │ │ ├── forest │ │ │ │ └── demo.go │ │ │ └── tree │ │ │ │ └── demo.go │ │ └── updates │ │ │ ├── README.md │ │ │ ├── forest │ │ │ └── demo.go │ │ │ └── tree │ │ │ └── demo.go │ │ ├── docs │ │ ├── forest-example.pdf │ │ ├── quota-algorithm.pdf │ │ ├── quota-manager.png │ │ ├── tree-cache-example.pdf │ │ ├── tree-example.pdf │ │ └── tree-example.txt │ │ ├── go-legacy.mod │ │ ├── go-sum.mod │ │ ├── main.go │ │ ├── quota │ │ ├── consumerinfo.go │ │ ├── core │ │ │ ├── allocation.go │ │ │ ├── allocation_test.go │ │ │ ├── allocationrecovery.go │ │ │ ├── allocationresponse.go │ │ │ ├── allocationresponse_test.go │ │ │ ├── consumer.go │ │ │ ├── forestconsumer.go │ │ │ ├── forestcontroller.go │ │ │ ├── helpers.go │ │ │ ├── quotanode.go │ │ │ ├── quotanode_test.go │ │ │ ├── quotatree.go │ │ │ ├── treecache.go │ │ │ ├── treecontroller.go │ │ │ ├── treecontroller_test.go │ │ │ ├── treesnapshot.go │ │ │ └── treesnapshot_test.go │ │ ├── quotamanager.go │ │ ├── quotamanager_test.go │ │ ├── quotamanagerundo_test.go │ │ └── utils │ │ │ ├── defaults.go │ │ │ └── types.go │ │ ├── samples │ │ ├── ExampleConsumer.json │ │ ├── ExampleTree.json │ │ ├── TestConsumer.json │ │ ├── TestForestConsumer.json │ │ ├── TestTree.json │ │ ├── forest │ │ │ ├── ContextTree.json │ │ │ ├── ServiceTree.json │ │ │ ├── job1.json │ │ │ ├── job2.json │ │ │ ├── job3.json │ │ │ ├── job4.json │ │ │ └── job5.json │ │ └── tree │ │ │ ├── ca.json │ │ │ ├── cb.json │ │ │ ├── cc.json │ │ │ ├── cd.json │ │ │ ├── ce.json │ │ │ ├── cf.json │ │ │ ├── cg.json │ │ │ ├── ch.json │ │ │ ├── ci.json │ │ │ ├── cj.json │ │ │ └── tree.json │ │ └── tree │ │ ├── node.go │ │ ├── node_test.go │ │ ├── tree.go │ │ └── tree_test.go │ ├── quota-simple-rest │ └── quota_rest_manager.go │ └── util │ └── utils.go └── test ├── e2e-kuttl-borrowing ├── install-quota-subtree.yaml └── steps │ ├── 00-assert.yaml │ ├── 01-assert.yaml │ ├── 02-assert.yaml │ ├── 02-install.yaml │ ├── 03-assert.yaml │ ├── 03-install.yaml │ ├── 04-assert.yaml │ └── 04-install.yaml ├── e2e-kuttl-deployment-01 └── steps │ ├── 00-assert.yaml │ ├── 00-install.yaml │ ├── 01-assert.yaml │ ├── 01-install.yaml │ ├── 02-assert.yaml │ ├── 02-install.yaml │ ├── 03-assert.yaml │ ├── 03-install.yaml │ ├── 04-assert.yaml │ ├── 04-install.yaml │ ├── 05-assert.yaml │ ├── 05-install-single-quota-tree.yaml │ ├── 06-assert.yaml │ ├── 06-install.yaml │ ├── 07-assert.yaml │ ├── 07-install.yaml │ ├── 08-assert.yaml │ ├── 08-install.yaml │ └── 99-cleanup.yaml ├── e2e-kuttl-deployment-02 └── steps │ ├── 00-assert.yaml │ ├── 00-install.yaml │ ├── 01-assert.yaml │ ├── 01-install.yaml │ ├── 02-assert.yaml │ ├── 02-install.yaml │ ├── 03-assert.yaml │ ├── 03-restart-mcad.yaml │ ├── 04-assert.yaml │ ├── 04-install.yaml │ └── 99-cleanup.yaml ├── e2e-kuttl-deployment-03 └── steps │ ├── 00-assert.yaml │ ├── 00-install.yaml │ ├── 01-assert.yaml │ ├── 01-install.yaml │ ├── 02-assert.yaml │ ├── 02-install.yaml │ ├── 03-assert.yaml │ ├── 03-install-new-quota-node.yaml │ ├── 04-assert.yaml │ ├── 04-install.yaml │ ├── 05-assert.yaml │ ├── 05-install.yaml │ └── 99-cleanup.yaml ├── e2e-kuttl-extended-resources └── steps │ ├── 00-assert.yaml │ ├── 01-assert.yaml │ ├── 01-install.yaml │ ├── 02-assert.yaml │ └── 02-install.yaml ├── e2e-kuttl ├── install-quota-subtree.yaml ├── quota-errors │ ├── 00-assert.yaml │ ├── 01-assert.yaml │ ├── 02-assert.yaml │ ├── 02-install.yaml │ ├── 03-assert.yaml │ ├── 03-install.yaml │ ├── 04-delete-app-wrapper.yaml │ ├── 05-reapply-app-wrapper.yaml │ └── 99-cleanup.yaml └── quota-forest │ ├── 00-assert.yaml │ ├── 01-assert.yaml │ ├── 02-assert.yaml │ ├── 02-install.yaml │ ├── 03-assert.yaml │ ├── 03-install.yaml │ ├── 04-assert.yaml │ ├── 04-install.yaml │ ├── 05-assert.yaml │ ├── 05-install.yaml │ ├── 06-assert.yaml │ ├── 06-install.yaml │ ├── 07-assert.yaml │ ├── 07-install.yaml │ ├── 08-assert.yaml │ ├── 08-install.yaml │ ├── 09-assert.yaml │ ├── 09-install.yaml │ ├── 10-assert.yaml │ ├── 10-install.yaml │ ├── 11-assert.yaml │ ├── 11-install.yaml │ └── 99-cleanup.yaml ├── e2e ├── e2e_test.go ├── queue.go ├── quota.go └── util.go ├── kuttl-test-borrowing.yaml ├── kuttl-test-deployment-01.yaml ├── kuttl-test-deployment-02.yaml ├── kuttl-test-deployment-03.yaml ├── kuttl-test-extended-resources.yaml ├── kuttl-test.yaml ├── perf-test ├── cleanup-mcad-kwok.sh ├── cleanup.sh ├── kwokmcadperf.sh ├── node.yaml ├── nodes.sh ├── perf.sh ├── preempt-exp-kwok.yaml ├── preempt-exp.yaml └── simulatingnodesandappwrappers.md └── yaml ├── 0001-aw-generic-deployment-3.yaml ├── 0002-aw-job-quota.yaml ├── 0003-aw-job-no-quota.yaml ├── 0004-aw-large-job-no-quota.yaml ├── 0005-aw-two-quota-jobs.yaml ├── 0006-aw-init-containers.yaml └── 0008-aw-default.yaml /.github/workflows/mcad-CI.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build mcad and run unit test and E2E tests 2 | name: MCAD-CI 3 | on: 4 | pull_request: 5 | branches: 6 | - 'main' 7 | - 'release-*' 8 | 9 | jobs: 10 | MCAD-CI: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: checkout code 15 | uses: actions/checkout@v3 16 | with: 17 | ref: "refs/pull/${{ github.event.number }}/merge" 18 | fetch-depth: 0 19 | 20 | - name: Set latest tag and Branch name 21 | run: | 22 | BRANCH=${{ github.event.pull_request.head.ref }} 23 | echo "GIT_BRANCH=$(echo "$BRANCH" | sed 's/[^A-Za-z0-9._-]/-/g' )" >> $GITHUB_ENV 24 | echo "TAG=$(git describe --abbrev=0 --tags)" >> $GITHUB_ENV 25 | 26 | - name: Set up Go 27 | uses: actions/setup-go@v3 28 | with: 29 | go-version: 1.19.10 30 | 31 | - name: Build 32 | run: 33 | make mcad-controller 34 | 35 | - name: Run Unit tests 36 | run: make run-test 37 | 38 | - name: Build Image 39 | run: | 40 | make images -e GIT_BRANCH=${{ env.GIT_BRANCH }} TAG=${{ env.GIT_BRANCH }}-${{ env.TAG }} 41 | 42 | - name: Run E2E tests 43 | run: | 44 | make run-e2e -e GIT_BRANCH=${{ env.GIT_BRANCH }} TAG=${{ env.GIT_BRANCH }}-${{ env.TAG }} 45 | 46 | -------------------------------------------------------------------------------- /.github/workflows/mcad-release.yml: -------------------------------------------------------------------------------- 1 | # This workflow will Build image and push to mcad quay repository and create a GitHub release tag 2 | 3 | name: mcad Release 4 | on: 5 | workflow_dispatch: 6 | inputs: 7 | tag: 8 | description: 'Release tag' 9 | required: true 10 | default: 'v0.0.0-dev' 11 | type: string 12 | 13 | jobs: 14 | release: 15 | runs-on: ubuntu-latest 16 | 17 | permissions: 18 | contents: write 19 | 20 | steps: 21 | - name: checkout code 22 | uses: actions/checkout@v3 23 | with: 24 | fetch-depth: 0 25 | 26 | - name: check tag format 27 | run: | 28 | if [[ "${{ github.event.inputs.tag }}" =~ ^v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+$ ]]; then 29 | echo "Tag format is valid." 30 | else 31 | echo "Invalid tag format: ${{ github.event.inputs.tag }}" 32 | exit 1 33 | fi 34 | 35 | - name: Create github release tag 36 | run: | 37 | if git rev-parse -q --verify "refs/tags/${{ github.event.inputs.tag }}"; then 38 | echo "Tag ${{ github.event.inputs.tag }} already exist. Exiting workflow." 39 | exit 1 40 | else 41 | gh release create ${{ github.event.inputs.tag }} --title "MCAD ${{ github.event.inputs.tag }} Release" --generate-notes --target ${{ github.ref }} 42 | fi 43 | env: 44 | GITHUB_TOKEN: ${{ github.token }} 45 | 46 | - name: Publish MCAD package 47 | run: | 48 | GOPROXY=proxy.golang.org go list -m github.com/project-codeflare/multi-cluster-app-dispatcher@${{ github.event.inputs.tag }} 49 | 50 | -------------------------------------------------------------------------------- /.github/workflows/update-codeflare-operator.yml: -------------------------------------------------------------------------------- 1 | name: Update CodeFlare operator with latest changes from MCAD 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'main' 7 | 8 | jobs: 9 | update-codeflare-operator: 10 | runs-on: ubuntu-latest 11 | if: github.repository == 'project-codeflare/multi-cluster-app-dispatcher' 12 | 13 | steps: 14 | - name: checkout MCAD code 15 | uses: actions/checkout@v3 16 | with: 17 | path: 'mcad' 18 | 19 | - name: Store latest MCAD Git SHA 20 | run: | 21 | echo "GIT_COMMIT_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV 22 | working-directory: mcad 23 | 24 | - name: checkout CodeFlare operator code 25 | uses: actions/checkout@v3 26 | with: 27 | repository: 'project-codeflare/codeflare-operator' 28 | token: ${{ env.GITHUB_TOKEN }} 29 | path: operator 30 | env: 31 | GITHUB_TOKEN: ${{ secrets.CODEFLARE_MACHINE_ACCOUNT_TOKEN }} 32 | 33 | - name: Update CodeFlare operator code to use latest MCAD version 34 | run: | 35 | sed -i -E "s/(.*MCAD_VERSION \?= ).*/\1${{ env.GIT_COMMIT_SHA }}/" Makefile 36 | sed -i -E "s/(.*MCAD_REF \?= ).*/\1dev/" Makefile 37 | make modules 38 | go mod tidy 39 | working-directory: operator 40 | 41 | - name: Commit CodeFlare operator changes in the code back to repository 42 | uses: stefanzweifel/git-auto-commit-action@v4 43 | with: 44 | commit_message: Update MCAD to latest dev 45 | create_branch: true 46 | repository: operator 47 | branch: dev 48 | push_options: '--force' 49 | 50 | - name: Create a PR in CodeFlare operator repo with code changes if not opened yet 51 | run: | 52 | if [[ $(gh pr view dev) && $(gh pr view dev --json state --jq .state) == "OPEN" ]]; then 53 | echo "PR already opened" 54 | else 55 | gh pr create --base "main" --fill --head dev 56 | fi 57 | env: 58 | GITHUB_TOKEN: ${{ secrets.CODEFLARE_MACHINE_ACCOUNT_TOKEN }} 59 | working-directory: operator 60 | 61 | - name: Post notification about failure to a Slack channel 62 | if: failure() 63 | uses: slackapi/slack-github-action@v1.24.0 64 | with: 65 | channel-id: "codeflare-nightlies" 66 | slack-message: "MCAD to CodeFlare operator upgrade action failed, " 67 | env: 68 | SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} 69 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM registry.access.redhat.com/ubi8/go-toolset:1.19.10-10 AS BUILDER 2 | ARG GO_BUILD_ARGS 3 | WORKDIR /workdir 4 | USER root 5 | 6 | COPY Makefile Makefile 7 | COPY go.mod go.mod 8 | COPY go.sum go.sum 9 | COPY cmd cmd 10 | COPY pkg pkg 11 | COPY hack hack 12 | 13 | ENV GO_BUILD_ARGS=$GO_BUILD_ARGS 14 | RUN echo "Go build args: $GO_BUILD_ARGS" && \ 15 | make mcad-controller 16 | 17 | FROM registry.access.redhat.com/ubi8/ubi-minimal:latest 18 | 19 | COPY --from=BUILDER /workdir/_output/bin/mcad-controller /usr/local/bin 20 | 21 | RUN true \ 22 | && microdnf update \ 23 | && microdnf clean all \ 24 | && true 25 | 26 | WORKDIR /usr/local/bin 27 | 28 | RUN chown -R 1000:1000 /usr/local/bin 29 | 30 | USER 1000 31 | -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | approvers: 2 | - anishasthana 3 | - asm582 4 | - astefanutti 5 | - metalcycling 6 | - sutaakar 7 | reviewers: 8 | - anishasthana 9 | - asm582 10 | - astefanutti 11 | - ChristianZaccaria 12 | - dimakis 13 | - dmatch01 14 | - KPostOffice 15 | - metalcycling 16 | - sutaakar 17 | - tardieu 18 | -------------------------------------------------------------------------------- /cmd/kar-controllers/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | /* 17 | Copyright 2019, 2021 The Multi-Cluster App Dispatcher Authors. 18 | 19 | Licensed under the Apache License, Version 2.0 (the "License"); 20 | you may not use this file except in compliance with the License. 21 | You may obtain a copy of the License at 22 | 23 | http://www.apache.org/licenses/LICENSE-2.0 24 | 25 | Unless required by applicable law or agreed to in writing, software 26 | distributed under the License is distributed on an "AS IS" BASIS, 27 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 28 | See the License for the specific language governing permissions and 29 | limitations under the License. 30 | */ 31 | package main 32 | 33 | import ( 34 | "flag" 35 | "fmt" 36 | "os" 37 | 38 | "k8s.io/klog/v2" 39 | 40 | "github.com/project-codeflare/multi-cluster-app-dispatcher/cmd/kar-controllers/app" 41 | "github.com/project-codeflare/multi-cluster-app-dispatcher/cmd/kar-controllers/app/options" 42 | ) 43 | 44 | func main() { 45 | s := options.NewServerOption() 46 | 47 | flagSet := flag.CommandLine 48 | klog.InitFlags(flagSet) 49 | s.AddFlags(flagSet) 50 | flag.Parse() 51 | 52 | if err := app.Run(s); err != nil { 53 | fmt.Fprintf(os.Stderr, "%v\n", err) 54 | os.Exit(1) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /config/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - bases/quota.codeflare.dev_quotasubtrees.yaml 6 | - bases/workload.codeflare.dev_appwrappers.yaml 7 | - bases/workload.codeflare.dev_schedulingspecs.yaml 8 | -------------------------------------------------------------------------------- /deployment/mcad-controller/.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 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /deployment/mcad-controller/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A Kubernetes Native Holistic Lifecycle Resource Manager for Applications 3 | name: mcad-controller 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /deployment/mcad-controller/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | The batch system of Kubernetes. 2 | -------------------------------------------------------------------------------- /deployment/mcad-controller/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | 18 | {{/* 19 | create image secret 20 | */}} 21 | {{- define "imagePullSecret" }} 22 | {{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" .Values.imagePullSecret.registry (printf "%s:%s" .Values.imagePullSecret.username .Values.imagePullSecret.password | b64enc) | b64enc }} 23 | {{- end }} 24 | -------------------------------------------------------------------------------- /deployment/mcad-controller/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | #{{ if .Values.configMap.name }} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: {{ .Values.configMap.name }} 6 | namespace: kube-system 7 | data: 8 | QUOTA_ENABLED: {{ .Values.configMap.quotaEnabled }} 9 | DISPATCHER_MODE: {{ .Values.configMap.dispatcherMode }} 10 | {{ if .Values.configMap.agentConfigs }}DISPATCHER_AGENT_CONFIGS: {{ .Values.configMap.agentConfigs }}{{ end }} 11 | PREEMPTION: {{ .Values.configMap.preemptionEnabled }} 12 | {{ if .Values.configMap.quotaRestUrl }}QUOTA_REST_URL: {{ .Values.configMap.quotaRestUrl }}{{ end }} 13 | {{ if .Values.configMap.podCreationTimeout }}DISPATCH_RESOURCE_RESERVATION_TIMEOUT: {{ .Values.configMap.podCreationTimeout }}{{ end }} 14 | #{{ end }} 15 | -------------------------------------------------------------------------------- /deployment/mcad-controller/templates/imageSecret.yaml: -------------------------------------------------------------------------------- 1 | #{{ if .Values.imagePullSecret.name }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ .Values.imagePullSecret.name }} 6 | namespace: kube-system 7 | type: kubernetes.io/dockerconfigjson 8 | data: 9 | .dockerconfigjson: {{ template "imagePullSecret" . }} 10 | #{{ end }} 11 | -------------------------------------------------------------------------------- /deployment/mcad-controller/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for MCAD-Controller. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | deploymentName: mcad-controller 5 | namespace: kube-system 6 | replicaCount: 1 7 | loglevel: 3 8 | 9 | image: 10 | repository: mcad-controller 11 | tag: latest 12 | pullPolicy: Always 13 | 14 | crd: 15 | 16 | httpImage: 17 | repository: restserver 18 | tag: latest 19 | pullPolicy: Always 20 | 21 | httpServerImage: 22 | repository: httpserver 23 | tag: latest 24 | pullPolicy: Always 25 | 26 | resources: 27 | limits: 28 | cpu: 2000m 29 | memory: 2048Mi 30 | requests: 31 | cpu: 2000m 32 | memory: 2048Mi 33 | 34 | imagePullSecret: 35 | name: 36 | username: iamapikey 37 | registry: registry.stage1.ng.bluemix.net 38 | password: dummyvalue 39 | 40 | serviceAccount: mcad-controller 41 | 42 | nodeSelector: 43 | hostname: 44 | 45 | configMap: 46 | name: 47 | quotaEnabled: '"false"' 48 | multiCluster: false 49 | dispatcherMode: '"false"' 50 | preemptionEnabled: '"false"' 51 | agentConfigs: "" 52 | quotaRestUrl: "" 53 | # String timeout in milliseconds 54 | podCreationTimeout: 55 | 56 | volumes: 57 | hostPath: 58 | 59 | coscheduler: 60 | rbac: 61 | apiGroup: 62 | resource: 63 | 64 | quotaManagement: 65 | rbac: 66 | apiGroup: 67 | resource: 68 | -------------------------------------------------------------------------------- /doc/images/mcad-release.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-codeflare/multi-cluster-app-dispatcher/d47de4a43faeb18c1dd2eac884cde597580a45fa/doc/images/mcad-release.png -------------------------------------------------------------------------------- /doc/images/mcad_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-codeflare/multi-cluster-app-dispatcher/d47de4a43faeb18c1dd2eac884cde597580a45fa/doc/images/mcad_logo.png -------------------------------------------------------------------------------- /doc/images/xqueuejob-controller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-codeflare/multi-cluster-app-dispatcher/d47de4a43faeb18c1dd2eac884cde597580a45fa/doc/images/xqueuejob-controller.png -------------------------------------------------------------------------------- /doc/usage/aw-01.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: 0001-aw-generic-deployment-1 5 | spec: 6 | resources: 7 | GenericItems: 8 | - replicas: 1 9 | generictemplate: 10 | apiVersion: apps/v1 11 | kind: Deployment 12 | metadata: 13 | name: 0001-aw-generic-deployment-1 14 | labels: 15 | app: 0001-aw-generic-deployment-1 16 | spec: 17 | selector: 18 | matchLabels: 19 | app: 0001-aw-generic-deployment-1 20 | replicas: 2 21 | template: 22 | metadata: 23 | labels: 24 | app: 0001-aw-generic-deployment-1 25 | spec: 26 | containers: 27 | - name: 0001-aw-generic-deployment-1 28 | image: kicbase/echo-server:1.0 29 | ports: 30 | - containerPort: 80 31 | resources: 32 | requests: 33 | cpu: 100m 34 | memory: 256Mi 35 | limits: 36 | cpu: 100m 37 | memory: 256Mi 38 | -------------------------------------------------------------------------------- /doc/usage/aw-02.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: 0002-aw-generic-deployment-2 5 | spec: 6 | schedulingSpec: 7 | minAvailable: 2 8 | resources: 9 | GenericItems: 10 | - replicas: 1 11 | generictemplate: 12 | apiVersion: apps/v1 13 | kind: Deployment 14 | metadata: 15 | name: 0002-aw-generic-deployment-2 16 | labels: 17 | app: 0002-aw-generic-deployment-2 18 | spec: 19 | selector: 20 | matchLabels: 21 | app: 0002-aw-generic-deployment-2 22 | replicas: 2 23 | template: 24 | metadata: 25 | labels: 26 | app: 0002-aw-generic-deployment-2 27 | spec: 28 | containers: 29 | - name: 0002-aw-generic-deployment-2 30 | image: kicbase/echo-server:1.0 31 | resources: 32 | requests: 33 | cpu: 75m 34 | memory: 256Mi 35 | limits: 36 | cpu: 75m 37 | memory: 256Mi 38 | -------------------------------------------------------------------------------- /doc/usage/debugger/README.md: -------------------------------------------------------------------------------- 1 | ## Local debugging with VSCode 2 | Steps outlining how to run MCAD locally from your IDE / debugger. 3 | - Ensure you are authenticated to your Kubernetes/OpenShift Cluster. 4 | - Copy the [launch.json.template](https://github.com/project-codeflare/multi-cluster-app-dispatcher/tree/main/doc/usage/debugger/launch.json.example) file and save it as `launch.json` in the `.vscode` folder in the root of your project. 5 | This can be done by running the following commands in the root of your project: 6 | ```bash 7 | mkdir --parents .vscode 8 | cp --interactive doc/usage/debugger/launch.json.template .vscode/launch.json 9 | ``` 10 | - In the `launch.json` file, update the `args` sections with the path to your kubeconfig. 11 | - In VSCode on the activity bar click `Run and Debug` or `CTRL + SHIFT + D` to start a local debugging session of MCAD. 12 | 13 | ### Optional 14 | To set the desired log level set `--v`, `` in the args sections of the `launch.json` file. 15 | -------------------------------------------------------------------------------- /doc/usage/debugger/launch.json.template: -------------------------------------------------------------------------------- 1 | { 2 | // MCAD Debugger configuration for VSCode 3 | 4 | // Use IntelliSense to learn about possible attributes. 5 | // Hover to view descriptions of existing attributes. 6 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 7 | "version": "0.2.0", 8 | "configurations": [ 9 | { 10 | "name": "Launch MCAD Controller", 11 | "type": "go", 12 | "request": "launch", 13 | "mode": "auto", 14 | "program": "cmd/kar-controllers/main.go", 15 | // Uncomment the line below to enable race testing. 16 | // "buildFlags": "-race", 17 | "env": { 18 | "DISPATCH_RESOURCE_RESERVATION_TIMEOUT":"120000", 19 | "PREEMPTION":"false", 20 | "DISPATCHER_MODE":"false", 21 | "QUOTA_ENABLED":"false", 22 | }, 23 | // To set the desired log level set "--v", "" in the args. 24 | "args": ["--kubeconfig", "", "--v", "15", "--logtostderr"], 25 | // This controls the working directory the code runs in 26 | "cwd": "${workspaceRoot}", 27 | "showLog": true 28 | }, 29 | { 30 | "name": "Launch MCAD Controller with QuotaManager", 31 | "type": "go", 32 | "request": "launch", 33 | "mode": "auto", 34 | "program": "cmd/kar-controllers/main.go", 35 | "buildFlags": "-race", 36 | "env": { 37 | "DISPATCH_RESOURCE_RESERVATION_TIMEOUT":"120000", 38 | "PREEMPTION":"false", 39 | "DISPATCHER_MODE":"false", 40 | }, 41 | // To set the desired log level set "--v", "" in the args. 42 | "args": ["--kubeconfig", "", "--quotaEnabled", "true", "--v", "4", "--logtostderr"], 43 | // This controls the working directory the code runs in 44 | "cwd": "${workspaceRoot}", 45 | "showLog": true, 46 | "port": 8081 47 | } 48 | ] 49 | } 50 | -------------------------------------------------------------------------------- /doc/usage/examples/aw-1-k8s-job1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: aw-generic-statefulset-2 5 | namespace: test1 6 | spec: 7 | schedulingSpec: 8 | minAvailable: 2 9 | resources: 10 | GenericItems: 11 | replicas: 1 12 | metadata: 13 | name: aw-generic-statefulset-2 14 | namespace: test1 15 | generictemplate: 16 | apiVersion: apps/v1 17 | kind: StatefulSet 18 | metadata: 19 | name: aw-generic-statefulset-2 20 | namespace: test1 21 | labels: 22 | app: aw-generic-statefulset-2 23 | spec: 24 | replicas: 2 25 | selector: 26 | matchLabels: 27 | app: aw-generic-statefulset-2 28 | template: 29 | metadata: 30 | labels: 31 | app: aw-generic-statefulset-2 32 | spec: 33 | containers: 34 | - name: aw-generic-statefulset-2 35 | image: k8s.gcr.io/echoserver:1.4 36 | imagePullPolicy: Never 37 | ports: 38 | - containerPort: 80 39 | -------------------------------------------------------------------------------- /doc/usage/examples/aw-1-k8s-job2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: aw-generic-statefulset-2 5 | namespace: test1 6 | spec: 7 | schedulingSpec: 8 | minAvailable: 2 9 | resources: 10 | Items: 11 | - replicas: 1 12 | type: StatefulSet 13 | template: 14 | apiVersion: apps/v1 15 | kind: StatefulSet 16 | metadata: 17 | name: aw-statefulset-2 18 | namespace: test1 19 | labels: 20 | app: aw-statefulset-2 21 | spec: 22 | replicas: 2 23 | selector: 24 | matchLabels: 25 | app: aw-statefulset-2 26 | template: 27 | metadata: 28 | labels: 29 | app: aw-statefulset-2 30 | spec: 31 | containers: 32 | - name: aw-statefulset-2 33 | image: k8s.gcr.io/echoserver:1.4 34 | imagePullPolicy: Never 35 | ports: 36 | - containerPort: 80 37 | -------------------------------------------------------------------------------- /doc/usage/examples/aw-1-k8s-job3.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: aw-generic-statefulset-2 5 | spec: 6 | resources: 7 | Items: 8 | - replicas: 1 9 | type: StatefulSet 10 | template: 11 | apiVersion: apps/v1 12 | kind: StatefulSet 13 | metadata: 14 | name: aw-generic-statefulset-2 15 | labels: 16 | app: aw-generic-statefulset-2 17 | spec: 18 | replicas: 2 19 | selector: 20 | matchLabels: 21 | app: aw-generic-statefulset-2 22 | template: 23 | metadata: 24 | labels: 25 | app: aw-generic-statefulset-2 26 | spec: 27 | containers: 28 | - name: aw-generic-statefulset-2 29 | image: k8s.gcr.io/echoserver:1.4 30 | imagePullPolicy: Never 31 | ports: 32 | - containerPort: 80 33 | -------------------------------------------------------------------------------- /doc/usage/examples/kuberay/config/xqueuejob-controller.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | annotations: 5 | meta.helm.sh/release-name: mcad 6 | meta.helm.sh/release-namespace: kube-system 7 | rbac.authorization.kubernetes.io/autoupdate: "true" 8 | labels: 9 | app.kubernetes.io/managed-by: Helm 10 | kubernetes.io/bootstrapping: rbac-defaults 11 | name: system:controller:xqueuejob-controller 12 | rules: 13 | - apiGroups: 14 | - workload.codeflare.dev 15 | resources: 16 | - xqueuejobs 17 | - queuejobs 18 | - schedulingspecs 19 | - appwrappers 20 | - appwrappers/finalizers 21 | - appwrappers/status 22 | verbs: 23 | - create 24 | - delete 25 | - deletecollection 26 | - get 27 | - list 28 | - patch 29 | - update 30 | - watch 31 | - apiGroups: 32 | - "" 33 | resources: 34 | - persistentvolumes 35 | - namespaces 36 | #for ray resources 37 | - lists 38 | verbs: 39 | - create 40 | - delete 41 | - deletecollection 42 | - get 43 | - list 44 | - patch 45 | - update 46 | - watch 47 | - apiGroups: 48 | - scheduling.sigs.k8s.io 49 | resources: 50 | - podgroups 51 | verbs: 52 | - get 53 | - list 54 | - watch 55 | - create 56 | - update 57 | - patch 58 | - delete 59 | #for ray resources 60 | - apiGroups: 61 | - ray.io 62 | resources: 63 | - rayclusters 64 | - rayclusters/finalizers 65 | - rayclusters/status 66 | verbs: 67 | - get 68 | - list 69 | - watch 70 | - create 71 | - update 72 | - patch 73 | - delete 74 | -------------------------------------------------------------------------------- /hack/.golint_failures: -------------------------------------------------------------------------------- 1 | cmd/kar-controllers/app 2 | cmd/kar-controllers/app/options 3 | cmd/kar-scheduler/app 4 | cmd/kar-scheduler/app/options 5 | pkg/apis/utils 6 | pkg/apis/v1alpha1 7 | pkg/client 8 | pkg/client/clientset 9 | pkg/client/clientset/scheme 10 | pkg/client/clientset/typed/v1 11 | pkg/client/informers/internalinterfaces 12 | pkg/karcli/job 13 | pkg/scheduler 14 | pkg/scheduler/actions/allocate 15 | pkg/scheduler/actions/decorate 16 | pkg/scheduler/actions/preempt 17 | pkg/scheduler/api 18 | pkg/scheduler/cache 19 | pkg/scheduler/framework 20 | pkg/scheduler/plugins/drf 21 | pkg/scheduler/plugins/gang 22 | pkg/scheduler/plugins/priority 23 | pkg/scheduler/util 24 | test 25 | -------------------------------------------------------------------------------- /hack/boilerplate/boilerplate.go.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, YEAR The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /hack/e2e-kind-config.yaml: -------------------------------------------------------------------------------- 1 | # this config file contains all config fields with comments 2 | kind: Cluster 3 | apiVersion: kind.x-k8s.io/v1alpha4 4 | # 1 control plane node and 1 workers 5 | nodes: 6 | # the control plane node config 7 | - role: control-plane 8 | # kubernetes version 1.26.6 from kind v0.20.0 9 | image: kindest/node:v1.26.6@sha256:6e2d8b28a5b601defe327b98bd1c2d1930b49e5d8c512e1895099e4504007adb 10 | # the worker 11 | - role: worker 12 | # kubernetes version 1.26.6 from kind v0.20.0 13 | image: kindest/node:v1.26.6@sha256:6e2d8b28a5b601defe327b98bd1c2d1930b49e5d8c512e1895099e4504007adb 14 | -------------------------------------------------------------------------------- /hack/install-etcd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2014 The Kubernetes Authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # Convenience script to download and install etcd in third_party. 18 | # Mostly just used by CI. 19 | 20 | set -o errexit 21 | set -o nounset 22 | set -o pipefail 23 | 24 | KUBE_ROOT=$(dirname "${BASH_SOURCE}")/.. 25 | source "${KUBE_ROOT}/hack/lib/init.sh" 26 | 27 | kube::etcd::install 28 | -------------------------------------------------------------------------------- /hack/update-gofmt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2014 The Kubernetes Authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # GoFmt apparently is changing @ head... 18 | 19 | set -o errexit 20 | set -o nounset 21 | set -o pipefail 22 | 23 | KUBE_ROOT=$(dirname "${BASH_SOURCE}")/.. 24 | source "${KUBE_ROOT}/hack/lib/init.sh" 25 | 26 | kube::golang::verify_go_version 27 | 28 | cd "${KUBE_ROOT}" 29 | 30 | find_files() { 31 | find . -not \( \ 32 | \( \ 33 | -wholename './output' \ 34 | -o -wholename './_output' \ 35 | -o -wholename './_gopath' \ 36 | -o -wholename './release' \ 37 | -o -wholename './target' \ 38 | -o -wholename '*/third_party/*' \ 39 | -o -wholename '*/vendor/*' \ 40 | -o -wholename './staging/src/k8s.io/client-go/*vendor/*' \ 41 | \) -prune \ 42 | \) -name '*.go' 43 | } 44 | 45 | GOFMT="gofmt -s -w" 46 | find_files | xargs $GOFMT 47 | -------------------------------------------------------------------------------- /hack/verify-gencode.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2017 The Kubernetes Authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # GoFmt apparently is changing @ head... 18 | 19 | set -o errexit 20 | set -o nounset 21 | set -o pipefail 22 | 23 | KUBE_ROOT=$(dirname "${BASH_SOURCE}")/.. 24 | source "${KUBE_ROOT}/hack/lib/init.sh" 25 | 26 | cd "${KUBE_ROOT}" 27 | 28 | find_files() { 29 | find . -not \( \ 30 | \( \ 31 | -wholename './output' \ 32 | -o -wholename './_output' \ 33 | -o -wholename './_gopath' \ 34 | -o -wholename './release' \ 35 | -o -wholename './target' \ 36 | -o -wholename '*/third_party/*' \ 37 | -o -wholename '*/vendor/*' \ 38 | -o -wholename './staging/src/k8s.io/client-go/*vendor/*' \ 39 | -o -wholename '*/bindata.go' \ 40 | \) -prune \ 41 | \) -name '*.go' 42 | } 43 | 44 | # gofmt exits with non-zero exit code if it finds a problem unrelated to 45 | # formatting (e.g., a file does not parse correctly). Without "|| true" this 46 | # would have led to no useful error message from gofmt, because the script would 47 | # have failed before getting to the "echo" in the block below. 48 | diff=$(find_files | xargs git diff 2>&1) || true 49 | if [[ -n "${diff}" ]]; then 50 | echo "${diff}" 51 | exit 1 52 | fi 53 | -------------------------------------------------------------------------------- /hack/verify-gofmt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2014 The Kubernetes Authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # GoFmt apparently is changing @ head... 18 | 19 | set -o errexit 20 | set -o nounset 21 | set -o pipefail 22 | 23 | KUBE_ROOT=$(dirname "${BASH_SOURCE}")/.. 24 | source "${KUBE_ROOT}/hack/lib/init.sh" 25 | 26 | cd "${KUBE_ROOT}" 27 | 28 | # Prefer bazel's gofmt. 29 | gofmt="external/io_bazel_rules_go_toolchain/bin/gofmt" 30 | if [[ ! -x "${gofmt}" ]]; then 31 | gofmt=$(which gofmt) 32 | kube::golang::verify_go_version 33 | fi 34 | 35 | find_files() { 36 | find . -not \( \ 37 | \( \ 38 | -wholename './output' \ 39 | -o -wholename './_output' \ 40 | -o -wholename './_gopath' \ 41 | -o -wholename './release' \ 42 | -o -wholename './target' \ 43 | -o -wholename '*/third_party/*' \ 44 | -o -wholename '*/vendor/*' \ 45 | -o -wholename './staging/src/k8s.io/client-go/*vendor/*' \ 46 | -o -wholename '*/bindata.go' \ 47 | \) -prune \ 48 | \) -name '*.go' 49 | } 50 | 51 | # gofmt exits with non-zero exit code if it finds a problem unrelated to 52 | # formatting (e.g., a file does not parse correctly). Without "|| true" this 53 | # would have led to no useful error message from gofmt, because the script would 54 | # have failed before getting to the "echo" in the block below. 55 | diff=$(find_files | xargs ${gofmt} -d -s 2>&1) || true 56 | if [[ -n "${diff}" ]]; then 57 | echo "${diff}" 58 | exit 1 59 | fi 60 | -------------------------------------------------------------------------------- /pkg/apis/controller/utils/utils.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | import ( 20 | "k8s.io/api/core/v1" 21 | "k8s.io/apimachinery/pkg/api/meta" 22 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 23 | "k8s.io/apimachinery/pkg/types" 24 | ) 25 | 26 | func GetController(obj interface{}) types.UID { 27 | accessor, err := meta.Accessor(obj) 28 | if err != nil { 29 | return "" 30 | } 31 | 32 | controllerRef := metav1.GetControllerOf(accessor) 33 | if controllerRef != nil { 34 | return controllerRef.UID 35 | } 36 | 37 | return "" 38 | } 39 | 40 | 41 | func GetJobID(pod *v1.Pod) types.UID { 42 | accessor, err := meta.Accessor(pod) 43 | if err != nil { 44 | return "" 45 | } 46 | 47 | controllerRef := metav1.GetControllerOf(accessor) 48 | if controllerRef != nil { 49 | return controllerRef.UID 50 | } 51 | 52 | return pod.UID 53 | } 54 | -------------------------------------------------------------------------------- /pkg/apis/controller/v1beta1/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // +k8s:deepcopy-gen=package 18 | // +kubebuilder:object:generate=true 19 | // +groupName=workload.codeflare.dev 20 | 21 | package v1beta1 22 | -------------------------------------------------------------------------------- /pkg/apis/controller/v1beta1/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1beta1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | "k8s.io/apimachinery/pkg/runtime" 22 | "k8s.io/apimachinery/pkg/runtime/schema" 23 | ) 24 | 25 | var ( 26 | SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) 27 | AddToScheme = SchemeBuilder.AddToScheme 28 | ) 29 | 30 | // GroupName is the group name used in this package. 31 | const GroupName = "workload.codeflare.dev" 32 | 33 | // SchemeGroupVersion is the group version used to register these objects. 34 | var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1"} 35 | 36 | // Resource takes an unqualified resource and returns a Group-qualified GroupResource. 37 | func Resource(resource string) schema.GroupResource { 38 | return SchemeGroupVersion.WithResource(resource).GroupResource() 39 | } 40 | 41 | // addKnownTypes adds the set of types defined in this package to the supplied scheme. 42 | func addKnownTypes(scheme *runtime.Scheme) error { 43 | scheme.AddKnownTypes(SchemeGroupVersion, 44 | &SchedulingSpec{}, 45 | &SchedulingSpecList{}, 46 | &AppWrapper{}, 47 | &AppWrapperList{}, 48 | ) 49 | 50 | metav1.AddToGroupVersion(scheme, SchemeGroupVersion) 51 | return nil 52 | } 53 | -------------------------------------------------------------------------------- /pkg/apis/quotaplugins/quotasubtree/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // +k8s:deepcopy-gen=package 18 | // +kubebuilder:object:generate=true 19 | // +groupName=quota.codeflare.dev 20 | 21 | package v1alpha1 22 | -------------------------------------------------------------------------------- /pkg/apis/quotaplugins/quotasubtree/v1alpha1/register.go: -------------------------------------------------------------------------------- 1 | package v1alpha1 2 | 3 | import ( 4 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 5 | "k8s.io/apimachinery/pkg/runtime" 6 | "k8s.io/apimachinery/pkg/runtime/schema" 7 | ) 8 | 9 | var ( 10 | SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) 11 | AddToScheme = SchemeBuilder.AddToScheme 12 | ) 13 | 14 | const ( 15 | // GroupName is the group name used in this package. 16 | GroupName = "quota.codeflare.dev" 17 | 18 | // GroupVersion is the version of scheduling group 19 | GroupVersion = "v1alpha1" 20 | ) 21 | 22 | // SchemeGroupVersion is the group version used to register these objects. 23 | var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: GroupVersion} 24 | 25 | // Resource takes an unqualified resource and returns a Group-qualified GroupResource. 26 | func Resource(resource string) schema.GroupResource { 27 | return SchemeGroupVersion.WithResource(resource).GroupResource() 28 | } 29 | 30 | // addKnownTypes adds the set of types defined in this package to the supplied scheme. 31 | func addKnownTypes(scheme *runtime.Scheme) error { 32 | scheme.AddKnownTypes(SchemeGroupVersion, 33 | &QuotaSubtree{}, 34 | &QuotaSubtreeList{}, 35 | ) 36 | metav1.AddToGroupVersion(scheme, SchemeGroupVersion) 37 | return nil 38 | } 39 | -------------------------------------------------------------------------------- /pkg/client/applyconfiguration/controller/v1beta1/appwrapperresourcelist.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by applyconfiguration-gen. DO NOT EDIT. 18 | 19 | package v1beta1 20 | 21 | // AppWrapperResourceListApplyConfiguration represents an declarative configuration of the AppWrapperResourceList type for use 22 | // with apply. 23 | type AppWrapperResourceListApplyConfiguration struct { 24 | GenericItems []AppWrapperGenericResourceApplyConfiguration `json:"GenericItems,omitempty"` 25 | } 26 | 27 | // AppWrapperResourceListApplyConfiguration constructs an declarative configuration of the AppWrapperResourceList type for use with 28 | // apply. 29 | func AppWrapperResourceList() *AppWrapperResourceListApplyConfiguration { 30 | return &AppWrapperResourceListApplyConfiguration{} 31 | } 32 | 33 | // WithGenericItems adds the given value to the GenericItems field in the declarative configuration 34 | // and returns the receiver, so that objects can be build by chaining "With" function invocations. 35 | // If called multiple times, values provided by each call will be appended to the GenericItems field. 36 | func (b *AppWrapperResourceListApplyConfiguration) WithGenericItems(values ...*AppWrapperGenericResourceApplyConfiguration) *AppWrapperResourceListApplyConfiguration { 37 | for i := range values { 38 | if values[i] == nil { 39 | panic("nil value passed to WithGenericItems") 40 | } 41 | b.GenericItems = append(b.GenericItems, *values[i]) 42 | } 43 | return b 44 | } 45 | -------------------------------------------------------------------------------- /pkg/client/applyconfiguration/controller/v1beta1/appwrapperservice.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by applyconfiguration-gen. DO NOT EDIT. 18 | 19 | package v1beta1 20 | 21 | import ( 22 | v1 "k8s.io/api/core/v1" 23 | ) 24 | 25 | // AppWrapperServiceApplyConfiguration represents an declarative configuration of the AppWrapperService type for use 26 | // with apply. 27 | type AppWrapperServiceApplyConfiguration struct { 28 | Spec *v1.ServiceSpec `json:"spec,omitempty"` 29 | } 30 | 31 | // AppWrapperServiceApplyConfiguration constructs an declarative configuration of the AppWrapperService type for use with 32 | // apply. 33 | func AppWrapperService() *AppWrapperServiceApplyConfiguration { 34 | return &AppWrapperServiceApplyConfiguration{} 35 | } 36 | 37 | // WithSpec sets the Spec field in the declarative configuration to the given value 38 | // and returns the receiver, so that objects can be built by chaining "With" function invocations. 39 | // If called multiple times, the Spec field is set to the value of the last call. 40 | func (b *AppWrapperServiceApplyConfiguration) WithSpec(value v1.ServiceSpec) *AppWrapperServiceApplyConfiguration { 41 | b.Spec = &value 42 | return b 43 | } 44 | -------------------------------------------------------------------------------- /pkg/client/applyconfiguration/controller/v1beta1/pendingpodspec.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by applyconfiguration-gen. DO NOT EDIT. 18 | 19 | package v1beta1 20 | 21 | import ( 22 | v1 "k8s.io/api/core/v1" 23 | ) 24 | 25 | // PendingPodSpecApplyConfiguration represents an declarative configuration of the PendingPodSpec type for use 26 | // with apply. 27 | type PendingPodSpecApplyConfiguration struct { 28 | PodName *string `json:"podname,omitempty"` 29 | Conditions []v1.PodCondition `json:"conditions,omitempty"` 30 | } 31 | 32 | // PendingPodSpecApplyConfiguration constructs an declarative configuration of the PendingPodSpec type for use with 33 | // apply. 34 | func PendingPodSpec() *PendingPodSpecApplyConfiguration { 35 | return &PendingPodSpecApplyConfiguration{} 36 | } 37 | 38 | // WithPodName sets the PodName field in the declarative configuration to the given value 39 | // and returns the receiver, so that objects can be built by chaining "With" function invocations. 40 | // If called multiple times, the PodName field is set to the value of the last call. 41 | func (b *PendingPodSpecApplyConfiguration) WithPodName(value string) *PendingPodSpecApplyConfiguration { 42 | b.PodName = &value 43 | return b 44 | } 45 | 46 | // WithConditions adds the given value to the Conditions field in the declarative configuration 47 | // and returns the receiver, so that objects can be build by chaining "With" function invocations. 48 | // If called multiple times, values provided by each call will be appended to the Conditions field. 49 | func (b *PendingPodSpecApplyConfiguration) WithConditions(values ...v1.PodCondition) *PendingPodSpecApplyConfiguration { 50 | for i := range values { 51 | b.Conditions = append(b.Conditions, values[i]) 52 | } 53 | return b 54 | } 55 | -------------------------------------------------------------------------------- /pkg/client/applyconfiguration/internal/internal.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by applyconfiguration-gen. DO NOT EDIT. 18 | 19 | package internal 20 | 21 | import ( 22 | "fmt" 23 | "sync" 24 | 25 | typed "sigs.k8s.io/structured-merge-diff/v4/typed" 26 | ) 27 | 28 | func Parser() *typed.Parser { 29 | parserOnce.Do(func() { 30 | var err error 31 | parser, err = typed.NewParser(schemaYAML) 32 | if err != nil { 33 | panic(fmt.Sprintf("Failed to parse schema: %v", err)) 34 | } 35 | }) 36 | return parser 37 | } 38 | 39 | var parserOnce sync.Once 40 | var parser *typed.Parser 41 | var schemaYAML = typed.YAMLObject(`types: 42 | - name: __untyped_atomic_ 43 | scalar: untyped 44 | list: 45 | elementType: 46 | namedType: __untyped_atomic_ 47 | elementRelationship: atomic 48 | map: 49 | elementType: 50 | namedType: __untyped_atomic_ 51 | elementRelationship: atomic 52 | - name: __untyped_deduced_ 53 | scalar: untyped 54 | list: 55 | elementType: 56 | namedType: __untyped_atomic_ 57 | elementRelationship: atomic 58 | map: 59 | elementType: 60 | namedType: __untyped_deduced_ 61 | elementRelationship: separable 62 | `) 63 | -------------------------------------------------------------------------------- /pkg/client/client_factory.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package client 17 | 18 | import ( 19 | "k8s.io/apimachinery/pkg/runtime" 20 | "k8s.io/apimachinery/pkg/runtime/serializer" 21 | "k8s.io/client-go/rest" 22 | 23 | arbv1 "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/apis/controller/v1beta1" 24 | ) 25 | 26 | func NewClient(cfg *rest.Config) (*rest.RESTClient, *runtime.Scheme, error) { 27 | scheme := runtime.NewScheme() 28 | if err := arbv1.AddToScheme(scheme); err != nil { 29 | return nil, nil, err 30 | } 31 | 32 | config := *cfg 33 | config.GroupVersion = &arbv1.SchemeGroupVersion 34 | config.APIPath = "/apis" 35 | config.ContentType = runtime.ContentTypeJSON 36 | config.NegotiatedSerializer = serializer.WithoutConversionCodecFactory{CodecFactory: serializer.NewCodecFactory(scheme)} 37 | 38 | client, err := rest.RESTClientFor(&config) 39 | if err != nil { 40 | return nil, nil, err 41 | } 42 | 43 | return client, scheme, nil 44 | } 45 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/fake/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | // This package has the automatically generated fake clientset. 20 | package fake 21 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/fake/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package fake 20 | 21 | import ( 22 | workloadv1beta1 "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/apis/controller/v1beta1" 23 | quotav1alpha1 "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/apis/quotaplugins/quotasubtree/v1alpha1" 24 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 | runtime "k8s.io/apimachinery/pkg/runtime" 26 | schema "k8s.io/apimachinery/pkg/runtime/schema" 27 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 28 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 29 | ) 30 | 31 | var scheme = runtime.NewScheme() 32 | var codecs = serializer.NewCodecFactory(scheme) 33 | 34 | var localSchemeBuilder = runtime.SchemeBuilder{ 35 | workloadv1beta1.AddToScheme, 36 | quotav1alpha1.AddToScheme, 37 | } 38 | 39 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 40 | // of clientsets, like in: 41 | // 42 | // import ( 43 | // "k8s.io/client-go/kubernetes" 44 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 45 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 46 | // ) 47 | // 48 | // kclientset, _ := kubernetes.NewForConfig(c) 49 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 50 | // 51 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 52 | // correctly. 53 | var AddToScheme = localSchemeBuilder.AddToScheme 54 | 55 | func init() { 56 | v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) 57 | utilruntime.Must(AddToScheme(scheme)) 58 | } 59 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/scheme/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | // This package contains the scheme of the automatically generated clientset. 20 | package scheme 21 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/scheme/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package scheme 20 | 21 | import ( 22 | workloadv1beta1 "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/apis/controller/v1beta1" 23 | quotav1alpha1 "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/apis/quotaplugins/quotasubtree/v1alpha1" 24 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 | runtime "k8s.io/apimachinery/pkg/runtime" 26 | schema "k8s.io/apimachinery/pkg/runtime/schema" 27 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 28 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 29 | ) 30 | 31 | var Scheme = runtime.NewScheme() 32 | var Codecs = serializer.NewCodecFactory(Scheme) 33 | var ParameterCodec = runtime.NewParameterCodec(Scheme) 34 | var localSchemeBuilder = runtime.SchemeBuilder{ 35 | workloadv1beta1.AddToScheme, 36 | quotav1alpha1.AddToScheme, 37 | } 38 | 39 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 40 | // of clientsets, like in: 41 | // 42 | // import ( 43 | // "k8s.io/client-go/kubernetes" 44 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 45 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 46 | // ) 47 | // 48 | // kclientset, _ := kubernetes.NewForConfig(c) 49 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 50 | // 51 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 52 | // correctly. 53 | var AddToScheme = localSchemeBuilder.AddToScheme 54 | 55 | func init() { 56 | v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) 57 | utilruntime.Must(AddToScheme(Scheme)) 58 | } 59 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/controller/v1beta1/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | // This package has the automatically generated typed clients. 20 | package v1beta1 21 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/controller/v1beta1/fake/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | // Package fake has the automatically generated clients. 20 | package fake 21 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/controller/v1beta1/fake/fake_controller_client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package fake 20 | 21 | import ( 22 | v1beta1 "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/client/clientset/versioned/typed/controller/v1beta1" 23 | rest "k8s.io/client-go/rest" 24 | testing "k8s.io/client-go/testing" 25 | ) 26 | 27 | type FakeWorkloadV1beta1 struct { 28 | *testing.Fake 29 | } 30 | 31 | func (c *FakeWorkloadV1beta1) AppWrappers(namespace string) v1beta1.AppWrapperInterface { 32 | return &FakeAppWrappers{c, namespace} 33 | } 34 | 35 | // RESTClient returns a RESTClient that is used to communicate 36 | // with API server by this client implementation. 37 | func (c *FakeWorkloadV1beta1) RESTClient() rest.Interface { 38 | var ret *rest.RESTClient 39 | return ret 40 | } 41 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/controller/v1beta1/generated_expansion.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package v1beta1 20 | 21 | type AppWrapperExpansion interface{} 22 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/quotasubtree/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | // This package has the automatically generated typed clients. 20 | package v1alpha1 21 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/quotasubtree/v1alpha1/fake/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | // Package fake has the automatically generated clients. 20 | package fake 21 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/quotasubtree/v1alpha1/fake/fake_quotasubtree_client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package fake 20 | 21 | import ( 22 | v1alpha1 "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/client/clientset/versioned/typed/quotasubtree/v1alpha1" 23 | rest "k8s.io/client-go/rest" 24 | testing "k8s.io/client-go/testing" 25 | ) 26 | 27 | type FakeQuotaV1alpha1 struct { 28 | *testing.Fake 29 | } 30 | 31 | func (c *FakeQuotaV1alpha1) QuotaSubtrees(namespace string) v1alpha1.QuotaSubtreeInterface { 32 | return &FakeQuotaSubtrees{c, namespace} 33 | } 34 | 35 | // RESTClient returns a RESTClient that is used to communicate 36 | // with API server by this client implementation. 37 | func (c *FakeQuotaV1alpha1) RESTClient() rest.Interface { 38 | var ret *rest.RESTClient 39 | return ret 40 | } 41 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/quotasubtree/v1alpha1/generated_expansion.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package v1alpha1 20 | 21 | type QuotaSubtreeExpansion interface{} 22 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/controller/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by informer-gen. DO NOT EDIT. 18 | 19 | package controller 20 | 21 | import ( 22 | v1beta1 "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/client/informers/externalversions/controller/v1beta1" 23 | internalinterfaces "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/client/informers/externalversions/internalinterfaces" 24 | ) 25 | 26 | // Interface provides access to each of this group's versions. 27 | type Interface interface { 28 | // V1beta1 provides access to shared informers for resources in V1beta1. 29 | V1beta1() v1beta1.Interface 30 | } 31 | 32 | type group struct { 33 | factory internalinterfaces.SharedInformerFactory 34 | namespace string 35 | tweakListOptions internalinterfaces.TweakListOptionsFunc 36 | } 37 | 38 | // New returns a new Interface. 39 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 40 | return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 41 | } 42 | 43 | // V1beta1 returns a new v1beta1.Interface. 44 | func (g *group) V1beta1() v1beta1.Interface { 45 | return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) 46 | } 47 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/controller/v1beta1/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by informer-gen. DO NOT EDIT. 18 | 19 | package v1beta1 20 | 21 | import ( 22 | internalinterfaces "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/client/informers/externalversions/internalinterfaces" 23 | ) 24 | 25 | // Interface provides access to all the informers in this group version. 26 | type Interface interface { 27 | // AppWrappers returns a AppWrapperInformer. 28 | AppWrappers() AppWrapperInformer 29 | } 30 | 31 | type version struct { 32 | factory internalinterfaces.SharedInformerFactory 33 | namespace string 34 | tweakListOptions internalinterfaces.TweakListOptionsFunc 35 | } 36 | 37 | // New returns a new Interface. 38 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 39 | return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 40 | } 41 | 42 | // AppWrappers returns a AppWrapperInformer. 43 | func (v *version) AppWrappers() AppWrapperInformer { 44 | return &appWrapperInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} 45 | } 46 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by informer-gen. DO NOT EDIT. 18 | 19 | package internalinterfaces 20 | 21 | import ( 22 | time "time" 23 | 24 | versioned "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/client/clientset/versioned" 25 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 | runtime "k8s.io/apimachinery/pkg/runtime" 27 | cache "k8s.io/client-go/tools/cache" 28 | ) 29 | 30 | // NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer. 31 | type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer 32 | 33 | // SharedInformerFactory a small interface to allow for adding an informer without an import cycle 34 | type SharedInformerFactory interface { 35 | Start(stopCh <-chan struct{}) 36 | InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer 37 | } 38 | 39 | // TweakListOptionsFunc is a function that transforms a v1.ListOptions. 40 | type TweakListOptionsFunc func(*v1.ListOptions) 41 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/quotasubtree/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by informer-gen. DO NOT EDIT. 18 | 19 | package quotasubtree 20 | 21 | import ( 22 | internalinterfaces "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/client/informers/externalversions/internalinterfaces" 23 | v1alpha1 "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/client/informers/externalversions/quotasubtree/v1alpha1" 24 | ) 25 | 26 | // Interface provides access to each of this group's versions. 27 | type Interface interface { 28 | // V1alpha1 provides access to shared informers for resources in V1alpha1. 29 | V1alpha1() v1alpha1.Interface 30 | } 31 | 32 | type group struct { 33 | factory internalinterfaces.SharedInformerFactory 34 | namespace string 35 | tweakListOptions internalinterfaces.TweakListOptionsFunc 36 | } 37 | 38 | // New returns a new Interface. 39 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 40 | return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 41 | } 42 | 43 | // V1alpha1 returns a new v1alpha1.Interface. 44 | func (g *group) V1alpha1() v1alpha1.Interface { 45 | return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) 46 | } 47 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/quotasubtree/v1alpha1/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by informer-gen. DO NOT EDIT. 18 | 19 | package v1alpha1 20 | 21 | import ( 22 | internalinterfaces "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/client/informers/externalversions/internalinterfaces" 23 | ) 24 | 25 | // Interface provides access to all the informers in this group version. 26 | type Interface interface { 27 | // QuotaSubtrees returns a QuotaSubtreeInformer. 28 | QuotaSubtrees() QuotaSubtreeInformer 29 | } 30 | 31 | type version struct { 32 | factory internalinterfaces.SharedInformerFactory 33 | namespace string 34 | tweakListOptions internalinterfaces.TweakListOptionsFunc 35 | } 36 | 37 | // New returns a new Interface. 38 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 39 | return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 40 | } 41 | 42 | // QuotaSubtrees returns a QuotaSubtreeInformer. 43 | func (v *version) QuotaSubtrees() QuotaSubtreeInformer { 44 | return "aSubtreeInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} 45 | } 46 | -------------------------------------------------------------------------------- /pkg/client/listers/controller/v1beta1/expansion_generated.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by lister-gen. DO NOT EDIT. 18 | 19 | package v1beta1 20 | 21 | // AppWrapperListerExpansion allows custom methods to be added to 22 | // AppWrapperLister. 23 | type AppWrapperListerExpansion interface{} 24 | 25 | // AppWrapperNamespaceListerExpansion allows custom methods to be added to 26 | // AppWrapperNamespaceLister. 27 | type AppWrapperNamespaceListerExpansion interface{} 28 | -------------------------------------------------------------------------------- /pkg/client/listers/quotasubtree/v1/expansion_generated.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by lister-gen. DO NOT EDIT. 18 | 19 | package v1 20 | 21 | // QuotaSubtreeListerExpansion allows custom methods to be added to 22 | // QuotaSubtreeLister. 23 | type QuotaSubtreeListerExpansion interface{} 24 | 25 | // QuotaSubtreeNamespaceListerExpansion allows custom methods to be added to 26 | // QuotaSubtreeNamespaceLister. 27 | type QuotaSubtreeNamespaceListerExpansion interface{} 28 | -------------------------------------------------------------------------------- /pkg/client/listers/quotasubtree/v1alpha1/expansion_generated.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by lister-gen. DO NOT EDIT. 18 | 19 | package v1alpha1 20 | 21 | // QuotaSubtreeListerExpansion allows custom methods to be added to 22 | // QuotaSubtreeLister. 23 | type QuotaSubtreeListerExpansion interface{} 24 | 25 | // QuotaSubtreeNamespaceListerExpansion allows custom methods to be added to 26 | // QuotaSubtreeNamespaceLister. 27 | type QuotaSubtreeNamespaceListerExpansion interface{} 28 | -------------------------------------------------------------------------------- /pkg/config/config.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package config 18 | 19 | // MCADConfiguration defines the core MCAD configuration. 20 | type MCADConfiguration struct { 21 | // dynamicPriority sets the controller to use dynamic priority. 22 | // If false, it sets the controller to use static priority. 23 | // It defaults to false. 24 | // +optional 25 | DynamicPriority *bool `json:"dynamicPriority,omitempty"` 26 | 27 | // preemption sets the controller to allow preemption. 28 | // Note: when set to true, the Kubernetes scheduler must be configured 29 | // to enable preemption. It defaults to false. 30 | // +optional 31 | Preemption *bool `json:"preemption,omitempty"` 32 | 33 | // backoffTime defines the duration, in seconds, a job will go away, 34 | // if it can not be scheduled. 35 | // +optional 36 | BackoffTime *int32 `json:"backoffTime,omitempty"` 37 | 38 | // headOfLineHoldingTime defines the duration in seconds a job can stay at the 39 | // Head Of Line without being bumped. 40 | // It defaults to 0. 41 | // +optional 42 | HeadOfLineHoldingTime *int32 `json:"headOfLineHoldingTime,omitempty"` 43 | 44 | // quotaEnabled sets whether quota management is enabled. 45 | // It defaults to false. 46 | // +optional 47 | QuotaEnabled *bool `json:"quotaEnabled,omitempty"` 48 | } 49 | 50 | // MCADConfigurationExtended defines the extended MCAD configuration, e.g., 51 | // for experimental features. 52 | type MCADConfigurationExtended struct { 53 | // dispatcher sets the controller in dispatcher mode, of in agent mode. 54 | // It defaults to false. 55 | // +optional 56 | Dispatcher *bool `json:"dispatcher,omitempty"` 57 | 58 | // agentConfigs contains paths to agent config file 59 | AgentConfigs []string `json:"agentConfigs,omitempty"` 60 | } 61 | -------------------------------------------------------------------------------- /pkg/config/support.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2023 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package config 18 | 19 | func (c *MCADConfiguration) IsQuotaEnabled() bool { 20 | return isTrue(c.QuotaEnabled) 21 | } 22 | 23 | func (c *MCADConfiguration) HasPreemption() bool { 24 | return isTrue(c.Preemption) 25 | } 26 | 27 | func (c *MCADConfiguration) HasDynamicPriority() bool { 28 | return isTrue(c.DynamicPriority) 29 | } 30 | 31 | func (c *MCADConfiguration) BackoffTimeOrDefault(val int32) int32 { 32 | if c.BackoffTime == nil { 33 | return val 34 | } 35 | return *c.BackoffTime 36 | } 37 | 38 | func (e *MCADConfigurationExtended) IsDispatcher() bool { 39 | return isTrue(e.Dispatcher) 40 | } 41 | 42 | func isTrue(v *bool) bool { 43 | return v != nil && *v 44 | } 45 | -------------------------------------------------------------------------------- /pkg/controller/clusterstate/api/cluster_info.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package api 18 | 19 | // ClusterInfo is a snapshot of cluster by cache. 20 | type ClusterInfo struct { 21 | Nodes []*NodeInfo 22 | } 23 | -------------------------------------------------------------------------------- /pkg/controller/clusterstate/api/helpers.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package api 18 | 19 | import ( 20 | v1 "k8s.io/api/core/v1" 21 | ) 22 | 23 | func NewStringsMap(source map[string]string) map[string]string { 24 | target := make(map[string]string) 25 | 26 | for k, v := range source { 27 | target[k] = v 28 | } 29 | return target 30 | } 31 | 32 | func NewTaints(source []v1.Taint) []v1.Taint { 33 | var target []v1.Taint 34 | if source == nil { 35 | target = make([]v1.Taint, 0) 36 | return target 37 | } 38 | 39 | target = make([]v1.Taint, len(source)) 40 | for _, t := range source { 41 | 42 | newTaint := v1.Taint{ 43 | Key: t.Key, 44 | Value: t.Value, 45 | Effect: t.Effect, 46 | TimeAdded: t.TimeAdded, 47 | } 48 | target = append(target, newTaint) 49 | } 50 | return target 51 | } 52 | -------------------------------------------------------------------------------- /pkg/controller/clusterstate/cache/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | /* 17 | Copyright 2019, 2021 The Multi-Cluster App Dispatcher Authors. 18 | 19 | Licensed under the Apache License, Version 2.0 (the "License"); 20 | you may not use this file except in compliance with the License. 21 | You may obtain a copy of the License at 22 | 23 | http://www.apache.org/licenses/LICENSE-2.0 24 | 25 | Unless required by applicable law or agreed to in writing, software 26 | distributed under the License is distributed on an "AS IS" BASIS, 27 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 28 | See the License for the specific language governing permissions and 29 | limitations under the License. 30 | */ 31 | package cache 32 | 33 | import ( 34 | "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/controller/clusterstate/api" 35 | dto "github.com/prometheus/client_model/go" 36 | ) 37 | 38 | // Cache collects pods/nodes/queues information 39 | // and provides information snapshot 40 | type Cache interface { 41 | // Run start informer 42 | Run(stopCh <-chan struct{}) 43 | 44 | // Snapshot deep copy overall cache information into snapshot 45 | Snapshot() *api.ClusterInfo 46 | 47 | // SchedulerConf return the property of scheduler configuration 48 | LoadConf(path string) (map[string]string, error) 49 | 50 | // WaitForCacheSync waits for all cache synced 51 | WaitForCacheSync(stopCh <-chan struct{}) bool 52 | 53 | // Obtains current cluster unallocated resources. 54 | GetUnallocatedResources() *api.Resource 55 | 56 | // Obtains current cluster unallocated histogram of resources 57 | GetUnallocatedHistograms() map[string]*dto.Metric 58 | } 59 | -------------------------------------------------------------------------------- /pkg/controller/maputils/sync_map.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package maputils 17 | 18 | import ( 19 | "fmt" 20 | "sync" 21 | ) 22 | 23 | //SyncCounterMap : map for keeping locks on structures 24 | // 25 | type SyncCounterMap struct { 26 | sync.Mutex 27 | m map[string]int 28 | } 29 | 30 | //NewSyncCounterMap : create a new sync map 31 | // 32 | func NewSyncCounterMap() *SyncCounterMap { 33 | return &SyncCounterMap{ 34 | m: make(map[string]int), 35 | } 36 | } 37 | 38 | //Set : create a lock 39 | // 40 | func (sm *SyncCounterMap) Set(k string, v int) { 41 | sm.Mutex.Lock() 42 | defer sm.Mutex.Unlock() 43 | 44 | sm.m[k] = v 45 | } 46 | 47 | //Get : get a lock 48 | // 49 | func (sm *SyncCounterMap) Get(k string) (int, bool) { 50 | sm.Mutex.Lock() 51 | defer sm.Mutex.Unlock() 52 | 53 | v, ok := sm.m[k] 54 | return v, ok 55 | } 56 | 57 | func (sm *SyncCounterMap) delete(k string) { 58 | sm.Mutex.Lock() 59 | defer sm.Mutex.Unlock() 60 | delete(sm.m, k) 61 | } 62 | 63 | //DecreaseCounter : 64 | // 65 | func (sm *SyncCounterMap) DecreaseCounter(k string) (int, error) { 66 | sm.Mutex.Lock() 67 | defer sm.Mutex.Unlock() 68 | 69 | v, ok := sm.m[k] 70 | if !ok { 71 | return 0, fmt.Errorf("Fail to find counter for key %s", k) 72 | } 73 | 74 | if v > 0 { 75 | v-- 76 | } 77 | 78 | if v == 0 { 79 | delete(sm.m, k) 80 | } else { 81 | sm.m[k] = v 82 | } 83 | 84 | return v, nil 85 | } 86 | -------------------------------------------------------------------------------- /pkg/controller/queuejob/queuejob_suite_test.go: -------------------------------------------------------------------------------- 1 | package queuejob_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/onsi/ginkgo" 7 | "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestQueuejob(t *testing.T) { 11 | gomega.RegisterFailHandler(ginkgo.Fail) 12 | ginkgo.RunSpecs(t, "Queuejob Suite") 13 | } 14 | -------------------------------------------------------------------------------- /pkg/controller/quota/quota_manager_interface.go: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------ {COPYRIGHT-TOP} --- 2 | // Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ------------------------------------------------------ {COPYRIGHT-END} --- 16 | package quota 17 | 18 | import ( 19 | arbv1 "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/apis/controller/v1beta1" 20 | clusterstateapi "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/controller/clusterstate/api" 21 | ) 22 | 23 | type QuotaManagerInterface interface { 24 | Fits(aw *arbv1.AppWrapper, requestedResources *clusterstateapi.Resource, clusterResources *clusterstateapi.Resource, proposedPremptions []*arbv1.AppWrapper) (bool, []*arbv1.AppWrapper, string) 25 | Release(aw *arbv1.AppWrapper) bool 26 | GetValidQuotaLabels() []string 27 | } 28 | -------------------------------------------------------------------------------- /pkg/controller/quota/quotaforestmanager/qm_lib_backend_with_quotasubt_mgr/quotasubtmgr/util/constants.go: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------ {COPYRIGHT-TOP} --- 2 | // Copyright 2019, 2021, 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ------------------------------------------------------ {COPYRIGHT-END} --- 16 | package util 17 | 18 | const ( 19 | // PodGroupLabel is the default label of coscheduling 20 | URMTreeLabel = "tree" 21 | ) 22 | -------------------------------------------------------------------------------- /pkg/health/health.go: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------ {COPYRIGHT-TOP} --- 2 | // Copyright 2022 The Multi-Cluster App Dispatcher Authors. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ------------------------------------------------------ {COPYRIGHT-END} --- 16 | package health 17 | 18 | import ( 19 | "fmt" 20 | "net/http" 21 | ) 22 | 23 | type Handler struct { 24 | } 25 | 26 | func (h *Handler) ServeHTTP(resp http.ResponseWriter, req *http.Request) { 27 | fmt.Fprint(resp, "ok") 28 | } 29 | -------------------------------------------------------------------------------- /pkg/health/health_test.go: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------ {COPYRIGHT-TOP} --- 2 | // Copyright 2022 The Multi-Cluster App Dispatcher Authors. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ------------------------------------------------------ {COPYRIGHT-END} --- 16 | package health 17 | 18 | import ( 19 | "net/http" 20 | "net/http/httptest" 21 | "testing" 22 | ) 23 | 24 | func TestHealthProbe(t *testing.T) { 25 | req, err := http.NewRequest("GET", "/healthz", nil) 26 | if err != nil { 27 | t.Fatal(err) 28 | } 29 | 30 | rr := httptest.NewRecorder() 31 | handler := Handler{} 32 | handler.ServeHTTP(rr, req) 33 | if status := rr.Code; status != http.StatusOK { 34 | t.Errorf("handler returned unexpected status: %v", status) 35 | } 36 | 37 | expected := "ok" 38 | if rr.Body.String() != expected { 39 | t.Errorf("handler returned unexpected body: got %v expected %v", 40 | rr.Body.String(), expected) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | vendor/ 16 | 17 | # Miscellaneous 18 | .DS_Store 19 | temp/ 20 | out.txt 21 | *.log 22 | -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/demos/updates/README.md: -------------------------------------------------------------------------------- 1 | # Testing dynamic tree updates 2 | 3 | Demonstrating various updates to single and multiple trees and refresh to the state of the tree. 4 | 5 | ## Single tree 6 | 7 | Slides to follow the test is [here](../../docs/tree-cache-example.pdf). 8 | 9 | ## Multiple trees 10 | 11 | -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/docs/forest-example.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-codeflare/multi-cluster-app-dispatcher/d47de4a43faeb18c1dd2eac884cde597580a45fa/pkg/quotaplugins/quota-forest/quota-manager/docs/forest-example.pdf -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/docs/quota-algorithm.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-codeflare/multi-cluster-app-dispatcher/d47de4a43faeb18c1dd2eac884cde597580a45fa/pkg/quotaplugins/quota-forest/quota-manager/docs/quota-algorithm.pdf -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/docs/quota-manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-codeflare/multi-cluster-app-dispatcher/d47de4a43faeb18c1dd2eac884cde597580a45fa/pkg/quotaplugins/quota-forest/quota-manager/docs/quota-manager.png -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/docs/tree-cache-example.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-codeflare/multi-cluster-app-dispatcher/d47de4a43faeb18c1dd2eac884cde597580a45fa/pkg/quotaplugins/quota-forest/quota-manager/docs/tree-cache-example.pdf -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/docs/tree-example.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/project-codeflare/multi-cluster-app-dispatcher/d47de4a43faeb18c1dd2eac884cde597580a45fa/pkg/quotaplugins/quota-forest/quota-manager/docs/tree-example.pdf -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/go-legacy.mod: -------------------------------------------------------------------------------- 1 | module github.ibm.com/ai-foundation/quota-manager 2 | 3 | go 1.16 4 | 5 | require k8s.io/klog/v2 v2.9.0 6 | -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/go-sum.mod: -------------------------------------------------------------------------------- 1 | github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= 2 | github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= 3 | k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM= 4 | k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= 5 | -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/quota/core/allocationresponse_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package core 17 | 18 | import ( 19 | "reflect" 20 | "testing" 21 | ) 22 | 23 | func TestAllocationResponse_Merge(t *testing.T) { 24 | type fields struct { 25 | consumerID string 26 | allocated bool 27 | message string 28 | preemptedIDs map[string]bool 29 | } 30 | type args struct { 31 | other *AllocationResponse 32 | } 33 | tests := []struct { 34 | name string 35 | fields fields 36 | args args 37 | want *AllocationResponse 38 | }{ 39 | { 40 | name: "test1", 41 | fields: fields{ 42 | consumerID: "C10", 43 | allocated: true, 44 | message: "success", 45 | preemptedIDs: map[string]bool{"C2": true, "C5": true}, 46 | }, 47 | args: args{ 48 | other: &AllocationResponse{ 49 | consumerID: "C10", 50 | allocated: true, 51 | message: "again", 52 | preemptedIDs: map[string]bool{"C5": true, "C3": true}, 53 | }, 54 | }, 55 | want: &AllocationResponse{ 56 | consumerID: "C10", 57 | allocated: true, 58 | message: "success again", 59 | preemptedIDs: map[string]bool{"C2": true, "C3": true, "C5": true}, 60 | }, 61 | }, 62 | } 63 | for _, tt := range tests { 64 | t.Run(tt.name, func(t *testing.T) { 65 | ar := &AllocationResponse{ 66 | consumerID: tt.fields.consumerID, 67 | allocated: tt.fields.allocated, 68 | message: tt.fields.message, 69 | preemptedIDs: tt.fields.preemptedIDs, 70 | } 71 | ar.Merge(tt.args.other) 72 | got := ar 73 | if !reflect.DeepEqual(got, tt.want) { 74 | t.Errorf("AllocationResponse_Merge = %v, want %v", got, tt.want) 75 | } 76 | }) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/quota/utils/defaults.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | var ( 20 | // DefaultTreeName : the default name of the tree (if unspecified) 21 | DefaultTreeName string = "default" 22 | 23 | // DefaultResourceNames : the default resource names 24 | DefaultResourceNames []string = []string{"cpu", "memory", "nvidia.com/gpu"} 25 | 26 | // DefaultTreeKind : the default kind attribute of the tree 27 | DefaultTreeKind string = "QuotaTree" 28 | 29 | // DefaultConsumerKind : the kind attribute for a consumer 30 | DefaultConsumerKind string = "Consumer" 31 | ) 32 | -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/quota/utils/types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | // JQuotaTree : JSON quota tree 20 | type JQuotaTree struct { 21 | Kind string `json:"kind"` 22 | MetaData JMetaData `json:"metadata"` 23 | Spec JTreeSpec `json:"spec"` 24 | } 25 | 26 | // JMetaData : common metada 27 | type JMetaData struct { 28 | Name string `json:"name"` 29 | } 30 | 31 | // JTreeSpec : spec of quota tree 32 | type JTreeSpec struct { 33 | ResourceNames []string `json:"resourceNames"` 34 | Nodes map[string]JNodeSpec `json:"nodes"` 35 | } 36 | 37 | // JNodeSpec : spec for a node in the quota tree 38 | type JNodeSpec struct { 39 | Parent string `json:"parent"` 40 | Quota map[string]string `json:"quota"` 41 | Hard string `json:"hard"` 42 | } 43 | 44 | // JTreeInfo : data about tree name and resource names 45 | type JTreeInfo struct { 46 | Name string `json:"name"` 47 | ResourceNames []string `json:"resourceNames"` 48 | } 49 | 50 | // JConsumer : JSON consumer 51 | type JConsumer struct { 52 | Kind string `json:"kind"` 53 | MetaData JMetaData `json:"metadata"` 54 | Spec JConsumerSpec `json:"spec"` 55 | } 56 | 57 | // JConsumerSpec : spec of consumer of multiple trees 58 | type JConsumerSpec struct { 59 | ID string `json:"id"` 60 | Trees []JConsumerTreeSpec `json:"trees"` 61 | } 62 | 63 | // JConsumerTreeSpec : consumer spec for a tree 64 | type JConsumerTreeSpec struct { 65 | ID string `json:"id"` 66 | TreeName string `json:"treeName"` 67 | GroupID string `json:"groupID"` 68 | Request map[string]int `json:"request"` 69 | Priority int `json:"priority"` 70 | CType int `json:"type"` 71 | UnPreemptable bool `json:"unPreemptable"` 72 | } 73 | -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/ExampleConsumer.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "C-1", 8 | "trees": [ 9 | { 10 | "treeName": "ExampleTree", 11 | "groupID": "K", 12 | "request": { 13 | "cpu": 4 14 | }, 15 | "priority": 0, 16 | "type": 0, 17 | "unPreemptable": true 18 | } 19 | ] 20 | } 21 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/ExampleTree.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "QuotaTree", 3 | "metadata": { 4 | "name": "ExampleTree" 5 | }, 6 | "spec": { 7 | "resourceNames": [ 8 | "cpu" 9 | ], 10 | "nodes": { 11 | "A": { 12 | "parent": "nil", 13 | "hard": "false", 14 | "quota": { 15 | "cpu": "10" 16 | } 17 | }, 18 | "B": { 19 | "parent": "A", 20 | "hard": "false", 21 | "quota": { 22 | "cpu": "2" 23 | } 24 | }, 25 | "C": { 26 | "parent": "A", 27 | "hard": "false", 28 | "quota": { 29 | "cpu": "6" 30 | } 31 | }, 32 | "D": { 33 | "parent": "A", 34 | "hard": "false", 35 | "quota": { 36 | "cpu": "2" 37 | } 38 | }, 39 | "E": { 40 | "parent": "B", 41 | "hard": "false", 42 | "quota": { 43 | "cpu": "1" 44 | } 45 | }, 46 | "F": { 47 | "parent": "B", 48 | "hard": "false", 49 | "quota": { 50 | "cpu": "1" 51 | } 52 | }, 53 | "G": { 54 | "parent": "C", 55 | "hard": "false", 56 | "quota": { 57 | "cpu": "3" 58 | } 59 | }, 60 | "H": { 61 | "parent": "C", 62 | "hard": "false", 63 | "quota": { 64 | "cpu": "3" 65 | } 66 | }, 67 | "K": { 68 | "parent": "G", 69 | "hard": "false", 70 | "quota": { 71 | "cpu": "1" 72 | } 73 | }, 74 | "L": { 75 | "parent": "G", 76 | "hard": "false", 77 | "quota": { 78 | "cpu": "2" 79 | } 80 | }, 81 | "M": { 82 | "parent": "H", 83 | "hard": "false", 84 | "quota": { 85 | "cpu": "1" 86 | } 87 | }, 88 | "N": { 89 | "parent": "H", 90 | "hard": "false", 91 | "quota": { 92 | "cpu": "2" 93 | } 94 | }, 95 | "I": { 96 | "parent": "D", 97 | "hard": "false", 98 | "quota": { 99 | "cpu": "1" 100 | } 101 | }, 102 | "J": { 103 | "parent": "D", 104 | "hard": "false", 105 | "quota": { 106 | "cpu": "1" 107 | } 108 | } 109 | } 110 | } 111 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/TestConsumer.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "C-1", 8 | "trees": [ 9 | { 10 | "treeName": "TestTree", 11 | "groupID": "D", 12 | "request": { 13 | "cpu": 4, 14 | "memory": 16 15 | }, 16 | "priority": 0, 17 | "type": 0, 18 | "unPreemptable": true 19 | } 20 | ] 21 | } 22 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/TestForestConsumer.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "C-1", 8 | "trees": [ 9 | { 10 | "treeName": "ContextTree", 11 | "groupID": "Context-1", 12 | "request": { 13 | "cpu": 2 14 | }, 15 | "priority": 0, 16 | "type": 0, 17 | "unPreemptable": false 18 | }, 19 | { 20 | "treeName": "ServiceTree", 21 | "groupID": "Srvc-X", 22 | "request": { 23 | "cpu": 8, 24 | "count": 1 25 | }, 26 | "priority": 0, 27 | "type": 0, 28 | "unPreemptable": false 29 | } 30 | ] 31 | } 32 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/TestTree.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "QuotaTree", 3 | "metadata": { 4 | "name": "TestTree" 5 | }, 6 | "spec": { 7 | "resourceNames": [ 8 | "cpu", 9 | "memory" 10 | ], 11 | "nodes": { 12 | 13 | "A": { 14 | "parent": "nil", 15 | "hard": "true", 16 | "quota": { 17 | "cpu": "10", 18 | "memory": "256" 19 | } 20 | }, 21 | 22 | "B": { 23 | "parent": "A", 24 | "hard": "true", 25 | "quota": { 26 | "cpu": "2", 27 | "memory": "64" 28 | } 29 | }, 30 | 31 | "C": { 32 | "parent": "A", 33 | "quota": { 34 | "cpu": "6", 35 | "memory": "64" 36 | } 37 | }, 38 | 39 | "D": { 40 | "parent": "A", 41 | "hard": "false", 42 | "quota": { 43 | "cpu": "2", 44 | "memory": "128" 45 | } 46 | } 47 | 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/forest/ContextTree.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "QuotaTree", 3 | "metadata": { 4 | "name": "ContextTree" 5 | }, 6 | "spec": { 7 | "resourceNames": [ 8 | "cpu" 9 | ], 10 | "nodes": { 11 | "Root": { 12 | "parent": "nil", 13 | "quota": { 14 | "cpu": "10" 15 | } 16 | }, 17 | "Org-A": { 18 | "parent": "Root", 19 | "quota": { 20 | "cpu": "4" 21 | } 22 | }, 23 | "Org-B": { 24 | "parent": "Root", 25 | "hard": "true", 26 | "quota": { 27 | "cpu": "6" 28 | } 29 | }, 30 | "Org-C": { 31 | "parent": "Root", 32 | "quota": { 33 | "cpu": "4" 34 | } 35 | }, 36 | "Context-1": { 37 | "parent": "Org-A", 38 | "quota": { 39 | "cpu": "1" 40 | } 41 | }, 42 | "Context-2": { 43 | "parent": "Org-A", 44 | "quota": { 45 | "cpu": "1" 46 | } 47 | }, 48 | "Context-3": { 49 | "parent": "Org-B", 50 | "quota": { 51 | "cpu": "2" 52 | } 53 | }, 54 | "Context-4": { 55 | "parent": "Org-B", 56 | "hard": "true", 57 | "quota": { 58 | "cpu": "2" 59 | } 60 | }, 61 | "Context-5": { 62 | "parent": "Org-C", 63 | "quota": { 64 | "cpu": "4" 65 | } 66 | } 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/forest/ServiceTree.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "QuotaTree", 3 | "metadata": { 4 | "name": "ServiceTree" 5 | }, 6 | "spec": { 7 | "resourceNames": [ 8 | "cpu", 9 | "disk" 10 | ], 11 | "nodes": { 12 | "Root": { 13 | "parent": "nil", 14 | "quota": { 15 | "cpu": "16", 16 | "disk": "12" 17 | } 18 | }, 19 | "Srvc-X": { 20 | "parent": "Root", 21 | "hard": "true", 22 | "quota": { 23 | "cpu": "3", 24 | "disk": "4" 25 | } 26 | }, 27 | "Srvc-Y": { 28 | "parent": "Root", 29 | "quota": { 30 | "cpu": "4", 31 | "disk": "4" 32 | } 33 | }, 34 | "Srvc-Z": { 35 | "parent": "Root", 36 | "quota": { 37 | "cpu": "5", 38 | "disk": "4" 39 | } 40 | } 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/forest/job1.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "job-1", 8 | "trees": [ 9 | { 10 | "treeName": "ContextTree", 11 | "groupID": "Context-4", 12 | "request": { 13 | "cpu": 2 14 | }, 15 | "priority": 0 16 | }, 17 | { 18 | "treeName": "ServiceTree", 19 | "groupID": "Srvc-X", 20 | "request": { 21 | "cpu": 2, 22 | "disk": 1 23 | }, 24 | "priority": 0 25 | } 26 | ] 27 | } 28 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/forest/job2.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "job-2", 8 | "trees": [ 9 | { 10 | "treeName": "ContextTree", 11 | "groupID": "Context-2", 12 | "request": { 13 | "cpu": 3 14 | }, 15 | "priority": 0 16 | }, 17 | { 18 | "treeName": "ServiceTree", 19 | "groupID": "Srvc-Y", 20 | "request": { 21 | "cpu": 1, 22 | "disk": 1 23 | }, 24 | "priority": 0 25 | } 26 | ] 27 | } 28 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/forest/job3.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "job-3", 8 | "trees": [ 9 | { 10 | "treeName": "ContextTree", 11 | "groupID": "Context-3", 12 | "request": { 13 | "cpu": 4 14 | }, 15 | "priority": 0 16 | }, 17 | { 18 | "treeName": "ServiceTree", 19 | "groupID": "Srvc-Z", 20 | "request": { 21 | "cpu": 4, 22 | "disk": 2 23 | }, 24 | "priority": 0 25 | } 26 | ] 27 | } 28 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/forest/job4.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "job-4", 8 | "trees": [ 9 | { 10 | "treeName": "ContextTree", 11 | "groupID": "Context-2", 12 | "request": { 13 | "cpu": 4 14 | }, 15 | "priority": 1 16 | }, 17 | { 18 | "treeName": "ServiceTree", 19 | "groupID": "Srvc-X", 20 | "request": { 21 | "cpu": 3, 22 | "disk": 4 23 | }, 24 | "priority": 1 25 | } 26 | ] 27 | } 28 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/forest/job5.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "job-5", 8 | "trees": [ 9 | { 10 | "treeName": "ContextTree", 11 | "groupID": "Context-4", 12 | "request": { 13 | "cpu": 4 14 | }, 15 | "priority": 1 16 | }, 17 | { 18 | "treeName": "ServiceTree", 19 | "groupID": "Srvc-Z", 20 | "request": { 21 | "cpu": 2, 22 | "disk": 8 23 | }, 24 | "priority": 1 25 | } 26 | ] 27 | } 28 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/tree/ca.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "a", 8 | "trees": [ 9 | { 10 | "treeName": "ExampleTree", 11 | "groupID": "N", 12 | "request": { 13 | "cpu": 1 14 | }, 15 | "priority": 0, 16 | "unPreemptable": false 17 | } 18 | ] 19 | } 20 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/tree/cb.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "b", 8 | "trees": [ 9 | { 10 | "treeName": "ExampleTree", 11 | "groupID": "N", 12 | "request": { 13 | "cpu": 1 14 | }, 15 | "priority": 0, 16 | "unPreemptable": false 17 | } 18 | ] 19 | } 20 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/tree/cc.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "c", 8 | "trees": [ 9 | { 10 | "treeName": "ExampleTree", 11 | "groupID": "N", 12 | "request": { 13 | "cpu": 1 14 | }, 15 | "priority": 0, 16 | "unPreemptable": false 17 | } 18 | ] 19 | } 20 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/tree/cd.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "d", 8 | "trees": [ 9 | { 10 | "treeName": "ExampleTree", 11 | "groupID": "N", 12 | "request": { 13 | "cpu": 2 14 | }, 15 | "priority": 1, 16 | "unPreemptable": false 17 | } 18 | ] 19 | } 20 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/tree/ce.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "e", 8 | "trees": [ 9 | { 10 | "treeName": "ExampleTree", 11 | "groupID": "L", 12 | "request": { 13 | "cpu": 3 14 | }, 15 | "priority": 0, 16 | "unPreemptable": false 17 | } 18 | ] 19 | } 20 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/tree/cf.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "f", 8 | "trees": [ 9 | { 10 | "treeName": "ExampleTree", 11 | "groupID": "E", 12 | "request": { 13 | "cpu": 3 14 | }, 15 | "priority": 0, 16 | "unPreemptable": false 17 | } 18 | ] 19 | } 20 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/tree/cg.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "g", 8 | "trees": [ 9 | { 10 | "treeName": "ExampleTree", 11 | "groupID": "J", 12 | "request": { 13 | "cpu": 1 14 | }, 15 | "priority": 0, 16 | "unPreemptable": false 17 | } 18 | ] 19 | } 20 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/tree/ch.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "h", 8 | "trees": [ 9 | { 10 | "treeName": "ExampleTree", 11 | "groupID": "K", 12 | "request": { 13 | "cpu": 1 14 | }, 15 | "priority": 0, 16 | "unPreemptable": false 17 | } 18 | ] 19 | } 20 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/tree/ci.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "i", 8 | "trees": [ 9 | { 10 | "treeName": "ExampleTree", 11 | "groupID": "I", 12 | "request": { 13 | "cpu": 3 14 | }, 15 | "priority": 1, 16 | "unPreemptable": false 17 | } 18 | ] 19 | } 20 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/quota-forest/quota-manager/samples/tree/cj.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Consumer", 3 | "metadata": { 4 | "name": "consumer-data" 5 | }, 6 | "spec": { 7 | "id": "j", 8 | "trees": [ 9 | { 10 | "treeName": "ExampleTree", 11 | "groupID": "F", 12 | "request": { 13 | "cpu": 2 14 | }, 15 | "priority": 0, 16 | "unPreemptable": false 17 | } 18 | ] 19 | } 20 | } -------------------------------------------------------------------------------- /pkg/quotaplugins/util/utils.go: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------ {COPYRIGHT-TOP} --- 2 | // Copyright 2022, 2023 The Multi-Cluster App Dispatcher Authors. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ------------------------------------------------------ {COPYRIGHT-END} --- 16 | 17 | package util 18 | 19 | import ( 20 | "fmt" 21 | "strings" 22 | ) 23 | 24 | const ( 25 | // AW Namespace used for building unique name for AW job 26 | NamespacePrefix string = "NAMESPACE_" 27 | 28 | // AW Name used for building unique name for AW job 29 | AppWrapperNamePrefix string = "_AWNAME_" 30 | ) 31 | 32 | func ParseId(id string) (string, string) { 33 | ns := "" 34 | n := "" 35 | 36 | // Extract the namespace seperator 37 | nspSplit := strings.Split(id, NamespacePrefix) 38 | if len(nspSplit) == 2 { 39 | // Extract the appwrapper seperator 40 | awnpSplit := strings.Split(nspSplit[1], AppWrapperNamePrefix) 41 | if len(awnpSplit) == 2 { 42 | // What is left if the namespace value in the first slice 43 | if len(awnpSplit[0]) > 0 { 44 | ns = awnpSplit[0] 45 | } 46 | // And the names value in the second slice 47 | if len(awnpSplit[1]) > 0 { 48 | n = awnpSplit[1] 49 | } 50 | } 51 | } 52 | return ns, n 53 | } 54 | 55 | func CreateId(ns string, n string) string { 56 | id := "" 57 | if len(ns) > 0 && len(n) > 0 { 58 | id = fmt.Sprintf("%s%s%s%s", NamespacePrefix, ns, AppWrapperNamePrefix, n) 59 | } 60 | return id 61 | } 62 | 63 | -------------------------------------------------------------------------------- /test/e2e-kuttl-borrowing/install-quota-subtree.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: quota.codeflare.dev/v1alpha1 3 | kind: QuotaSubtree 4 | metadata: 5 | name: context-root 6 | namespace: kube-system 7 | labels: 8 | tree: quota_context 9 | spec: 10 | children: 11 | - name: context-root 12 | quotas: 13 | requests: 14 | cpu: 1075m 15 | memory: 1045Mi 16 | nvidia.com/gpu: 16 17 | --- 18 | apiVersion: quota.codeflare.dev/v1alpha1 19 | kind: QuotaSubtree 20 | metadata: 21 | name: service-root 22 | namespace: kube-system 23 | labels: 24 | tree: quota_service 25 | spec: 26 | children: 27 | - name: service-root 28 | quotas: 29 | requests: 30 | cpu: 1075m 31 | memory: 1045Mi 32 | nvidia.com/gpu: 16 33 | --- 34 | apiVersion: quota.codeflare.dev/v1alpha1 35 | kind: QuotaSubtree 36 | metadata: 37 | name: context-root-children 38 | namespace: kube-system 39 | labels: 40 | tree: quota_context 41 | spec: 42 | parent: context-root 43 | children: 44 | - name: gold 45 | quotas: 46 | hardLimit: false 47 | requests: 48 | cpu: 1075m 49 | memory: 450Mi 50 | nvidia.com/gpu: 8 51 | - name: silver 52 | quotas: 53 | hardLimit: false 54 | requests: 55 | cpu: 1075m 56 | memory: 400Mi 57 | nvidia.com/gpu: 8 58 | - name: bronze 59 | quotas: 60 | hardLimit: true 61 | requests: 62 | cpu: 900m 63 | memory: 300Mi 64 | nvidia.com/gpu: 8 65 | - name: default 66 | quotas: 67 | hardLimit: false 68 | requests: 69 | cpu: 0m 70 | memory: 0Mi 71 | nvidia.com/gpu: 0 72 | --- 73 | apiVersion: quota.codeflare.dev/v1alpha1 74 | kind: QuotaSubtree 75 | metadata: 76 | name: service-root-children 77 | namespace: kube-system 78 | labels: 79 | tree: quota_service 80 | spec: 81 | parent: service-root 82 | children: 83 | - name: gold 84 | quotas: 85 | requests: 86 | cpu: 1075m 87 | memory: 1045Mi 88 | nvidia.com/gpu: 16 89 | - name: default 90 | quotas: 91 | hardLimit: false 92 | requests: 93 | cpu: 0m 94 | memory: 0Mi 95 | nvidia.com/gpu: 0 96 | -------------------------------------------------------------------------------- /test/e2e-kuttl-borrowing/steps/00-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify CRDs existence 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: appwrappers.workload.codeflare.dev 6 | status: 7 | acceptedNames: 8 | kind: AppWrapper 9 | listKind: AppWrapperList 10 | plural: appwrappers 11 | singular: appwrapper 12 | storedVersions: 13 | - v1beta1 14 | --- 15 | apiVersion: apiextensions.k8s.io/v1 16 | kind: CustomResourceDefinition 17 | metadata: 18 | name: quotasubtrees.quota.codeflare.dev 19 | status: 20 | acceptedNames: 21 | kind: QuotaSubtree 22 | singular: quotasubtree 23 | plural: quotasubtrees 24 | storedVersions: 25 | - v1alpha1 26 | -------------------------------------------------------------------------------- /test/e2e-kuttl-borrowing/steps/01-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify subtree creations 2 | apiVersion: quota.codeflare.dev/v1alpha1 3 | kind: QuotaSubtree 4 | metadata: 5 | name: context-root 6 | namespace: kube-system 7 | labels: 8 | tree: quota_context 9 | --- 10 | apiVersion: quota.codeflare.dev/v1alpha1 11 | kind: QuotaSubtree 12 | metadata: 13 | name: service-root 14 | namespace: kube-system 15 | labels: 16 | tree: quota_service 17 | --- 18 | apiVersion: quota.codeflare.dev/v1alpha1 19 | kind: QuotaSubtree 20 | metadata: 21 | name: context-root-children 22 | namespace: kube-system 23 | labels: 24 | tree: quota_context 25 | --- 26 | apiVersion: quota.codeflare.dev/v1alpha1 27 | kind: QuotaSubtree 28 | metadata: 29 | name: service-root-children 30 | namespace: kube-system 31 | labels: 32 | tree: quota_service 33 | -------------------------------------------------------------------------------- /test/e2e-kuttl-borrowing/steps/02-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify test namespace existence 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: test -------------------------------------------------------------------------------- /test/e2e-kuttl-borrowing/steps/02-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: test -------------------------------------------------------------------------------- /test/e2e-kuttl-borrowing/steps/03-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify job is running 2 | --- 3 | apiVersion: workload.codeflare.dev/v1beta1 4 | kind: AppWrapper 5 | metadata: 6 | name: my-job-1 7 | namespace: test 8 | status: 9 | state: Running 10 | -------------------------------------------------------------------------------- /test/e2e-kuttl-borrowing/steps/03-install.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: my-job-1 6 | namespace: test 7 | labels: 8 | quota_context: "silver" 9 | quota_service: "gold" 10 | spec: 11 | schedulingSpec: 12 | minAvailable: 2 13 | resources: 14 | GenericItems: 15 | - replicas: 1 16 | completionstatus: Complete 17 | custompodresources: 18 | - replicas: 2 19 | requests: 20 | cpu: 500m 21 | nvidia.com/gpu: 8 22 | memory: 300Mi 23 | limits: 24 | cpu: 500m 25 | nvidia.com/gpu: 8 26 | memory: 300Mi 27 | generictemplate: 28 | apiVersion: batch/v1 29 | kind: Job 30 | metadata: 31 | name: my-job-1 32 | namespace: test 33 | labels: 34 | appwrapper.mcad.ibm.com: my-job-1 35 | spec: 36 | parallelism: 1 37 | completions: 1 38 | template: 39 | metadata: 40 | name: my-job-1 41 | namespace: test 42 | labels: 43 | appwrapper.mcad.ibm.com: my-job-1 44 | spec: 45 | terminationGracePeriodSeconds: 1 46 | restartPolicy: Never 47 | containers: 48 | - name: ubuntu 49 | image: ubuntu:latest 50 | imagePullPolicy: IfNotPresent 51 | command: 52 | - sh 53 | - -c 54 | - | 55 | sleep infinity 56 | resources: 57 | requests: 58 | cpu: 500m 59 | nvidia.com/gpu: 8 60 | memory: 300Mi 61 | limits: 62 | cpu: 500m 63 | nvidia.com/gpu: 8 64 | memory: 300Mi 65 | -------------------------------------------------------------------------------- /test/e2e-kuttl-borrowing/steps/04-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify job is running 2 | --- 3 | apiVersion: workload.codeflare.dev/v1beta1 4 | kind: AppWrapper 5 | metadata: 6 | name: my-job-2 7 | namespace: test 8 | status: 9 | state: Running 10 | -------------------------------------------------------------------------------- /test/e2e-kuttl-borrowing/steps/04-install.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: my-job-2 6 | namespace: test 7 | labels: 8 | quota_context: "gold" 9 | quota_service: "gold" 10 | spec: 11 | schedulingSpec: 12 | minAvailable: 1 13 | resources: 14 | GenericItems: 15 | - replicas: 1 16 | completionstatus: Complete 17 | custompodresources: 18 | - replicas: 1 19 | requests: 20 | cpu: 500m 21 | nvidia.com/gpu: 8 22 | memory: 300Mi 23 | limits: 24 | cpu: 500m 25 | nvidia.com/gpu: 8 26 | memory: 300Mi 27 | generictemplate: 28 | apiVersion: batch/v1 29 | kind: Job 30 | metadata: 31 | name: my-job-2 32 | namespace: test 33 | labels: 34 | appwrapper.mcad.ibm.com: my-job-2 35 | spec: 36 | parallelism: 1 37 | completions: 1 38 | template: 39 | metadata: 40 | name: my-job-2 41 | namespace: test 42 | labels: 43 | appwrapper.mcad.ibm.com: my-job-2 44 | spec: 45 | terminationGracePeriodSeconds: 1 46 | restartPolicy: Never 47 | containers: 48 | - name: ubuntu 49 | image: ubuntu:latest 50 | imagePullPolicy: IfNotPresent 51 | command: 52 | - sh 53 | - -c 54 | - | 55 | sleep infinity 56 | resources: 57 | requests: 58 | cpu: 500m 59 | nvidia.com/gpu: 8 60 | memory: 300Mi 61 | limits: 62 | cpu: 500m 63 | nvidia.com/gpu: 8 64 | memory: 300Mi 65 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-01/steps/00-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify CRDs existence 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: appwrappers.workload.codeflare.dev 6 | status: 7 | acceptedNames: 8 | kind: AppWrapper 9 | listKind: AppWrapperList 10 | plural: appwrappers 11 | singular: appwrapper 12 | storedVersions: 13 | - v1beta1 14 | --- 15 | # Verify test namespace existence 16 | apiVersion: v1 17 | kind: Namespace 18 | metadata: 19 | name: start-up 20 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-01/steps/00-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: start-up 5 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-01/steps/01-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify AppWrapper was dispatched and pod was created 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: no-quota-deployment-01 6 | namespace: start-up 7 | status: 8 | state: Running 9 | --- 10 | apiVersion: apps/v1 11 | kind: Deployment 12 | metadata: 13 | name: no-quota-deployment-01 14 | namespace: start-up 15 | labels: 16 | app: no-quota-deployment-01 17 | appwrapper.mcad.ibm.com: no-quota-deployment-01 18 | resourceName: no-quota-deployment-01 19 | status: 20 | availableReplicas: 1 21 | observedGeneration: 1 22 | readyReplicas: 1 23 | replicas: 1 24 | updatedReplicas: 1 25 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-01/steps/01-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: no-quota-deployment-01 5 | namespace: start-up 6 | spec: 7 | resources: 8 | GenericItems: 9 | - replicas: 1 10 | generictemplate: 11 | apiVersion: apps/v1 12 | kind: Deployment 13 | metadata: 14 | name: no-quota-deployment-01 15 | namespace: start-up 16 | labels: 17 | app: no-quota-deployment-01 18 | spec: 19 | selector: 20 | matchLabels: 21 | app: no-quota-deployment-01 22 | replicas: 1 23 | template: 24 | metadata: 25 | labels: 26 | app: deployment-echoserver-01 27 | spec: 28 | containers: 29 | - name: no-quota-deployment-01 30 | image: kicbase/echo-server:1.0 31 | ports: 32 | - containerPort: 80 33 | resources: 34 | requests: 35 | cpu: 300m 36 | memory: 32Mi 37 | limits: 38 | cpu: 300m 39 | memory: 32Mi 40 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-01/steps/02-assert.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: no-quota-job-02 6 | namespace: start-up 7 | status: 8 | state: Completed 9 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-01/steps/02-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: no-quota-job-02 5 | namespace: start-up 6 | spec: 7 | schedulingSpec: 8 | minAvailable: 1 9 | resources: 10 | GenericItems: 11 | - replicas: 1 12 | completionstatus: Complete 13 | custompodresources: 14 | - replicas: 1 15 | requests: 16 | cpu: 500m 17 | nvidia.com/gpu: 0 18 | memory: 300Mi 19 | limits: 20 | cpu: 500m 21 | nvidia.com/gpu: 0 22 | memory: 300Mi 23 | generictemplate: 24 | apiVersion: batch/v1 25 | kind: Job 26 | metadata: 27 | name: no-quota-job-02 28 | namespace: start-up 29 | labels: 30 | appwrapper.mcad.ibm.com: no-quota-job-02 31 | spec: 32 | parallelism: 1 33 | completions: 1 34 | template: 35 | metadata: 36 | name: no-quota-job-1 37 | namespace: start-up 38 | labels: 39 | appwrapper.mcad.ibm.com: no-quota-job-02 40 | spec: 41 | terminationGracePeriodSeconds: 1 42 | restartPolicy: Never 43 | containers: 44 | - name: ubuntu 45 | image: ubuntu:latest 46 | imagePullPolicy: IfNotPresent 47 | command: 48 | - sh 49 | - -c 50 | - | 51 | sleep 30 52 | resources: 53 | requests: 54 | cpu: 500m 55 | nvidia.com/gpu: 0 56 | memory: 300Mi 57 | limits: 58 | cpu: 500m 59 | nvidia.com/gpu: 0 60 | memory: 300Mi 61 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-01/steps/04-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify CRDs existence 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: appwrappers.workload.codeflare.dev 6 | status: 7 | acceptedNames: 8 | kind: AppWrapper 9 | listKind: AppWrapperList 10 | plural: appwrappers 11 | singular: appwrapper 12 | storedVersions: 13 | - v1beta1 14 | --- 15 | apiVersion: apiextensions.k8s.io/v1 16 | kind: CustomResourceDefinition 17 | metadata: 18 | name: quotasubtrees.quota.codeflare.dev 19 | status: 20 | acceptedNames: 21 | kind: QuotaSubtree 22 | singular: quotasubtree 23 | plural: quotasubtrees 24 | storedVersions: 25 | - v1alpha1 26 | --- 27 | apiVersion: apps/v1 28 | kind: Deployment 29 | metadata: 30 | annotations: 31 | meta.helm.sh/release-name: mcad-controller 32 | meta.helm.sh/release-namespace: kube-system 33 | labels: 34 | app: custom-metrics-apiserver 35 | app.kubernetes.io/managed-by: Helm 36 | chart: mcad-controller-0.1.0 37 | name: mcad-controller 38 | namespace: kube-system 39 | status: 40 | availableReplicas: 1 41 | observedGeneration: 1 42 | readyReplicas: 1 43 | replicas: 1 44 | updatedReplicas: 1 45 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-01/steps/04-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kuttl.dev/v1beta1 2 | kind: TestStep 3 | apply: [] 4 | assert: [] 5 | error: [] 6 | unitTest: false 7 | delete: [] 8 | commands: 9 | - script: helm delete -n kube-system mcad-controller 10 | - script: helm upgrade --install mcad-controller ${ROOT_DIR}/deployment/mcad-controller --namespace kube-system --wait --set loglevel=${LOG_LEVEL} --set resources.requests.cpu=1000m --set resources.requests.memory=1024Mi --set resources.limits.cpu=4000m --set resources.limits.memory=4096Mi --set image.repository=$IMAGE_REPOSITORY_MCAD --set image.tag=$IMAGE_TAG_MCAD --set image.pullPolicy=$MCAD_IMAGE_PULL_POLICY --set configMap.quotaEnabled='"true"' --set quotaManagement.rbac.apiGroup=quota.codeflare.dev --set quotaManagement.rbac.resource=quotasubtrees --set configMap.name=mcad-controller-configmap --set configMap.preemptionEnabled='"true"' 11 | 12 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-01/steps/05-assert.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: quota.codeflare.dev/v1alpha1 3 | kind: QuotaSubtree 4 | metadata: 5 | name: context-root 6 | namespace: kube-system 7 | labels: 8 | tree: quota_context 9 | spec: 10 | children: 11 | - name: context-root 12 | --- 13 | apiVersion: quota.codeflare.dev/v1alpha1 14 | kind: QuotaSubtree 15 | metadata: 16 | name: context-root-children 17 | namespace: kube-system 18 | labels: 19 | tree: quota_context 20 | spec: 21 | parent: context-root 22 | children: 23 | - name: gold 24 | - name: silver 25 | - name: bronze 26 | - name: default 27 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-01/steps/05-install-single-quota-tree.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: quota.codeflare.dev/v1alpha1 3 | kind: QuotaSubtree 4 | metadata: 5 | name: context-root 6 | namespace: kube-system 7 | labels: 8 | tree: quota_context 9 | spec: 10 | children: 11 | - name: context-root 12 | quotas: 13 | requests: 14 | cpu: 1950m 15 | memory: 1500Mi 16 | --- 17 | apiVersion: quota.codeflare.dev/v1alpha1 18 | kind: QuotaSubtree 19 | metadata: 20 | name: context-root-children 21 | namespace: kube-system 22 | labels: 23 | tree: quota_context 24 | spec: 25 | parent: context-root 26 | children: 27 | - name: gold 28 | quotas: 29 | requests: 30 | cpu: 1075m 31 | memory: 450Mi 32 | - name: silver 33 | quotas: 34 | hardLimit: false 35 | requests: 36 | cpu: 1075m 37 | memory: 400Mi 38 | - name: bronze 39 | quotas: 40 | hardLimit: true 41 | requests: 42 | cpu: 900m 43 | memory: 300Mi 44 | - name: default 45 | quotas: 46 | hardLimit: false 47 | requests: 48 | cpu: 0m 49 | memory: 0Mi 50 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-01/steps/06-assert.yaml: -------------------------------------------------------------------------------- 1 | #Verify AppWrappers finished successfully 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: no-quota-job-06 6 | namespace: start-up 7 | status: 8 | state: Pending 9 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-01/steps/07-assert.yaml: -------------------------------------------------------------------------------- 1 | #Verify AppWrappers finished successfully 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: no-quota-job-06 6 | namespace: start-up 7 | status: 8 | state: Running 9 | --- 10 | apiVersion: v1 11 | kind: Pod 12 | metadata: 13 | namespace: start-up 14 | labels: 15 | appwrapper.mcad.ibm.com: no-quota-job-06 16 | job-name: no-quota-job-06 17 | resourceName: no-quota-job-06 18 | 19 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-01/steps/07-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kuttl.dev/v1beta1 2 | kind: TestStep 3 | apply: [] 4 | assert: [] 5 | error: [] 6 | unitTest: false 7 | delete: [] 8 | commands: 9 | - command: kubectl delete appwrappers -n start-up no-quota-deployment-01 hold-completion-job-03 no-quota-job-02 --wait 10 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-01/steps/08-assert.yaml: -------------------------------------------------------------------------------- 1 | #Verify AppWrappers finished successfully 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: bronze-quota-job-08 6 | namespace: start-up 7 | status: 8 | state: Completed 9 | 10 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-01/steps/08-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: bronze-quota-job-08 5 | namespace: start-up 6 | labels: 7 | quota_context: bronze 8 | spec: 9 | schedulingSpec: 10 | minAvailable: 1 11 | resources: 12 | GenericItems: 13 | - replicas: 1 14 | completionstatus: Complete 15 | custompodresources: 16 | - replicas: 1 17 | requests: 18 | cpu: 300m 19 | nvidia.com/gpu: 0 20 | memory: 300Mi 21 | limits: 22 | cpu: 300m 23 | nvidia.com/gpu: 0 24 | memory: 300Mi 25 | generictemplate: 26 | apiVersion: batch/v1 27 | kind: Job 28 | metadata: 29 | name: bronze-quota-job-08 30 | namespace: start-up 31 | labels: 32 | appwrapper.mcad.ibm.com: bronze-quota-job-08 33 | spec: 34 | parallelism: 1 35 | completions: 1 36 | template: 37 | metadata: 38 | name: bronze-quota-job-08 39 | namespace: start-up 40 | labels: 41 | appwrapper.mcad.ibm.com: bronze-quota-job-08 42 | spec: 43 | terminationGracePeriodSeconds: 1 44 | restartPolicy: Never 45 | containers: 46 | - name: ubuntu 47 | image: ubuntu:latest 48 | imagePullPolicy: IfNotPresent 49 | command: 50 | - sh 51 | - -c 52 | - | 53 | sleep 30 54 | resources: 55 | requests: 56 | cpu: 300m 57 | nvidia.com/gpu: 0 58 | memory: 300Mi 59 | limits: 60 | cpu: 300m 61 | nvidia.com/gpu: 0 62 | memory: 300Mi 63 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-01/steps/99-cleanup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kuttl.dev/v1beta1 2 | kind: TestStep 3 | apply: [] 4 | assert: [] 5 | error: [] 6 | unitTest: false 7 | delete: [] 8 | commands: 9 | - command: kubectl delete appwrappers -n start-up --all --wait 10 | - command: kubectl delete deployments,pods,jobs -n start-up --all --wait 11 | - command: kubectl delete namespace start-up --wait 12 | - command: kubectl delete quotasubtrees -n kube-system --all --wait 13 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-02/steps/00-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify CRDs existence 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: appwrappers.workload.codeflare.dev 6 | status: 7 | acceptedNames: 8 | kind: AppWrapper 9 | listKind: AppWrapperList 10 | plural: appwrappers 11 | singular: appwrapper 12 | storedVersions: 13 | - v1beta1 14 | --- 15 | # Verify test namespace existence 16 | apiVersion: v1 17 | kind: Namespace 18 | metadata: 19 | name: start-up-02 20 | --- 21 | # Verify subtree creations 22 | apiVersion: quota.codeflare.dev/v1alpha1 23 | kind: QuotaSubtree 24 | metadata: 25 | name: context-root 26 | namespace: kube-system 27 | labels: 28 | tree: quota_context 29 | --- 30 | apiVersion: quota.codeflare.dev/v1alpha1 31 | kind: QuotaSubtree 32 | metadata: 33 | name: service-root 34 | namespace: kube-system 35 | labels: 36 | tree: quota_service 37 | --- 38 | apiVersion: quota.codeflare.dev/v1alpha1 39 | kind: QuotaSubtree 40 | metadata: 41 | name: context-root-children 42 | namespace: kube-system 43 | labels: 44 | tree: quota_context 45 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-02/steps/00-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: start-up-02 5 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-02/steps/01-assert.yaml: -------------------------------------------------------------------------------- 1 | #Verify AppWrappers finished successfully 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: bronze-quota-job-01 6 | namespace: start-up-02 7 | status: 8 | state: Running 9 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-02/steps/02-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify AppWrapper was dispatched and pod was created 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: no-quota-deployment-02 6 | namespace: start-up-02 7 | status: 8 | state: Running 9 | --- 10 | apiVersion: apps/v1 11 | kind: Deployment 12 | metadata: 13 | name: no-quota-deployment-02 14 | namespace: start-up-02 15 | labels: 16 | app: no-quota-deployment-02 17 | appwrapper.mcad.ibm.com: no-quota-deployment-02 18 | resourceName: no-quota-deployment-02 19 | status: 20 | availableReplicas: 1 21 | observedGeneration: 1 22 | readyReplicas: 1 23 | replicas: 1 24 | updatedReplicas: 1 25 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-02/steps/02-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: no-quota-deployment-02 5 | namespace: start-up-02 6 | spec: 7 | resources: 8 | GenericItems: 9 | - replicas: 1 10 | generictemplate: 11 | apiVersion: apps/v1 12 | kind: Deployment 13 | metadata: 14 | name: no-quota-deployment-02 15 | namespace: start-up-02 16 | labels: 17 | app: no-quota-deployment-02 18 | spec: 19 | selector: 20 | matchLabels: 21 | app: no-quota-deployment-02 22 | replicas: 1 23 | template: 24 | metadata: 25 | labels: 26 | app: deployment-echoserver-01 27 | spec: 28 | containers: 29 | - name: no-quota-deployment-01 30 | image: kicbase/echo-server:1.0 31 | ports: 32 | - containerPort: 80 33 | resources: 34 | requests: 35 | cpu: 300m 36 | memory: 32Mi 37 | limits: 38 | cpu: 300m 39 | memory: 32Mi 40 | 41 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-02/steps/03-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mcad-controller 5 | namespace: kube-system 6 | annotations: 7 | meta.helm.sh/release-name: mcad-controller 8 | meta.helm.sh/release-namespace: kube-system 9 | labels: 10 | app: custom-metrics-apiserver 11 | app.kubernetes.io/managed-by: Helm 12 | chart: mcad-controller-0.1.0 13 | status: 14 | availableReplicas: 1 15 | readyReplicas: 1 16 | replicas: 1 17 | updatedReplicas: 1 18 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-02/steps/03-restart-mcad.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kuttl.dev/v1beta1 2 | kind: TestStep 3 | apply: [] 4 | assert: [] 5 | error: [] 6 | unitTest: false 7 | delete: [] 8 | commands: 9 | # the rollout restart doesn't seem to reliably kill running pods on the kind cluster 10 | # - command: kubectl rollout restart deployment/mcad-controller -n kube-system 11 | - script: "kubectl -n kube-system get pods | grep mcad-controller | cut -d' ' -f1 | xargs kubectl -n kube-system delete pod $1" -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-02/steps/04-assert.yaml: -------------------------------------------------------------------------------- 1 | #Verify AppWrappers finished successfully 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: gold-quota-job-04 6 | namespace: start-up-02 7 | status: 8 | state: Running 9 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-02/steps/99-cleanup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kuttl.dev/v1beta1 2 | kind: TestStep 3 | apply: [] 4 | assert: [] 5 | error: [] 6 | unitTest: false 7 | delete: [] 8 | commands: 9 | - command: kubectl delete appwrappers -n start-up-02 --all --wait 10 | - command: kubectl delete deployments,pods,jobs -n start-up-02 --all --wait 11 | - command: kubectl delete namespace start-up-02 --wait 12 | - command: kubectl delete quotasubtrees -n kube-system --all --wait 13 | 14 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-03/steps/00-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify CRDs existence 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: appwrappers.workload.codeflare.dev 6 | status: 7 | acceptedNames: 8 | kind: AppWrapper 9 | listKind: AppWrapperList 10 | plural: appwrappers 11 | singular: appwrapper 12 | storedVersions: 13 | - v1beta1 14 | --- 15 | # Verify test namespace existence 16 | apiVersion: v1 17 | kind: Namespace 18 | metadata: 19 | name: start-up-03 20 | --- 21 | # Verify subtree creations 22 | apiVersion: quota.codeflare.dev/v1alpha1 23 | kind: QuotaSubtree 24 | metadata: 25 | name: context-root 26 | namespace: kube-system 27 | labels: 28 | tree: quota_context 29 | --- 30 | apiVersion: quota.codeflare.dev/v1alpha1 31 | kind: QuotaSubtree 32 | metadata: 33 | name: service-root 34 | namespace: kube-system 35 | labels: 36 | tree: quota_service 37 | --- 38 | apiVersion: quota.codeflare.dev/v1alpha1 39 | kind: QuotaSubtree 40 | metadata: 41 | name: context-root-children 42 | namespace: kube-system 43 | labels: 44 | tree: quota_context 45 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-03/steps/00-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: start-up-03 5 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-03/steps/01-assert.yaml: -------------------------------------------------------------------------------- 1 | #Verify AppWrappers finished successfully 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: bronze-quota-job-01 6 | namespace: start-up-03 7 | status: 8 | state: Running 9 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-03/steps/02-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify AppWrapper was dispatched and pod was created 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: no-quota-deployment-02 6 | namespace: start-up-03 7 | status: 8 | state: Running 9 | --- 10 | apiVersion: apps/v1 11 | kind: Deployment 12 | metadata: 13 | name: no-quota-deployment-02 14 | namespace: start-up-03 15 | labels: 16 | app: no-quota-deployment-02 17 | appwrapper.mcad.ibm.com: no-quota-deployment-02 18 | resourceName: no-quota-deployment-02 19 | status: 20 | availableReplicas: 1 21 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-03/steps/02-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: no-quota-deployment-02 5 | namespace: start-up-03 6 | spec: 7 | resources: 8 | GenericItems: 9 | - replicas: 1 10 | generictemplate: 11 | apiVersion: apps/v1 12 | kind: Deployment 13 | metadata: 14 | name: no-quota-deployment-02 15 | namespace: start-up-03 16 | labels: 17 | app: no-quota-deployment-02 18 | spec: 19 | selector: 20 | matchLabels: 21 | app: no-quota-deployment-02 22 | replicas: 1 23 | template: 24 | metadata: 25 | labels: 26 | app: deployment-echoserver-01 27 | spec: 28 | containers: 29 | - name: no-quota-deployment-01 30 | image: kicbase/echo-server:1.0 31 | ports: 32 | - containerPort: 80 33 | resources: 34 | requests: 35 | cpu: 300m 36 | memory: 32Mi 37 | limits: 38 | cpu: 300m 39 | memory: 32Mi 40 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-03/steps/03-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: quota.codeflare.dev/v1alpha1 2 | kind: QuotaSubtree 3 | metadata: 4 | name: actinides-root 5 | namespace: kube-system 6 | labels: 7 | tree: quota_actinides 8 | spec: 9 | children: 10 | - name: actinides-root 11 | --- 12 | apiVersion: quota.codeflare.dev/v1alpha1 13 | kind: QuotaSubtree 14 | metadata: 15 | name: actinides-children 16 | namespace: kube-system 17 | labels: 18 | tree: quota_actinides 19 | spec: 20 | parent: actinides-root 21 | children: 22 | - name: plutonium 23 | - name: lawrencium 24 | --- 25 | apiVersion: quota.codeflare.dev/v1alpha1 26 | kind: QuotaSubtree 27 | metadata: 28 | name: context-root 29 | namespace: kube-system 30 | labels: 31 | tree: quota_context 32 | --- 33 | apiVersion: quota.codeflare.dev/v1alpha1 34 | kind: QuotaSubtree 35 | metadata: 36 | name: service-root 37 | namespace: kube-system 38 | labels: 39 | tree: quota_service 40 | --- 41 | apiVersion: quota.codeflare.dev/v1alpha1 42 | kind: QuotaSubtree 43 | metadata: 44 | name: context-root-children 45 | namespace: kube-system 46 | labels: 47 | tree: quota_context 48 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-03/steps/03-install-new-quota-node.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: quota.codeflare.dev/v1alpha1 2 | kind: QuotaSubtree 3 | metadata: 4 | name: actinides-root 5 | namespace: kube-system 6 | labels: 7 | tree: quota_actinides 8 | spec: 9 | children: 10 | - name: actinides-root 11 | quotas: 12 | requests: 13 | cpu: 1075m 14 | memory: 1045Mi 15 | --- 16 | apiVersion: quota.codeflare.dev/v1alpha1 17 | kind: QuotaSubtree 18 | metadata: 19 | name: actinides-children 20 | namespace: kube-system 21 | labels: 22 | tree: quota_actinides 23 | spec: 24 | parent: actinides-root 25 | children: 26 | - name: plutonium 27 | quotas: 28 | requests: 29 | cpu: 1075m 30 | memory: 1045Mi 31 | - name: lawrencium 32 | quotas: 33 | hardLimit: true 34 | requests: 35 | cpu: 1075m 36 | memory: 1045Mi 37 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-03/steps/04-assert.yaml: -------------------------------------------------------------------------------- 1 | #Verify AppWrappers finished successfully 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: gold-quota-job-04 6 | namespace: start-up-03 7 | status: 8 | state: Completed 9 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-03/steps/05-assert.yaml: -------------------------------------------------------------------------------- 1 | #Verify AppWrappers finished successfully 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: plutonium-quota-job-05 6 | namespace: start-up-03 7 | status: 8 | state: Completed 9 | -------------------------------------------------------------------------------- /test/e2e-kuttl-deployment-03/steps/99-cleanup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kuttl.dev/v1beta1 2 | kind: TestStep 3 | apply: [] 4 | assert: [] 5 | error: [] 6 | unitTest: false 7 | delete: [] 8 | commands: 9 | - command: kubectl delete appwrappers -n start-up-03 --all --wait 10 | - command: kubectl delete deployments,pods,jobs -n start-up-03 --all --wait 11 | - command: kubectl delete namespace start-up-03 --wait 12 | - command: kubectl delete quotasubtrees -n kube-system --all --wait 13 | -------------------------------------------------------------------------------- /test/e2e-kuttl-extended-resources/steps/00-assert.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Verify that GPUs are a resource for the node 3 | apiVersion: v1 4 | kind: Node 5 | metadata: 6 | name: test-worker 7 | status: 8 | allocatable: 9 | nvidia.com/gpu: "8" 10 | 11 | -------------------------------------------------------------------------------- /test/e2e-kuttl-extended-resources/steps/01-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify that the namespace was created 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: extended-resources 6 | -------------------------------------------------------------------------------- /test/e2e-kuttl-extended-resources/steps/01-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: extended-resources 5 | -------------------------------------------------------------------------------- /test/e2e-kuttl-extended-resources/steps/02-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: gpu-job 5 | namespace: extended-resources 6 | status: 7 | conditions: 8 | - type: Complete 9 | -------------------------------------------------------------------------------- /test/e2e-kuttl-extended-resources/steps/02-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: gpu-job 5 | namespace: extended-resources 6 | spec: 7 | template: 8 | spec: 9 | restartPolicy: Never 10 | containers: 11 | - name: gpu-job 12 | image: ubuntu:latest 13 | command: [ "/bin/bash", "-c", "--" ] 14 | args: [ "sleep 10;" ] 15 | resources: 16 | requests: 17 | nvidia.com/gpu: 8 18 | limits: 19 | nvidia.com/gpu: 8 20 | -------------------------------------------------------------------------------- /test/e2e-kuttl/install-quota-subtree.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: quota.codeflare.dev/v1alpha1 3 | kind: QuotaSubtree 4 | metadata: 5 | name: context-root 6 | namespace: kube-system 7 | labels: 8 | tree: quota_context 9 | spec: 10 | children: 11 | - name: context-root 12 | quotas: 13 | requests: 14 | cpu: 1075m 15 | memory: 1045Mi 16 | nvidia.com/gpu: 16 17 | --- 18 | apiVersion: quota.codeflare.dev/v1alpha1 19 | kind: QuotaSubtree 20 | metadata: 21 | name: service-root 22 | namespace: kube-system 23 | labels: 24 | tree: quota_service 25 | spec: 26 | children: 27 | - name: service-root 28 | quotas: 29 | requests: 30 | cpu: 1075m 31 | memory: 1045Mi 32 | nvidia.com/gpu: 16 33 | --- 34 | apiVersion: quota.codeflare.dev/v1alpha1 35 | kind: QuotaSubtree 36 | metadata: 37 | name: context-root-children 38 | namespace: kube-system 39 | labels: 40 | tree: quota_context 41 | spec: 42 | parent: context-root 43 | children: 44 | - name: gold 45 | quotas: 46 | hardLimit: false 47 | requests: 48 | cpu: 1075m 49 | memory: 450Mi 50 | nvidia.com/gpu: 8 51 | - name: silver 52 | quotas: 53 | hardLimit: false 54 | requests: 55 | cpu: 1075m 56 | memory: 400Mi 57 | nvidia.com/gpu: 8 58 | - name: bronze 59 | quotas: 60 | hardLimit: true 61 | requests: 62 | cpu: 900m 63 | memory: 300Mi 64 | nvidia.com/gpu: 8 65 | - name: default 66 | quotas: 67 | hardLimit: false 68 | requests: 69 | cpu: 0m 70 | memory: 0Mi 71 | nvidia.com/gpu: 0 72 | --- 73 | apiVersion: quota.codeflare.dev/v1alpha1 74 | kind: QuotaSubtree 75 | metadata: 76 | name: service-root-children 77 | namespace: kube-system 78 | labels: 79 | tree: quota_service 80 | spec: 81 | parent: service-root 82 | children: 83 | - name: gold 84 | quotas: 85 | requests: 86 | cpu: 1075m 87 | memory: 1045Mi 88 | nvidia.com/gpu: 16 89 | - name: default 90 | quotas: 91 | hardLimit: false 92 | requests: 93 | cpu: 0m 94 | memory: 0Mi 95 | nvidia.com/gpu: 0 96 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-errors/00-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify CRDs existence 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: appwrappers.workload.codeflare.dev 6 | status: 7 | acceptedNames: 8 | kind: AppWrapper 9 | listKind: AppWrapperList 10 | plural: appwrappers 11 | singular: appwrapper 12 | storedVersions: 13 | - v1beta1 14 | --- 15 | apiVersion: apiextensions.k8s.io/v1 16 | kind: CustomResourceDefinition 17 | metadata: 18 | name: quotasubtrees.quota.codeflare.dev 19 | status: 20 | acceptedNames: 21 | kind: QuotaSubtree 22 | singular: quotasubtree 23 | plural: quotasubtrees 24 | storedVersions: 25 | - v1alpha1 26 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-errors/01-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify subtree creations 2 | apiVersion: quota.codeflare.dev/v1alpha1 3 | kind: QuotaSubtree 4 | metadata: 5 | name: context-root 6 | namespace: kube-system 7 | labels: 8 | tree: quota_context 9 | --- 10 | apiVersion: quota.codeflare.dev/v1alpha1 11 | kind: QuotaSubtree 12 | metadata: 13 | name: service-root 14 | namespace: kube-system 15 | labels: 16 | tree: quota_service 17 | --- 18 | apiVersion: quota.codeflare.dev/v1alpha1 19 | kind: QuotaSubtree 20 | metadata: 21 | name: context-root-children 22 | namespace: kube-system 23 | labels: 24 | tree: quota_context 25 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-errors/02-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify test namespace existence 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: quota-errors -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-errors/02-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: quota-errors -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-errors/03-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify AppWrapper was dispatched and pod was created 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: deployment-silver-lo-pri-1replica 6 | namespace: quota-errors 7 | labels: 8 | quota_context: "silver" 9 | quota_service: "gold" 10 | status: 11 | state: Running 12 | --- 13 | apiVersion: apps/v1 14 | kind: Deployment 15 | metadata: 16 | name: deployment-silver-lo-pri-1replica 17 | namespace: quota-errors 18 | labels: 19 | app: deployment-silver-lo-pri-1replica 20 | appwrapper.mcad.ibm.com: deployment-silver-lo-pri-1replica 21 | resourceName: deployment-silver-lo-pri-1replica 22 | status: 23 | availableReplicas: 1 24 | observedGeneration: 1 25 | readyReplicas: 1 26 | replicas: 1 27 | updatedReplicas: 1 28 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-errors/03-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: deployment-silver-lo-pri-1replica 5 | namespace: quota-errors 6 | labels: 7 | quota_context: "silver" 8 | quota_service: "gold" 9 | spec: 10 | resources: 11 | GenericItems: 12 | - replicas: 1 13 | generictemplate: 14 | apiVersion: apps/v1 15 | kind: Deployment 16 | metadata: 17 | name: deployment-silver-lo-pri-1replica 18 | namespace: quota-errors 19 | labels: 20 | app: deployment-silver-lo-pri-1replica 21 | spec: 22 | selector: 23 | matchLabels: 24 | app: deployment-silver-lo-pri-1replica 25 | replicas: 1 26 | template: 27 | metadata: 28 | labels: 29 | app: deployment-silver-lo-pri-1replica 30 | spec: 31 | containers: 32 | - name: deployment-silver-lo-pri-1replica 33 | image: kicbase/echo-server:1.0 34 | ports: 35 | - containerPort: 80 36 | resources: 37 | requests: 38 | cpu: 100m 39 | memory: 32Mi 40 | limits: 41 | cpu: 100m 42 | memory: 32Mi 43 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-errors/04-delete-app-wrapper.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kuttl.dev/v1beta1 2 | kind: TestStep 3 | apply: [] 4 | assert: [] 5 | error: [] 6 | unitTest: false 7 | delete: [] 8 | commands: 9 | - command: kubectl delete appwrapper -n quota-errors deployment-silver-lo-pri-1replica 10 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-errors/05-reapply-app-wrapper.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kuttl.dev/v1beta1 2 | kind: TestStep 3 | apply: 4 | - 03-install.yaml 5 | assert: 6 | - 03-assert.yaml 7 | error: [] 8 | unitTest: false 9 | delete: [] 10 | commands: [] -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-errors/99-cleanup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kuttl.dev/v1beta1 2 | kind: TestStep 3 | apply: [] 4 | assert: [] 5 | error: [] 6 | unitTest: false 7 | delete: [] 8 | commands: 9 | - command: kubectl delete namespace quota-errors --wait -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/00-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify CRDs existence 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: appwrappers.workload.codeflare.dev 6 | status: 7 | acceptedNames: 8 | kind: AppWrapper 9 | listKind: AppWrapperList 10 | plural: appwrappers 11 | singular: appwrapper 12 | storedVersions: 13 | - v1beta1 14 | --- 15 | apiVersion: apiextensions.k8s.io/v1 16 | kind: CustomResourceDefinition 17 | metadata: 18 | name: quotasubtrees.quota.codeflare.dev 19 | status: 20 | acceptedNames: 21 | kind: QuotaSubtree 22 | singular: quotasubtree 23 | plural: quotasubtrees 24 | storedVersions: 25 | - v1alpha1 26 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/01-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify subtree creations 2 | apiVersion: quota.codeflare.dev/v1alpha1 3 | kind: QuotaSubtree 4 | metadata: 5 | name: context-root 6 | namespace: kube-system 7 | labels: 8 | tree: quota_context 9 | --- 10 | apiVersion: quota.codeflare.dev/v1alpha1 11 | kind: QuotaSubtree 12 | metadata: 13 | name: service-root 14 | namespace: kube-system 15 | labels: 16 | tree: quota_service 17 | --- 18 | apiVersion: quota.codeflare.dev/v1alpha1 19 | kind: QuotaSubtree 20 | metadata: 21 | name: context-root-children 22 | namespace: kube-system 23 | labels: 24 | tree: quota_context 25 | --- 26 | apiVersion: quota.codeflare.dev/v1alpha1 27 | kind: QuotaSubtree 28 | metadata: 29 | name: service-root-children 30 | namespace: kube-system 31 | labels: 32 | tree: quota_service 33 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/02-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify test namespace existence 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: test -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/02-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: test -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/03-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify delay step 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: job-delay-step 6 | namespace: test 7 | status: 8 | succeeded: 1 -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/03-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: job-delay-step 5 | namespace: test 6 | spec: 7 | template: 8 | spec: 9 | containers: 10 | - name: job-delay-step 11 | image: ubuntu:latest 12 | command: [ "/bin/bash", "-c", "--" ] 13 | args: [ "sleep 10;" ] 14 | restartPolicy: Never 15 | backoffLimit: 4 16 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/04-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify AppWrapper was dispatched and pod was created 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: job-gold-lo-pri-1replica 6 | namespace: test 7 | labels: 8 | quota_context: "gold" 9 | quota_service: "gold" 10 | status: 11 | state: Running 12 | --- 13 | apiVersion: v1 14 | kind: Pod 15 | metadata: 16 | name: job-gold-lo-pri-1replica-0 17 | namespace: test 18 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/04-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: job-gold-lo-pri-1replica 5 | namespace: test 6 | labels: 7 | quota_context: "gold" 8 | quota_service: "gold" 9 | spec: 10 | service: 11 | spec: {} 12 | resources: 13 | GenericItems: 14 | - replicas: 1 15 | generictemplate: 16 | apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 17 | kind: StatefulSet 18 | metadata: 19 | name: job-gold-lo-pri-1replica 20 | namespace: test 21 | labels: 22 | app: job-gold-lo-pri-1replica 23 | spec: 24 | selector: 25 | matchLabels: 26 | app: job-gold-lo-pri-1replica 27 | replicas: 1 28 | template: 29 | metadata: 30 | labels: 31 | app: job-gold-lo-pri-1replica 32 | size: "1" 33 | spec: 34 | containers: 35 | - name: job-gold-lo-pri-1replica 36 | image: registry.access.redhat.com/ubi8/ubi:latest 37 | command: 38 | - /bin/sh 39 | - -c 40 | - while true; do sleep 10; done 41 | resources: 42 | requests: 43 | cpu: 600m 44 | memory: 95Mi 45 | limits: 46 | cpu: 600m 47 | memory: 95Mi 48 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/05-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify that quota management is enabled by checking the queuing is happening (e.g. no available quota for quota ids provided in AW) 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: job-bad-quota-id-10replica 6 | namespace: test 7 | labels: 8 | quota_context: "context-root2" 9 | quota_service: "service-root2" 10 | status: 11 | state: Pending 12 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/05-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: job-bad-quota-id-10replica 5 | namespace: test 6 | labels: 7 | quota_context: "context-root2" 8 | quota_service: "service-root2" 9 | spec: 10 | service: 11 | spec: {} 12 | resources: 13 | GenericItems: 14 | - replicas: 1 15 | generictemplate: 16 | apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 17 | kind: StatefulSet 18 | metadata: 19 | name: job-bad-quota-id-10replica 20 | namespace: test 21 | labels: 22 | app: job-bad-quota-id-10replica 23 | spec: 24 | selector: 25 | matchLabels: 26 | app: job-bad-quota-id-10replica 27 | replicas: 10 28 | template: 29 | metadata: 30 | labels: 31 | app: job-bad-quota-id-10replica 32 | size: "1" 33 | spec: 34 | containers: 35 | - name: job-bad-quota-id-10replica 36 | image: registry.access.redhat.com/ubi8/ubi:latest 37 | command: 38 | - /bin/sh 39 | - -c 40 | - while true; do sleep 10; done 41 | resources: 42 | requests: 43 | cpu: 100m 44 | memory: 95Mi 45 | limits: 46 | cpu: 100m 47 | memory: 95Mi 48 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/06-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify that quota management preempted lower priority job 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: job-gold-high-pri-1replica 6 | namespace: test 7 | labels: 8 | quota_context: "gold" 9 | quota_service: "gold" 10 | status: 11 | state: Running 12 | --- 13 | apiVersion: v1 14 | kind: Pod 15 | metadata: 16 | name: job-gold-high-pri-1replica-0 17 | namespace: test 18 | --- 19 | apiVersion: workload.codeflare.dev/v1beta1 20 | kind: AppWrapper 21 | metadata: 22 | name: job-bad-quota-id-10replica 23 | namespace: test 24 | labels: 25 | quota_context: "context-root2" 26 | quota_service: "service-root2" 27 | status: 28 | state: Pending 29 | --- 30 | apiVersion: workload.codeflare.dev/v1beta1 31 | kind: AppWrapper 32 | metadata: 33 | name: job-gold-lo-pri-1replica 34 | namespace: test 35 | labels: 36 | quota_context: "gold" 37 | quota_service: "gold" 38 | status: 39 | state: Pending 40 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/06-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: job-gold-high-pri-1replica 5 | namespace: test 6 | labels: 7 | quota_context: "gold" 8 | quota_service: "gold" 9 | spec: 10 | service: 11 | spec: {} 12 | priority: 1000 13 | resources: 14 | GenericItems: 15 | - replicas: 1 16 | generictemplate: 17 | apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 18 | kind: StatefulSet 19 | metadata: 20 | name: job-gold-high-pri-1replica 21 | namespace: test 22 | labels: 23 | app: job-gold-high-pri-1replica 24 | spec: 25 | selector: 26 | matchLabels: 27 | app: job-gold-high-pri-1replica 28 | replicas: 1 29 | template: 30 | metadata: 31 | labels: 32 | app: job-gold-high-pri-1replica 33 | size: "1" 34 | spec: 35 | containers: 36 | - name: job-gold-high-pri-1replica 37 | image: registry.access.redhat.com/ubi8/ubi:latest 38 | command: 39 | - /bin/sh 40 | - -c 41 | - while true; do sleep 10; done 42 | resources: 43 | requests: 44 | cpu: 600m 45 | memory: 95Mi 46 | limits: 47 | cpu: 600m 48 | memory: 95Mi 49 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/07-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify that quota management is enabled using different quota ids 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: job-1-bronze-1replica 6 | namespace: test 7 | labels: 8 | quota_context: "bronze" 9 | quota_service: "gold" 10 | status: 11 | state: Running 12 | --- 13 | apiVersion: v1 14 | kind: Pod 15 | metadata: 16 | name: job-1-bronze-1replica-0 17 | namespace: test 18 | --- 19 | apiVersion: workload.codeflare.dev/v1beta1 20 | kind: AppWrapper 21 | metadata: 22 | name: job-gold-high-pri-1replica 23 | namespace: test 24 | labels: 25 | quota_context: "gold" 26 | quota_service: "gold" 27 | status: 28 | state: Running 29 | --- 30 | apiVersion: v1 31 | kind: Pod 32 | metadata: 33 | name: job-gold-high-pri-1replica-0 34 | namespace: test 35 | --- 36 | apiVersion: workload.codeflare.dev/v1beta1 37 | kind: AppWrapper 38 | metadata: 39 | name: job-bad-quota-id-10replica 40 | namespace: test 41 | labels: 42 | quota_context: "context-root2" 43 | quota_service: "service-root2" 44 | status: 45 | state: Pending 46 | --- 47 | apiVersion: workload.codeflare.dev/v1beta1 48 | kind: AppWrapper 49 | metadata: 50 | name: job-gold-lo-pri-1replica 51 | namespace: test 52 | labels: 53 | quota_context: "gold" 54 | quota_service: "gold" 55 | status: 56 | state: Pending 57 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/07-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: job-1-bronze-1replica 5 | namespace: test 6 | labels: 7 | quota_context: "bronze" 8 | quota_service: "gold" 9 | spec: 10 | service: 11 | spec: {} 12 | priority: 1000 13 | resources: 14 | GenericItems: 15 | - replicas: 1 16 | generictemplate: 17 | apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 18 | kind: StatefulSet 19 | metadata: 20 | name: job-1-bronze-1replica 21 | namespace: test 22 | labels: 23 | app: job-1-bronze-1replica 24 | spec: 25 | selector: 26 | matchLabels: 27 | app: job-1-bronze-1replica 28 | replicas: 1 29 | template: 30 | metadata: 31 | labels: 32 | app: job-1-bronze-1replica 33 | size: "1" 34 | spec: 35 | containers: 36 | - name: job-1-bronze-1replica 37 | image: registry.access.redhat.com/ubi8/ubi:latest 38 | command: 39 | - /bin/sh 40 | - -c 41 | - while true; do sleep 10; done 42 | resources: 43 | requests: 44 | cpu: 400m 45 | memory: 95Mi 46 | limits: 47 | cpu: 400m 48 | memory: 95Mi 49 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/08-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify that quota management hard limit 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: job-2-bronze-1replica 6 | namespace: test 7 | labels: 8 | quota_context: "bronze" 9 | quota_service: "gold" 10 | status: 11 | state: Pending 12 | --- 13 | apiVersion: workload.codeflare.dev/v1beta1 14 | kind: AppWrapper 15 | metadata: 16 | name: job-1-bronze-1replica 17 | namespace: test 18 | labels: 19 | quota_context: "bronze" 20 | quota_service: "gold" 21 | status: 22 | state: Running 23 | --- 24 | apiVersion: v1 25 | kind: Pod 26 | metadata: 27 | name: job-1-bronze-1replica-0 28 | namespace: test 29 | --- 30 | apiVersion: workload.codeflare.dev/v1beta1 31 | kind: AppWrapper 32 | metadata: 33 | name: job-gold-high-pri-1replica 34 | namespace: test 35 | labels: 36 | quota_context: "gold" 37 | quota_service: "gold" 38 | status: 39 | state: Running 40 | --- 41 | apiVersion: v1 42 | kind: Pod 43 | metadata: 44 | name: job-gold-high-pri-1replica-0 45 | namespace: test 46 | --- 47 | apiVersion: workload.codeflare.dev/v1beta1 48 | kind: AppWrapper 49 | metadata: 50 | name: job-bad-quota-id-10replica 51 | namespace: test 52 | labels: 53 | quota_context: "context-root2" 54 | quota_service: "service-root2" 55 | status: 56 | state: Pending 57 | --- 58 | apiVersion: workload.codeflare.dev/v1beta1 59 | kind: AppWrapper 60 | metadata: 61 | name: job-gold-lo-pri-1replica 62 | namespace: test 63 | labels: 64 | quota_context: "gold" 65 | quota_service: "gold" 66 | status: 67 | state: Pending 68 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/08-install.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: job-2-bronze-1replica 5 | namespace: test 6 | labels: 7 | quota_context: "bronze" 8 | quota_service: "gold" 9 | spec: 10 | service: 11 | spec: {} 12 | priority: 1000 13 | resources: 14 | GenericItems: 15 | - replicas: 1 16 | generictemplate: 17 | apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 18 | kind: StatefulSet 19 | metadata: 20 | name: job-2-bronze-1replica 21 | namespace: test 22 | labels: 23 | app: job-2-bronze-1replica 24 | spec: 25 | selector: 26 | matchLabels: 27 | app: job-2-bronze-1replica 28 | replicas: 1 29 | template: 30 | metadata: 31 | labels: 32 | app: job-2-bronze-1replica 33 | size: "1" 34 | spec: 35 | containers: 36 | - name: job-2-bronze-1replica 37 | image: registry.access.redhat.com/ubi8/ubi:latest 38 | command: 39 | - /bin/sh 40 | - -c 41 | - while true; do sleep 10; done 42 | resources: 43 | requests: 44 | cpu: 400m 45 | memory: 95Mi 46 | limits: 47 | cpu: 400m 48 | memory: 95Mi 49 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/09-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify AppWrappers finished successfully 2 | --- 3 | apiVersion: workload.codeflare.dev/v1beta1 4 | kind: AppWrapper 5 | metadata: 6 | name: my-job-1 7 | namespace: test 8 | status: 9 | state: Completed 10 | --- 11 | apiVersion: workload.codeflare.dev/v1beta1 12 | kind: AppWrapper 13 | metadata: 14 | name: my-job-2 15 | namespace: test 16 | status: 17 | state: Completed 18 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/10-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify AppWrapper without quota finished successfully 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: job-without-labels 6 | namespace: test 7 | # labels: 8 | # Skipping validation for now, until we understand the root cause for 9 | # https://github.com/project-codeflare/multi-cluster-app-dispatcher/issues/297 10 | # quota_context: default 11 | # quota_service: default 12 | status: 13 | state: Completed 14 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/10-install.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: job-without-labels 6 | namespace: test 7 | spec: 8 | schedulingSpec: 9 | minAvailable: 1 10 | resources: 11 | GenericItems: 12 | - replicas: 1 13 | completionstatus: Complete 14 | custompodresources: 15 | - replicas: 1 16 | requests: 17 | cpu: 900m 18 | nvidia.com/gpu: 0 19 | memory: 300Mi 20 | limits: 21 | cpu: 900m 22 | nvidia.com/gpu: 0 23 | memory: 300Mi 24 | generictemplate: 25 | apiVersion: batch/v1 26 | kind: Job 27 | metadata: 28 | name: job-without-labels 29 | namespace: test 30 | labels: 31 | appwrapper.mcad.ibm.com: job-without-labels 32 | spec: 33 | parallelism: 1 34 | completions: 1 35 | template: 36 | metadata: 37 | name: job-without-labels 38 | namespace: test 39 | labels: 40 | appwrapper.mcad.ibm.com: job-without-labels 41 | spec: 42 | terminationGracePeriodSeconds: 1 43 | restartPolicy: Never 44 | containers: 45 | - name: ubuntu 46 | image: ubuntu:latest 47 | imagePullPolicy: IfNotPresent 48 | command: 49 | - sh 50 | - -c 51 | - | 52 | sleep 30 53 | resources: 54 | requests: 55 | cpu: 900m 56 | nvidia.com/gpu: 0 57 | memory: 300Mi 58 | limits: 59 | cpu: 900m 60 | nvidia.com/gpu: 0 61 | memory: 300Mi 62 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/11-assert.yaml: -------------------------------------------------------------------------------- 1 | # Verify AppWrapper without quota finished successfully 2 | apiVersion: workload.codeflare.dev/v1beta1 3 | kind: AppWrapper 4 | metadata: 5 | name: job-with-labels-no-quota 6 | namespace: test 7 | labels: 8 | my-label-key: my-label-value 9 | # Skipping validation for now, until we understand the root cause for 10 | # https://github.com/project-codeflare/multi-cluster-app-dispatcher/issues/297 11 | # quota_context: default 12 | # quota_service: default 13 | status: 14 | state: Running 15 | -------------------------------------------------------------------------------- /test/e2e-kuttl/quota-forest/99-cleanup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kuttl.dev/v1beta1 2 | kind: TestStep 3 | apply: [] 4 | assert: [] 5 | error: [] 6 | unitTest: false 7 | delete: [] 8 | commands: 9 | - command: kubectl delete namespace test --wait 10 | -------------------------------------------------------------------------------- /test/e2e/e2e_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019, 2021 The Multi-Cluster App Dispatcher Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package e2e 18 | 19 | import ( 20 | "testing" 21 | 22 | . "github.com/onsi/ginkgo" 23 | . "github.com/onsi/gomega" 24 | ) 25 | 26 | func TestE2E(t *testing.T) { 27 | RegisterFailHandler(Fail) 28 | RunSpecs(t, "MCAD Test Suite") 29 | } 30 | -------------------------------------------------------------------------------- /test/e2e/quota.go: -------------------------------------------------------------------------------- 1 | //go:build private 2 | // +build private 3 | 4 | /* 5 | Copyright 2019, 2021 The Multi-Cluster App Dispatcher Authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | package e2e 21 | 22 | import ( 23 | . "github.com/onsi/ginkgo" 24 | . "github.com/onsi/gomega" 25 | 26 | arbv1 "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/apis/controller/v1beta1" 27 | ) 28 | 29 | var _ = Describe("Quota E2E Test", func() { 30 | 31 | It("Create AppWrapper - Generic Pod Only - Sufficient Quota 1 Tree", func() { 32 | context := initTestContext() 33 | var appwrappers []*arbv1.AppWrapper 34 | appwrappersPtr := &appwrappers 35 | defer cleanupTestObjectsPtr(context, appwrappersPtr) 36 | 37 | aw := createGenericPodAW(context, "aw-generic-pod-1") 38 | appwrappers = append(appwrappers, aw) 39 | 40 | err := waitAWPodsReady(context, aw) 41 | Expect(err).NotTo(HaveOccurred()) 42 | }) 43 | 44 | It("Create AppWrapper - Generic Pod Only - Insufficient Quota 1 Tree", func() { 45 | context := initTestContext() 46 | var appwrappers []*arbv1.AppWrapper 47 | appwrappersPtr := &appwrappers 48 | defer cleanupTestObjectsPtr(context, appwrappersPtr) 49 | 50 | aw := createGenericPodAWCustomDemand(context, "aw-generic-large-cpu-pod-1", "9000m") 51 | appwrappers = append(appwrappers, aw) 52 | 53 | err := waitAWPodsReady(context, aw) 54 | Expect(err).To(HaveOccurred()) 55 | 56 | }) 57 | }) 58 | -------------------------------------------------------------------------------- /test/kuttl-test-borrowing.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kuttl.dev/v1beta1 2 | kind: TestSuite 3 | testDirs: 4 | - test/e2e-kuttl-borrowing/ 5 | timeout: 60 6 | artifactsDir: _output/logs 7 | commands: 8 | - script: helm upgrade --install mcad-controller deployment/mcad-controller --namespace kube-system --wait --set loglevel=${LOG_LEVEL} --set resources.requests.cpu=1000m --set resources.requests.memory=1024Mi --set resources.limits.cpu=4000m --set resources.limits.memory=4096Mi --set image.repository=$IMAGE_REPOSITORY_MCAD --set image.tag=$IMAGE_TAG_MCAD --set image.pullPolicy=$MCAD_IMAGE_PULL_POLICY --set configMap.quotaEnabled='"true"' --set quotaManagement.rbac.apiGroup=ibm.com --set quotaManagement.rbac.resource=quotasubtrees --set configMap.name=mcad-controller-configmap --set configMap.preemptionEnabled='"true"' 9 | - script: kubectl apply -f ${ROOT_DIR}/test/e2e-kuttl-borrowing/install-quota-subtree.yaml 10 | -------------------------------------------------------------------------------- /test/kuttl-test-deployment-01.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kuttl.dev/v1beta1 2 | kind: TestSuite 3 | testDirs: 4 | - test/e2e-kuttl-deployment-01/ 5 | timeout: 240 6 | artifactsDir: _output/logs 7 | commands: 8 | - script: helm upgrade --install mcad-controller ${ROOT_DIR}/deployment/mcad-controller --namespace kube-system --wait --timeout 2m0s --set loglevel=${LOG_LEVEL} --set resources.requests.cpu=1000m --set resources.requests.memory=1024Mi --set resources.limits.cpu=4000m --set resources.limits.memory=4096Mi --set image.repository=$IMAGE_REPOSITORY_MCAD --set image.tag=$IMAGE_TAG_MCAD --set image.pullPolicy=$MCAD_IMAGE_PULL_POLICY --set configMap.quotaEnabled='"false"' 9 | -------------------------------------------------------------------------------- /test/kuttl-test-deployment-02.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kuttl.dev/v1beta1 2 | kind: TestSuite 3 | testDirs: 4 | - test/e2e-kuttl-deployment-02/ 5 | timeout: 300 6 | artifactsDir: _output/logs 7 | commands: 8 | - script: helm upgrade --install mcad-controller ${ROOT_DIR}/deployment/mcad-controller --namespace kube-system --wait --timeout 2m0s --set loglevel=${LOG_LEVEL} --set resources.requests.cpu=1000m --set resources.requests.memory=1024Mi --set resources.limits.cpu=4000m --set resources.limits.memory=4096Mi --set image.repository=$IMAGE_REPOSITORY_MCAD --set image.tag=$IMAGE_TAG_MCAD --set image.pullPolicy=$MCAD_IMAGE_PULL_POLICY --set configMap.quotaEnabled='"true"' --set quotaManagement.rbac.apiGroup=quota.codeflare.dev --set quotaManagement.rbac.resource=quotasubtrees --set configMap.name=mcad-controller-configmap --set configMap.preemptionEnabled='"true"' 9 | - script: kubectl apply -f ${ROOT_DIR}/test/e2e-kuttl/install-quota-subtree.yaml 10 | -------------------------------------------------------------------------------- /test/kuttl-test-deployment-03.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kuttl.dev/v1beta1 2 | kind: TestSuite 3 | testDirs: 4 | - test/e2e-kuttl-deployment-03/ 5 | timeout: 90 6 | crdDir: config/crd/bases 7 | artifactsDir: _output/logs 8 | commands: 9 | - script: kubectl apply -f ${ROOT_DIR}/test/e2e-kuttl/install-quota-subtree.yaml 10 | - script: helm upgrade --install mcad-controller deployment/mcad-controller --skip-crds --namespace kube-system --wait --set loglevel=${LOG_LEVEL} --set resources.requests.cpu=1000m --set resources.requests.memory=1024Mi --set resources.limits.cpu=4000m --set resources.limits.memory=4096Mi --set image.repository=$IMAGE_REPOSITORY_MCAD --set image.tag=$IMAGE_TAG_MCAD --set image.pullPolicy=$MCAD_IMAGE_PULL_POLICY --set configMap.quotaEnabled='"true"' --set quotaManagement.rbac.apiGroup=quota.codeflare.dev --set quotaManagement.rbac.resource=quotasubtrees --set configMap.name=mcad-controller-configmap --set configMap.preemptionEnabled='"true"' 11 | -------------------------------------------------------------------------------- /test/kuttl-test-extended-resources.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kuttl.dev/v1beta1 2 | kind: TestSuite 3 | testDirs: 4 | - test/e2e-kuttl-extended-resources/ 5 | timeout: 60 6 | artifactsDir: _output/logs 7 | commands: 8 | -------------------------------------------------------------------------------- /test/kuttl-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kuttl.dev/v1beta1 2 | kind: TestSuite 3 | testDirs: 4 | - test/e2e-kuttl/ 5 | timeout: 420 6 | artifactsDir: _output/logs 7 | commands: 8 | - script: helm upgrade --install mcad-controller deployment/mcad-controller --namespace kube-system --wait --set loglevel=${LOG_LEVEL} --set resources.requests.cpu=1000m --set resources.requests.memory=1024Mi --set resources.limits.cpu=4000m --set resources.limits.memory=4096Mi --set image.repository=$IMAGE_REPOSITORY_MCAD --set image.tag=$IMAGE_TAG_MCAD --set image.pullPolicy=$MCAD_IMAGE_PULL_POLICY --set configMap.quotaEnabled='"true"' --set quotaManagement.rbac.apiGroup=quota.codeflare.dev --set quotaManagement.rbac.resource=quotasubtrees --set configMap.name=mcad-controller-configmap --set configMap.preemptionEnabled='"true"' 9 | - script: kubectl apply -f ${ROOT_DIR}/test/e2e-kuttl/install-quota-subtree.yaml 10 | -------------------------------------------------------------------------------- /test/perf-test/cleanup-mcad-kwok.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for i in `kubectl get appwrapper -n default |grep fake-defaultaw | awk '{print $1}'`; do kubectl delete appwrapper $i -n default ; done 4 | -------------------------------------------------------------------------------- /test/perf-test/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for i in `kubectl get appwrapper -n default |grep defaultaw | awk '{print $1}'`; do kubectl delete appwrapper $i -n default ; done 4 | -------------------------------------------------------------------------------- /test/perf-test/node.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Node 3 | metadata: 4 | annotations: 5 | node.alpha.kubernetes.io/ttl: "0" 6 | kwok.x-k8s.io/node: fake 7 | labels: 8 | beta.kubernetes.io/arch: amd64 9 | beta.kubernetes.io/os: linux 10 | kubernetes.io/arch: amd64 11 | kubernetes.io/hostname: kwok-node-0 12 | kubernetes.io/os: linux 13 | kubernetes.io/role: agent 14 | node-role.kubernetes.io/agent: "" 15 | type: kwok 16 | name: kwok-node-0 17 | spec: 18 | taints: # Avoid scheduling actual running pods to fake Node 19 | - effect: NoSchedule 20 | key: kwok.x-k8s.io/node 21 | value: fake 22 | status: 23 | allocatable: 24 | cpu: 32 25 | nvidia.com/gpu: 32 26 | memory: 256Gi 27 | pods: 110 28 | capacity: 29 | cpu: 32 30 | nvidia.com/gpu: 32 31 | memory: 256Gi 32 | pods: 110 33 | nodeInfo: 34 | architecture: amd64 35 | bootID: "" 36 | containerRuntimeVersion: "" 37 | kernelVersion: "" 38 | kubeProxyVersion: fake 39 | kubeletVersion: fake 40 | machineID: "" 41 | operatingSystem: linux 42 | osImage: "" 43 | systemUUID: "" 44 | phase: Running 45 | -------------------------------------------------------------------------------- /test/perf-test/preempt-exp-kwok.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: fake-defaultaw-schd-spec-with-timeout-1 5 | namespace: default 6 | spec: 7 | schedulingSpec: 8 | minAvailable: 1 9 | requeuing: 10 | timeInSeconds: 120 11 | growthType: "exponential" 12 | priority: 9 13 | resources: 14 | Items: [] 15 | GenericItems: 16 | - replicas: 1 17 | completionstatus: Complete 18 | custompodresources: 19 | - replicas: 1 20 | requests: 21 | cpu: 10m 22 | memory: 10M 23 | nvidia.com/gpu: 0 24 | limits: 25 | cpu: 500m 26 | memory: 128M 27 | nvidia.com/gpu: 0 28 | generictemplate: 29 | apiVersion: batch/v1 30 | kind: Job 31 | metadata: 32 | namespace: default 33 | name: fake-defaultaw-schd-spec-with-timeout-1 34 | spec: 35 | parallelism: 1 36 | completions: 1 37 | template: 38 | metadata: 39 | namespace: default 40 | labels: 41 | appwrapper.mcad.ibm.com: "fake-defaultaw-schd-spec-with-timeout-1" 42 | spec: 43 | affinity: 44 | nodeAffinity: 45 | requiredDuringSchedulingIgnoredDuringExecution: 46 | nodeSelectorTerms: 47 | - matchExpressions: 48 | - key: type 49 | operator: In 50 | values: 51 | - kwok 52 | # A taints was added to an automatically created Node. 53 | # You can remove taints of Node or add this tolerations. 54 | tolerations: 55 | - key: "kwok.x-k8s.io/node" 56 | operator: "Exists" 57 | effect: "NoSchedule" 58 | containers: 59 | - name: fake-defaultaw-schd-spec-with-timeout-1 60 | image: fake-image 61 | restartPolicy: Never 62 | -------------------------------------------------------------------------------- /test/perf-test/preempt-exp.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: defaultaw-schd-spec-with-timeout-1 5 | namespace: default 6 | spec: 7 | schedulingSpec: 8 | minAvailable: 1 9 | requeuing: 10 | timeInSeconds: 120 11 | growthType: "exponential" 12 | priority: 9 13 | resources: 14 | GenericItems: 15 | - replicas: 1 16 | completionstatus: Complete 17 | custompodresources: 18 | - replicas: 1 19 | requests: 20 | cpu: 500m 21 | memory: 128M 22 | nvidia.com/gpu: 0 23 | limits: 24 | cpu: 500m 25 | memory: 128M 26 | nvidia.com/gpu: 0 27 | generictemplate: 28 | apiVersion: batch/v1 29 | kind: Job 30 | metadata: 31 | namespace: default 32 | name: defaultaw-schd-spec-with-timeout-1 33 | labels: 34 | appwrapper.mcad.ibm.com: defaultaw-schd-spec-with-timeout-1 35 | spec: 36 | parallelism: 1 37 | completions: 1 38 | template: 39 | metadata: 40 | namespace: default 41 | labels: 42 | appwrapper.mcad.ibm.com: "defaultaw-schd-spec-with-timeout-1" 43 | spec: 44 | containers: 45 | - name: defaultaw-schd-spec-with-timeout-1 46 | image: ubi8-minimal:latest 47 | command: [ "/bin/bash", "-c", "--" ] 48 | args: [ "sleep 10" ] 49 | resources: 50 | requests: 51 | memory: "128Mi" 52 | cpu: "500m" 53 | limits: 54 | memory: "128Mi" 55 | cpu: "500m" 56 | restartPolicy: Never 57 | -------------------------------------------------------------------------------- /test/yaml/0001-aw-generic-deployment-3.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: 0001-aw-generic-deployment-3 5 | spec: 6 | resources: 7 | GenericItems: 8 | - replicas: 1 9 | generictemplate: 10 | apiVersion: apps/v1 11 | kind: Deployment 12 | metadata: 13 | name: 0001-aw-generic-deployment-3 14 | labels: 15 | app: 0001-aw-generic-deployment-3 16 | spec: 17 | selector: 18 | matchLabels: 19 | app: 0001-aw-generic-deployment-3 20 | replicas: 3 21 | template: 22 | metadata: 23 | labels: 24 | app: 0001-aw-generic-deployment-3 25 | spec: 26 | containers: 27 | - name: 0001-aw-generic-deployment-3 28 | image: kicbase/echo-server:1.0 29 | ports: 30 | - containerPort: 80 31 | resources: 32 | requests: 33 | cpu: 100m 34 | memory: 32Mi 35 | limits: 36 | cpu: 100m 37 | memory: 32Mi 38 | -------------------------------------------------------------------------------- /test/yaml/0002-aw-job-quota.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: my-job-1 5 | namespace: test 6 | labels: 7 | quota_context: "bronze" 8 | quota_service: "gold" 9 | spec: 10 | schedulingSpec: 11 | minAvailable: 1 12 | resources: 13 | GenericItems: 14 | - replicas: 1 15 | completionstatus: Complete 16 | custompodresources: 17 | - replicas: 1 18 | requests: 19 | cpu: 900m 20 | nvidia.com/gpu: 0 21 | memory: 300Mi 22 | limits: 23 | cpu: 900m 24 | nvidia.com/gpu: 0 25 | memory: 300Mi 26 | generictemplate: 27 | apiVersion: batch/v1 28 | kind: Job 29 | metadata: 30 | name: my-job-1 31 | namespace: test 32 | labels: 33 | appwrapper.mcad.ibm.com: my-job-1 34 | spec: 35 | parallelism: 1 36 | completions: 1 37 | template: 38 | metadata: 39 | name: my-job-1 40 | namespace: test 41 | labels: 42 | appwrapper.mcad.ibm.com: my-job-1 43 | spec: 44 | terminationGracePeriodSeconds: 1 45 | restartPolicy: Never 46 | containers: 47 | - name: ubuntu 48 | image: ubuntu:latest 49 | imagePullPolicy: IfNotPresent 50 | command: 51 | - sh 52 | - -c 53 | - | 54 | sleep 30 55 | resources: 56 | requests: 57 | cpu: 900m 58 | nvidia.com/gpu: 0 59 | memory: 300Mi 60 | limits: 61 | cpu: 900m 62 | nvidia.com/gpu: 0 63 | memory: 300Mi 64 | -------------------------------------------------------------------------------- /test/yaml/0003-aw-job-no-quota.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: my-no-quota-job-0003 5 | namespace: test 6 | spec: 7 | schedulingSpec: 8 | minAvailable: 1 9 | resources: 10 | GenericItems: 11 | - replicas: 1 12 | completionstatus: Complete 13 | custompodresources: 14 | - replicas: 1 15 | requests: 16 | cpu: 900m 17 | nvidia.com/gpu: 0 18 | memory: 300Mi 19 | limits: 20 | cpu: 900m 21 | nvidia.com/gpu: 0 22 | memory: 300Mi 23 | generictemplate: 24 | apiVersion: batch/v1 25 | kind: Job 26 | metadata: 27 | name: my-no-quota-job-0003 28 | namespace: test 29 | labels: 30 | appwrapper.mcad.ibm.com: my-no-quota-job-0003 31 | spec: 32 | parallelism: 1 33 | completions: 1 34 | template: 35 | metadata: 36 | name: my-no-quota-job-0003 37 | namespace: test 38 | labels: 39 | appwrapper.mcad.ibm.com: my-no-quota-job-0003 40 | spec: 41 | terminationGracePeriodSeconds: 1 42 | restartPolicy: Never 43 | containers: 44 | - name: ubuntu 45 | image: ubuntu:latest 46 | imagePullPolicy: IfNotPresent 47 | command: 48 | - sh 49 | - -c 50 | - | 51 | sleep 30 52 | resources: 53 | requests: 54 | cpu: 900m 55 | nvidia.com/gpu: 0 56 | memory: 300Mi 57 | limits: 58 | cpu: 900m 59 | nvidia.com/gpu: 0 60 | memory: 300Mi 61 | -------------------------------------------------------------------------------- /test/yaml/0004-aw-large-job-no-quota.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: large-job-no-quota 5 | namespace: test 6 | spec: 7 | schedulingSpec: 8 | minAvailable: 1 9 | resources: 10 | GenericItems: 11 | - replicas: 1 12 | completionstatus: Complete 13 | custompodresources: 14 | - replicas: 1 15 | requests: 16 | cpu: 3000m 17 | nvidia.com/gpu: 0 18 | memory: 300Mi 19 | limits: 20 | cpu: 3000m 21 | nvidia.com/gpu: 0 22 | memory: 300Mi 23 | generictemplate: 24 | apiVersion: batch/v1 25 | kind: Job 26 | metadata: 27 | name: large-job-no-quota 28 | namespace: test 29 | labels: 30 | appwrapper.mcad.ibm.com: large-job-no-quota 31 | spec: 32 | parallelism: 1 33 | completions: 1 34 | template: 35 | metadata: 36 | name: large-job-no-quota 37 | namespace: test 38 | labels: 39 | appwrapper.mcad.ibm.com: large-job-no-quota 40 | spec: 41 | terminationGracePeriodSeconds: 1 42 | restartPolicy: Never 43 | containers: 44 | - name: ubuntu 45 | image: ubuntu:latest 46 | imagePullPolicy: IfNotPresent 47 | command: 48 | - sh 49 | - -c 50 | - | 51 | sleep 30 52 | resources: 53 | requests: 54 | cpu: 3000m 55 | nvidia.com/gpu: 0 56 | memory: 300Mi 57 | limits: 58 | cpu: 3000m 59 | nvidia.com/gpu: 0 60 | memory: 300Mi 61 | -------------------------------------------------------------------------------- /test/yaml/0008-aw-default.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workload.codeflare.dev/v1beta1 2 | kind: AppWrapper 3 | metadata: 4 | name: defaultaw-schd-spec-with-timeout-1 5 | namespace: default 6 | spec: 7 | # schedulingSpec: 8 | # minAvailable: 1 9 | # requeuing: 10 | # timeInSeconds: 120 11 | # growthType: "exponential" 12 | priority: 9 13 | resources: 14 | GenericItems: 15 | - replicas: 1 16 | # completionstatus: Complete 17 | custompodresources: 18 | - replicas: 1 19 | requests: 20 | cpu: 500m 21 | memory: 512Mi 22 | nvidia.com/gpu: 0 23 | limits: 24 | cpu: 500m 25 | memory: 512Mi 26 | nvidia.com/gpu: 0 27 | generictemplate: 28 | apiVersion: batch/v1 29 | kind: Job 30 | metadata: 31 | namespace: default 32 | name: defaultaw-schd-spec-with-timeout-1 33 | # labels: 34 | # appwrapper.mcad.ibm.com: defaultaw-schd-spec-with-timeout-1 35 | spec: 36 | parallelism: 1 37 | completions: 1 38 | template: 39 | metadata: 40 | namespace: default 41 | labels: 42 | appwrapper.mcad.ibm.com: "defaultaw-schd-spec-with-timeout-1" 43 | spec: 44 | containers: 45 | - name: defaultaw-schd-spec-with-timeout-1 46 | image: ubuntu:latest 47 | command: [ "/bin/bash", "-c", "--" ] 48 | args: [ "sleep 10" ] 49 | resources: 50 | requests: 51 | memory: "512Mi" 52 | cpu: "500m" 53 | limits: 54 | memory: "512Mi" 55 | cpu: "500m" 56 | restartPolicy: Never 57 | --------------------------------------------------------------------------------