├── .gitattributes ├── .github ├── actions │ └── retest-action │ │ ├── Dockerfile │ │ ├── action.yml │ │ └── entrypoint.sh ├── dependabot.yml └── workflows │ ├── commands.yml │ ├── scorecard.yml │ └── test.yaml ├── .gitignore ├── .golangci.yml ├── .yamllint.yaml ├── CODE-OF-CONDUCT.md ├── CONTRIBUTING.md ├── CONVENTIONS.md ├── DCO ├── Documentation ├── cnitool.md └── spec-upgrades.md ├── GOVERNANCE.md ├── LICENSE ├── MAINTAINERS ├── Makefile ├── README.md ├── RELEASING.md ├── ROADMAP.md ├── SPEC.md ├── cnitool ├── README.md └── cnitool.go ├── go.mod ├── go.sum ├── libcni ├── api.go ├── api_test.go ├── backwards_compatibility_test.go ├── conf.go ├── conf_test.go └── libcni_suite_test.go ├── logo.png ├── mk ├── dependencies │ └── golangci.sh └── lint.mk ├── pkg ├── invoke │ ├── args.go │ ├── args_test.go │ ├── delegate.go │ ├── delegate_test.go │ ├── exec.go │ ├── exec_test.go │ ├── fakes │ │ ├── cni_args.go │ │ ├── raw_exec.go │ │ └── version_decoder.go │ ├── find.go │ ├── find_test.go │ ├── get_version_integration_test.go │ ├── invoke_suite_test.go │ ├── os_unix.go │ ├── os_windows.go │ ├── raw_exec.go │ └── raw_exec_test.go ├── ns │ ├── ns_darwin.go │ ├── ns_linux.go │ └── ns_windows.go ├── skel │ ├── skel.go │ ├── skel_suite_test.go │ └── skel_test.go ├── types │ ├── 100 │ │ ├── types.go │ │ ├── types_suite_test.go │ │ └── types_test.go │ ├── 020 │ │ ├── types.go │ │ ├── types_suite_test.go │ │ └── types_test.go │ ├── 040 │ │ ├── types.go │ │ ├── types_suite_test.go │ │ └── types_test.go │ ├── args.go │ ├── args_test.go │ ├── create │ │ └── create.go │ ├── internal │ │ ├── convert.go │ │ └── create.go │ ├── types.go │ ├── types_suite_test.go │ └── types_test.go ├── utils │ ├── utils.go │ └── utils_test.go └── version │ ├── conf.go │ ├── conf_test.go │ ├── legacy_examples │ ├── example_runtime.go │ ├── examples.go │ ├── legacy_examples_suite_test.go │ └── legacy_examples_test.go │ ├── plugin.go │ ├── plugin_test.go │ ├── reconcile.go │ ├── reconcile_test.go │ ├── testhelpers │ ├── testhelpers.go │ ├── testhelpers_suite_test.go │ └── testhelpers_test.go │ ├── version.go │ ├── version_suite_test.go │ └── version_test.go ├── plugins ├── debug │ ├── README.md │ ├── go.mod │ ├── go.sum │ └── main.go └── test │ ├── noop │ ├── debug │ │ └── debug.go │ ├── main.go │ ├── noop_suite_test.go │ └── noop_test.go │ └── sleep │ └── main.go ├── scripts ├── docker-run.sh ├── exec-plugins.sh └── priv-net-run.sh └── test.sh /.gitattributes: -------------------------------------------------------------------------------- 1 | # Don't rewrite line endings 2 | *.go -text 3 | -------------------------------------------------------------------------------- /.github/actions/retest-action/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.20 2 | 3 | RUN apk add --no-cache curl jq 4 | 5 | COPY entrypoint.sh /entrypoint.sh 6 | 7 | ENTRYPOINT ["/entrypoint.sh"] 8 | -------------------------------------------------------------------------------- /.github/actions/retest-action/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Re-Test' 2 | description: 'Re-Runs the last workflow for a PR' 3 | inputs: 4 | token: 5 | description: 'GitHub API Token' 6 | required: true 7 | runs: 8 | using: 'docker' 9 | image: 'Dockerfile' 10 | env: 11 | GITHUB_TOKEN: ${{ inputs.token }} 12 | -------------------------------------------------------------------------------- /.github/actions/retest-action/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -ex 4 | 5 | if ! jq -e '.issue.pull_request' ${GITHUB_EVENT_PATH}; then 6 | echo "Not a PR... Exiting." 7 | exit 0 8 | fi 9 | 10 | if [ "$(jq -r '.comment.body' ${GITHUB_EVENT_PATH})" != "/retest" ]; then 11 | echo "Nothing to do... Exiting." 12 | exit 0 13 | fi 14 | 15 | PR_URL=$(jq -r '.issue.pull_request.url' ${GITHUB_EVENT_PATH}) 16 | 17 | curl --request GET \ 18 | --url "${PR_URL}" \ 19 | --header "authorization: Bearer ${GITHUB_TOKEN}" \ 20 | --header "content-type: application/json" > pr.json 21 | 22 | ACTOR=$(jq -r '.user.login' pr.json) 23 | BRANCH=$(jq -r '.head.ref' pr.json) 24 | 25 | curl --request GET \ 26 | --url "https://api.github.com/repos/${GITHUB_REPOSITORY}/actions/runs?event=pull_request&actor=${ACTOR}&branch=${BRANCH}" \ 27 | --header "authorization: Bearer ${GITHUB_TOKEN}" \ 28 | --header "content-type: application/json" | jq '.workflow_runs | max_by(.run_number)' > run.json 29 | 30 | RERUN_URL=$(jq -r '.rerun_url' run.json) 31 | 32 | curl --request POST \ 33 | --url "${RERUN_URL}" \ 34 | --header "authorization: Bearer ${GITHUB_TOKEN}" \ 35 | --header "content-type: application/json" 36 | 37 | 38 | REACTION_URL="$(jq -r '.comment.url' ${GITHUB_EVENT_PATH})/reactions" 39 | 40 | curl --request POST \ 41 | --url "${REACTION_URL}" \ 42 | --header "authorization: Bearer ${GITHUB_TOKEN}" \ 43 | --header "accept: application/vnd.github.squirrel-girl-preview+json" \ 44 | --header "content-type: application/json" \ 45 | --data '{ "content" : "rocket" }' -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "docker" 9 | directory: "/.github/actions/retest-action" 10 | schedule: 11 | interval: "weekly" 12 | - package-ecosystem: "github-actions" 13 | directory: "/" 14 | schedule: 15 | interval: "weekly" 16 | - package-ecosystem: "gomod" 17 | directory: "/" 18 | schedule: 19 | interval: "weekly" 20 | groups: 21 | golang: 22 | patterns: 23 | - "*" 24 | - package-ecosystem: "gomod" 25 | directory: "/plugins/debug" 26 | schedule: 27 | interval: "weekly" 28 | -------------------------------------------------------------------------------- /.github/workflows/commands.yml: -------------------------------------------------------------------------------- 1 | name: commands 2 | on: 3 | issue_comment: 4 | types: [created] 5 | 6 | jobs: 7 | retest: 8 | if: github.repository == 'containernetworking/cni' 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Check out code 12 | uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 13 | 14 | - name: Re-Test Action 15 | uses: ./.github/actions/retest-action 16 | with: 17 | token: ${{ secrets.REPO_ACCESS_TOKEN }} 18 | -------------------------------------------------------------------------------- /.github/workflows/scorecard.yml: -------------------------------------------------------------------------------- 1 | name: Scorecard supply-chain security 2 | on: 3 | branch_protection_rule: 4 | push: 5 | branches: 6 | - main 7 | schedule: 8 | - cron: 29 15 * * 0 9 | permissions: read-all 10 | jobs: 11 | analysis: 12 | name: Scorecard analysis 13 | permissions: 14 | id-token: write 15 | security-events: write 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout code 19 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 20 | with: 21 | persist-credentials: false 22 | 23 | - name: Run analysis 24 | uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 25 | with: 26 | results_file: results.sarif 27 | results_format: sarif 28 | publish_results: true 29 | 30 | - name: Upload artifact 31 | uses: actions/upload-artifact@97a0fba1372883ab732affbe8f94b823f91727db # v3.pre.node20 32 | with: 33 | name: SARIF file 34 | path: results.sarif 35 | retention-days: 5 36 | 37 | - name: Upload to code-scanning 38 | uses: github/codeql-action/upload-sarif@8214744c546c1e5c8f03dde8fab3a7353211988d # v3.26.7 39 | with: 40 | sarif_file: results.sarif 41 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: test 3 | 4 | on: ["push", "pull_request"] 5 | 6 | env: 7 | GO_VERSION: "1.22" 8 | LINUX_ARCHES: "amd64 386 arm arm64 s390x mips64le ppc64le" 9 | 10 | jobs: 11 | lint: 12 | name: Lint 13 | permissions: 14 | contents: read 15 | pull-requests: read 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: setup go 19 | uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 20 | with: 21 | go-version: ${{ env.GO_VERSION }} 22 | 23 | - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 24 | 25 | - uses: ibiqlik/action-yamllint@2576378a8e339169678f9939646ee3ee325e845c # v3.1.1 26 | with: 27 | format: auto 28 | config_file: .yamllint.yaml 29 | 30 | - uses: golangci/golangci-lint-action@aaa42aa0628b4ae2578232a66b541047968fac86 # v6.1.0 31 | with: 32 | args: --verbose 33 | version: v1.57.1 34 | 35 | build: 36 | name: Build all linux architectures 37 | needs: lint 38 | runs-on: ubuntu-latest 39 | steps: 40 | - name: setup go 41 | uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 42 | with: 43 | go-version: ${{ env.GO_VERSION }} 44 | 45 | - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 46 | 47 | - name: Build on all supported architectures 48 | run: | 49 | set -e 50 | for arch in ${LINUX_ARCHES}; do 51 | echo "Building for arch $arch" 52 | GOARCH=$arch go build ./... 53 | done 54 | 55 | test-linux: 56 | name: Run tests on Linux amd64 57 | needs: build 58 | runs-on: ubuntu-latest 59 | steps: 60 | - name: setup go 61 | uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 62 | with: 63 | go-version: ${{ env.GO_VERSION }} 64 | 65 | - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 66 | 67 | - name: Install test binaries 68 | run: | 69 | go install github.com/mattn/goveralls@v0.0.12 70 | go install github.com/modocache/gover@latest 71 | 72 | - name: test 73 | run: COVERALLS=1 ./test.sh 74 | 75 | - env: 76 | COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }} 77 | name: Send coverage to coveralls 78 | run: | 79 | PATH=$PATH:$(go env GOPATH)/bin 80 | gover 81 | goveralls -coverprofile=gover.coverprofile -service=github 82 | 83 | test-win: 84 | name: Build and run tests on Windows 85 | needs: build 86 | runs-on: windows-latest 87 | steps: 88 | - name: setup go 89 | uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 90 | with: 91 | go-version: ${{ env.GO_VERSION }} 92 | 93 | - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 94 | 95 | - name: test 96 | run: bash ./test.sh 97 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.sw[ponm] 3 | .vagrant 4 | release-* 5 | cnitool/cnitool -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | linters: 2 | enable: 3 | - contextcheck 4 | - errcheck 5 | - errorlint 6 | - gci 7 | - ginkgolinter 8 | - gocritic 9 | - gofumpt 10 | - govet 11 | - ineffassign 12 | - misspell 13 | - nolintlint 14 | - nonamedreturns 15 | - predeclared 16 | - staticcheck 17 | - typecheck 18 | - unconvert 19 | - unused 20 | - whitespace 21 | 22 | linters-settings: 23 | gci: 24 | sections: 25 | - standard 26 | - default 27 | - prefix(github.com/containernetworking) 28 | 29 | run: 30 | timeout: 5m 31 | -------------------------------------------------------------------------------- /.yamllint.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | 4 | rules: 5 | document-start: disable 6 | line-length: disable 7 | truthy: 8 | ignore: | 9 | .github/workflows/*.yml 10 | .github/workflows/*.yaml 11 | -------------------------------------------------------------------------------- /CODE-OF-CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Community Code of Conduct 2 | 3 | CNI follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | CNI is [Apache 2.0 licensed](LICENSE) and accepts contributions via GitHub 4 | pull requests. This document outlines some of the conventions on development 5 | workflow, commit message formatting, contact points and other resources to make 6 | it easier to get your contribution accepted. 7 | 8 | We gratefully welcome improvements to documentation as well as to code. 9 | 10 | ## Certificate of Origin 11 | 12 | By contributing to this project you agree to the Developer Certificate of 13 | Origin (DCO). This document was created by the Linux Kernel community and is a 14 | simple statement that you, as a contributor, have the legal right to make the 15 | contribution. See the [DCO](DCO) file for details. 16 | 17 | ## Email and Chat 18 | 19 | The project uses the cni-dev email list, IRC chat, and Slack: 20 | - Email: [cni-dev](https://groups.google.com/forum/#!forum/cni-dev) 21 | - IRC: #[containernetworking](irc://irc.freenode.net:6667/#containernetworking) channel on [freenode.net](https://freenode.net/) 22 | - Slack: #cni on the [CNCF slack](https://slack.cncf.io/). NOTE: the previous CNI Slack (containernetworking.slack.com) has been sunsetted. 23 | 24 | Please avoid emailing maintainers found in the MAINTAINERS file directly. They 25 | are very busy and read the mailing lists. 26 | 27 | ## Getting Started 28 | 29 | - Fork the repository on GitHub 30 | - Read the [README](README.md) for build and test instructions 31 | - Play with the project, submit bugs, submit pull requests! 32 | 33 | ## Contribution workflow 34 | 35 | This is a rough outline of how to prepare a contribution: 36 | 37 | - Create a topic branch from where you want to base your work (usually branched from main). 38 | - Make commits of logical units. 39 | - Make sure your commit messages are in the proper format (see below). 40 | - Push your changes to a topic branch in your fork of the repository. 41 | - If you changed code: 42 | - add automated tests to cover your changes, using the [Ginkgo](https://onsi.github.io/ginkgo/) & [Gomega](https://onsi.github.io/gomega/) style 43 | - if the package did not previously have any test coverage, add it to the list 44 | of `TESTABLE` packages in the `test.sh` script. 45 | - run the full test script and ensure it passes 46 | - Make sure any new code files have a license header (this is now enforced by automated tests) 47 | - Submit a pull request to the original repository. 48 | 49 | ## How to run the test suite 50 | 51 | We generally require test coverage of any new features or bug fixes. 52 | 53 | Here's how you can run the test suite on any system (even Mac or Windows) using 54 | [Vagrant](https://www.vagrantup.com/) and a hypervisor of your choice: 55 | 56 | ```bash 57 | vagrant up 58 | vagrant ssh 59 | # you're now in a shell in a virtual machine 60 | sudo su 61 | cd /go/src/github.com/containernetworking/cni 62 | 63 | # to run the full test suite 64 | ./test.sh 65 | 66 | # to focus on a particular test suite 67 | cd libcni 68 | go test 69 | ``` 70 | 71 | ## Acceptance policy 72 | 73 | These things will make a PR more likely to be accepted: 74 | 75 | - a well-described requirement 76 | - tests for new code 77 | - tests for old code! 78 | - new code and tests follow the conventions in old code and tests 79 | - a good commit message (see below) 80 | 81 | In general, we will merge a PR once two maintainers have endorsed it. 82 | Trivial changes (e.g., corrections to spelling) may get waved through. 83 | For substantial changes, more people may become involved, and you might get asked to resubmit the PR or divide the changes into more than one PR. 84 | 85 | ### Format of the Commit Message 86 | 87 | We follow a rough convention for commit messages that is designed to answer two 88 | questions: what changed and why. The subject line should feature the what and 89 | the body of the commit should describe the why. 90 | 91 | ```md 92 | scripts: add the test-cluster command 93 | 94 | this uses tmux to setup a test cluster that you can easily kill and 95 | start for debugging. 96 | 97 | Fixes #38 98 | ``` 99 | 100 | The format can be described more formally as follows: 101 | 102 | ```md 103 | : 104 | 105 | 106 | 107 |