From 33f3dff6ed3b9da4aa372869726dc5fa74436aa8 Mon Sep 17 00:00:00 2001 From: Lucian Petrut Date: Fri, 20 Sep 2024 10:47:16 +0300 Subject: [PATCH] Add calico rock definitions (#1) --- .gitattributes | 1 + .github/ISSUE_TEMPLATE/bug_report.yaml | 54 ++++ .github/ISSUE_TEMPLATE/feature_request.md | 21 ++ .github/workflows/cla-check.yaml | 9 + .github/workflows/pull_request.yaml | 41 +++ .gitignore | 5 + LICENSE | 201 ++++++++++++++ README.md | 2 +- calico/v3.28.0/apiserver/rockcraft.yaml | 53 ++++ calico/v3.28.0/cni/rockcraft.yaml | 97 +++++++ calico/v3.28.0/csi/rockcraft.yaml | 43 +++ calico/v3.28.0/ctl/rockcraft.yaml | 42 +++ .../key-cert-provisioner/rockcraft.yaml | 41 +++ .../v3.28.0/kube-controllers/rockcraft.yaml | 52 ++++ .../node-driver-registrar/rockcraft.yaml | 41 +++ calico/v3.28.0/node/rockcraft.yaml | 248 ++++++++++++++++++ .../pod2daemon-flexvol/pebble_entrypoint.sh | 11 + .../v3.28.0/pod2daemon-flexvol/rockcraft.yaml | 57 ++++ calico/v3.28.0/typha/pebble_entrypoint.sh | 11 + calico/v3.28.0/typha/rockcraft.yaml | 67 +++++ tests/.copyright.tmpl | 2 + tests/__init__.py | 0 tests/integration/__init__.py | 4 + tests/integration/conftest.py | 5 + tests/integration/test_calico.py | 204 ++++++++++++++ tests/requirements-dev.txt | 5 + tests/requirements-test.txt | 6 + tests/sanity/__init__.py | 4 + tests/sanity/test_calico.py | 211 +++++++++++++++ tests/tox.ini | 82 ++++++ .../fix_image_component_handling.patch | 38 +++ .../v1.34.0/fix_imageset_checks.patch | 30 +++ tigera-operator/v1.34.0/rockcraft.yaml | 49 ++++ trivy.yaml | 3 + 34 files changed, 1739 insertions(+), 1 deletion(-) create mode 100644 .gitattributes create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yaml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/workflows/cla-check.yaml create mode 100644 .github/workflows/pull_request.yaml create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 calico/v3.28.0/apiserver/rockcraft.yaml create mode 100644 calico/v3.28.0/cni/rockcraft.yaml create mode 100644 calico/v3.28.0/csi/rockcraft.yaml create mode 100644 calico/v3.28.0/ctl/rockcraft.yaml create mode 100644 calico/v3.28.0/key-cert-provisioner/rockcraft.yaml create mode 100644 calico/v3.28.0/kube-controllers/rockcraft.yaml create mode 100644 calico/v3.28.0/node-driver-registrar/rockcraft.yaml create mode 100644 calico/v3.28.0/node/rockcraft.yaml create mode 100755 calico/v3.28.0/pod2daemon-flexvol/pebble_entrypoint.sh create mode 100644 calico/v3.28.0/pod2daemon-flexvol/rockcraft.yaml create mode 100755 calico/v3.28.0/typha/pebble_entrypoint.sh create mode 100644 calico/v3.28.0/typha/rockcraft.yaml create mode 100644 tests/.copyright.tmpl create mode 100644 tests/__init__.py create mode 100644 tests/integration/__init__.py create mode 100644 tests/integration/conftest.py create mode 100644 tests/integration/test_calico.py create mode 100644 tests/requirements-dev.txt create mode 100644 tests/requirements-test.txt create mode 100644 tests/sanity/__init__.py create mode 100644 tests/sanity/test_calico.py create mode 100644 tests/tox.ini create mode 100644 tigera-operator/v1.34.0/fix_image_component_handling.patch create mode 100644 tigera-operator/v1.34.0/fix_imageset_checks.patch create mode 100644 tigera-operator/v1.34.0/rockcraft.yaml create mode 100644 trivy.yaml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fcadb2c --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text eol=lf diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml new file mode 100644 index 0000000..fada03f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -0,0 +1,54 @@ +name: Bug Report +description: Something is not working + +body: + - type: markdown + attributes: + value: | + Thank you for submitting an issue. Please fill in the template below + information about the bug you encountered. + + - type: textarea + id: summary + attributes: + label: Summary + description: Please explain the bug in a few short sentences. + placeholder: Detail the bug here... + validations: + required: true + + - type: textarea + id: what-should-happen + attributes: + label: What Should Happen Instead? + description: Please explain what the expected behavior is. + placeholder: Explain the expected outcome... + validations: + required: true + + - type: textarea + id: reproduction-steps + attributes: + label: Reproduction Steps + description: Are you able to consistently reproduce the issue? Please add a list of steps that lead to the bug. + placeholder: "1.\n2.\n" + validations: + required: true + + - type: textarea + id: suggest-fix + attributes: + label: Can you suggest a fix? + description: How do you propose that the issue be fixed? + placeholder: Suggest a fix if you have one... + + - type: textarea + id: contribute-fix + attributes: + label: Are you interested in contributing with a fix? + description: yes/no, or @mention maintainers. Community contributions are welcome. + placeholder: Are you willing to contribute a fix? + + - type: markdown + attributes: + value: Thank you for making the rocks better diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..b727d0e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,21 @@ +--- +name: Feature Request +about: Suggest a new feature +--- + + + +#### Summary + + +#### Why is this important? + + +#### Are you interested in contributing to this feature? + + + + \ No newline at end of file diff --git a/.github/workflows/cla-check.yaml b/.github/workflows/cla-check.yaml new file mode 100644 index 0000000..75e5796 --- /dev/null +++ b/.github/workflows/cla-check.yaml @@ -0,0 +1,9 @@ +name: cla-check +on: [pull_request_target] + +jobs: + cla-check: + runs-on: ubuntu-latest + steps: + - name: Check if CLA signed + uses: canonical/has-signed-canonical-cla@v1 diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml new file mode 100644 index 0000000..b33dd52 --- /dev/null +++ b/.github/workflows/pull_request.yaml @@ -0,0 +1,41 @@ +name: Push Multiarch Images +on: + pull_request: + push: + branches: + - main + +jobs: + build-and-push-arch-specifics: + name: Build Rocks and Push Arch Specific Images + uses: canonical/k8s-workflows/.github/workflows/build_rocks.yaml@main + with: + owner: ${{ github.repository_owner }} + trivy-image-config: "trivy.yaml" + multiarch-awareness: true + cache-action: ${{ (github.event_name == 'push') && 'save' || 'restore' }} + # pinning to use rockcraft 1.3.0 feature `entrypoint-service` + rockcraft-revisions: '{"amd64": "1783", "arm64": "1784"}' + arch-skipping-maximize-build-space: '["arm64"]' + platform-labels: '{"arm64": ["self-hosted", "Linux", "ARM64", "jammy"]}' + run-tests: + uses: canonical/k8s-workflows/.github/workflows/run_tests.yaml@main + needs: [build-and-push-arch-specifics] + secrets: inherit + with: + rock-metas: ${{ needs.build-and-push-arch-specifics.outputs.rock-metas }} + scan-images: + uses: canonical/k8s-workflows/.github/workflows/scan_images.yaml@main + needs: [build-and-push-arch-specifics] + secrets: inherit + with: + upload-result: ${{ github.event_name == 'push' }} + images: ${{ needs.build-and-push-arch-specifics.outputs.images }} + trivy-image-config: ./trivy.yaml + build-and-push-multiarch-manifest: + name: Combine Rocks and Push Multiarch Manifest + uses: canonical/k8s-workflows/.github/workflows/assemble_multiarch_image.yaml@main + needs: [build-and-push-arch-specifics] + with: + rock-metas: ${{ needs.build-and-push-arch-specifics.outputs.rock-metas }} + dry-run: ${{ github.event_name != 'push' }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5f9d73b --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.rock +**/__pycache__ +.pytest_cache +.venv +.tox diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index d7a1cc4..af1bd80 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# calico-rocks \ No newline at end of file +# calico-rocks diff --git a/calico/v3.28.0/apiserver/rockcraft.yaml b/calico/v3.28.0/apiserver/rockcraft.yaml new file mode 100644 index 0000000..0bd5026 --- /dev/null +++ b/calico/v3.28.0/apiserver/rockcraft.yaml @@ -0,0 +1,53 @@ +name: calico-apiserver +summary: Calico apiserver ROCK image. +description: > + This rock is a drop in replacement for the + docker.io/calico/apiserver:v3.28.0 image. +version: v3.28.0 +license: Apache-2.0 + +base: ubuntu@24.04 +build-base: ubuntu@24.04 +platforms: + amd64: + arm64: + +entrypoint-service: apiserver +services: + apiserver: + command: /code/apiserver [ ] + override: replace + startup: enabled + +parts: + build-deps: + plugin: nil + build-snaps: + - go/1.22/stable + + apiserver: + after: [build-deps] + plugin: go + source-type: git + source: https://github.com/projectcalico/calico + source-tag: v3.28.0 + source-depth: 1 + build-environment: + - PACKAGE_NAME: github.com/projectcalico/calico/apiserver + - CGO_ENABLED: 0 + override-build: | + APISERVER_VERSION=`git describe --tags --dirty --always --abbrev=12` + APISERVER_BUILD_DATE=`date -u +'%FT%T%z'` + APISERVER_GIT_REVISION=`git rev-parse --short HEAD` + APISERVER_GIT_DESCRIPTION=`git describe --tags` + + LDFLAGS="-X ${PACKAGE_NAME}/cmd/apiserver/server.VERSION=${APISERVER_VERSION}" + LDFLAGS="$LDFLAGS -X ${PACKAGE_NAME}/cmd/apiserver/server.BUILD_DATE=${APISERVER_BUILD_DATE}" + LDFLAGS="$LDFLAGS -X ${PACKAGE_NAME}/cmd/apiserver/server.GIT_DESCRIPTION=${APISERVER_GIT_DESCRIPTION}" \ + LDFLAGS="$LDFLAGS -X ${PACKAGE_NAME}/cmd/apiserver/server.GIT_REVISION=${APISERVER_GIT_REVISION}" + + mkdir -p $CRAFT_PART_INSTALL/code + go build -o $CRAFT_PART_INSTALL/code/apiserver \ + -v -buildvcs=false -ldflags "$LDFLAGS" \ + ./apiserver/cmd/apiserver + diff --git a/calico/v3.28.0/cni/rockcraft.yaml b/calico/v3.28.0/cni/rockcraft.yaml new file mode 100644 index 0000000..d97038f --- /dev/null +++ b/calico/v3.28.0/cni/rockcraft.yaml @@ -0,0 +1,97 @@ +name: calico-cni +summary: Calico cni ROCK image. +description: > + This rock is a drop in replacement for the + docker.io/calico/cni:v3.28.0 image. +version: v3.28.0 +license: Apache-2.0 + +base: ubuntu@24.04 +build-base: ubuntu@24.04 +platforms: + amd64: + arm64: + +entrypoint-service: cni +services: + cni: + command: /opt/cni/bin/install [ ] + override: replace + startup: enabled + +parts: + build-deps: + plugin: nil + build-snaps: + - go/1.22/stable + + cni: + after: [build-deps] + plugin: go + source-type: git + source: https://github.com/projectcalico/calico + source-tag: v3.28.0 + source-depth: 1 + build-environment: + - GIT_VERSION: v3.28.0 + - CGO_ENABLED: 0 + override-build: | + LDFLAGS="-X main.VERSION=${GIT_VERSION}" + + mkdir -p $CRAFT_PART_INSTALL/opt/cni/bin + go build -o $CRAFT_PART_INSTALL/opt/cni/bin \ + -v -buildvcs=false -ldflags "$LDFLAGS" \ + ./cni-plugin/cmd/calico + + go build -o $CRAFT_PART_INSTALL/opt/cni/bin \ + -v -buildvcs=false -ldflags "$LDFLAGS" \ + ./cni-plugin/cmd/install + + cp $CRAFT_PART_INSTALL/opt/cni/bin/calico \ + $CRAFT_PART_INSTALL/opt/cni/bin/calico-ipam + + cni-plugins: + after: [build-deps] + plugin: go + source-type: git + source: https://github.com/projectcalico/containernetworking-plugins + source-tag: v1.1.1-calico+go-1.22.5 + source-depth: 1 + override-build: | + GIT_VERSION=v3.28.0 + + LDFLAGS="-X github.com/containernetworking/plugins/pkg/utils/buildversion.BuildVersion=${GIT_VERSION}" + + GOFLAGS='-buildvcs=false' CGO_ENABLED=0 \ + ./build_linux.sh -ldflags "$LDFLAGS" + + mkdir -p $CRAFT_PART_INSTALL/opt/cni/bin + cp bin/host-local bin/portmap bin/loopback bin/tuning bin/bandwidth \ + $CRAFT_PART_INSTALL/opt/cni/bin/ + + flannel: + after: [build-deps] + plugin: go + source-type: git + source: https://github.com/projectcalico/flannel-cni-plugin + source-tag: v1.2.0-flannel2-go1.22.5 + source-depth: 1 + override-build: | + case `arch` in + amd64 | x86_64) + export ARCH=amd64 + ;; + arm64 | aarch64) + export ARCH=arm64 + ;; + *) + echo "Unupported cpu architecture: $(arch)" + exit 1 + ;; + esac + + VERSION=v1.2.0-flannel2-go1.22.5 \ + make build_linux + + mkdir -p $CRAFT_PART_INSTALL/opt/cni/bin + cp dist/flannel-$ARCH $CRAFT_PART_INSTALL/opt/cni/bin/ diff --git a/calico/v3.28.0/csi/rockcraft.yaml b/calico/v3.28.0/csi/rockcraft.yaml new file mode 100644 index 0000000..7c6fdd5 --- /dev/null +++ b/calico/v3.28.0/csi/rockcraft.yaml @@ -0,0 +1,43 @@ +name: calico-csi +summary: Calico csi ROCK image. +description: > + This rock is a drop in replacement for the + docker.io/calico/csi:v3.28.0 image. +version: v3.28.0 +license: Apache-2.0 + +base: ubuntu@24.04 +build-base: ubuntu@24.04 +platforms: + amd64: + arm64: + +entrypoint-service: csi +services: + csi: + command: /usr/bin/csi-driver [ ] + override: replace + startup: enabled + +parts: + build-deps: + plugin: nil + build-snaps: + - go/1.22/stable + + csi: + after: [build-deps] + plugin: go + source-type: git + source: https://github.com/projectcalico/calico + source-tag: v3.28.0 + source-depth: 1 + build-environment: + - CGO_ENABLED: 0 + override-build: | + mkdir -p $CRAFT_PART_INSTALL/usr/bin + + go build -o $CRAFT_PART_INSTALL/usr/bin/csi-driver \ + -v -buildvcs=false \ + ./pod2daemon/csidriver/main.go + diff --git a/calico/v3.28.0/ctl/rockcraft.yaml b/calico/v3.28.0/ctl/rockcraft.yaml new file mode 100644 index 0000000..ee31aa3 --- /dev/null +++ b/calico/v3.28.0/ctl/rockcraft.yaml @@ -0,0 +1,42 @@ +name: calico-ctl +summary: Calico ctl ROCK image. +description: > + This rock is a drop in replacement for the + docker.io/calico/ctl:v3.28.0 image. +version: v3.28.0 +license: Apache-2.0 + +base: ubuntu@24.04 +build-base: ubuntu@24.04 +platforms: + amd64: + arm64: + +entrypoint-service: ctl +services: + ctl: + command: /usr/bin/calicoctl [ ] + override: replace + startup: enabled + +parts: + build-deps: + plugin: nil + build-snaps: + - go/1.22/stable + + ctl: + after: [build-deps] + plugin: go + source-type: git + source: https://github.com/projectcalico/calico + source-tag: v3.28.0 + source-depth: 1 + build-environment: + - CGO_ENABLED: 0 + override-build: | + mkdir -p $CRAFT_PART_INSTALL/usr/bin + go build -o $CRAFT_PART_INSTALL/usr/bin/ctl \ + -v -buildvcs=false \ + ./calicoctl/calicoctl/calicoctl.go + diff --git a/calico/v3.28.0/key-cert-provisioner/rockcraft.yaml b/calico/v3.28.0/key-cert-provisioner/rockcraft.yaml new file mode 100644 index 0000000..322d799 --- /dev/null +++ b/calico/v3.28.0/key-cert-provisioner/rockcraft.yaml @@ -0,0 +1,41 @@ +name: calico-key-cert-provisioner +summary: Calico key-cert-provisioner ROCK image. +description: > + This rock is a drop in replacement for the + docker.io/calico/key-cert-provisioner:v3.28.0 image. +version: v3.28.0 +license: Apache-2.0 + +base: ubuntu@24.04 +build-base: ubuntu@24.04 +platforms: + amd64: + arm64: + +entrypoint-service: key-cert-provisioner +services: + key-cert-provisioner: + command: /usr/bin/key-cert-provisioner [ ] + override: replace + startup: enabled + +parts: + build-deps: + plugin: nil + build-snaps: + - go/1.22/stable + + key-cert-provisioner: + after: [build-deps] + plugin: go + source-type: git + source: https://github.com/projectcalico/calico + source-tag: v3.28.0 + source-depth: 1 + build-environment: + - CGO_ENABLED: 0 + override-build: | + mkdir -p $CRAFT_PART_INSTALL/usr/bin + go build -o $CRAFT_PART_INSTALL/usr/bin/key-cert-provisioner \ + -v -buildvcs=false \ + ./key-cert-provisioner/cmd/main.go diff --git a/calico/v3.28.0/kube-controllers/rockcraft.yaml b/calico/v3.28.0/kube-controllers/rockcraft.yaml new file mode 100644 index 0000000..cf58759 --- /dev/null +++ b/calico/v3.28.0/kube-controllers/rockcraft.yaml @@ -0,0 +1,52 @@ +name: calico-kube-controllers +summary: Calico kube-controllers ROCK image. +description: > + This rock is a drop in replacement for the + docker.io/calico/kube-controllers:v3.28.0 image. +version: v3.28.0 +license: Apache-2.0 + +base: ubuntu@24.04 +build-base: ubuntu@24.04 +platforms: + amd64: + arm64: + +entrypoint-service: kube-controllers +services: + kube-controllers: + command: /usr/bin/kube-controllers [ ] + override: replace + startup: enabled + +parts: + build-deps: + plugin: nil + build-snaps: + - go/1.22/stable + + kube-controllers: + after: [build-deps] + plugin: go + source-type: git + source: https://github.com/projectcalico/calico + source-tag: v3.28.0 + source-depth: 1 + build-environment: + - GIT_VERSION: v3.28.0 + - CGO_ENABLED: 0 + override-build: | + LDFLAGS="-X main.VERSION=v3.28.0" + + mkdir -p $CRAFT_PART_INSTALL/usr/bin + + go build -o $CRAFT_PART_INSTALL/usr/bin/kube-controllers \ + -v -buildvcs=false -ldflags "$LDFLAGS" \ + ./kube-controllers/cmd/kube-controllers/ + + go build -o $CRAFT_PART_INSTALL/usr/bin/check-status \ + -v -buildvcs=false -ldflags "$LDFLAGS" \ + ./kube-controllers/cmd/check-status/ + + mkdir -p $CRAFT_PART_INSTALL/status + chmod a+rw $CRAFT_PART_INSTALL/status diff --git a/calico/v3.28.0/node-driver-registrar/rockcraft.yaml b/calico/v3.28.0/node-driver-registrar/rockcraft.yaml new file mode 100644 index 0000000..a98f9e3 --- /dev/null +++ b/calico/v3.28.0/node-driver-registrar/rockcraft.yaml @@ -0,0 +1,41 @@ +name: calico-node-driver-registrar +summary: Calico node-driver-registrar ROCK image. +description: > + This rock is a drop in replacement for the + docker.io/calico/node-driver-registrar:v3.28.0 image. +version: v3.28.0 +license: Apache-2.0 + +base: ubuntu@24.04 +build-base: ubuntu@24.04 +platforms: + amd64: + arm64: + +entrypoint-service: node-driver-registrar +services: + node-driver-registrar: + command: /usr/bin/node-driver-registrar [ ] + override: replace + startup: enabled + +parts: + build-deps: + plugin: nil + build-snaps: + - go/1.22/stable + + node-driver-registrar: + after: [build-deps] + plugin: go + source-type: git + source: https://github.com/kubernetes-csi/node-driver-registrar + source-commit: a498c31b88cd31f8ea7bafd0d715a75f9939fa1f + build-environment: + - CGO_ENABLED: 0 + override-build: | + mkdir -p $CRAFT_PART_INSTALL/usr/bin + go build -o $CRAFT_PART_INSTALL/usr/bin/node-driver-registrar \ + -v -buildvcs=false \ + cmd/csi-node-driver-registrar/*.go + diff --git a/calico/v3.28.0/node/rockcraft.yaml b/calico/v3.28.0/node/rockcraft.yaml new file mode 100644 index 0000000..b3d76cf --- /dev/null +++ b/calico/v3.28.0/node/rockcraft.yaml @@ -0,0 +1,248 @@ +name: calico-node +summary: Calico node ROCK image. +description: > + This rock is a drop in replacement for the + docker.io/calico/node:v3.28.0 image. +version: v3.28.0 +license: Apache-2.0 + +base: ubuntu@24.04 +build-base: ubuntu@24.04 +platforms: + amd64: + arm64: + +environment: + SVDIR: /etc/service/enabled + +entrypoint-service: node +services: + node: + # The reference image uses the "runit" service runner, which is + # somehow redundant since we have Pebble. + # For the time being, we'll use the same entry point. This spares + # us from translating the "runit" configuration. + command: start_runit [ ] + override: replace + startup: enabled + +parts: + build-deps: + plugin: nil + build-snaps: + - go/1.22/stable + build-packages: + - autoconf + - automake + - clang + - clang-16 + - gcc + - g++ + - iproute2 + - jq + - libcurl4-openssl-dev + - libpcap0.8-dev + - libtool + - llvm + - make + - libpcre3-dev + - pkg-config + - protobuf-compiler + - wget + - zip + - libelf-dev + # Calico v3.28.0 isn't compatible with libbpf>=1.0 and throws + # deprecation warnings (treated as errors) with libbpf v0.7.0. + # + # Uncomment the following and drop the custom libbpf section + # for Calico >= v3.29.0. + # - libbpf-dev + # bird deps: + - libncurses-dev + - libreadline-dev + - bison + - flex + runtime-deps: + plugin: nil + stage-packages: + - iptables + - nftables + - ipset + - iproute2 + - libpcap0.8t64 + - libcryptsetup12 + - gzip + - net-tools + - kmod + - procps + # conntrack dependencies + - libnetfilter-cthelper0 + - libnetfilter-cttimeout1 + - libnetfilter-queue1 + - conntrackd + - conntrack + - nfct + libbpf: + after: [build-deps] + source: https://github.com/libbpf/libbpf + source-tag: v0.6.1 + source-type: git + source-depth: 1 + plugin: nil + override-build: | + # Calico v3.28.0 isn't compatible with libbpf>=1.0. + # v0.7.0 has deprecated some helpers, throwing deprecation + # warnings (treated as errors). + cd src + make install + node: + after: [libbpf, runtime-deps] + plugin: go + source-type: git + source: https://github.com/projectcalico/calico + source-tag: v3.28.0 + source-depth: 1 + stage-packages: + # runit gets installed separately as we need to address some + # conflicting paths. + - runit + build-environment: + - GIT_VERSION: v3.28.0 + - CGO_ENABLED: 1 + - PACKAGE_NAME: github.com/projectcalico/calico/node + override-build: | + BUILD_DATE=`date -u +'%FT%T%z'` + GIT_REVISION=`git rev-parse --short HEAD` + GIT_DESCRIPTION=`git describe --tags` + + CALICO_BPF_PATH=$CRAFT_PART_BUILD/felix/bpf-gpl + # vendorized libbpf path + LIBBPF_PATH=$CALICO_BPF_PATH/include/libbpf/src/ + + case `arch` in + amd64 | x86_64) + export ARCH=amd64 + ;; + arm64 | aarch64) + export ARCH=arm64 + ;; + *) + echo "Unupported cpu architecture: $(arch)" + exit 1 + ;; + esac + + mkdir -p felix/bpf-gpl/include/libbpf/src/$ARCH + # The go project expects the vendorized libbpf library (>1.0), + # while the filters from bpf-apache and bpf-gpl expect a preinstalled + # libbpf<1.0. + # Changed in Calico 3.29.0. + make -j -C felix/bpf-gpl/include/libbpf/src BUILD_STATIC_ONLY=1 OBJDIR=$ARCH + make -j -C felix/bpf-apache all + make -j -C felix/bpf-gpl all + + mkdir -p $CRAFT_PART_INSTALL/usr/lib/calico/bpf/ + cp -r felix/bpf-gpl/bin/* $CRAFT_PART_INSTALL/usr/lib/calico/bpf/ + cp -r felix/bpf-apache/bin/* $CRAFT_PART_INSTALL/usr/lib/calico/bpf/ + + mkdir -p $CRAFT_PART_INSTALL/etc/calico + # Remove the default runit service symlink, we'll use calico's structure + # instead. + rm -f $CRAFT_PART_INSTALL/etc/service + cp -r $CRAFT_PART_BUILD/confd/etc/calico/* $CRAFT_PART_INSTALL/etc/calico/ + cp -r $CRAFT_PART_BUILD/node/filesystem/etc/* $CRAFT_PART_INSTALL/etc/ + cp -r $CRAFT_PART_BUILD/node/filesystem/sbin $CRAFT_PART_INSTALL/ + + # TODO: The reference image includes "runit" service configuration, however + # these services aren't actually used. The helm chart defines entry + # points that invoke the calico binaries directly. + # + # These "runit" definitions are included in /etc/service/available and + # the reference image sets SVDIR as /etc/service/enabled (unused). + # + # The problem is that the "runit" package sets /etc/service as a symlink + # pointing to "/etc/runit/runsvdir/current", which causes a conflict that + # breaks Rockcraft. + + LDFLAGS="-X ${PACKAGE_NAME}/pkg/lifecycle/startup.VERSION=${GIT_VERSION}" + LDFLAGS="$LDFLAGS -X ${PACKAGE_NAME}/buildinfo.BuildDate=${BUILD_DATE}" + LDFLAGS="$LDFLAGS -X ${PACKAGE_NAME}/buildinfo.GitVersion=${GIT_DESCRIPTION}" \ + LDFLAGS="$LDFLAGS -X ${PACKAGE_NAME}/buildinfo.GitRevision=${GIT_REVISION}" + + export CGO_LDFLAGS="-L${LIBBPF_PATH}/${ARCH} -lbpf -lelf -lz" + export CGO_CFLAGS="-I${LIBBPF_PATH} -I${CALICO_BPF_PATH}" + + mkdir -p $CRAFT_PART_INSTALL/bin + go build -o $CRAFT_PART_INSTALL/bin/calico-node \ + -v -buildvcs=false -ldflags "$LDFLAGS" \ + ./node/cmd/calico-node/main.go + + go build -o $CRAFT_PART_INSTALL/bin/mountns \ + -v -buildvcs=false -ldflags "$LDFLAGS" \ + ./node/cmd/mountns + + chmod u+s $CRAFT_PART_INSTALL/bin/calico-node + chmod u+s $CRAFT_PART_INSTALL/bin/mountns + bird: + after: [build-deps] + plugin: go + source-type: git + source: https://github.com/projectcalico/bird + source-tag: feature-ipinip + source-depth: 1 + override-build: | + DIST=dist/ + OBJ=obj/ + mkdir -p $DIST + mkdir -p $OBJ + + case `arch` in + amd64 | x86_64) + export ARCH=amd64 + DIST_SUBDIR="amd64" + ;; + arm64 | aarch64) + export ARCH=aarch64 + DIST_SUBDIR="arm64" + ;; + *) + echo "Unupported cpu architecture: $(arch)" + exit 1 + ;; + esac + export TARGETARCH=$ARCH + + DIST=$DIST OBJ=$OBJ ./create_binaries.sh + + mkdir -p $CRAFT_PART_INSTALL/bin + cp -r $DIST/$DIST_SUBDIR/bird $DIST/$DIST_SUBDIR/bird6 \ + $DIST/$DIST_SUBDIR/birdcl $DIST/$DIST_SUBDIR/birdcl6 \ + $CRAFT_PART_INSTALL/bin + + chmod u+s $CRAFT_PART_INSTALL/bin/bird + chmod u+s $CRAFT_PART_INSTALL/bin/bird6 + bpftool: + after: [build-deps] + plugin: nil + source-type: git + source: https://github.com/libbpf/bpftool.git + source-tag: main + source-depth: 1 + build-packages: + - xz-utils + - libzstd-dev + - libcap-dev + - llvm-dev + - binutils-dev + override-build: | + git submodule update --init --recursive + + # libelf requires zstd on Ubuntu 24.04, this hasn't been addressed + # in bpftool yet. + sed -i 's/-lelf/-lelf -lzstd/g' src/Makefile + + mkdir -p bin + EXTRA_CFLAGS=--static OUTPUT=`realpath bin`/ make -C src -j "$(nproc)" + + mkdir -p $CRAFT_PART_INSTALL/bin + cp ./bin/bpftool $CRAFT_PART_INSTALL/bin/bpftool diff --git a/calico/v3.28.0/pod2daemon-flexvol/pebble_entrypoint.sh b/calico/v3.28.0/pod2daemon-flexvol/pebble_entrypoint.sh new file mode 100755 index 0000000..cce6316 --- /dev/null +++ b/calico/v3.28.0/pod2daemon-flexvol/pebble_entrypoint.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +echo "invocation: $0 $@" + +# Required to prevent Pebble from considering the service to have +# exited too quickly to be worth restarting or respecting the +# "on-failure: shutdown" directive and thus hanging indefinitely: +# https://github.com/canonical/pebble/issues/240#issuecomment-1599722443 +sleep 1.1 + +/usr/local/bin/flexvol.sh "$@" diff --git a/calico/v3.28.0/pod2daemon-flexvol/rockcraft.yaml b/calico/v3.28.0/pod2daemon-flexvol/rockcraft.yaml new file mode 100644 index 0000000..419c132 --- /dev/null +++ b/calico/v3.28.0/pod2daemon-flexvol/rockcraft.yaml @@ -0,0 +1,57 @@ +name: calico-pod2daemon-flexvol +summary: Calico pod2daemon-flexvol ROCK image. +description: > + This rock is a drop in replacement for the + docker.io/calico/pod2daemon-flexvol:v3.28.0 image. +version: v3.28.0 +license: Apache-2.0 + +base: ubuntu@24.04 +build-base: ubuntu@24.04 +platforms: + amd64: + arm64: + +entrypoint-service: pod2daemon-flexvol +services: + pod2daemon-flexvol: + command: /pebble_entrypoint.sh [ ] + override: replace + startup: enabled + on-success: shutdown + on-failure: shutdown + +parts: + build-deps: + plugin: nil + build-snaps: + - go/1.22/stable + + pod2daemon-flexvol: + after: [build-deps] + plugin: go + source-type: git + source: https://github.com/projectcalico/calico + source-tag: v3.28.0 + source-depth: 1 + build-environment: + - CGO_ENABLED: 0 + override-build: | + mkdir -p $CRAFT_PART_INSTALL/usr/local/bin + + go build -o $CRAFT_PART_INSTALL/usr/local/bin/flexvol \ + -v -buildvcs=false \ + ./pod2daemon/flexvol/flexvoldriver.go + + cp ./pod2daemon/flexvol/docker-image/flexvol.sh \ + $CRAFT_PART_INSTALL/usr/local/bin/ + + add-entrypoint: + plugin: dump + source: . + source-type: local + stage: + - pebble_entrypoint.sh + override-stage: | + craftctl default + chmod a+rx "${CRAFT_PART_INSTALL}/pebble_entrypoint.sh" diff --git a/calico/v3.28.0/typha/pebble_entrypoint.sh b/calico/v3.28.0/typha/pebble_entrypoint.sh new file mode 100755 index 0000000..fc275aa --- /dev/null +++ b/calico/v3.28.0/typha/pebble_entrypoint.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +echo "invocation: $0 $@" + +# Required to prevent Pebble from considering the service to have +# exited too quickly to be worth restarting or respecting the +# "on-failure: shutdown" directive and thus hanging indefinitely: +# https://github.com/canonical/pebble/issues/240#issuecomment-1599722443 +sleep 1.1 + +/usr/bin/calico-typha "$@" diff --git a/calico/v3.28.0/typha/rockcraft.yaml b/calico/v3.28.0/typha/rockcraft.yaml new file mode 100644 index 0000000..2919f60 --- /dev/null +++ b/calico/v3.28.0/typha/rockcraft.yaml @@ -0,0 +1,67 @@ +name: calico-typha +summary: Calico typha ROCK image. +description: > + This rock is a drop in replacement for the + docker.io/calico/typha:v3.28.0 image. +version: v3.28.0 +license: Apache-2.0 + +base: ubuntu@24.04 +build-base: ubuntu@24.04 +platforms: + amd64: + arm64: + +entrypoint-service: typha +services: + typha: + command: /pebble_entrypoint.sh [ ] + override: replace + startup: enabled + +parts: + build-deps: + plugin: nil + build-snaps: + - go/1.22/stable + + typha: + after: [build-deps] + plugin: go + source-type: git + source: https://github.com/projectcalico/calico + source-tag: v3.28.0 + source-depth: 1 + build-environment: + - CGO_ENABLED: 0 + - PACKAGE_NAME: github.com/projectcalico/calico/typha + override-build: | + + TYPHA_BUILD_DATE=`date -u +'%FT%T%z'` + TYPHA_GIT_REVISION=`git rev-parse --short HEAD` + TYPHA_GIT_DESCRIPTION=`git describe --tags` + TYPHA_BUILD_ID=`git rev-parse HEAD || uuidgen | sed 's/-//g'` + + + LDFLAGS="-X ${PACKAGE_NAME}/pkg/buildinfo.BuildDate=${TYPHA_BUILD_DATE}" + LDFLAGS="$LDFLAGS -X ${PACKAGE_NAME}/pkg/buildinfo.GitVersion=${TYPHA_GIT_DESCRIPTION}" \ + LDFLAGS="$LDFLAGS -X ${PACKAGE_NAME}/pkg/buildinfo.GitRevision=${TYPHA_GIT_REVISION}" + LDFLAGS="$LDFLAGS -B 0x${TYPHA_BUILD_ID}" + + mkdir -p $CRAFT_PART_INSTALL/usr/bin + go build -o $CRAFT_PART_INSTALL/usr/bin/calico-typha \ + -v -buildvcs=false \ + ./typha/cmd/calico-typha + + mkdir -p $CRAFT_PART_INSTALL/etc/calico + cp ./typha/docker-image/typha.cfg $CRAFT_PART_INSTALL/etc/calico/typha.cfg + + add-entrypoint: + plugin: dump + source: . + source-type: local + stage: + - pebble_entrypoint.sh + override-stage: | + craftctl default + chmod a+rx "${CRAFT_PART_INSTALL}/pebble_entrypoint.sh" diff --git a/tests/.copyright.tmpl b/tests/.copyright.tmpl new file mode 100644 index 0000000..1eb2340 --- /dev/null +++ b/tests/.copyright.tmpl @@ -0,0 +1,2 @@ +Copyright ${years} ${owner}. +See LICENSE file for licensing details diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py new file mode 100644 index 0000000..9367a5b --- /dev/null +++ b/tests/integration/__init__.py @@ -0,0 +1,4 @@ +# +# Copyright 2024 Canonical, Ltd. +# See LICENSE file for licensing details +# diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py new file mode 100644 index 0000000..1ca658c --- /dev/null +++ b/tests/integration/conftest.py @@ -0,0 +1,5 @@ +# +# Copyright 2024 Canonical, Ltd. +# See LICENSE file for licensing details +# +pytest_plugins = ["k8s_test_harness.plugin"] diff --git a/tests/integration/test_calico.py b/tests/integration/test_calico.py new file mode 100644 index 0000000..4dbbaaf --- /dev/null +++ b/tests/integration/test_calico.py @@ -0,0 +1,204 @@ +# +# Copyright 2024 Canonical, Ltd. +# See LICENSE file for licensing details +# + +import json +import platform +import subprocess + +import pytest +from k8s_test_harness import harness +from k8s_test_harness.util import env_util, k8s_util + + +def get_image_platform(): + arch = platform.machine() + match arch: + case "x86_64": + return "amd64" + case "aarch64": + return "arm64" + case _: + raise Exception(f"Unsupported cpu platform: {arch}") + + +IMG_PLATFORM = get_image_platform() +INSTALL_NAME = "calico" + +OPERATOR_NS = "default" +CALICO_SYSTEM_NS = "calico-system" +CALICO_API_NS = "calico-apiserver" + +APISERVER_SPEC = r""" +# This section configures the Calico API server. +# For more information, see: +# https://docs.tigera.io/calico/latest/reference/installation/api +apiVersion: operator.tigera.io/v1 +kind: APIServer +metadata: + name: default +spec: {} +""" + + +def get_installation_spec(registry, repo): + return f""" +# This section includes base Calico installation configuration. +# For more information, see: https://docs.tigera.io/calico/latest/reference/installation/api#operator.tigera.io/v1.Installation +apiVersion: operator.tigera.io/v1 +kind: Installation +metadata: + name: default +spec: + # Image format://: + registry: {registry} + imagePath: "{repo}" + imagePrefix: calico- + + # Configures Calico networking. + calicoNetwork: + ipPools: + - name: default-ipv4-ippool + blockSize: 26 + cidr: 192.168.0.0/16 + encapsulation: VXLANCrossSubnet + natOutgoing: Disabled + nodeSelector: !all() +""" + + +def get_image_sha256_digest(image): + cmd = ["docker", "manifest", "inspect", image, "-v"] + proc = subprocess.run(cmd, check=True, capture_output=True) + out_json = json.loads(proc.stdout.decode("utf8")) + return out_json["Descriptor"]["digest"] + + +def get_imageset_spec(operator_version, calico_version): + spec = { + "apiVersion": "operator.tigera.io/v1", + "kind": "ImageSet", + "metadata": {"name": f"calico-{calico_version}"}, + "spec": {"images": []}, + } + + # The Calico operator will error out if we pass other images than the ones + # that it expects. + calico_images = [ + "calico-node", + "calico-cni", + "calico-typha", + "calico-kube-controllers", + "calico-csi", + "calico-apiserver", + "calico-ctl", + "calico-pod2daemon-flexvol", + "calico-key-cert-provisioner", + "calico-node-driver-registrar", + ] + images = list(zip(calico_images, [calico_version] * len(calico_images))) + images.append(("calico-tigera-operator", operator_version)) + + for image, version in images: + rock = env_util.get_build_meta_info_for_rock_version( + image, version, IMG_PLATFORM + ) + sha256_digest = get_image_sha256_digest(rock.image) + prefix = rock.image.split("/")[1] + + spec["spec"]["images"].append( + { + "image": f"{prefix}/{image}", + "digest": sha256_digest, + } + ) + + return json.dumps(spec) + + +def parse_image(image): + # We expect the image to look like this: + # ghcr.io/$repo/$name:$tag + parts = image.split("/") + return { + "registry": parts[0], + "repo": parts[1], + "name": parts[2].split(":")[0], + "tag": parts[2].split(":")[1], + } + + +@pytest.mark.parametrize("operator_version,calico_version", [("v1.34.0", "v3.28.0")]) +def test_calico( + function_instance: harness.Instance, operator_version: str, calico_version: str +): + operator_rock = env_util.get_build_meta_info_for_rock_version( + "calico-tigera-operator", operator_version, IMG_PLATFORM + ) + calicoctl_rock = env_util.get_build_meta_info_for_rock_version( + "calico-ctl", calico_version, IMG_PLATFORM + ) + + op_img_info = parse_image(operator_rock.image) + ctl_img_info = parse_image(calicoctl_rock.image) + + registry = op_img_info["registry"] + repo = op_img_info["repo"] + + helm_command = k8s_util.get_helm_install_command( + name=INSTALL_NAME, + chart_name="tigera-operator", + repository="https://docs.tigera.io/calico/charts", + namespace=OPERATOR_NS, + set_configs=[ + f"tigeraOperator.image={op_img_info['repo']}/{op_img_info['name']}", + f"tigeraOperator.version={op_img_info['tag']}", + f"tigeraOperator.registry={op_img_info['registry']}", + f"calicoctl.image={ctl_img_info['registry']}/{ctl_img_info['name']}/{ctl_img_info['tag']}", + f"calicoctl.tag={ctl_img_info['tag']}", + # We'll use a custom installation spec, so we need to disable + # the default one. + "installation.enabled=false", + "apiServer.enabled=false", + ], + ) + function_instance.exec(helm_command) + + k8s_util.wait_for_deployment(function_instance, "tigera-operator", OPERATOR_NS) + + installation_spec = get_installation_spec(registry, repo) + imageset_spec = get_imageset_spec(operator_version, calico_version) + apiserver_spec = APISERVER_SPEC + + function_instance.exec( + ["k8s", "kubectl", "apply", "-f", "-"], input=bytes(installation_spec, "utf8") + ) + function_instance.exec( + ["k8s", "kubectl", "apply", "-f", "-"], input=bytes(imageset_spec, "utf8") + ) + function_instance.exec( + ["k8s", "kubectl", "apply", "-f", "-"], input=bytes(apiserver_spec, "utf8") + ) + + k8s_util.wait_for_deployment( + function_instance, + "calico-kube-controllers", + CALICO_SYSTEM_NS, + retry_delay_s=10, + retry_times=12, + ) + k8s_util.wait_for_deployment( + function_instance, + "calico-typha", + CALICO_SYSTEM_NS, + retry_delay_s=10, + retry_times=12, + ) + k8s_util.wait_for_deployment( + function_instance, + "calico-apiserver", + CALICO_API_NS, + retry_delay_s=10, + retry_times=12, + ) diff --git a/tests/requirements-dev.txt b/tests/requirements-dev.txt new file mode 100644 index 0000000..a66721a --- /dev/null +++ b/tests/requirements-dev.txt @@ -0,0 +1,5 @@ +black==24.3.0 +codespell==2.2.4 +flake8==6.0.0 +isort==5.12.0 +licenseheaders==0.8.8 diff --git a/tests/requirements-test.txt b/tests/requirements-test.txt new file mode 100644 index 0000000..61f4f37 --- /dev/null +++ b/tests/requirements-test.txt @@ -0,0 +1,6 @@ +coverage[toml]==7.2.5 +pytest==7.3.1 +PyYAML==6.0.1 +tenacity==8.2.3 +charmed-kubeflow-chisme>=0.4 +git+https://github.com/canonical/k8s-test-harness.git@main diff --git a/tests/sanity/__init__.py b/tests/sanity/__init__.py new file mode 100644 index 0000000..9367a5b --- /dev/null +++ b/tests/sanity/__init__.py @@ -0,0 +1,4 @@ +# +# Copyright 2024 Canonical, Ltd. +# See LICENSE file for licensing details +# diff --git a/tests/sanity/test_calico.py b/tests/sanity/test_calico.py new file mode 100644 index 0000000..5036a26 --- /dev/null +++ b/tests/sanity/test_calico.py @@ -0,0 +1,211 @@ +# +# Copyright 2024 Canonical, Ltd. +# See LICENSE file for licensing details +# + +import platform + +import pytest +from k8s_test_harness.util import docker_util, env_util + + +def get_image_platform(): + arch = platform.machine() + match arch: + case "x86_64": + return "amd64" + case "aarch64": + return "arm64" + case _: + raise Exception(f"Unsupported cpu platform: {arch}") + + +IMG_PLATFORM = get_image_platform() + +CALICO_VERSIONS = ["v3.28.0"] +OPERATOR_VERSIONS = ["v1.34.0"] + + +@pytest.mark.parametrize("version", CALICO_VERSIONS) +def test_apiserver(version: str): + rock = env_util.get_build_meta_info_for_rock_version( + "calico-apiserver", version, IMG_PLATFORM + ) + + expected_helpstr = "run a calico api server" + + docker_run = docker_util.run_in_docker(rock.image, ["/code/apiserver", "--help"]) + assert expected_helpstr in docker_run.stdout + + +@pytest.mark.parametrize("version", CALICO_VERSIONS) +def test_cni(version: str): + rock = env_util.get_build_meta_info_for_rock_version( + "calico-cni", version, IMG_PLATFORM + ) + + expected_files = [ + "/opt/cni/bin/calico", + "/opt/cni/bin/install", + "/opt/cni/bin/calico-ipam", + ] + docker_util.ensure_image_contains_paths(rock.image, expected_files) + + docker_run = docker_util.run_in_docker( + rock.image, ["/opt/cni/bin/calico", "--help"] + ) + assert "Usage of Calico:" in docker_run.stderr + + docker_run = docker_util.run_in_docker( + rock.image, ["/opt/cni/bin/calico-ipam", "--help"] + ) + assert "Usage of calico-ipam:" in docker_run.stderr + + +@pytest.mark.parametrize("version", CALICO_VERSIONS) +def test_csi(version: str): + rock = env_util.get_build_meta_info_for_rock_version( + "calico-csi", version, IMG_PLATFORM + ) + + docker_run = docker_util.run_in_docker( + rock.image, ["/usr/bin/csi-driver", "--help"] + ) + assert "Kubelet communicates with the CSI plugin" in docker_run.stderr + + +@pytest.mark.parametrize("version", CALICO_VERSIONS) +def test_ctl(version: str): + rock = env_util.get_build_meta_info_for_rock_version( + "calico-ctl", version, IMG_PLATFORM + ) + + docker_run = docker_util.run_in_docker(rock.image, ["/usr/bin/ctl", "--help"]) + assert "The calicoctl command line tool is used to" in docker_run.stdout + + +@pytest.mark.parametrize("version", CALICO_VERSIONS) +def test_kube_controllers(version: str): + rock = env_util.get_build_meta_info_for_rock_version( + "calico-kube-controllers", version, IMG_PLATFORM + ) + + docker_run = docker_util.run_in_docker( + rock.image, ["/usr/bin/kube-controllers", "--help"] + ) + assert "Usage of /usr/bin/kube-controllers" in docker_run.stderr + + docker_run = docker_util.run_in_docker( + rock.image, + ["/usr/bin/check-status", "--help"], + check_exit_code=False, + ) + assert "Usage of check-status:" in docker_run.stderr + + +@pytest.mark.parametrize("version", CALICO_VERSIONS) +def test_node(version: str): + rock = env_util.get_build_meta_info_for_rock_version( + "calico-node", version, IMG_PLATFORM + ) + + expected_files = [ + "/etc/rc.local", + "/etc/nsswitch.conf", + "/etc/calico/felix.cfg", + "/etc/service/available/cni/run", + "/usr/lib/calico/bpf/filter.o", + "/sbin/start_runit", + "/sbin/restart-calico-confd", + "/bin/bird", + "/bin/bird6", + "/bin/birdcl", + "/bin/birdcl6", + "/bin/bpftool", + "/bin/calico-node", + "/bin/mountns", + ] + docker_util.ensure_image_contains_paths(rock.image, expected_files) + + docker_run = docker_util.run_in_docker( + rock.image, ["/bin/calico-node", "--help"], check_exit_code=False + ) + assert "Usage of Calico:" in docker_run.stderr + + docker_run = docker_util.run_in_docker(rock.image, ["/bin/bird", "--help"]) + assert "Usage: bird" in docker_run.stderr + + docker_run = docker_util.run_in_docker(rock.image, ["/bin/bird6", "--help"]) + assert "Usage: bird6" in docker_run.stderr + + docker_run = docker_util.run_in_docker(rock.image, ["/bin/bpftool", "--help"]) + assert "Usage: bpftool" in docker_run.stderr + + +@pytest.mark.parametrize("version", CALICO_VERSIONS) +def test_flexvol(version: str): + rock = env_util.get_build_meta_info_for_rock_version( + "calico-pod2daemon-flexvol", version, IMG_PLATFORM + ) + + docker_run = docker_util.run_in_docker( + rock.image, ["/usr/local/bin/flexvol", "--help"] + ) + assert "flexvoldrv [command]" in docker_run.stdout + + docker_run = docker_util.run_in_docker( + rock.image, ["/usr/local/bin/flexvol.sh", "--help"], check_exit_code=False + ) + assert "usage: /usr/local/bin/flexvol.sh" in docker_run.stdout + + +@pytest.mark.parametrize("version", CALICO_VERSIONS) +def test_typha(version: str): + rock = env_util.get_build_meta_info_for_rock_version( + "calico-typha", version, IMG_PLATFORM + ) + + expected_files = [ + "/etc/calico/typha.cfg", + "/usr/bin/calico-typha", + ] + docker_util.ensure_image_contains_paths(rock.image, expected_files) + + docker_run = docker_util.run_in_docker( + rock.image, ["/usr/bin/calico-typha", "--help"] + ) + assert "Typha, Calico's fan-out proxy." in docker_run.stdout + + +@pytest.mark.parametrize("version", CALICO_VERSIONS) +def test_key_cert_provisioner(version: str): + rock = env_util.get_build_meta_info_for_rock_version( + "calico-key-cert-provisioner", version, IMG_PLATFORM + ) + + docker_run = docker_util.run_in_docker( + rock.image, ["/usr/bin/key-cert-provisioner", "--help"] + ) + assert "Usage of /usr/bin/key-cert-provisioner" in docker_run.stderr + + +@pytest.mark.parametrize("version", CALICO_VERSIONS) +def test_node_driver_registrar(version: str): + rock = env_util.get_build_meta_info_for_rock_version( + "calico-node-driver-registrar", version, IMG_PLATFORM + ) + + docker_run = docker_util.run_in_docker( + rock.image, ["node-driver-registrar", "--help"] + ) + assert "Usage of node-driver-registrar" in docker_run.stderr + + +@pytest.mark.parametrize("version", OPERATOR_VERSIONS) +def test_operator(version: str): + rock = env_util.get_build_meta_info_for_rock_version( + "calico-tigera-operator", version, IMG_PLATFORM + ) + + docker_run = docker_util.run_in_docker(rock.image, ["/usr/bin/operator", "--help"]) + assert "Usage of /usr/bin/operator" in docker_run.stderr diff --git a/tests/tox.ini b/tests/tox.ini new file mode 100644 index 0000000..0350641 --- /dev/null +++ b/tests/tox.ini @@ -0,0 +1,82 @@ +[tox] +no_package = True +skip_missing_interpreters = True +env_list = format, lint, integration, sanity +min_version = 4.0.0 + +[testenv] +set_env = + PYTHONBREAKPOINT=pdb.set_trace + PY_COLORS=1 +pass_env = + PYTHONPATH + +[testenv:format] +description = Apply coding style standards to code +deps = -r {tox_root}/requirements-dev.txt +commands = + licenseheaders -t {tox_root}/.copyright.tmpl -cy -o 'Canonical, Ltd' -d {tox_root}/sanity + isort {tox_root}/sanity --profile=black + black {tox_root}/sanity + + licenseheaders -t {tox_root}/.copyright.tmpl -cy -o 'Canonical, Ltd' -d {tox_root}/integration + isort {tox_root}/integration --profile=black + black {tox_root}/integration + +[testenv:lint] +description = Check code against coding style standards +deps = -r {tox_root}/requirements-dev.txt +commands = + codespell {tox_root}/sanity + flake8 {tox_root}/sanity + licenseheaders -t {tox_root}/.copyright.tmpl -cy -o 'Canonical, Ltd' -d {tox_root}/sanity --dry + isort {tox_root}/sanity --profile=black --check + black {tox_root}/sanity --check --diff + + codespell {tox_root}/integration + flake8 {tox_root}/integration + licenseheaders -t {tox_root}/.copyright.tmpl -cy -o 'Canonical, Ltd' -d {tox_root}/integration --dry + isort {tox_root}/integration --profile=black --check + black {tox_root}/integration --check --diff + +[testenv:sanity] +description = Run integration tests +deps = + -r {tox_root}/requirements-test.txt +commands = + pytest -v \ + --maxfail 1 \ + --tb native \ + --log-cli-level DEBUG \ + --disable-warnings \ + {posargs} \ + {tox_root}/sanity +pass_env = + TEST_* + ROCK_* + BUILT_ROCKS_METADATA + +[testenv:integration] +description = Run integration tests +deps = + -r {tox_root}/requirements-test.txt +commands = + pytest -v \ + --maxfail 1 \ + --tb native \ + --log-cli-level DEBUG \ + --disable-warnings \ + {posargs} \ + {tox_root}/integration +pass_env = + TEST_* + ROCK_* + BUILT_ROCKS_METADATA + +[flake8] +max-line-length = 120 +select = E,W,F,C,N +# E231,E241,E222,E221 rules are not aware of f-strings +ignore = W503,E231,E241,E222,E221 +exclude = venv,.git,.tox,.tox_env,.venv,build,dist,*.egg_info +show-source = true diff --git a/tigera-operator/v1.34.0/fix_image_component_handling.patch b/tigera-operator/v1.34.0/fix_image_component_handling.patch new file mode 100644 index 0000000..0e81b1c --- /dev/null +++ b/tigera-operator/v1.34.0/fix_image_component_handling.patch @@ -0,0 +1,38 @@ +From 2e4c26edd41894a3ec0a05418233800e4a3fdf80 Mon Sep 17 00:00:00 2001 +From: Lucian Petrut +Date: Thu, 12 Sep 2024 12:03:48 +0000 +Subject: [PATCH] Fix image component handling, honoring Installation spec + +components.GetReference currently ignores the image prefix and path +specified in the "Installation" spec. + +It makes a copy of the image component, appends the configured image +path and prefix but then it uses the original component image when +looping over the image set. + +The fix is trivial, we just have to use the modified image string. +--- + pkg/components/references.go | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/pkg/components/references.go b/pkg/components/references.go +index bcf6cb95..68be249b 100644 +--- a/pkg/components/references.go ++++ b/pkg/components/references.go +@@ -85,12 +85,12 @@ func GetReference(c Component, registry, imagePath, imagePrefix string, is *oper + } + + for _, img := range is.Spec.Images { +- if img.Image == c.Image { ++ if img.Image == image { + return fmt.Sprintf("%s%s@%s", registry, image, img.Digest), nil + } + } + +- return "", fmt.Errorf("ImageSet did not contain image %s", c.Image) ++ return "", fmt.Errorf("ImageSet did not contain image %s", image) + } + + func ReplaceImagePath(image, imagePath string) string { +-- +2.39.2 (Apple Git-143) diff --git a/tigera-operator/v1.34.0/fix_imageset_checks.patch b/tigera-operator/v1.34.0/fix_imageset_checks.patch new file mode 100644 index 0000000..245d86a --- /dev/null +++ b/tigera-operator/v1.34.0/fix_imageset_checks.patch @@ -0,0 +1,30 @@ +From d358aa98f1c82171af5afe815909a6d8ade0168a Mon Sep 17 00:00:00 2001 +From: Lucian Petrut +Date: Thu, 12 Sep 2024 13:58:24 +0000 +Subject: [PATCH] quick hack: disable image set check + +Calico currently checks if the image set that it received matches +the upstream images, which prevents us from using custom images. + +This quick hack will just ignore unknown images. However, we should +use the Installation spec to parse the images, just like GetReference +does. +--- + pkg/controller/utils/imageset/imageset.go | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/pkg/controller/utils/imageset/imageset.go b/pkg/controller/utils/imageset/imageset.go +index a825ddb9..b21aa693 100644 +--- a/pkg/controller/utils/imageset/imageset.go ++++ b/pkg/controller/utils/imageset/imageset.go +@@ -122,7 +122,7 @@ func ValidateImageSet(is *operator.ImageSet) error { + } + } + +- if len(unknownImages) == 0 && len(invalidDigests) == 0 { ++ if len(invalidDigests) == 0 { + return nil + } + +-- +2.43.0 diff --git a/tigera-operator/v1.34.0/rockcraft.yaml b/tigera-operator/v1.34.0/rockcraft.yaml new file mode 100644 index 0000000..91ad1be --- /dev/null +++ b/tigera-operator/v1.34.0/rockcraft.yaml @@ -0,0 +1,49 @@ +name: calico-tigera-operator +summary: Calico tigera-operator ROCK image. +description: > + This rock is a drop in replacement for the + docker.io/tigera/operator:v1.34.0 image. +version: v1.34.0 +license: Apache-2.0 + +base: ubuntu@24.04 +build-base: ubuntu@24.04 +platforms: + amd64: + arm64: + +entrypoint-service: tigera-operator +services: + tigera-operator: + command: /usr/bin/operator [ ] + override: replace + startup: enabled + +parts: + build-deps: + plugin: nil + build-snaps: + - go/1.22/stable + + tigera-operator: + after: [build-deps] + plugin: go + source-type: git + source: https://github.com/tigera/operator + source-tag: v1.34.0 + source-depth: 1 + build-environment: + - GIT_VERSION: v1.34.0 + - CGO_ENABLED: 0 + - PACKAGE_NAME: github.com/tigera/operator + override-build: | + export EMAIL=root@localhost + git am --ignore-whitespace $CRAFT_PROJECT_DIR/fix_image_component_handling.patch + git am --ignore-whitespace $CRAFT_PROJECT_DIR/fix_imageset_checks.patch + + LDFLAGS="-X ${PACKAGE_NAME}/version.VERSION=${GIT_VERSION} -s -w" + + mkdir -p $CRAFT_PART_INSTALL/usr/bin + go build -o $CRAFT_PART_INSTALL/usr/bin/operator \ + -v -buildvcs=false \ + ./main.go diff --git a/trivy.yaml b/trivy.yaml new file mode 100644 index 0000000..c895d69 --- /dev/null +++ b/trivy.yaml @@ -0,0 +1,3 @@ +timeout: 20m +scan: + offline-scan: true