diff --git a/.github/dependabot.yml b/.github/dependabot.yml index fa0edaacff62..eac997d313a2 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -51,7 +51,6 @@ updates: # runc/containerd - dependency-name: github.com/containerd/containerd - - dependency-name: github.com/opencontainers/runc - package-ecosystem: github-actions directory: / diff --git a/.github/workflows/autopilot-branch-to-latest.yaml b/.github/workflows/autopilot-branch-to-latest.yaml index 9d5cc3b03491..789be371ec06 100644 --- a/.github/workflows/autopilot-branch-to-latest.yaml +++ b/.github/workflows/autopilot-branch-to-latest.yaml @@ -60,7 +60,7 @@ jobs: docker save tool:latest | gzip > tool-latest.tar.gz - name: Cache Tool Image - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: tool-${{ github.sha }}-${{ github.run_id }} path: tool-latest.tar.gz @@ -83,7 +83,7 @@ jobs: terraform_version: ${{ env.TERRAFORM_VERSION }} - name: Cache Tool Image (restore) - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: tool-${{ github.sha }}-${{ github.run_id }} path: tool-latest.tar.gz @@ -116,7 +116,7 @@ jobs: echo "vpcid=$(terraform output -raw vpc_id)" >> $GITHUB_OUTPUT - name: Cache Infrastructure Terraform - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: terraform-${{ github.sha }}-${{ github.run_id }} path: ${{ env.TOOL_DATADIR }}/terraform.tfstate @@ -202,7 +202,7 @@ jobs: terraform_version: ${{ env.TERRAFORM_VERSION }} - name: Cache Tool Image (restore) - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: tool-${{ github.sha }}-${{ github.run_id }} path: tool-latest.tar.gz @@ -245,7 +245,7 @@ jobs: persist-credentials: false - name: Cache Tool Image (restore) - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: tool-${{ github.sha }}-${{ github.run_id }} path: tool-latest.tar.gz @@ -256,7 +256,7 @@ jobs: rm tool-latest.tar.gz - name: Cache Infrastructure Terraform (restore) - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: terraform-${{ github.sha }}-${{ github.run_id }} path: ${{ env.TOOL_DATADIR }}/terraform.tfstate diff --git a/.github/workflows/backport.yaml b/.github/workflows/backport.yaml index 775a93a7af2a..6ffdb5a95d11 100644 --- a/.github/workflows/backport.yaml +++ b/.github/workflows/backport.yaml @@ -34,7 +34,7 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} - name: Create backport PRs # should be kept in sync with `version` - uses: zeebe-io/backport-action@v2.3.0 + uses: zeebe-io/backport-action@v2.4.1 with: # Config README: https://github.com/zeebe-io/backport-action#backport-action github_token: ${{ secrets.GH_BACKPORT_TOKEN }} diff --git a/.github/workflows/build-airgap-image-bundle.yml b/.github/workflows/build-airgap-image-bundle.yml index e01c8c64c245..9960d615b6ea 100644 --- a/.github/workflows/build-airgap-image-bundle.yml +++ b/.github/workflows/build-airgap-image-bundle.yml @@ -20,9 +20,6 @@ jobs: name: "${{ inputs.target-os }}-${{ inputs.target-arch }}" runs-on: ubuntu-22.04 - outputs: - cache-key: ${{ steps.cache-airgap-image-bundle-calc-key.outputs.cache-key }} - env: TARGET_OS: ${{ inputs.target-os }} TARGET_ARCH: ${{ inputs.target-arch }} @@ -38,11 +35,9 @@ jobs: with: name: airgap-image-list-${{ inputs.target-os }}-${{ inputs.target-arch }} - # Capture the calculated image bundle source hash in a build output, so - # it can be shared between the cache actions in this job and in the - # smoketests. Do this in a separate step, as the hashFiles function is - # evaluated before the step execution. So all the required files need to - # exist before that. + # Capture the calculated image bundle source hash in a separate step, as + # the hashFiles function is evaluated before the step execution. So all + # the required files need to exist before that. - name: "Cache :: Airgap image bundle :: Calculate cache key" id: cache-airgap-image-bundle-calc-key env: @@ -52,11 +47,10 @@ jobs: - name: "Cache :: Airgap image bundle" id: cache-airgap-image-bundle - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: ${{ steps.cache-airgap-image-bundle-calc-key.outputs.cache-key }} path: airgap-image-bundle-${{ inputs.target-os }}-${{ inputs.target-arch }}.tar - lookup-only: true - name: "Build :: Airgap image bundle" if: steps.cache-airgap-image-bundle.outputs.cache-hit != 'true' @@ -64,3 +58,10 @@ jobs: mkdir -p "embedded-bins/staging/$TARGET_OS/bin" make --touch airgap-images.txt make "airgap-image-bundle-$TARGET_OS-$TARGET_ARCH.tar" + + - name: "Upload :: Airgap image bundle" + uses: actions/upload-artifact@v4 + with: + name: airgap-image-bundle-${{ inputs.target-os }}-${{ inputs.target-arch }} + path: airgap-image-bundle-${{ inputs.target-os }}-${{ inputs.target-arch }}.tar + compression-level: 0 diff --git a/.github/workflows/build-k0s.yml b/.github/workflows/build-k0s.yml index 83533d51176c..61732b0d12f9 100644 --- a/.github/workflows/build-k0s.yml +++ b/.github/workflows/build-k0s.yml @@ -40,7 +40,7 @@ jobs: echo executable-suffix="$executableSuffix" >>"$GITHUB_OUTPUT" - name: "Cache :: embedded binaries" - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: build-k0s-${{ inputs.target-os }}-${{ inputs.target-arch }}-embedded-bins-${{ hashFiles('embedded-bins/**/*') }} path: | @@ -51,7 +51,7 @@ jobs: pkg/assets/zz_generated_offsets_${{ inputs.target-os }}.go - name: "Cache :: GOCACHE" - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: build-k0s-${{ inputs.target-os }}-${{ inputs.target-arch }}-gocache-${{ github.ref_name }}-${{ github.sha }} restore-keys: | @@ -60,7 +60,7 @@ jobs: build/cache/go/build - name: "Cache :: GOMODCACHE" - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: build-k0s-${{ inputs.target-os }}-${{ inputs.target-arch }}-gomodcache-${{ hashFiles('go.sum') }} path: | diff --git a/.github/workflows/check-network.yaml b/.github/workflows/check-network.yaml index 2f2ca20f4e12..e817550d2e67 100644 --- a/.github/workflows/check-network.yaml +++ b/.github/workflows/check-network.yaml @@ -15,7 +15,6 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_TERRAFORM_KEY }} AWS_DEFAULT_REGION: eu-west-1 TF_VERSION: 1.2.2 - K0SCTL_VERSION: 0.17.1 KUBECONFIG: ${{ github.workspace }}/kubeconfig name: "K8s Network Conformance Testing" @@ -69,7 +68,7 @@ jobs: run: terraform init - name: Cache embedded binaries - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: ${{ runner.os }}-embedded-bins-linux-${{ hashFiles('embedded-bins/**/*') }} path: | @@ -79,7 +78,7 @@ jobs: embedded-bins/Makefile.variables pkg/assets/zz_generated_offsets_linux.go - name: Cache GOCACHE - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: ${{ runner.os }}-build-gocache-linux-${{ github.ref_name }}-${{ github.sha }} restore-keys: | @@ -87,7 +86,7 @@ jobs: path: | build/cache/go/build - name: Cache GOMODCACHE - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: ${{ runner.os }}-build-gomodcache-linux-${{ hashFiles('go.sum') }} path: | @@ -135,7 +134,7 @@ jobs: id: k0sctl run: | # download k0sctl - curl --silent -L "https://github.com/k0sproject/k0sctl/releases/download/v${K0SCTL_VERSION}/k0sctl-linux-x64" -o k0sctl + curl --silent -L "https://github.com/k0sproject/k0sctl/releases/download/${K0SCTL_VERSION}/k0sctl-linux-x64" -o k0sctl chmod +x ./k0sctl ./k0sctl apply -c k0sctl.yaml diff --git a/.github/workflows/dependabot-prs.yaml b/.github/workflows/dependabot-prs.yaml new file mode 100644 index 000000000000..7b73771a73fd --- /dev/null +++ b/.github/workflows/dependabot-prs.yaml @@ -0,0 +1,26 @@ +name: Dependabot PRs +on: pull_request + +permissions: + contents: write + pull-requests: write + +jobs: + auto-merge: + name: Auto-merge version updates + if: github.actor == 'dependabot[bot]' + runs-on: ubuntu-latest + + steps: + - name: Fetch Dependabot metadata + id: metadata + uses: dependabot/fetch-metadata@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Enable auto-merge + if: contains(fromJSON('["version-update:semver-minor", "version-update:semver-patch"]'), steps.metadata.outputs.update-type) + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_URL: ${{ github.event.pull_request.html_url }} + run: gh pr merge --auto --merge -- "$PR_URL" diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index bb7902b81bf1..e453c7cfee5c 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -54,6 +54,12 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | + k0sSortVersion=$(./vars.sh FROM=. k0s_sort_version) + mkdir -p build/cache/bin + curl -sSLo build/cache/bin/k0s_sort --retry 5 --retry-all-errors "https://github.com/k0sproject/version/releases/download/$k0sSortVersion/k0s_sort-linux-amd64" + chmod +x build/cache/bin/k0s_sort + export PATH="$(realpath build/cache/bin):$PATH" + set -x k8sVersion="$(./vars.sh kubernetes_version)" majorVersion="${k8sVersion%%.*}" @@ -118,7 +124,7 @@ jobs: persist-credentials: false - name: Cache GOCACHE - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: unittests-k0s-linux-amd64-gocache-${{ github.ref_name }}-${{ github.sha }} restore-keys: | @@ -128,7 +134,7 @@ jobs: build/cache/go/build - name: Cache GOMODCACHE - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: unittests-k0s-linux-amd64-gomodcache-${{ hashFiles('go.sum') }} restore-keys: | @@ -139,13 +145,7 @@ jobs: - name: Run unit tests env: EMBEDDED_BINS_BUILDMODE: none - run: | - make bindata - make --touch codegen - make check-unit - - - name: Validate OCI images manifests - run: make check-image-validity + run: make check-unit unittests-k0s-windows-amd64: name: "Unit tests :: windows-amd64" @@ -170,7 +170,7 @@ jobs: go-version: ${{ env.GO_VERSION }} - name: Cache GOCACHE - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: unittests-k0s-windows-amd64-gocache-${{ github.ref_name }}-${{ github.sha }} restore-keys: | @@ -179,7 +179,7 @@ jobs: ~\AppData\Local\go-build - name: Cache GOMODCACHE - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: unittests-k0s-windows-amd64-gomodcache-${{ hashFiles('go.sum') }} restore-keys: | @@ -194,9 +194,7 @@ jobs: GO: go GO_ENV: '' run: | - make --touch .k0sbuild.docker-image.k0s go.sum - make bindata - make --touch codegen + make --touch .k0sbuild.docker-image.k0s make check-unit smoketests: @@ -238,23 +236,14 @@ jobs: chmod +x k0s ./k0s sysinfo - - name: Cache airgap image bundle - id: cache-airgap-image-bundle + - name: Download airgap image bundle if: contains(matrix.smoke-suite, 'airgap') - uses: actions/cache@v3 + uses: actions/download-artifact@v4 with: - key: ${{ needs.build-airgap-image-bundle.outputs.cache-key }} - path: airgap-image-bundle-linux-amd64.tar + name: airgap-image-bundle-linux-amd64 - name: Run inttest - env: - NEEDS_AIRGAP_IMAGE_BUNDLE: ${{ contains(matrix.smoke-suite, 'airgap') }} - run: | - [ "$NEEDS_AIRGAP_IMAGE_BUNDLE" != true ] || [ -f airgap-image-bundle-linux-amd64.tar ] || { - echo Airgap image bundle file missing! - exit 1 - } - make -C inttest ${{ matrix.smoke-suite }} + run: make -C inttest ${{ matrix.smoke-suite }} - name: Collect k0s logs and support bundle if: failure() @@ -362,7 +351,7 @@ jobs: go-version: ${{ env.GO_VERSION }} - name: Cache embedded binaries - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: ${{ runner.os }}-embedded-bins-${{ matrix.arch }}-${{ hashFiles('**/embedded-bins/**/*') }} path: | @@ -373,7 +362,7 @@ jobs: pkg/assets/zz_generated_offsets_linux.go - name: Cache GOCACHE - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: ${{ runner.os }}-smoketest-arm-gocache-${{ matrix.arch }}-${{ github.ref_name }}-${{ github.sha }} restore-keys: | @@ -382,7 +371,7 @@ jobs: build/cache/go/build - name: Cache GOMODCACHE - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: ${{ runner.os }}-smoketest-arm-gomodcache-${{ matrix.arch }}-${{ hashFiles('go.sum') }} path: | @@ -414,7 +403,7 @@ jobs: - name: Cache airgap image bundle id: cache-airgap-image-bundle - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: airgap-image-bundle-linux-${{ matrix.arch }}-${{ hashFiles('Makefile', 'airgap-images.txt', 'hack/image-bundler/*') }} path: | diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 6535623a2d0d..d7fbdf2e26b1 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -39,7 +39,7 @@ jobs: fetch-depth: 0 - name: Go caches - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: ${{ runner.os }}-lint-go-caches-${{ hashFiles('go.sum') }} path: | diff --git a/.github/workflows/ostests-e2e.yaml b/.github/workflows/ostests-e2e.yaml index a7269dd80447..04a4d9577cd9 100644 --- a/.github/workflows/ostests-e2e.yaml +++ b/.github/workflows/ostests-e2e.yaml @@ -35,7 +35,6 @@ on: k0sctl-version: type: string description: The k0sctl version to use when bootstrapping the test cluster. - default: 0.17.1 secrets: aws-access-key-id: description: The AWS access key ID to use when provisioning test resources. @@ -82,9 +81,15 @@ jobs: - name: "Workflow run :: Prepare" working-directory: ./ + env: + K0SCTL_VERSION: ${{ inputs.k0sctl-version }} run: | kubernetesVersion="$(./vars.sh kubernetes_version)" + k0sctlVersion="${K0SCTL_VERSION:-$(./vars.sh FROM=hack/tool k0sctl_version)}" + + set -x echo KUBERNETES_VERSION="$kubernetesVersion" >>"$GITHUB_ENV" + echo K0SCTL_VERSION="$k0sctlVersion" >>"$GITHUB_ENV" - name: "Terraform :: Requisites :: Download k0s" if: inputs.k0s-version == '' @@ -95,7 +100,6 @@ jobs: - name: "Terraform :: Requisites :: Prepare" env: - K0SCTL_VERSION: ${{ inputs.k0sctl-version }} K0S_VERSION: ${{ inputs.k0s-version }} K0S_EXECUTABLE_PATH: ${{ github.workspace }}/.cache/k0s run: | @@ -103,7 +107,7 @@ jobs: jq --version mkdir -p "$(dirname -- "$TF_VAR_k0sctl_executable_path")" - curl -sSLo "$TF_VAR_k0sctl_executable_path" "https://github.com/k0sproject/k0sctl/releases/download/v${K0SCTL_VERSION}/k0sctl-linux-x64" + curl -sSLo "$TF_VAR_k0sctl_executable_path" "https://github.com/k0sproject/k0sctl/releases/download/${K0SCTL_VERSION}/k0sctl-linux-x64" chmod +x -- "$TF_VAR_k0sctl_executable_path" "$TF_VAR_k0sctl_executable_path" version diff --git a/.github/workflows/prepare-build-env.sh b/.github/workflows/prepare-build-env.sh index f109421c535f..2f04f4a8dfc9 100755 --- a/.github/workflows/prepare-build-env.sh +++ b/.github/workflows/prepare-build-env.sh @@ -3,18 +3,21 @@ set -eu goVersion="$(./vars.sh go_version)" +k0sctlVersion="$(./vars.sh FROM=hack/tool k0sctl_version)" golangciLintVersion="$(./vars.sh FROM=hack/tools golangci-lint_version)" pythonVersion="$(./vars.sh FROM=docs python_version)" cat <>"$GITHUB_ENV" GO_VERSION=$goVersion GOLANGCI_LINT_VERSION=$golangciLintVersion +K0SCTL_VERSION=$k0sctlVersion PYTHON_VERSION=$pythonVersion EOF -# shellcheck disable=SC1090 -. "$GITHUB_ENV" - echo ::group::OS Environment env | sort echo ::endgroup:: + +echo ::group::Build Environment +cat -- "$GITHUB_ENV" +echo ::endgroup:: diff --git a/.github/workflows/publish-docs-manual.yml b/.github/workflows/publish-docs-manual.yml index 4b2fc0699d7e..f67acd694a1d 100644 --- a/.github/workflows/publish-docs-manual.yml +++ b/.github/workflows/publish-docs-manual.yml @@ -3,7 +3,7 @@ on: workflow_dispatch: inputs: version: - description: 'Version tag (e.g."v1.29.0+k0s.0")' + description: 'Version tag (e.g."v1.29.1+k0s.0")' required: true env: diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index ce6a756bec50..9867f50932b3 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -27,17 +27,17 @@ jobs: cache: pip cache-dependency-path: docs/requirements.txt - - name: Set up Go ${{ env.GO_VERSION }} - uses: actions/setup-go@v3 - with: - go-version: ${{ env.GO_VERSION }} - - name: Install dependencies run: | pip install --disable-pip-version-check -r docs/requirements_pip.txt pip --version pip install --disable-pip-version-check -r docs/requirements.txt - go install github.com/k0sproject/version/cmd/k0s_sort@v0.4.2 + + k0sSortVersion=$(./vars.sh FROM=. k0s_sort_version) + mkdir -p build/cache/bin + curl -sSLo build/cache/bin/k0s_sort --retry 5 --retry-all-errors "https://github.com/k0sproject/version/releases/download/$k0sSortVersion/k0s_sort-linux-amd64" + chmod +x build/cache/bin/k0s_sort + printf '%s\n' "$(realpath build/cache/bin)" >>"$GITHUB_PATH" - name: Generate docs env: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e6d5db5c8c46..36e675e74b6c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,9 +5,6 @@ on: tags: - v* # Push events to matching v*, i.e. v1.0, v20.15.10 -env: - K0SCTL_VERSION: 0.13.2 - jobs: release: env: @@ -29,7 +26,7 @@ jobs: echo TAG_NAME="${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT - name: Create Release id: create_release - uses: shogo82148/actions-create-release@v1.5.2 + uses: shogo82148/actions-create-release@v1.7.0 with: release_name: ${{ steps.branch_name.outputs.TAG_NAME }} draft: true # So we can manually edit before publishing @@ -90,17 +87,12 @@ jobs: COSIGN_KEY: ${{ secrets.COSIGN_KEY }} COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} run: | - echo $COSIGN_KEY | base64 -d > cosign.key - docker run --rm \ - -v "$(CURDIR):/k0s" \ - gcr.io/projectsigstore/cosign:v2.2.0 \ - sign-blob \ - --key /k0s/cosign.key \ - --tlog-upload=false \ - /k0s/k0s --output-file /k0s/k0s.sig + curl -sSLo cosign https://github.com/sigstore/cosign/releases/download/v2.2.0/cosign-linux-amd64 + chmod +x ./cosign + COSIGN_KEY="$(printf %s "$COSIGN_KEY" | base64 -d)" ./cosign sign-blob --key env://COSIGN_KEY --tlog-upload=false --output-file=k0s.sig k0s + cat k0s.sig - name: Upload Release Assets - Binary - id: upload-release-asset uses: shogo82148/actions-upload-release-asset@v1.7.2 with: upload_url: ${{ needs.release.outputs.upload_url }} @@ -109,7 +101,6 @@ jobs: asset_content_type: application/octet-stream - name: Upload Release Assets - Signature - id: upload-release-asset uses: shogo82148/actions-upload-release-asset@v1.7.2 with: upload_url: ${{ needs.release.outputs.upload_url }} @@ -124,7 +115,6 @@ jobs: path: ./k0s - name: Upload Release Assets - Bundle - id: upload-release-asset-images uses: shogo82148/actions-upload-release-asset@v1.7.2 with: upload_url: ${{ needs.release.outputs.upload_url }} @@ -173,21 +163,16 @@ jobs: COSIGN_KEY: ${{ secrets.COSIGN_KEY }} COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} run: | - echo $COSIGN_KEY | base64 -d > cosign.key - docker run --rm \ - -v "$(CURDIR):/k0s" \ - gcr.io/projectsigstore/cosign:v2.2.0 \ - sign-blob \ - --key /k0s/cosign.key \ - --tlog-upload=false \ - /k0s/k0s.exe --output-file /k0s/k0s.exe.sig + curl -sSLo cosign https://github.com/sigstore/cosign/releases/download/v2.2.0/cosign-linux-amd64 + chmod +x ./cosign + COSIGN_KEY="$(printf %s "$COSIGN_KEY" | base64 -d)" ./cosign sign-blob --key env://COSIGN_KEY --tlog-upload=false --output-file=k0s.exe.sig k0s.exe + cat k0s.exe.sig - name: Clean Docker run: | docker system prune --all --volumes --force - name: Upload Release Assets - id: upload-release-asset uses: shogo82148/actions-upload-release-asset@v1.7.2 with: upload_url: ${{ needs.release.outputs.upload_url }} @@ -196,7 +181,6 @@ jobs: asset_content_type: application/octet-stream - name: Upload Release Assets - Signature - id: upload-release-asset uses: shogo82148/actions-upload-release-asset@v1.7.2 with: upload_url: ${{ needs.release.outputs.upload_url }} @@ -247,14 +231,10 @@ jobs: COSIGN_KEY: ${{ secrets.COSIGN_KEY }} COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} run: | - echo $COSIGN_KEY | base64 -d > cosign.key - docker run --rm \ - -v "$(CURDIR):/k0s" \ - gcr.io/projectsigstore/cosign:v2.2.0 \ - sign-blob \ - --key /k0s/cosign.key \ - --tlog-upload=false \ - /k0s/k0s --output-file /k0s/k0s.sig + curl -sSLo cosign https://github.com/sigstore/cosign/releases/download/v2.2.0/cosign-linux-arm64 + chmod +x ./cosign + COSIGN_KEY="$(printf %s "$COSIGN_KEY" | base64 -d)" ./cosign sign-blob --key env://COSIGN_KEY --tlog-upload=false --output-file=k0s.sig k0s + cat k0s.sig - name: Set up Go for smoke tests uses: actions/setup-go@v3 @@ -275,7 +255,6 @@ jobs: path: tests/*.log - name: Upload Release Assets - Binary - id: upload-release-asset uses: shogo82148/actions-upload-release-asset@v1.7.2 with: upload_url: ${{ needs.release.outputs.upload_url }} @@ -284,7 +263,6 @@ jobs: asset_content_type: application/octet-stream - name: Upload Release Assets - Signature - id: upload-release-asset uses: shogo82148/actions-upload-release-asset@v1.7.2 with: upload_url: ${{ needs.release.outputs.upload_url }} @@ -299,7 +277,6 @@ jobs: path: ./k0s - name: Upload Release Assets - Bundle - id: upload-release-asset-images uses: shogo82148/actions-upload-release-asset@v1.7.2 with: upload_url: ${{ needs.release.outputs.upload_url }} @@ -355,14 +332,10 @@ jobs: COSIGN_KEY: ${{ secrets.COSIGN_KEY }} COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} run: | - echo $COSIGN_KEY | base64 -d > cosign.key - docker run --rm \ - -v "$(CURDIR):/k0s" \ - gcr.io/projectsigstore/cosign:v2.2.0 \ - sign-blob \ - --key /k0s/cosign.key \ - --tlog-upload=false \ - /k0s/k0s --output-file /k0s/k0s.sig + curl -sSLo cosign https://github.com/sigstore/cosign/releases/download/v2.2.0/cosign-linux-arm + chmod +x ./cosign + COSIGN_KEY="$(printf %s "$COSIGN_KEY" | base64 -d)" ./cosign sign-blob --key env://COSIGN_KEY --tlog-upload=false --output-file=k0s.sig k0s + cat k0s.sig - name: Set up Go for smoke tests uses: actions/setup-go@v3 @@ -383,7 +356,6 @@ jobs: path: tests/*.log - name: Upload Release Assets - Binary - id: upload-release-asset uses: shogo82148/actions-upload-release-asset@v1.7.2 with: upload_url: ${{ needs.release.outputs.upload_url }} @@ -392,7 +364,6 @@ jobs: asset_content_type: application/octet-stream - name: Upload Release Assets - Signature - id: upload-release-asset uses: shogo82148/actions-upload-release-asset@v1.7.2 with: upload_url: ${{ needs.release.outputs.upload_url }} @@ -407,7 +378,6 @@ jobs: path: ./k0s - name: Upload Release Assets - Bundle - id: upload-release-asset-images uses: shogo82148/actions-upload-release-asset@v1.7.2 with: upload_url: ${{ needs.release.outputs.upload_url }} @@ -540,7 +510,6 @@ jobs: make sign-pub-key - name: Upload Release Assets - SBOM - id: upload-release-asset-images uses: shogo82148/actions-upload-release-asset@v1.7.2 with: upload_url: ${{ needs.release.outputs.upload_url }} @@ -613,10 +582,9 @@ jobs: terraform apply -auto-approve - name: Create k0s Cluster using k0sctl - id: k0sctl run: | # download k0sctl - curl --silent -L "https://github.com/k0sproject/k0sctl/releases/download/v${K0SCTL_VERSION}/k0sctl-linux-x64" -o k0sctl + curl --silent -L "https://github.com/k0sproject/k0sctl/releases/download/${K0SCTL_VERSION}/k0sctl-linux-x64" -o k0sctl chmod +x ./k0sctl ./k0sctl apply -c k0sctl.yaml diff --git a/Makefile b/Makefile index d91bc05627a2..d6a3635d471a 100644 --- a/Makefile +++ b/Makefile @@ -30,10 +30,9 @@ EMBEDDED_BINS_BUILDMODE ?= docker TARGET_OS ?= linux BUILD_UID ?= $(shell id -u) BUILD_GID ?= $(shell id -g) -BUILD_GO_FLAGS := -tags osusergo -buildvcs=false -trimpath -# See https://github.com/mattn/go-sqlite3/issues/1164#issuecomment-1635253695 -# Remove when https://github.com/mattn/go-sqlite3/issues/1164 is released -BUILD_CGO_CFLAGS := -D_LARGEFILE64_SOURCE +BUILD_GO_TAGS ?= osusergo +BUILD_GO_FLAGS = -tags=$(subst $(space),$(comma),$(BUILD_GO_TAGS)) -buildvcs=false -trimpath +BUILD_CGO_CFLAGS := BUILD_GO_LDFLAGS_EXTRA := DEBUG ?= false @@ -128,15 +127,14 @@ pkg/apis/autopilot/v1beta2/.controller-gen.stamp: gen_output_dir = autopilot pkg/apis/%/.controller-gen.stamp: .k0sbuild.docker-image.k0s hack/tools/boilerplate.go.txt hack/tools/Makefile.variables rm -rf 'static/manifests/$(gen_output_dir)/CustomResourceDefinition' rm -f -- '$(dir $@)'zz_*.go - CGO_ENABLED=0 $(GO) install sigs.k8s.io/controller-tools/cmd/controller-gen@v$(controller-gen_version) - $(GO_ENV) controller-gen \ + CGO_ENABLED=0 $(GO) run sigs.k8s.io/controller-tools/cmd/controller-gen@v$(controller-gen_version) \ crd \ paths="./$(dir $@)..." \ output:crd:artifacts:config=./static/manifests/$(gen_output_dir)/CustomResourceDefinition \ object:headerFile=hack/tools/boilerplate.go.txt touch -- '$@' -clientset_input_dirs := pkg/apis/autopilot/v1beta2 pkg/apis/k0s/v1beta1 +clientset_input_dirs := pkg/apis/autopilot/v1beta2 pkg/apis/k0s/v1beta1 pkg/apis/helm/v1beta1 codegen_targets += pkg/client/clientset/.client-gen.stamp pkg/client/clientset/.client-gen.stamp: $(shell find $(clientset_input_dirs) -type f -name \*.go -not -name \*_test.go -not -name zz_\*) pkg/client/clientset/.client-gen.stamp: .k0sbuild.docker-image.k0s hack/tools/boilerplate.go.txt embedded-bins/Makefile.variables @@ -159,17 +157,11 @@ static/zz_generated_assets.go: $(shell find $(static_asset_dirs) -type f) CGO_ENABLED=0 $(GO) install github.com/kevinburke/go-bindata/go-bindata@v$(go-bindata_version) $(GO_ENV) go-bindata -o '$@' -pkg static -prefix static $(patsubst %,%/...,$(static_asset_dirs)) -codegen_targets += pkg/assets/zz_generated_offsets_$(TARGET_OS).go -zz_os = $(patsubst pkg/assets/zz_generated_offsets_%.go,%,$@) -print_empty_generated_offsets = printf "%s\n\n%s\n%s\n" \ - "package assets" \ - "var BinData = map[string]struct{ offset, size, originalSize int64 }{}" \ - "var BinDataSize int64" ifeq ($(EMBEDDED_BINS_BUILDMODE),none) -pkg/assets/zz_generated_offsets_linux.go pkg/assets/zz_generated_offsets_windows.go: - rm -f bindata_$(zz_os) && touch bindata_$(zz_os) - $(print_empty_generated_offsets) > $@ +BUILD_GO_TAGS += noembedbins else +codegen_targets += pkg/assets/zz_generated_offsets_$(TARGET_OS).go +zz_os = $(patsubst pkg/assets/zz_generated_offsets_%.go,%,$@) pkg/assets/zz_generated_offsets_linux.go: .bins.linux.stamp pkg/assets/zz_generated_offsets_windows.go: .bins.windows.stamp pkg/assets/zz_generated_offsets_linux.go pkg/assets/zz_generated_offsets_windows.go: .k0sbuild.docker-image.k0s go.sum @@ -178,10 +170,6 @@ pkg/assets/zz_generated_offsets_linux.go pkg/assets/zz_generated_offsets_windows -prefix embedded-bins/staging/$(zz_os)/ embedded-bins/staging/$(zz_os)/bin endif -# needed for unit tests on macos -pkg/assets/zz_generated_offsets_darwin.go: - $(print_empty_generated_offsets) > $@ - k0s: TARGET_OS = linux k0s: BUILD_GO_CGO_ENABLED = 1 k0s: .k0sbuild.docker-image.k0s @@ -190,12 +178,11 @@ k0s.exe: TARGET_OS = windows k0s.exe: BUILD_GO_CGO_ENABLED = 0 k0s.exe k0s: $(GO_SRCS) $(codegen_targets) go.sum - CGO_ENABLED=$(BUILD_GO_CGO_ENABLED) CGO_CFLAGS='$(BUILD_CGO_CFLAGS)' GOOS=$(TARGET_OS) $(GO) build $(BUILD_GO_FLAGS) -ldflags='$(LD_FLAGS)' -o $@.code main.go - cat $@.code bindata_$(TARGET_OS) > $@.tmp \ - && rm -f $@.code \ - && printf "\nk0s size: %s\n\n" "$$(du -sh $@.tmp | cut -f1)" \ - && chmod +x $@.tmp \ - && mv $@.tmp $@ + CGO_ENABLED=$(BUILD_GO_CGO_ENABLED) CGO_CFLAGS='$(BUILD_CGO_CFLAGS)' GOOS=$(TARGET_OS) $(GO) build $(BUILD_GO_FLAGS) -ldflags='$(LD_FLAGS)' -o '$@' main.go +ifneq ($(EMBEDDED_BINS_BUILDMODE),none) + cat -- bindata_$(TARGET_OS) >>$@ +endif + @printf '\n%s size: %s\n\n' '$@' "$$(du -sh -- $@ | cut -f1)" .bins.windows.stamp .bins.linux.stamp: embedded-bins/Makefile.variables $(MAKE) -C embedded-bins \ @@ -208,7 +195,10 @@ codegen: $(codegen_targets) # bindata contains the parts of codegen which aren't version controlled. .PHONY: bindata -bindata: static/zz_generated_assets.go pkg/assets/zz_generated_offsets_$(TARGET_OS).go +bindata: static/zz_generated_assets.go +ifneq ($(EMBEDDED_BINS_BUILDMODE),none) +bindata: pkg/assets/zz_generated_offsets_$(TARGET_OS).go +endif .PHONY: lint-copyright lint-copyright: @@ -216,9 +206,9 @@ lint-copyright: .PHONY: lint-go lint-go: GOLANGCI_LINT_FLAGS ?= -lint-go: .k0sbuild.docker-image.k0s go.sum codegen +lint-go: .k0sbuild.docker-image.k0s go.sum bindata CGO_ENABLED=0 $(GO) install github.com/golangci/golangci-lint/cmd/golangci-lint@v$(golangci-lint_version) - CGO_CFLAGS='$(BUILD_CGO_CFLAGS)' $(GO_ENV) golangci-lint run --verbose $(GOLANGCI_LINT_FLAGS) $(GO_LINT_DIRS) + CGO_CFLAGS='$(BUILD_CGO_CFLAGS)' $(GO_ENV) golangci-lint run --verbose --build-tags=$(subst $(space),$(comma),$(BUILD_GO_TAGS)) $(GOLANGCI_LINT_FLAGS) $(GO_LINT_DIRS) .PHONY: lint lint: lint-copyright lint-go @@ -255,12 +245,9 @@ check-unit: GO_TEST_RACE ?= else check-unit: GO_TEST_RACE ?= -race endif -check-unit: go.sum codegen - CGO_CFLAGS='$(BUILD_CGO_CFLAGS)' $(GO) test -tags=hack $(GO_TEST_RACE) -ldflags='$(LD_FLAGS)' `$(GO) list -tags=hack $(GO_CHECK_UNIT_DIRS)` - -.PHONY: check-image-validity -check-image-validity: go.sum - $(GO) run -tags=hack hack/validate-images/main.go -architectures amd64,arm64,arm +check-unit: BUILD_GO_TAGS += hack +check-unit: .k0sbuild.docker-image.k0s go.sum bindata + CGO_CFLAGS='$(BUILD_CGO_CFLAGS)' $(GO) test -tags=$(subst $(space),$(comma),$(BUILD_GO_TAGS)) $(GO_TEST_RACE) -ldflags='$(LD_FLAGS)' `$(GO) list -tags=$(subst $(space),$(comma),$(BUILD_GO_TAGS)) $(GO_CHECK_UNIT_DIRS)` .PHONY: clean-gocache clean-gocache: diff --git a/cmd/controller/certificates.go b/cmd/controller/certificates.go index 22680503df0a..8a47305193ac 100644 --- a/cmd/controller/certificates.go +++ b/cmd/controller/certificates.go @@ -63,7 +63,7 @@ func (c *Certificates) Init(ctx context.Context) error { return fmt.Errorf("failed to read ca cert: %w", err) } c.CACert = string(cert) - kubeConfigAPIUrl := fmt.Sprintf("https://localhost:%d", c.ClusterSpec.API.Port) + kubeConfigAPIUrl := fmt.Sprintf("https://%s:%d", c.ClusterSpec.API.APIServerAddress(), c.ClusterSpec.API.Port) eg.Go(func() error { // Front proxy CA if err := c.CertManager.EnsureCA("front-proxy-ca", "kubernetes-front-proxy-ca"); err != nil { diff --git a/cmd/controller/controller.go b/cmd/controller/controller.go index 85cbd1850033..f925a83f2fea 100644 --- a/cmd/controller/controller.go +++ b/cmd/controller/controller.go @@ -185,6 +185,7 @@ func (c *command) start(ctx context.Context) error { } logrus.Infof("using api address: %s", nodeConfig.Spec.API.Address) + logrus.Infof("using api bind-address: %s", nodeConfig.Spec.API.BindAddress) logrus.Infof("using listen port: %d", nodeConfig.Spec.API.Port) logrus.Infof("using sans: %s", nodeConfig.Spec.API.SANs) @@ -263,11 +264,13 @@ func (c *command) start(ctx context.Context) error { } nodeComponents.Add(ctx, leaderElector) - nodeComponents.Add(ctx, &applier.Manager{ - K0sVars: c.K0sVars, - KubeClientFactory: adminClientFactory, - LeaderElector: leaderElector, - }) + if !slices.Contains(c.DisableComponents, constant.ApplierManagerComponentName) { + nodeComponents.Add(ctx, &applier.Manager{ + K0sVars: c.K0sVars, + KubeClientFactory: adminClientFactory, + LeaderElector: leaderElector, + }) + } if !c.SingleNode && !slices.Contains(c.DisableComponents, constant.ControlAPIComponentName) { nodeComponents.Add(ctx, &controller.K0SControlAPI{ @@ -469,7 +472,7 @@ func (c *command) start(ctx context.Context) error { return err } clusterComponents.Add(ctx, reconciler) - clusterComponents.Add(ctx, controller.NewKubeletConfig(c.K0sVars, adminClientFactory, nodeConfig)) + clusterComponents.Add(ctx, controller.NewKubeletConfig(c.K0sVars)) } if !slices.Contains(c.DisableComponents, constant.SystemRbacComponentName) { diff --git a/docs/README.md b/docs/README.md index 0f218615ed83..dcabe1276746 100644 --- a/docs/README.md +++ b/docs/README.md @@ -31,7 +31,7 @@ Before that mishap we had 4776 stargazers, making k0s one of the most popular Ku - Scalable from a single node to large, [high-available](high-availability.md) clusters - Supports custom [Container Network Interface (CNI)](networking.md) plugins (Kube-Router is the default, Calico is offered as a preconfigured alternative) - Supports custom [Container Runtime Interface (CRI)](runtime.md) plugins (containerd is the default) -- Supports all Kubernetes storage options with [Container Storage Interface (CSI)](storage.md), includes [OpenEBS host-local storage provider](storage.md#bundled-openebs-storage) +- Supports all Kubernetes storage options with [Container Storage Interface (CSI)](storage.md), includes [OpenEBS host-local storage provider](examples/openebs.md) - Supports a variety of [datastore backends](configuration.md#specstorage): etcd (default for multi-node clusters), SQLite (default for single node clusters), MySQL, and PostgreSQL - Supports x86-64, ARM64 and ARMv7 - Includes [Konnectivity service](networking.md#controller-worker-communication), CoreDNS and Metrics Server diff --git a/docs/autopilot.md b/docs/autopilot.md index af6a10c0bc46..56689c025021 100644 --- a/docs/autopilot.md +++ b/docs/autopilot.md @@ -106,7 +106,7 @@ spec: version: v{{{ extra.k8s_version }}}+k0s.0 platforms: linux-amd64: - url: https://github.com/k0sproject/k0s/releases/download/v1.29.0+k0s.0/k0s-v1.29.0+k0s.0-amd64 + url: https://github.com/k0sproject/k0s/releases/download/v{{{ extra.k8s_version }}}+k0s.0/k0s-v{{{ extra.k8s_version }}}+k0s.0-amd64 sha256: '0000000000000000000000000000000000000000000000000000000000000000' targets: controllers: diff --git a/docs/configuration-validation.md b/docs/configuration-validation.md index ea9b1f8ed996..dedee6795baf 100644 --- a/docs/configuration-validation.md +++ b/docs/configuration-validation.md @@ -9,6 +9,6 @@ k0s config validate --config path/to/config/file `config validate` sub-command can validate the following: 1. YAML formatting -2. [SAN addresses](/configuration/#specapi) -3. [Network providers](/configuration/#specnetwork) -4. [Worker profiles](/configuration/#specworkerprofiles) +2. [SAN addresses](configuration.md#specapi) +3. [Network providers](configuration.md#specnetwork) +4. [Worker profiles](configuration.md#specworkerprofiles) diff --git a/docs/configuration.md b/docs/configuration.md index f051e4fad03e..dfcef4990fea 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -35,7 +35,7 @@ options should be placed in the `spec.k0s.config` section of the k0sctl's configuration file. See the section on how to install [k0s via k0sctl][k0sctl-install] and the [k0sctl README] for more information. -[k0sctl-install]: ../k0sctl-install +[k0sctl-install]: k0sctl-install.md [k0sctl README]: https://github.com/k0sproject/k0sctl/blob/main/README.md ## Configuration file reference @@ -55,6 +55,7 @@ spec: externalAddress: my-lb-address.example.com k0sApiPort: 9443 port: 6443 + bindAddress: 192.0.2.1 sans: - 192.168.68.104 controllerManager: {} @@ -91,6 +92,7 @@ spec: mtu: 0 peerRouterASNs: "" peerRouterIPs: "" + extraArgs: nodeLocalLoadBalancing: enabled: false envoyProxy: @@ -124,9 +126,10 @@ spec: ### `spec.api` | Element | Description | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +|--------------------------| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `externalAddress` | The loadbalancer address (for k0s controllers running behind a loadbalancer). Configures all cluster components to connect to this address and also configures this address for use when joining new nodes to the cluster. | -| `address` | Local address on which to bind an API. Also serves as one of the addresses pushed on the k0s create service certificate on the API. Defaults to first non-local address found on the node. | +| `address` | Local address on which to bind an API. Also serves as one of the addresses pushed on the k0s create service certificate on the API. Defaults to first non-local address found on the node. | +| `bindAddress` | The IP address for the Kubernetes API server to to listen on. The associated interface(s) must be reachable by the rest of the cluster. Will be added as an additional subject alternative name to the API server's TLS certificate. If blank or an unspecified address (`0.0.0.0` or `::`), all interfaces and IP address families will be used. This is effectively the value for the API server's `--bind-address` CLI flag. | | `sans` | List of additional addresses to push to API servers serving the certificate. | | `extraArgs` | Map of key-values (strings) for any extra arguments to pass down to Kubernetes api-server process. | | `port`¹ | Custom port for kube-api server to listen on (default: 6443) | @@ -136,12 +139,25 @@ spec: ### `spec.storage` -| Element | Description | -| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `type` | Type of the data store (valid values:`etcd` or `kine`). **Note**: Type `etcd` will cause k0s to create and manage an elastic etcd cluster within the controller nodes. | -| `etcd.peerAddress` | Node address used for etcd cluster peering. | -| `etcd.extraArgs` | Map of key-values (strings) for any extra arguments to pass down to etcd process. | -| `kine.dataSource` | [kine](https://github.com/k3s-io/kine) datasource URL. | +| Element | Description | +|------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `type` | Type of the data store (valid values:`etcd` or `kine`). **Note**: Type `etcd` will cause k0s to create and manage an elastic etcd cluster within the controller nodes. | +| `etcd.peerAddress` | Node address used for etcd cluster peering. | +| `etcd.extraArgs` | Map of key-values (strings) for any extra arguments to pass down to etcd process. | +| `kine.dataSource` | [kine](https://github.com/k3s-io/kine) datasource URL. | +| `etcd.externalCluster` | Configuration when etcd is externally managed, i.e. running on dedicated nodes. See [`spec.storage.etcd.externalCluster`](#specstorageetcdexternalcluster) | + +#### `spec.storage.etcd.externalCluster` + +k0s can also work with externally managed Etcd cluster. If this is configured, k0s will NOT set up etcd, it has to be managed manually. + +| Element | Description | +|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------| +| `endpoints` | Array of Etcd endpoints to use. | +| `etcdPrefix` | Prefix to use for this cluster. The same external Etcd cluster can be used for several k0s clusters, each prefixed with unique prefix to store data with. | +| `caFile` | CaFile is the host path to a file with Etcd cluster CA certificate. | +| `clientCertFile` | ClientCertFile is the host path to a file with TLS certificate for etcd client. | +| `clientKeyFile` | ClientKeyFile is the host path to a file with TLS key for etcd client. | ### `spec.network` @@ -213,15 +229,16 @@ CALICO_IPV6POOL_CIDR: "{{ spec.network.dualStack.IPv6podCIDR }}" #### `spec.network.kuberouter` | Element | Description | -| ---------------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +|------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `autoMTU` | Autodetection of used MTU (default: `true`). | | `mtu` | Override MTU setting, if `autoMTU` must be set to `false`). | | `metricsPort` | Kube-router metrics server port. Set to 0 to disable metrics (default: `8080`). | -| `peerRouterIPs` | Comma-separated list of [global peer addresses](https://github.com/cloudnativelabs/kube-router/blob/master/docs/bgp.md#global-external-bgp-peers). | -| `peerRouterASNs` | Comma-separated list of [global peer ASNs](https://github.com/cloudnativelabs/kube-router/blob/master/docs/bgp.md#global-external-bgp-peers). | +| `peerRouterIPs` | DEPRECATED: Use extraArgs with peerRouterIPs instead. Comma-separated list of [global peer addresses](https://github.com/cloudnativelabs/kube-router/blob/master/docs/bgp.md#global-external-bgp-peers). | +| `peerRouterASNs` | DEPRECATED: Use extraArgs with peerRouterASNs instead. Comma-separated list of [global peer ASNs](https://github.com/cloudnativelabs/kube-router/blob/master/docs/bgp.md#global-external-bgp-peers). | | `hairpin` | Hairpin mode, supported modes `Enabled`: enabled cluster wide, `Allowed`: must be allowed per service [using annotations](https://github.com/cloudnativelabs/kube-router/blob/master/docs/user-guide.md#hairpin-mode), `Disabled`: doesn't work at all (default: Enabled) | | `hairpinMode` | **Deprecated** Use `hairpin` instead. If both `hairpin` and `hairpinMode` are defined, this is ignored. If only hairpinMode is configured explicitly activates hairpinMode (https://github.com/cloudnativelabs/kube-router/blob/master/docs/user-guide.md#hairpin-mode). | -| `ipMasq` | IP masquerade for traffic originating from the pod network, and destined outside of it (default: false) | +| `ipMasq` | IP masquerade for traffic originating from the pod network, and destined outside of it (default: false) | +| `extraArgs` | Extra arguments to pass to kube-router. Can be also used to override any k0s managed args. For reference, see kube-router [documentation](https://github.com/cloudnativelabs/kube-router/blob/master/docs/user-guide.md#command-line-options). (default: empty) | **Note**: Kube-router allows many networking aspects to be configured per node, service, and pod (for more information, refer to the [Kube-router user guide](https://github.com/cloudnativelabs/kube-router/blob/master/docs/user-guide.md)). @@ -263,16 +280,13 @@ ipvs: Configuration options related to k0s's [node-local load balancing] feature. -**Note:** This feature is experimental! Expect instabilities and/or breaking -changes. - | Element | Description | | ---------------- | ----------------------------------------------------------------------------------------------------------------------------- | | `enabled` | Indicates if node-local load balancing should be used to access Kubernetes API servers from worker nodes. Default: `false`. | | `type` | The type of the node-local load balancer to deploy on worker nodes. Default: `EnvoyProxy`. (This is the only option for now.) | | `envoyProxy` | Configuration options related to the "EnvoyProxy" type of load balancing. | -[node-local load balancing]: ../nllb +[node-local load balancing]: nllb.md ##### `spec.network.nodeLocalLoadBalancing.envoyProxy` @@ -474,7 +488,7 @@ In the runtime the image names are calculated as `my.own.repo/calico/kube-contro `spec.extensions.storage` controls bundled storage provider. The default value `external` makes no storage deployed. -To enable [embedded host-local storage provider](storage.md#bundled-openebs-storage) use the following configuration: +To enable [embedded host-local storage provider](examples/openebs.md) use the following configuration: ```yaml spec: @@ -509,8 +523,8 @@ users to build a minimal Kubernetes control plane and use what ever components they need to fulfill their need for the control plane. Disabling the system components happens through a command line flag for the controller process: -```sh ---disable-components strings disable components (valid items: api-config,autopilot,control-api,coredns,csr-approver,endpoint-reconciler,helm,konnectivity-server,kube-controller-manager,kube-proxy,kube-scheduler,metrics-server,network-provider,node-role,system-rbac,worker-config) +```text +--disable-components strings disable components (valid items: applier-manager,autopilot,control-api,coredns,csr-approver,endpoint-reconciler,helm,konnectivity-server,kube-controller-manager,kube-proxy,kube-scheduler,metrics-server,network-provider,node-role,system-rbac,worker-config) ``` **Note:** As of k0s 1.26, the kubelet-config component has been replaced by the diff --git a/docs/examples/nginx-ingress.md b/docs/examples/nginx-ingress.md index 3be0ba42e5f7..eeea3b728013 100644 --- a/docs/examples/nginx-ingress.md +++ b/docs/examples/nginx-ingress.md @@ -268,4 +268,4 @@ For more information about NGINX Ingress Controller installation, take a look at ## Alternative examples for Ingress Controllers on k0s -[Traefik Ingress](../traefik-ingress) +[Traefik Ingress](traefik-ingress.md) diff --git a/docs/examples/openebs.md b/docs/examples/openebs.md new file mode 100644 index 000000000000..e71513d0f8e6 --- /dev/null +++ b/docs/examples/openebs.md @@ -0,0 +1,184 @@ +# OpenEBS + +This tutorial covers the installation of OpenEBS as a Helm extension, both from +scratch and how to migrate it from a storage extension. + +## Installing OpenEBS from scratch + +**WARNING**: Do not configure OpenEBS as both a storage extension and a Helm +extension. It's considered an invalid configuration and k0s will entirely ignore +the configuration to prevent accidental upgrades or downgrades. The chart +objects defined in the API will still behave normally. + +OpenEBS can be installed as a helm chart by adding it as an extension to your configuration: + +```yaml + extensions: + helm: + repositories: + - name: openebs-internal + url: https://openebs.github.io/charts + charts: + - name: openebs + chartname: openebs-internal/openebs + version: "3.9.0" + namespace: openebs + order: 1 + values: | + localprovisioner: + hostpathClass: + enabled: true + isDefaultClass: false +``` + +If you want OpenEBS to be your default storage class, set `isDefaultClass` to `true`. + +## Migrating bundled OpenEBS to helm extension + +The bundled OpenEBS extension is already a helm extension installed as a +`chart.helm.k0sproject.io`. For this reason, all we have to do is to remove the +manifests and to clean up the object. However, this must be done in a specific order +to prevent data loss. + +**WARNING**: Not following the steps in the precise order presented by the +documentation may provoke data loss. + +The first step to perform the migration is to disable the `applier-manager` +component on all controllers. For each controller, restart the controller +with the flag `--disable-components=applier-manager`. If you already had this flag, +set it to `--disable-components=,applier-manager`. + +Once the `applier-manager` is disabled in every running controller, you need to modify +the configuration to use `external_storage` instead of `openebs_local_storage`. + +If you are using [dynamic configuration](../dynamic-configuration.md), you can +change it with this command: + +```shell +kubectl patch clusterconfig -n kube-system k0s --patch '{"spec":{"extensions":{"storage":{"type":"external_storage"}}}}' --type=merge +``` + +If you are using a static configuration file, replace `spec.extensions.storage.type` +from `openebs_local_storage` to `external_storage` in all control plane nodes and +restart all the control plane nodes one by one. + +When the configuration is set to `external_storage` and the servers are +restarted, you must manage the it as a chart object in the API: + +```shell +kubectl get chart -n kube-system k0s-addon-chart-openebs -o yaml +``` + +First, remove the labels and annotations related to the stack applier: + +```shell +k0s kc annotate -n kube-system chart k0s-addon-chart-openebs k0s.k0sproject.io/stack-checksum- +k0s kc label -n kube-system chart k0s-addon-chart-openebs k0s.k0sproject.io/stack- +``` + +After the annotations and labels are removed, remove the manifest file **on each +controller**. This file is located in +`/manifests/helm/_helm_extension_openebs.yaml`, which in +most installations defaults to +`/var/lib/k0s/manifests/helm/0_helm_extension_openebs.yaml`. + +**WARNING**: Not removing the old manifest file from all controllers may cause +the manifest to be reapplied, reverting your changes and potentially casuing +data loss. + +Finally, we want to re-enable the `applier-manager` and restart all controllers +without the `--disable-components=applier-manager` flag. + +Once the migration is coplete, you'll be able to update the OpenEBS chart. +Let's take v3.9.0 as an example: + +```shell +kubectl patch chart -n kube-system k0s-addon-chart-openebs --patch '{"spec":{"version":"3.9.0"}}' --type=merge +``` + +## Usage + +Once installed, the cluster will have two storage classes available for you to use: + +```shell +k0s kubectl get storageclass +``` + +```shell +NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE +openebs-device openebs.io/local Delete WaitForFirstConsumer false 24s +openebs-hostpath openebs.io/local Delete WaitForFirstConsumer false 24s +``` + +The `openebs-hostpath` is the storage class that maps to `/var/openebs/local`. + +The `openebs-device` is not configured and could be configured by [manifest deployer](../manifests.md) accordingly to the [OpenEBS documentation](https://docs.openebs.io/) + +### Example + +Use following manifests as an example of pod with mounted volume: + +```yaml +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: nginx-pvc + namespace: default +spec: + accessModes: + - ReadWriteOnce + storageClassName: openebs-hostpath + resources: + requests: + storage: 5Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx + namespace: default + labels: + app: nginx +spec: + selector: + matchLabels: + app: nginx + strategy: + type: Recreate + template: + metadata: + labels: + app: nginx + spec: + containers: + - image: nginx + name: nginx + volumeMounts: + - name: persistent-storage + mountPath: /var/lib/nginx + volumes: + - name: persistent-storage + persistentVolumeClaim: + claimName: nginx-pvc +``` + +```shell +k0s kubectl apply -f nginx.yaml +``` + +```shell +persistentvolumeclaim/nginx-pvc created +deployment.apps/nginx created +bash-5.1# k0s kc get pods +NAME READY STATUS RESTARTS AGE +nginx-d95bcb7db-gzsdt 1/1 Running 0 30s +``` + +```shell +k0s kubectl get pv +``` + +```shell +NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE +pvc-9a7fae2d-eb03-42c3-aaa9-1a807d5df12f 5Gi RWO Delete Bound default/nginx-pvc openebs-hostpath 30s +``` diff --git a/docs/external-runtime-deps.md b/docs/external-runtime-deps.md index 462b24954baa..a7b14b021bb8 100644 --- a/docs/external-runtime-deps.md +++ b/docs/external-runtime-deps.md @@ -169,7 +169,7 @@ In order to use containerd in conjunction with [AppArmor], it must be enabled in the kernel and the `/sbin/apparmor_parser` executable must be installed on the host, otherwise containerd will [disable][cd-aa] AppArmor support. -[cd-aa]: https://github.com/containerd/containerd/blob/v1.7.8/pkg/apparmor/apparmor_linux.go#L34-L45 +[cd-aa]: https://github.com/containerd/containerd/blob/v1.7.12/pkg/apparmor/apparmor_linux.go#L34-L45 [AppArmor]: https://wiki.ubuntu.com/AppArmor #### iptables diff --git a/docs/high-availability.md b/docs/high-availability.md index c3c6f3f0f290..ccc3a77e09dd 100644 --- a/docs/high-availability.md +++ b/docs/high-availability.md @@ -84,10 +84,15 @@ First and foremost, all controllers should utilize the same CA certificates and /var/lib/k0s/pki/etcd/ca.crt ``` -To generate these certificates, you have two options: either generate them manually using the instructions provided [here](../custom-ca/) and then share it across controller nodes, or utilize k0sctl for automated generation and sharing. +To generate these certificates, you have two options: either generate them +manually using the instructions for [installing custom CA certificates], and +then share them between controller nodes, or use k0sctl to generate and share +them automatically. The second important aspect is: the load balancer address must be configured to k0s either by using `k0s.yaml` or by using k0sctl to automatically deploy all controllers with the same configuration: +[installing custom CA certificates]: custom-ca.md + ### Configuration using k0s.yaml (for each controller) Note to update your load balancer's public ip address into two places. diff --git a/docs/k0s-in-docker.md b/docs/k0s-in-docker.md index 619b75d8d924..a2b71e12ab0a 100644 --- a/docs/k0s-in-docker.md +++ b/docs/k0s-in-docker.md @@ -54,7 +54,7 @@ For each required worker: Access your cluster using kubectl: ```sh -docker exec k0s kubectl get nodes +docker exec k0s k0s kubectl get nodes ``` Alternatively, grab the kubeconfig file with `docker exec k0s cat /var/lib/k0s/pki/admin.conf` and paste it into [Lens](https://github.com/lensapp/lens/). diff --git a/docs/nllb.md b/docs/nllb.md index 958efb4097ac..01303b5bbcfa 100644 --- a/docs/nllb.md +++ b/docs/nllb.md @@ -1,8 +1,5 @@ # Node-local load balancing -**Note:** This feature is experimental! Expect instabilities and/or breaking -changes. - For clusters that don't have an [externally managed load balancer] for the k0s control plane, there is another option to get a highly available control plane, at least from within the cluster. K0s calls this "node-local load balancing". In @@ -13,7 +10,7 @@ with the cluster using management tools such as [Lens](https://k8slens.dev/) or `kubectl`), but rather makes the cluster itself internally resilient to controller node outages. -[externally managed load balancer]: ../high-availability/#load-balancer +[externally managed load balancer]: high-availability.md#load-balancer ## Technical functionality @@ -37,7 +34,7 @@ following: * The cluster doesn't use an externally managed load balancer, i.e. the cluster configuration doesn't specify a non-empty [`spec.api.externalAddress`][specapi]. -* K0s isn't running as a [single node](../k0s-single-node/), i.e. it isn't +* K0s isn't running as a [single node](k0s-single-node.md), i.e. it isn't started using the `--single` flag. * The cluster should have multiple controller nodes. Node-local load balancing also works with a single controller node, but is only useful in conjunction @@ -53,7 +50,7 @@ spec: type: EnvoyProxy ``` -Or alternatively, if using [`k0sctl`](../k0sctl-install/), add the following to +Or alternatively, if using [`k0sctl`](k0sctl-install.md), add the following to the k0sctl configuration (`k0sctl.yaml`): ```yaml @@ -71,7 +68,7 @@ All newly added worker nodes will then use node-local load balancing. The k0s worker process on worker nodes that are already running must be restarted for the new configuration to take effect. -[specapi]: ../configuration/#specapi +[specapi]: configuration.md#specapi ## Full example using `k0sctl` @@ -135,7 +132,7 @@ $ k0sctl apply ⣿⣿⣿⣿⣟⠋⠀⠀⠀⠀⠀⢸⣿⡇⠀⢰⣾⣿⠀⠀⣿⣿⡇⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀███ ███ ███ ⣿⣿⡏⠻⣿⣷⣤⡀⠀⠀⠀⠸⠛⠁⠀⠸⠋⠁⠀⠀⣿⣿⡇⠈⠉⠉⠉⠉⠉⠉⠉⠉⢹⣿⣿⠀███ ███ ███ ⣿⣿⡇⠀⠀⠙⢿⣿⣦⣀⠀⠀⠀⣠⣶⣶⣶⣶⣶⣶⣿⣿⡇⢰⣶⣶⣶⣶⣶⣶⣶⣶⣾⣿⣿⠀█████████ ███ ██████████ -k0sctl 0.17.1 Copyright 2023, k0sctl authors. +k0sctl 0.17.2 Copyright 2023, k0sctl authors. By continuing to use k0sctl you agree to these terms: https://k0sproject.io/licenses/eula level=info msg="==> Running phase: Connect to hosts" @@ -255,8 +252,8 @@ listed, too: ```console $ kubectl get nodes -owide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME -k0s-worker-0 Ready 2m16s v{{{ extra.k8s_version }}}+k0s 10.81.146.198 Alpine Linux v3.17 5.15.83-0-virt containerd://1.7.8 -k0s-worker-1 Ready 2m15s v{{{ extra.k8s_version }}}+k0s 10.81.146.51 Alpine Linux v3.17 5.15.83-0-virt containerd://1.7.8 +k0s-worker-0 Ready 2m16s v{{{ extra.k8s_version }}}+k0s 10.81.146.198 Alpine Linux v3.17 5.15.83-0-virt containerd://1.7.12 +k0s-worker-1 Ready 2m15s v{{{ extra.k8s_version }}}+k0s 10.81.146.51 Alpine Linux v3.17 5.15.83-0-virt containerd://1.7.12 ``` There is one node-local load balancer pod running for each worker node: @@ -301,8 +298,8 @@ $ sed -i s#https://10\\.81\\.146\\.254:6443#https://10.81.146.184:6443#g k0s-kub $ kubectl get nodes -owide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME -k0s-worker-0 Ready 3m35s v{{{ extra.k8s_version }}}+k0s 10.81.146.198 Alpine Linux v3.17 5.15.83-0-virt containerd://1.7.8 -k0s-worker-1 Ready 3m34s v{{{ extra.k8s_version }}}+k0s 10.81.146.51 Alpine Linux v3.17 5.15.83-0-virt containerd://1.7.8 +k0s-worker-0 Ready 3m35s v{{{ extra.k8s_version }}}+k0s 10.81.146.198 Alpine Linux v3.17 5.15.83-0-virt containerd://1.7.12 +k0s-worker-1 Ready 3m34s v{{{ extra.k8s_version }}}+k0s 10.81.146.51 Alpine Linux v3.17 5.15.83-0-virt containerd://1.7.12 $ kubectl -n kube-system get pods -owide -l app.kubernetes.io/managed-by=k0s,app.kubernetes.io/component=nllb NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES diff --git a/docs/raspberry-pi4.md b/docs/raspberry-pi4.md index 76046fe44243..fc936aba5731 100644 --- a/docs/raspberry-pi4.md +++ b/docs/raspberry-pi4.md @@ -294,7 +294,7 @@ When the cluster is up, try to have a look: ```console ubuntu@ubuntu:~$ sudo k0s kc get nodes -owide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME -ubuntu Ready control-plane 4m41s v{{{ extra.k8s_version }}}+k0s 10.152.56.54 Ubuntu 22.04.1 LTS 5.15.0-1013-raspi containerd://1.7.8 +ubuntu Ready control-plane 4m41s v{{{ extra.k8s_version }}}+k0s 10.152.56.54 Ubuntu 22.04.1 LTS 5.15.0-1013-raspi containerd://1.7.12 ubuntu@ubuntu:~$ sudo k0s kc get pod -owide -A NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kube-system kube-proxy-kkv2l 1/1 Running 0 4m44s 10.152.56.54 ubuntu @@ -503,7 +503,7 @@ Using the above kubeconfig, you can now access and use the cluster: ```console ubuntu@ubuntu:~$ KUBECONFIG=/path/to/kubeconfig kubectl get nodes,deployments,pods -owide -A NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME -node/ubuntu Ready 5m1s v{{{ extra.k8s_version }}}+k0s 10.152.56.54 Ubuntu 22.04.1 LTS 5.15.0-1013-raspi containerd://1.7.8 +node/ubuntu Ready 5m1s v{{{ extra.k8s_version }}}+k0s 10.152.56.54 Ubuntu 22.04.1 LTS 5.15.0-1013-raspi containerd://1.7.12 NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR kube-system deployment.apps/coredns 1/1 1 1 33m coredns registry.k8s.io/coredns/coredns:v1.7.0 k8s-app=kube-dns diff --git a/docs/requirements.txt b/docs/requirements.txt index 50e3fe581481..e6d09340e94f 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -4,16 +4,16 @@ click==8.1.7 colorama==0.4.6 ghp-import==2.1.0 idna==3.6 -Jinja2==3.1.2 -Markdown==3.5.1 -MarkupSafe==2.1.3 +Jinja2==3.1.3 +Markdown==3.5.2 +MarkupSafe==2.1.4 mdx-truly-sane-lists==1.3 mergedeep==1.3.4 mike==2.0.0 mkdocs==1.5.3 mkdocs-exclude==1.0.2 mkdocs-macros-plugin==1.0.5 -mkdocs-material==9.5.3 +mkdocs-material==9.5.5 mkdocs-material-extensions==1.3.1 packaging==23.2 Pygments==2.17.2 diff --git a/docs/storage.md b/docs/storage.md index 907f8e2ed83a..16a445098aef 100644 --- a/docs/storage.md +++ b/docs/storage.md @@ -1,14 +1,46 @@ # Storage -k0s supports any volume provider that implements the [CSI specification](https://github.com/container-storage-interface/spec). For convenience, k0s comes bundled in with support for [OpenEBS local path provisioner](https://openebs.io/docs/concepts/localpv). +## CSI + +k0s supports a wide range of different storage options by utilizing Container Storage Interface (CSI). All Kubernetes storage solutions are supported and users can easily select the storage that fits best for their needs. + +When the storage solution implements CSI, kubernetes can communicate with the storage to create and configure persistent volumes. This makes it easy to dynamically provision the requested volumes. It also expands the supported storage solutions from the previous generation, in-tree volume plugins. More information about the CSI concept is described on the [Kubernetes Blog](https://kubernetes.io/blog/2019/01/15/container-storage-interface-ga/). + +![k0s storage](img/k0s_storage.png) + +### Installing 3rd party storage solutions + +Follow your storage driver's installation instructions. Note that by default the Kubelet installed by k0s uses a slightly different path for its working directory (`/varlib/k0s/kubelet` instead of `/var/lib/kubelet`). Consult the CSI driver's configuration documentation on how to customize this path. The actual path can differ if you defined the flag `--data-dir`. + +## Example storage solutions + +Different Kubernetes storage solutions are explained in the [official Kubernetes storage documentation](https://kubernetes.io/docs/concepts/storage/volumes/). All of them can be used with k0s. Here are some popular ones: + +- Rook-Ceph (Open Source) +- MinIO (Open Source) +- Gluster (Open Source) +- Longhorn (Open Source) +- Amazon EBS +- Google Persistent Disk +- Azure Disk +- Portworx + +If you are looking for a fault-tolerant storage with data replication, you can find a k0s tutorial for configuring Ceph storage with Rook [in here](examples/rook-ceph.md). + +## Bundled OpenEBS storage (deprecated) + +Bundled OpenEBS was deprecated in favor of running it [as a helm extension](./examples/openebs.md), +this documentation is maintained as a reference for existing installations. -The choise of which CSI provider to use depends heavily on the use case and infrastructure you're running on and the use case you have. +This was done for three reasons: -## Bundled OpenEBS storage +1. By installing it as a helm extension, users have more control and flexibility without adding complexity. +2. It allows users to choose the OpenEBS version independent of their k0s version. +3. It makes the k0s configuration more consistent. -K0s comes out with bundled OpenEBS installation which can be enabled by using [configuration file](./configuration.md) +For new installations or to migrate existing installations, please refer to the [OpenEBS extension page](./examples/openebs.md). -Use following configuration as an example: +The OpenEBS extension is enabled by setting [`spec.extensions.storage.type`](configuration.md#specextensionsstorage) to``openebs_local_storage`: ```yaml spec: @@ -101,30 +133,3 @@ k0s kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-9a7fae2d-eb03-42c3-aaa9-1a807d5df12f 5Gi RWO Delete Bound default/nginx-pvc openebs-hostpath 30s ``` - -## CSI - -k0s supports a wide range of different storage options by utilizing Container Storage Interface (CSI). All Kubernetes storage solutions are supported and users can easily select the storage that fits best for their needs. - -When the storage solution implements Container Storage Interface (CSI), containers can communicate with the storage for creation and configuration of persistent volumes. This makes it easy to dynamically provision the requested volumes. It also expands the supported storage solutions from the previous generation, in-tree volume plugins. More information about the CSI concept is described on the [Kubernetes Blog](https://kubernetes.io/blog/2019/01/15/container-storage-interface-ga/). - -![k0s storage](img/k0s_storage.png) - -### Installing 3rd party storage solutions - -Follow your storage driver's installation instructions. Note that the Kubelet installed by k0s uses a slightly different path for its working directory (`/varlib/k0s/kubelet` instead of `/var/lib/kubelet`). Consult the CSI driver's configuration documentation on how to customize this path. - -## Example storage solutions - -Different Kubernetes storage solutions are explained in the [official Kubernetes storage documentation](https://kubernetes.io/docs/concepts/storage/volumes/). All of them can be used with k0s. Here are some popular ones: - -- Rook-Ceph (Open Source) -- MinIO (Open Source) -- Gluster (Open Source) -- Longhorn (Open Source) -- Amazon EBS -- Google Persistent Disk -- Azure Disk -- Portworx - -If you are looking for a fault-tolerant storage with data replication, you can find a k0s tutorial for configuring Ceph storage with Rook [in here](examples/rook-ceph.md). diff --git a/docs/system-monitoring.md b/docs/system-monitoring.md index b8e144d19a88..5537f9eefdc0 100644 --- a/docs/system-monitoring.md +++ b/docs/system-monitoring.md @@ -11,6 +11,50 @@ You can read more about metrics for Kubernetes system components [here](https:// sudo k0s install controller --enable-metrics-scraper ``` +Once enabled, a new set of objects will appear in the cluster: + +```shell +❯ ~ kubectl get all -n k0s-system +NAME READY STATUS RESTARTS AGE +pod/k0s-pushgateway-6c5d8c54cf-bh8sb 1/1 Running 0 43h + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/k0s-pushgateway ClusterIP 10.100.11.116 9091/TCP 43h + +NAME READY UP-TO-DATE AVAILABLE AGE +deployment.apps/k0s-pushgateway 1/1 1 1 43h + +NAME DESIRED CURRENT READY AGE +replicaset.apps/k0s-pushgateway-6c5d8c54cf 1 1 1 43h +``` + +That's not enough to start scraping these additional metrics. For Prometheus +Operator](https://prometheus-operator.dev/) based solutions, you can create a +`ServiceMonitor` for it like this: + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: k0s + namespace: k0s-system +spec: + endpoints: + - port: http + selector: + matchLabels: + app: k0s-observability + component: pushgateway + k0s.k0sproject.io/stack: metrics +``` + +Note that it won't clear alerts like "KubeControllerManagerDown" or +"KubeSchedulerDown" as they are based on Prometheus' internal "up" metrics. But +you can get rid of these alerts by modifying them to detect a working component +like this: + +absent(apiserver_audit_event_total{job="kube-scheduler"}) + ## Jobs The list of components which is scrapped by k0s: @@ -26,4 +70,4 @@ The list of components which is scrapped by k0s: ![k0s metrics exposure architecture](img/pushgateway.png) -k0s uses pushgateway with TTL to make it possible to detect issues with the metrics delivery. Default TTL is 2 minutes. \ No newline at end of file +k0s uses pushgateway with TTL to make it possible to detect issues with the metrics delivery. Default TTL is 2 minutes. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 979e8c5c31fa..0b3c54cab643 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -67,7 +67,7 @@ io.containerd.snapshotter.v1 zfs linux/amd64 ok ... ``` -- create a containerd config according to the [documentation](/runtime): `$ containerd config default > /etc/k0s/containerd.toml` +- create a containerd config according to the [documentation](runtime.md): `$ containerd config default > /etc/k0s/containerd.toml` - modify the line in `/etc/k0s/containerd.toml`: ```toml diff --git a/docs/verifying-signs.md b/docs/verifying-signs.md index 1bbeeb0dc8a2..495ff73869d5 100644 --- a/docs/verifying-signs.md +++ b/docs/verifying-signs.md @@ -6,7 +6,7 @@ Binaries can be verified using the `cosign` tool, for example: ```shell cosign verify-blob \ - --key https://github.com/k0sproject/k0s/releases/download/v1.29.0%2Bk0s.0/cosign.pub \ - --signature https://github.com/k0sproject/k0s/releases/download/v1.29.0%2Bk0s.0/k0s-v1.29.0+k0s.0-amd64.sig \ - --payload k0s-v1.29.0+k0s.0-amd64 + --key https://github.com/k0sproject/k0s/releases/download/v{{{ extra.k8s_version }}}%2Bk0s.0/cosign.pub \ + --signature https://github.com/k0sproject/k0s/releases/download/v{{{ extra.k8s_version }}}%2Bk0s.0/k0s-v1.29.1+k0s.0-amd64.sig \ + --payload k0s-v{{{ extra.k8s_version }}}+k0s.0-amd64 ``` diff --git a/embedded-bins/Makefile.variables b/embedded-bins/Makefile.variables index 4c81f16f79f4..1678b332e95c 100644 --- a/embedded-bins/Makefile.variables +++ b/embedded-bins/Makefile.variables @@ -1,7 +1,7 @@ alpine_version = 3.19 alpine_patch_version = $(alpine_version).0 golang_buildimage=docker.io/library/golang:$(go_version)-alpine$(alpine_version) -go_version = 1.21.5 +go_version = 1.21.6 runc_version = 1.1.11 runc_buildimage = $(golang_buildimage) @@ -12,7 +12,7 @@ runc_build_go_tags = "seccomp" #runc_build_go_ldflags = runc_build_go_ldflags_extra = "-w -s -extldflags=-static" -containerd_version = 1.7.8 +containerd_version = 1.7.12 containerd_buildimage = $(golang_buildimage) containerd_build_go_tags = "apparmor,selinux" containerd_build_shim_go_cgo_enabled = 0 @@ -22,7 +22,7 @@ containerd_build_shim_go_cgo_enabled = 0 #containerd_build_go_ldflags = containerd_build_go_ldflags_extra = "-w -s -extldflags=-static" -kubernetes_version = 1.29.0 +kubernetes_version = 1.29.1 helm_version = 3.11.1 kubernetes_buildimage = $(golang_buildimage) kubernetes_build_go_tags = "providerless" @@ -32,21 +32,18 @@ kubernetes_build_go_flags = "-v" #kubernetes_build_go_ldflags = kubernetes_build_go_ldflags_extra = "-extldflags=-static" -kine_version = 0.11.2 +kine_version = 0.11.3 kine_buildimage = $(golang_buildimage) #kine_build_go_tags = #kine_build_go_cgo_enabled = -# Flags taken from https://github.com/k3s-io/kine/blob/v0.11.2/scripts/build#L22 +# Flags taken from https://github.com/k3s-io/kine/blob/v0.11.3/scripts/build#L22 kine_build_go_cgo_cflags = -DSQLITE_ENABLE_DBSTAT_VTAB=1 -DSQLITE_USE_ALLOCA=1 -# See https://github.com/mattn/go-sqlite3/issues/1164#issuecomment-1635253695 -# Remove when https://github.com/mattn/go-sqlite3/issues/1164 is released -kine_build_go_cgo_cflags += -D_LARGEFILE64_SOURCE #kine_build_go_flags = kine_build_go_ldflags = "-w -s" kine_build_go_ldflags_extra = "-extldflags=-static" -etcd_version = 3.5.10 +etcd_version = 3.5.11 etcd_buildimage = $(golang_buildimage) #etcd_build_go_tags = etcd_build_go_cgo_enabled = 0 diff --git a/examples/bootloose-ha-controllers/Dockerfile b/examples/bootloose-ha-controllers/Dockerfile index 512ee1fc55bf..be55ca75ef0e 100644 --- a/examples/bootloose-ha-controllers/Dockerfile +++ b/examples/bootloose-ha-controllers/Dockerfile @@ -2,7 +2,7 @@ FROM quay.io/k0sproject/bootloose-ubuntu18.04 ADD k0s.service /etc/systemd/system/k0s.service -RUN curl -L -o /usr/local/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/v1.29.0/bin/linux/amd64/kubectl && \ +RUN curl -L -o /usr/local/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/v1.29.1/bin/linux/amd64/kubectl && \ chmod +x /usr/local/bin/kubectl ENV KUBECONFIG=/var/lib/k0s/pki/admin.conf diff --git a/go.mod b/go.mod index efc9747a1bb6..537ea0496e1d 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/k0sproject/k0s go 1.21.0 -toolchain go1.21.5 +toolchain go1.21.6 // k0s require ( @@ -19,26 +19,23 @@ require ( github.com/cilium/ebpf v0.12.3 github.com/cloudflare/cfssl v1.6.4 github.com/containerd/cgroups/v3 v3.0.3 - github.com/containerd/containerd v1.7.8 + github.com/containerd/containerd v1.7.12 github.com/denisbrodbeck/machineid v1.0.1 - github.com/estesp/manifest-tool/v2 v2.1.3 - github.com/evanphx/json-patch v5.6.0+incompatible + github.com/evanphx/json-patch v5.7.0+incompatible github.com/fsnotify/fsnotify v1.7.0 github.com/go-logr/logr v1.4.1 github.com/go-openapi/jsonpointer v0.20.2 - github.com/go-playground/validator/v10 v10.16.0 + github.com/go-playground/validator/v10 v10.17.0 github.com/google/go-cmp v0.6.0 github.com/hashicorp/terraform-exec v0.20.0 - github.com/imdario/mergo v0.3.16 github.com/k0sproject/bootloose v0.7.2 github.com/k0sproject/dig v0.2.0 - github.com/k0sproject/version v0.4.2 + github.com/k0sproject/version v0.6.0 github.com/kardianos/service v1.2.2 github.com/logrusorgru/aurora/v3 v3.0.0 github.com/mesosphere/toml-merge v0.2.0 github.com/mitchellh/go-homedir v1.1.0 github.com/olekukonko/tablewriter v0.0.5 - github.com/opencontainers/image-spec v1.1.0-rc5 github.com/opencontainers/runtime-spec v1.1.0 github.com/otiai10/copy v1.14.0 github.com/pelletier/go-toml v1.9.5 @@ -53,44 +50,45 @@ require ( github.com/vishvananda/netlink v1.2.1-beta.2 github.com/vmware-tanzu/sonobuoy v0.57.1 github.com/zcalusic/sysinfo v1.0.2 - go.etcd.io/etcd/api/v3 v3.5.10 - go.etcd.io/etcd/client/pkg/v3 v3.5.10 - go.etcd.io/etcd/client/v3 v3.5.10 - go.etcd.io/etcd/etcdutl/v3 v3.5.10 + go.etcd.io/etcd/api/v3 v3.5.11 + go.etcd.io/etcd/client/pkg/v3 v3.5.11 + go.etcd.io/etcd/client/v3 v3.5.11 + go.etcd.io/etcd/etcdutl/v3 v3.5.11 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.26.0 - golang.org/x/crypto v0.17.0 + golang.org/x/crypto v0.18.0 golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb golang.org/x/mod v0.14.0 - golang.org/x/sync v0.5.0 + golang.org/x/sync v0.6.0 golang.org/x/sys v0.16.0 - golang.org/x/tools v0.16.1 - google.golang.org/grpc v1.60.1 - helm.sh/helm/v3 v3.13.3 + golang.org/x/tools v0.17.0 + google.golang.org/grpc v1.61.0 + helm.sh/helm/v3 v3.14.0 ) // Kubernetes require ( - k8s.io/api v0.29.0 - k8s.io/apiextensions-apiserver v0.29.0 - k8s.io/apimachinery v0.29.0 - k8s.io/cli-runtime v0.29.0 - k8s.io/client-go v0.29.0 - k8s.io/cloud-provider v0.29.0 - k8s.io/component-base v0.29.0 - k8s.io/component-helpers v0.29.0 - k8s.io/cri-api v0.29.0 - k8s.io/kube-aggregator v0.29.0 - k8s.io/kubectl v0.29.0 - k8s.io/kubelet v0.29.0 - k8s.io/kubernetes v1.29.0 - k8s.io/mount-utils v0.29.0 + k8s.io/api v0.29.1 + k8s.io/apiextensions-apiserver v0.29.1 + k8s.io/apimachinery v0.29.1 + k8s.io/cli-runtime v0.29.1 + k8s.io/client-go v0.29.1 + k8s.io/cloud-provider v0.29.1 + k8s.io/component-base v0.29.1 + k8s.io/component-helpers v0.29.1 + k8s.io/cri-api v0.29.1 + k8s.io/kube-aggregator v0.29.1 + k8s.io/kubectl v0.29.1 + k8s.io/kubelet v0.29.1 + k8s.io/kubernetes v1.29.1 + k8s.io/mount-utils v0.29.1 k8s.io/utils v0.0.0-20230726121419-3b25d923346b - sigs.k8s.io/controller-runtime v0.16.3 + sigs.k8s.io/controller-runtime v0.17.0 sigs.k8s.io/yaml v1.4.0 ) require ( + dario.cat/mergo v1.0.0 // indirect github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect @@ -137,7 +135,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/evanphx/json-patch/v5 v5.8.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect github.com/fatih/camelcase v1.0.0 // indirect github.com/fatih/color v1.13.0 // indirect @@ -164,7 +162,7 @@ require ( github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/google/uuid v1.3.1 // indirect + github.com/google/uuid v1.4.0 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/gosuri/uitable v0.0.4 // indirect @@ -176,6 +174,7 @@ require ( github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/terraform-json v0.19.0 // indirect github.com/huandu/xstrings v1.4.0 // indirect + github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/intel/goresctrl v0.3.0 // indirect github.com/jmoiron/sqlx v1.3.5 // indirect @@ -194,8 +193,8 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect - github.com/mattn/go-sqlite3 v1.14.16 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mattn/go-sqlite3 v1.14.19 // indirect + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect @@ -205,6 +204,7 @@ require ( github.com/moby/sys/sequential v0.5.0 // indirect github.com/moby/sys/signal v0.7.0 // indirect github.com/moby/sys/symlink v0.2.0 // indirect + github.com/moby/sys/user v0.1.0 // indirect github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -213,15 +213,15 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/runc v1.1.11 // indirect + github.com/opencontainers/image-spec v1.1.0-rc5 // indirect github.com/opencontainers/selinux v1.11.0 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.16.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.10.1 // indirect + github.com/prometheus/client_golang v1.18.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/rubenv/sql-migrate v1.5.2 // indirect @@ -244,44 +244,43 @@ require ( github.com/zmap/zcrypto v0.0.0-20210511125630-18f1e0152cfc // indirect github.com/zmap/zlint/v3 v3.1.0 // indirect go.etcd.io/bbolt v1.3.8 // indirect - go.etcd.io/etcd/client/v2 v2.305.10 // indirect - go.etcd.io/etcd/pkg/v3 v3.5.10 // indirect - go.etcd.io/etcd/raft/v3 v3.5.10 // indirect - go.etcd.io/etcd/server/v3 v3.5.10 // indirect + go.etcd.io/etcd/client/v2 v2.305.11 // indirect + go.etcd.io/etcd/pkg/v3 v3.5.11 // indirect + go.etcd.io/etcd/raft/v3 v3.5.11 // indirect + go.etcd.io/etcd/server/v3 v3.5.11 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 // indirect - go.opentelemetry.io/otel v1.19.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 // indirect - go.opentelemetry.io/otel/metric v1.19.0 // indirect - go.opentelemetry.io/otel/sdk v1.19.0 // indirect - go.opentelemetry.io/otel/trace v1.19.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect + go.opentelemetry.io/otel v1.20.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 // indirect + go.opentelemetry.io/otel/metric v1.20.0 // indirect + go.opentelemetry.io/otel/sdk v1.20.0 // indirect + go.opentelemetry.io/otel/trace v1.20.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect - golang.org/x/net v0.19.0 // indirect - golang.org/x/oauth2 v0.13.0 // indirect - golang.org/x/term v0.15.0 // indirect + golang.org/x/net v0.20.0 // indirect + golang.org/x/oauth2 v0.14.0 // indirect + golang.org/x/term v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect + google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiserver v0.29.0 // indirect - k8s.io/controller-manager v0.29.0 // indirect + k8s.io/apiserver v0.29.1 // indirect + k8s.io/controller-manager v0.29.1 // indirect k8s.io/klog/v2 v2.110.1 // indirect - k8s.io/kms v0.29.0 // indirect + k8s.io/kms v0.29.1 // indirect k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect - k8s.io/metrics v0.29.0 // indirect + k8s.io/metrics v0.29.1 // indirect oras.land/oras-go v1.2.4 // indirect - oras.land/oras-go/v2 v2.2.1 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect @@ -292,35 +291,35 @@ require ( // Replacements duplicated from upstream Kubernetes replace ( - // https://github.com/kubernetes/kubernetes/blob/v1.29.0/go.mod#L251-L282 - k8s.io/api => k8s.io/api v0.29.0 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.29.0 - k8s.io/apimachinery => k8s.io/apimachinery v0.29.0 - k8s.io/apiserver => k8s.io/apiserver v0.29.0 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.29.0 - k8s.io/client-go => k8s.io/client-go v0.29.0 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.29.0 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.29.0 - k8s.io/code-generator => k8s.io/code-generator v0.29.0 - k8s.io/component-base => k8s.io/component-base v0.29.0 - k8s.io/component-helpers => k8s.io/component-helpers v0.29.0 - k8s.io/controller-manager => k8s.io/controller-manager v0.29.0 - k8s.io/cri-api => k8s.io/cri-api v0.29.0 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.29.0 - k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.29.0 - k8s.io/endpointslice => k8s.io/endpointslice v0.29.0 - k8s.io/kms => k8s.io/kms v0.29.0 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.29.0 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.29.0 - k8s.io/kube-proxy => k8s.io/kube-proxy v0.29.0 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.29.0 - k8s.io/kubectl => k8s.io/kubectl v0.29.0 - k8s.io/kubelet => k8s.io/kubelet v0.29.0 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.29.0 - k8s.io/metrics => k8s.io/metrics v0.29.0 - k8s.io/mount-utils => k8s.io/mount-utils v0.29.0 - k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.29.0 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.29.0 - k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.29.0 - k8s.io/sample-controller => k8s.io/sample-controller v0.29.0 + // https://github.com/kubernetes/kubernetes/blob/v1.29.1/go.mod#L251-L282 + k8s.io/api => k8s.io/api v0.29.1 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.29.1 + k8s.io/apimachinery => k8s.io/apimachinery v0.29.1 + k8s.io/apiserver => k8s.io/apiserver v0.29.1 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.29.1 + k8s.io/client-go => k8s.io/client-go v0.29.1 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.29.1 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.29.1 + k8s.io/code-generator => k8s.io/code-generator v0.29.1 + k8s.io/component-base => k8s.io/component-base v0.29.1 + k8s.io/component-helpers => k8s.io/component-helpers v0.29.1 + k8s.io/controller-manager => k8s.io/controller-manager v0.29.1 + k8s.io/cri-api => k8s.io/cri-api v0.29.1 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.29.1 + k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.29.1 + k8s.io/endpointslice => k8s.io/endpointslice v0.29.1 + k8s.io/kms => k8s.io/kms v0.29.1 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.29.1 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.29.1 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.29.1 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.29.1 + k8s.io/kubectl => k8s.io/kubectl v0.29.1 + k8s.io/kubelet => k8s.io/kubelet v0.29.1 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.29.1 + k8s.io/metrics => k8s.io/metrics v0.29.1 + k8s.io/mount-utils => k8s.io/mount-utils v0.29.1 + k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.29.1 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.29.1 + k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.29.1 + k8s.io/sample-controller => k8s.io/sample-controller v0.29.1 ) diff --git a/go.sum b/go.sum index dc4bc1368b6d..1ca0cbaaa0f7 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.110.8 h1:tyNdfIxjzaWctIiLYOTalaLKZ17SI44SKFW26QbOhME= -cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= -cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go v0.110.10 h1:LXy9GEO+timppncPIAZoOj3l58LIU9k+kn48AN7IO3Y= +cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= +cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= @@ -96,8 +96,8 @@ github.com/cloudflare/cfssl v1.6.4/go.mod h1:8b3CQMxfWPAeom3zBnGJ6sd+G1NkL5TXqmD github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= -github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 h1:7To3pQ+pZo0i3dsWEbinPNFs5gPSBOsJtx3wTT94VBY= +github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA= github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= @@ -107,8 +107,8 @@ github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2 github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= -github.com/containerd/containerd v1.7.8 h1:RkwgOW3AVUT3H/dyT0W03Dc8AzlpMG65lX48KftOFSM= -github.com/containerd/containerd v1.7.8/go.mod h1:L/Hn9qylJtUFT7cPeM0Sr3fATj+WjHwRQ0lyrYk3OPY= +github.com/containerd/containerd v1.7.12 h1:+KQsnv4VnzyxWcfO9mlxxELaoztsDEjOuCMPAuPqgU0= +github.com/containerd/containerd v1.7.12/go.mod h1:/5OMpE1p0ylxtEUGY8kuCYkDRzJm9NO1TFMWjUpdevk= github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY= @@ -180,12 +180,10 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= -github.com/estesp/manifest-tool/v2 v2.1.3 h1:Xd0oxiwkXIcCYVdU4s7IZBIPYy5xbRJE2hzqQqb81EE= -github.com/estesp/manifest-tool/v2 v2.1.3/go.mod h1:fVIu8tz5/04LXjFyE/LLd+uD8VFHXy38YFbCN4GrWHM= -github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= -github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= -github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= +github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= +github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= @@ -228,8 +226,8 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= -github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= @@ -244,8 +242,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.16.0 h1:x+plE831WK4vaKHO/jpgUGsvLKIqRRkz6M78GuJAfGE= -github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.17.0 h1:SmVVlfAOtlZncTxRuinDPomC2DkXJ4E5T9gDA0AIH74= +github.com/go-playground/validator/v10 v10.17.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -328,8 +326,8 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= @@ -380,7 +378,6 @@ github.com/intel/goresctrl v0.3.0 h1:K2D3GOzihV7xSBedGxONSlaw/un1LZgWsc9IfqipN4c github.com/intel/goresctrl v0.3.0/go.mod h1:fdz3mD85cmP9sHD8JUlrNWAxvwM86CrbmVXltEKd7zk= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg= @@ -396,8 +393,8 @@ github.com/k0sproject/bootloose v0.7.2 h1:K3IRlP8WSBWuNqT7SN/L6nw3rYY+aMpfqylOQ2 github.com/k0sproject/bootloose v0.7.2/go.mod h1:BwIRhmv1ioCQsOeTa6qeSlBFzu5OTpINP9BIjVAXjEc= github.com/k0sproject/dig v0.2.0 h1:cNxEIl96g9kqSMfPSZLhpnZ0P8bWXKv08nxvsMHop5w= github.com/k0sproject/dig v0.2.0/go.mod h1:rBcqaQlJpcKdt2x/OE/lPvhGU50u/e95CSm5g/r4s78= -github.com/k0sproject/version v0.4.2 h1:zrbT5xRv1ai4N102ZaHTTq9Zqf6pAGFm9WCxHaC9QHY= -github.com/k0sproject/version v0.4.2/go.mod h1:oEjuz2ItQQtAnGyRgwEV9m5R6/9rjoFC6EiEEzbkFdI= +github.com/k0sproject/version v0.6.0 h1:Wi8wu9j+H36+okIQA47o/YHbzNpKeIYj8IjGdJOdqsI= +github.com/k0sproject/version v0.6.0/go.mod h1:5/7Js62gDCLBP6mEs0mUcYEEkYneM5qXDKN/hyFlQTM= github.com/kardianos/service v1.2.2 h1:ZvePhAHfvo0A7Mftk/tEzqEZ7Q4lgnR8sGz4xu1YX60= github.com/kardianos/service v1.2.2/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM= github.com/karrick/godirwalk v1.17.0 h1:b4kY7nqDdioR/6qnbHQyDvmA17u5G1cZ6J+CZXwSWoI= @@ -459,11 +456,11 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= -github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI= +github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mesosphere/toml-merge v0.2.0 h1:stCUgrwbictiebeHRqEJ1NfQl/h5noyFKR0LBWjWXxQ= github.com/mesosphere/toml-merge v0.2.0/go.mod h1:WYpgeqeG5puUtv2NREGyOIqTnYuWswyo7CBgx6QK80s= github.com/miekg/dns v1.1.25 h1:dFwPR6SfLtrSwgDcIq2bcU/gVutB4sNApq2HBdqcakg= @@ -490,6 +487,8 @@ github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/moby/sys/symlink v0.2.0 h1:tk1rOM+Ljp0nFmfOIBtlV3rTDlWOwFRhjEeAhZB0nZc= github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= +github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg= +github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -520,20 +519,18 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/ginkgo/v2 v2.14.0 h1:vSmGj2Z5YPb9JwCWT6z6ihcUvDhuXLc3sJiqd3jMKAY= +github.com/onsi/ginkgo/v2 v2.14.0/go.mod h1:JkUdW7JkN0V6rFvsHcJ478egV3XH9NxpD27Hal/PhZw= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= -github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= +github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= -github.com/opencontainers/runc v1.1.11 h1:9LjxyVlE0BPMRP2wuQDRlHV4941Jp9rc3F0+YKimopA= -github.com/opencontainers/runc v1.1.11/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -552,7 +549,6 @@ github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rK github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -562,23 +558,23 @@ github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjz github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= +github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= -github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo= github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= @@ -690,46 +686,46 @@ github.com/zmap/zlint/v3 v3.1.0 h1:WjVytZo79m/L1+/Mlphl09WBob6YTGljN5IGWZFpAv0= github.com/zmap/zlint/v3 v3.1.0/go.mod h1:L7t8s3sEKkb0A2BxGy1IWrxt1ZATa1R4QfJZaQOD3zU= go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= -go.etcd.io/etcd/api/v3 v3.5.10 h1:szRajuUUbLyppkhs9K6BRtjY37l66XQQmw7oZRANE4k= -go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI= -go.etcd.io/etcd/client/pkg/v3 v3.5.10 h1:kfYIdQftBnbAq8pUWFXfpuuxFSKzlmM5cSn76JByiT0= -go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U= -go.etcd.io/etcd/client/v2 v2.305.10 h1:MrmRktzv/XF8CvtQt+P6wLUlURaNpSDJHFZhe//2QE4= -go.etcd.io/etcd/client/v2 v2.305.10/go.mod h1:m3CKZi69HzilhVqtPDcjhSGp+kA1OmbNn0qamH80xjA= -go.etcd.io/etcd/client/v3 v3.5.10 h1:W9TXNZ+oB3MCd/8UjxHTWK5J9Nquw9fQBLJd5ne5/Ao= -go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= -go.etcd.io/etcd/etcdutl/v3 v3.5.10 h1:o57fNgdP9Y99wZzpQ5ky5Jb6323/nisMtCOj1+kQwgc= -go.etcd.io/etcd/etcdutl/v3 v3.5.10/go.mod h1:vDoQpV0zo5HFlK8tgE8cTwZB+RQuWGHa2G3wAZvIJ88= -go.etcd.io/etcd/pkg/v3 v3.5.10 h1:WPR8K0e9kWl1gAhB5A7gEa5ZBTNkT9NdNWrR8Qpo1CM= -go.etcd.io/etcd/pkg/v3 v3.5.10/go.mod h1:TKTuCKKcF1zxmfKWDkfz5qqYaE3JncKKZPFf8c1nFUs= -go.etcd.io/etcd/raft/v3 v3.5.10 h1:cgNAYe7xrsrn/5kXMSaH8kM/Ky8mAdMqGOxyYwpP0LA= -go.etcd.io/etcd/raft/v3 v3.5.10/go.mod h1:odD6kr8XQXTy9oQnyMPBOr0TVe+gT0neQhElQ6jbGRc= -go.etcd.io/etcd/server/v3 v3.5.10 h1:4NOGyOwD5sUZ22PiWYKmfxqoeh72z6EhYjNosKGLmZg= -go.etcd.io/etcd/server/v3 v3.5.10/go.mod h1:gBplPHfs6YI0L+RpGkTQO7buDbHv5HJGG/Bst0/zIPo= +go.etcd.io/etcd/api/v3 v3.5.11 h1:B54KwXbWDHyD3XYAwprxNzTe7vlhR69LuBgZnMVvS7E= +go.etcd.io/etcd/api/v3 v3.5.11/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4= +go.etcd.io/etcd/client/pkg/v3 v3.5.11 h1:bT2xVspdiCj2910T0V+/KHcVKjkUrCZVtk8J2JF2z1A= +go.etcd.io/etcd/client/pkg/v3 v3.5.11/go.mod h1:seTzl2d9APP8R5Y2hFL3NVlD6qC/dOT+3kvrqPyTas4= +go.etcd.io/etcd/client/v2 v2.305.11 h1:ZqdKLNJnWpE3bUaaj3XZ5xWyCi+7Vspgk9E0hlIBguE= +go.etcd.io/etcd/client/v2 v2.305.11/go.mod h1:vX2j5tMynwOateY6BfVmLol3gYOIkbhqjs/BqRsdIOw= +go.etcd.io/etcd/client/v3 v3.5.11 h1:ajWtgoNSZJ1gmS8k+icvPtqsqEav+iUorF7b0qozgUU= +go.etcd.io/etcd/client/v3 v3.5.11/go.mod h1:a6xQUEqFJ8vztO1agJh/KQKOMfFI8og52ZconzcDJwE= +go.etcd.io/etcd/etcdutl/v3 v3.5.11 h1:yzw6yHDYfKU3IW7akusVCmxXJexRgH88a4C21iOSWFc= +go.etcd.io/etcd/etcdutl/v3 v3.5.11/go.mod h1:p7jTKqjyEjl/lyTzhHuQ5kqQt1FhQlRHw8TK90WjHQI= +go.etcd.io/etcd/pkg/v3 v3.5.11 h1:U5+/mZh+jps8VRWv7+xPiK1tC1hRBOBYdn7zCqtWyOY= +go.etcd.io/etcd/pkg/v3 v3.5.11/go.mod h1:bLfwo6YEgpOAMBZJsZg5AiSS+mxNTRJi15Dvp9kKW68= +go.etcd.io/etcd/raft/v3 v3.5.11 h1:eeimaNIT9DjV4bdLSy4FjLQ/KGSAiG1L5T1nTf5VoZg= +go.etcd.io/etcd/raft/v3 v3.5.11/go.mod h1:Tp7kZJVtWJWLiMCPrgkimiOB5ZYi8YM93onQihpG724= +go.etcd.io/etcd/server/v3 v3.5.11 h1:FEa0ImvoXdIPa81/vZUKpnJ74fpQ5ZivseoIKMPzfpg= +go.etcd.io/etcd/server/v3 v3.5.11/go.mod h1:CS0+TwcuRlhg1I5CpA3YlisOcoqJB1h1GMRgje75uDs= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 h1:ZOLJc06r4CB42laIXg/7udr0pbZyuAihN10A/XuiQRY= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0/go.mod h1:5z+/ZWJQKXa9YT34fQNx5K8Hd1EoIhvtUygUQPqEOgQ= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 h1:KfYpVmrjI7JuToy5k8XV3nkapjWx48k4E4JOtVstzQI= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0/go.mod h1:SeQhzAEccGVZVEy7aH87Nh0km+utSpo1pTv6eMMop48= -go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= -go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 h1:3d+S281UTjM+AbF31XSOYn1qXn3BgIdWl8HNEpx08Jk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0/go.mod h1:0+KuTDyKL4gjKCF75pHOX4wuzYDUZYfAQdSu43o+Z2I= -go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= -go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= -go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= -go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= -go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= -go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0 h1:PzIubN4/sjByhDRHLviCjJuweBXWFZWhghjg7cS28+M= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0/go.mod h1:Ct6zzQEuGK3WpJs2n4dn+wfJYzd/+hNnxMRTWjGn30M= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= +go.opentelemetry.io/otel v1.20.0 h1:vsb/ggIY+hUjD/zCAQHpzTmndPqv/ml2ArbsbfBYTAc= +go.opentelemetry.io/otel v1.20.0/go.mod h1:oUIGj3D77RwJdM6PPZImDpSZGDvkD9fhesHny69JFrs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 h1:DeFD0VgTZ+Cj6hxravYYZE2W4GlneVH81iAOPjZkzk8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0/go.mod h1:GijYcYmNpX1KazD5JmWGsi4P7dDTTTnfv1UbGn84MnU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 h1:gvmNvqrPYovvyRmCSygkUDyL8lC5Tl845MLEwqpxhEU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0/go.mod h1:vNUq47TGFioo+ffTSnKNdob241vePmtNZnAODKapKd0= +go.opentelemetry.io/otel/metric v1.20.0 h1:ZlrO8Hu9+GAhnepmRGhSU7/VkpjrNowxRN9GyKR4wzA= +go.opentelemetry.io/otel/metric v1.20.0/go.mod h1:90DRw3nfK4D7Sm/75yQ00gTJxtkBxX+wu6YaNymbpVM= +go.opentelemetry.io/otel/sdk v1.20.0 h1:5Jf6imeFZlZtKv9Qbo6qt2ZkmWtdWx/wzcCbNUlAWGM= +go.opentelemetry.io/otel/sdk v1.20.0/go.mod h1:rmkSx1cZCm/tn16iWDn1GQbLtsW/LvsdEEFzCSRM6V0= +go.opentelemetry.io/otel/trace v1.20.0 h1:+yxVAPZPbQhbC3OfAkeIVTky6iTFpcr4SiY9om7mXSQ= +go.opentelemetry.io/otel/trace v1.20.0/go.mod h1:HJSK7F/hA5RlzpZ0zKDCHCDHm556LCDtKaAo6JmBFUU= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= -go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= @@ -741,8 +737,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb h1:xIApU0ow1zwMa2uL1VDNeQlNVFTWMQxZUZCMDy0Q4Us= golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= @@ -772,11 +768,11 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= -golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= +golang.org/x/oauth2 v0.14.0 h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0= +golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -785,8 +781,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -830,8 +826,8 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -853,8 +849,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -869,20 +865,20 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 h1:SeZZZx0cP0fqUyA+oRzP9k7cSwJlvDFiROO72uwD6i0= -google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97/go.mod h1:t1VqOqqvce95G3hIDCT5FeO3YUc6Q4Oe24L/+rNMxRk= -google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 h1:W18sezcAYs+3tDZX4F80yctqa12jcP1PUS2gQu1zTPU= -google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97/go.mod h1:iargEX0SFPm3xcfMI0d1domjg0ZF4Aa0p2awqyxhvF0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 h1:6GQBEOdGkX6MMTLT9V+TjtIRZCw9VPD5Z+yHY9wMgS0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 h1:Jyp0Hsi0bmHXG6k9eATXoYtjd6e2UzZ1SCn/wIupY14= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= -google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= +google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -923,60 +919,58 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= -helm.sh/helm/v3 v3.13.3 h1:0zPEdGqHcubehJHP9emCtzRmu8oYsJFRrlVF3TFj8xY= -helm.sh/helm/v3 v3.13.3/go.mod h1:3OKO33yI3p4YEXtTITN2+4oScsHeQe71KuzhlZ+aPfg= +helm.sh/helm/v3 v3.14.0 h1:TaZIH6uOchn7L27ptwnnuHJiFrT/BsD4dFdp/HLT2nM= +helm.sh/helm/v3 v3.14.0/go.mod h1:2itvvDv2WSZXTllknfQo6j7u3VVgMAvm8POCDgYH424= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= -k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= -k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= -k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= -k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= -k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= -k8s.io/apiserver v0.29.0 h1:Y1xEMjJkP+BIi0GSEv1BBrf1jLU9UPfAnnGGbbDdp7o= -k8s.io/apiserver v0.29.0/go.mod h1:31n78PsRKPmfpee7/l9NYEv67u6hOL6AfcE761HapDM= -k8s.io/cli-runtime v0.29.0 h1:q2kC3cex4rOBLfPOnMSzV2BIrrQlx97gxHJs21KxKS4= -k8s.io/cli-runtime v0.29.0/go.mod h1:VKudXp3X7wR45L+nER85YUzOQIru28HQpXr0mTdeCrk= -k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8= -k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38= -k8s.io/cloud-provider v0.29.0 h1:Qgk/jHsSKGRk/ltTlN6e7eaNuuamLROOzVBd0RPp94M= -k8s.io/cloud-provider v0.29.0/go.mod h1:gBCt7YYKFV4oUcJ/0xF9lS/9il4MxKunJ+ZKvh39WGo= -k8s.io/component-base v0.29.0 h1:T7rjd5wvLnPBV1vC4zWd/iWRbV8Mdxs+nGaoaFzGw3s= -k8s.io/component-base v0.29.0/go.mod h1:sADonFTQ9Zc9yFLghpDpmNXEdHyQmFIGbiuZbqAXQ1M= -k8s.io/component-helpers v0.29.0 h1:Y8W70NGeitKxWwhsPo/vEQbQx5VqJV+3xfLpP3V1VxU= -k8s.io/component-helpers v0.29.0/go.mod h1:j2coxVfmzTOXWSE6sta0MTgNSr572Dcx68F6DD+8fWc= -k8s.io/controller-manager v0.29.0 h1:kEv9sKLnjDkoSqeouWp2lZ8P33an5wrDJpOMqoyD7pc= -k8s.io/controller-manager v0.29.0/go.mod h1:UKtadWkULF5bfX7vu3hHppzY/hz88C03t70GItg/x08= -k8s.io/cri-api v0.29.0 h1:atenAqOltRsFqcCQlFFpDnl/R4aGfOELoNLTDJfd7t8= -k8s.io/cri-api v0.29.0/go.mod h1:Rls2JoVwfC7kW3tndm7267kriuRukQ02qfht0PCRuIc= +k8s.io/api v0.29.1 h1:DAjwWX/9YT7NQD4INu49ROJuZAAAP/Ijki48GUPzxqw= +k8s.io/api v0.29.1/go.mod h1:7Kl10vBRUXhnQQI8YR/R327zXC8eJ7887/+Ybta+RoQ= +k8s.io/apiextensions-apiserver v0.29.1 h1:S9xOtyk9M3Sk1tIpQMu9wXHm5O2MX6Y1kIpPMimZBZw= +k8s.io/apiextensions-apiserver v0.29.1/go.mod h1:zZECpujY5yTW58co8V2EQR4BD6A9pktVgHhvc0uLfeU= +k8s.io/apimachinery v0.29.1 h1:KY4/E6km/wLBguvCZv8cKTeOwwOBqFNjwJIdMkMbbRc= +k8s.io/apimachinery v0.29.1/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= +k8s.io/apiserver v0.29.1 h1:e2wwHUfEmMsa8+cuft8MT56+16EONIEK8A/gpBSco+g= +k8s.io/apiserver v0.29.1/go.mod h1:V0EpkTRrJymyVT3M49we8uh2RvXf7fWC5XLB0P3SwRw= +k8s.io/cli-runtime v0.29.1 h1:By3WVOlEWYfyxhGko0f/IuAOLQcbBSMzwSaDren2JUs= +k8s.io/cli-runtime v0.29.1/go.mod h1:vjEY9slFp8j8UoMhV5AlO8uulX9xk6ogfIesHobyBDU= +k8s.io/client-go v0.29.1 h1:19B/+2NGEwnFLzt0uB5kNJnfTsbV8w6TgQRz9l7ti7A= +k8s.io/client-go v0.29.1/go.mod h1:TDG/psL9hdet0TI9mGyHJSgRkW3H9JZk2dNEUS7bRks= +k8s.io/cloud-provider v0.29.1 h1:bDLpOSpysWrtU2PCkvyP2sUTwRBa6MGCmxt68CRRW/8= +k8s.io/cloud-provider v0.29.1/go.mod h1:u50Drm6AbuoKpsVbAstNiFHGgbSVHuJV4TWN5imdM2w= +k8s.io/component-base v0.29.1 h1:MUimqJPCRnnHsskTTjKD+IC1EHBbRCVyi37IoFBrkYw= +k8s.io/component-base v0.29.1/go.mod h1:fP9GFjxYrLERq1GcWWZAE3bqbNcDKDytn2srWuHTtKc= +k8s.io/component-helpers v0.29.1 h1:54MMEDu6xeJmMtAKztsPwu0kJKr4+jCUzaEIn2UXRoc= +k8s.io/component-helpers v0.29.1/go.mod h1:+I7xz4kfUgxWAPJIVKrqe4ml4rb9UGpazlOmhXYo+cY= +k8s.io/controller-manager v0.29.1 h1:bTnJFF/OWooRVeJ4QLA1ApuPH+fjHSmcVMMeL7qvI2E= +k8s.io/controller-manager v0.29.1/go.mod h1:fVhGGuBiB0B2yT2+OHXZaA88owVn5zkv18A+G9E9Qlw= +k8s.io/cri-api v0.29.1 h1:pQwYDahnAX9K8KtdV8PD1eeNexMJojEj1t/5kAMX61E= +k8s.io/cri-api v0.29.1/go.mod h1:9fQTFm+wi4FLyqrkVUoMJiUB3mE74XrVvHz8uFY/sSw= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kms v0.29.0 h1:KJ1zaZt74CgvgV3NR7tnURJ/mJOKC5X3nwon/WdwgxI= -k8s.io/kms v0.29.0/go.mod h1:mB0f9HLxRXeXUfHfn1A7rpwOlzXI1gIWu86z6buNoYA= -k8s.io/kube-aggregator v0.29.0 h1:N4fmtePxOZ+bwiK1RhVEztOU+gkoVkvterHgpwAuiTw= -k8s.io/kube-aggregator v0.29.0/go.mod h1:bjatII63ORkFg5yUFP2qm2OC49R0wwxZhRVIyJ4Z4X0= +k8s.io/kms v0.29.1 h1:6dMOaxllwiAZ8p3Hys65b78MDG+hONpBBpk1rQsaEtk= +k8s.io/kms v0.29.1/go.mod h1:Hqkx3zEGWThUTbcSkK508DUv4c1HOJOB5qihSoLBWgU= +k8s.io/kube-aggregator v0.29.1 h1:ArCHuHNT2vNOQbrFBjt23nUs+08w1KcLABuWUinOD4U= +k8s.io/kube-aggregator v0.29.1/go.mod h1:Wdf0L0CWYwhUKs+KaYiM+NwqkZTp0Erd/wgefvyZBwQ= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/kubectl v0.29.0 h1:Oqi48gXjikDhrBF67AYuZRTcJV4lg2l42GmvsP7FmYI= -k8s.io/kubectl v0.29.0/go.mod h1:0jMjGWIcMIQzmUaMgAzhSELv5WtHo2a8pq67DtviAJs= -k8s.io/kubelet v0.29.0 h1:SX5hlznTBcGIrS1scaf8r8p6m3e475KMifwt9i12iOk= -k8s.io/kubelet v0.29.0/go.mod h1:kvKS2+Bz2tgDOG1S1q0TH2z1DasNuVF+8p6Aw7xvKkI= -k8s.io/kubernetes v1.29.0 h1:DOLN7g8+nnAYBi8JHoW0+/MCrZKDPIqAxzLCXDXd0cg= -k8s.io/kubernetes v1.29.0/go.mod h1:9kztbUQf9stVDcIYXx+BX3nuGCsAQDsuClkGMpPs3pA= -k8s.io/metrics v0.29.0 h1:a6dWcNM+EEowMzMZ8trka6wZtSRIfEA/9oLjuhBksGc= -k8s.io/metrics v0.29.0/go.mod h1:UCuTT4dC/x/x6ODSk87IWIZQnuAfcwxOjb1gjWJdjMA= -k8s.io/mount-utils v0.29.0 h1:KcUE0bFHONQC10V3SuLWQ6+l8nmJggw9lKLpDftIshI= -k8s.io/mount-utils v0.29.0/go.mod h1:N3lDK/G1B8R/IkAt4NhHyqB07OqEr7P763z3TNge94U= +k8s.io/kubectl v0.29.1 h1:rWnW3hi/rEUvvg7jp4iYB68qW5un/urKbv7fu3Vj0/s= +k8s.io/kubectl v0.29.1/go.mod h1:SZzvLqtuOJYSvZzPZR9weSuP0wDQ+N37CENJf0FhDF4= +k8s.io/kubelet v0.29.1 h1:cso8Dk8dymkj8q+EvW/aCbIYU2aOkH27gho48tYza/8= +k8s.io/kubelet v0.29.1/go.mod h1:hTl/naFcCVG1Ku17fMgj/krbheBwBkf3gnFhaboMx7E= +k8s.io/kubernetes v1.29.1 h1:fxJFVb8uqbYZDYHpwIsAndBQs360cQGb0xa1gYFh3fo= +k8s.io/kubernetes v1.29.1/go.mod h1:xZPKU0yO0CBbLTnbd+XGyRmmtmaVuJykDb8gNCkeeUE= +k8s.io/metrics v0.29.1 h1:qutc3aIPMCniMuEApuLaeYX47rdCn8eycVDx7R6wMlQ= +k8s.io/metrics v0.29.1/go.mod h1:JrbV2U71+v7d/9qb90UVKL8r0uJ6Z2Hy4V7mDm05cKs= +k8s.io/mount-utils v0.29.1 h1:veXlIm52Y4tm3H0pG03cOdkw0KOJxYDa0fQqhJCoqvQ= +k8s.io/mount-utils v0.29.1/go.mod h1:9IWJTMe8tG0MYMLEp60xK9GYVeCdA3g4LowmnVi+t9Y= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= oras.land/oras-go v1.2.4 h1:djpBY2/2Cs1PV87GSJlxv4voajVOMZxqqtq9AB8YNvY= oras.land/oras-go v1.2.4/go.mod h1:DYcGfb3YF1nKjcezfX2SNlDAeQFKSXmf+qrFmrh4324= -oras.land/oras-go/v2 v2.2.1 h1:3VJTYqy5KfelEF9c2jo1MLSpr+TM3mX8K42wzZcd6qE= -oras.land/oras-go/v2 v2.2.1/go.mod h1:GeAwLuC4G/JpNwkd+bSZ6SkDMGaaYglt6YK2WvZP7uQ= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 h1:TgtAeesdhpm2SGwkQasmbeqDo8th5wOBA5h/AjTKA4I= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0/go.mod h1:VHVDI/KrK4fjnV61bE2g3sA7tiETLn8sooImelsCx3Y= -sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= -sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= +sigs.k8s.io/controller-runtime v0.17.0 h1:fjJQf8Ukya+VjogLO6/bNX9HE6Y2xpsO5+fyS26ur/s= +sigs.k8s.io/controller-runtime v0.17.0/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0= diff --git a/hack/gen-bindata/gen_bindata.go b/hack/gen-bindata/gen_bindata.go index 64579feba0b2..ad72cb9dd62f 100644 --- a/hack/gen-bindata/gen_bindata.go +++ b/hack/gen-bindata/gen_bindata.go @@ -180,7 +180,8 @@ func GenBindata(name string, args ...string) error { }) } -var packageTemplate = template.Must(template.New("").Parse(`// Code generated by go generate; DO NOT EDIT. +var packageTemplate = template.Must(template.New("").Parse(`//go:build !noembedbins +// Code generated by go generate; DO NOT EDIT. // datafile: {{ .OutFile }} diff --git a/hack/gen-bindata/gen_bindata_test.go b/hack/gen-bindata/gen_bindata_test.go index 07b10270400b..e87230e904b9 100644 --- a/hack/gen-bindata/gen_bindata_test.go +++ b/hack/gen-bindata/gen_bindata_test.go @@ -49,7 +49,8 @@ func TestGenBindata_BasicExecution(t *testing.T) { tmpDir := t.TempDir() defer testutil.Chdir(t, tmpDir)() - const expected = `// Code generated by go generate; DO NOT EDIT. + const expected = `//go:build !noembedbins +// Code generated by go generate; DO NOT EDIT. // datafile: ./bindata diff --git a/hack/ostests/modules/k0sctl/main.tf b/hack/ostests/modules/k0sctl/main.tf index 3b74f32cad73..3713ec2c5b84 100644 --- a/hack/ostests/modules/k0sctl/main.tf +++ b/hack/ostests/modules/k0sctl/main.tf @@ -27,10 +27,10 @@ locals { num_workers = length([for h in terraform_data.k0sctl_apply.output.hosts : h if h.is_worker]) } -resource "terraform_data" "konnectivity_available" { +resource "terraform_data" "pre_flight_checks" { triggers_replace = [ sha256(jsonencode(terraform_data.k0sctl_apply.output.k0sctl_config)), - sha256(file("${path.module}/wait-for-konnectivity.sh")), + sha256(file("${path.module}/pre-flight-checks.sh")), ] input = { @@ -51,7 +51,7 @@ resource "terraform_data" "konnectivity_available" { inline = [ "#!/usr/bin/env sh", format("set -- %d %d", local.num_controllers, local.num_workers), - file("${path.module}/wait-for-konnectivity.sh"), + file("${path.module}/pre-flight-checks.sh"), ] } } diff --git a/hack/ostests/modules/k0sctl/outputs.tf b/hack/ostests/modules/k0sctl/outputs.tf index 35ee9a8a7786..b68159283ed5 100644 --- a/hack/ostests/modules/k0sctl/outputs.tf +++ b/hack/ostests/modules/k0sctl/outputs.tf @@ -1,15 +1,15 @@ output "hosts" { - value = terraform_data.konnectivity_available.output.hosts + value = terraform_data.pre_flight_checks.output.hosts description = "The hosts that have been provisioned by k0sctl." } output "ssh_private_key_filename" { - value = terraform_data.konnectivity_available.output.ssh_private_key_filename + value = terraform_data.pre_flight_checks.output.ssh_private_key_filename description = "The name of the private key file that has been used to authenticate via SSH." } output "k0sctl_config" { - value = terraform_data.konnectivity_available.output.k0sctl_config + value = terraform_data.pre_flight_checks.output.k0sctl_config description = "The k0sctl config that has been used." } diff --git a/hack/ostests/modules/k0sctl/wait-for-konnectivity.sh b/hack/ostests/modules/k0sctl/pre-flight-checks.sh similarity index 74% rename from hack/ostests/modules/k0sctl/wait-for-konnectivity.sh rename to hack/ostests/modules/k0sctl/pre-flight-checks.sh index af97cbc346ad..10082c37f630 100755 --- a/hack/ostests/modules/k0sctl/wait-for-konnectivity.sh +++ b/hack/ostests/modules/k0sctl/pre-flight-checks.sh @@ -37,7 +37,7 @@ countSeenControllers() { } testKonnectivityPods() { - pods="$(kubectl -n kube-system get po -l k8s-app=konnectivity-agent -oname)" + pods="$(kubectl -n kube-system get po -l k8s-app=konnectivity-agent --field-selector=status.phase=Running -oname)" seenPods=0 for pod in $pods; do @@ -50,6 +50,10 @@ testKonnectivityPods() { [ $seenPods -eq "$expectedWorkers" ] } +testCoreDnsDeployment() { + kubectl -n kube-system wait --for=condition=Available --timeout=9s deploy/coredns +} + main() { { [ $# -eq 2 ] \ @@ -67,8 +71,7 @@ main() { echo Expecting "$expectedWorkers" pods with "$expectedControllers" controller connections each ... >&2 failedAttempts=0 - while :; do - ! testKonnectivityPods || return 0 + while ! testKonnectivityPods; do failedAttempts=$((failedAttempts + 1)) if [ $failedAttempts -gt 30 ]; then echo Giving up after $failedAttempts failed attempts ... >&2 @@ -77,6 +80,19 @@ main() { echo Attempt $failedAttempts failed, retrying in ten seconds ... >&2 sleep 10 done + + echo Waiting for CoreDNS deployment to become available ... >&2 + + failedAttempts=0 + while ! testCoreDnsDeployment; do + failedAttempts=$((failedAttempts + 1)) + if [ $failedAttempts -gt 30 ]; then + echo Giving up after $failedAttempts failed attempts ... >&2 + return 1 + fi + echo Attempt $failedAttempts failed, retrying in a second ... >&2 + sleep 1 + done } main "$@" diff --git a/hack/tool/go.mod b/hack/tool/go.mod index 38fefc3e1187..3a48e15953ed 100644 --- a/hack/tool/go.mod +++ b/hack/tool/go.mod @@ -2,11 +2,11 @@ module tool go 1.21 -toolchain go1.21.5 +toolchain go1.21.6 require ( github.com/hashicorp/terraform-exec v0.20.0 - github.com/k0sproject/k0sctl v0.17.1 + github.com/k0sproject/k0sctl v0.17.4 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 ) @@ -23,6 +23,8 @@ require ( github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect + github.com/bodgit/ntlmssp v0.0.0-20231224131242-ee0981b06f47 // indirect + github.com/bodgit/windows v1.0.1 // indirect github.com/carlmjohnson/versioninfo v0.22.5 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/creasty/defaults v1.7.0 // indirect @@ -30,7 +32,7 @@ require ( github.com/davidmz/go-pageant v1.0.2 // indirect github.com/denisbrodbeck/machineid v1.0.1 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.16.0 // indirect @@ -38,7 +40,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/terraform-json v0.19.0 // indirect @@ -53,16 +55,17 @@ require ( github.com/jellydator/validation v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/k0sproject/dig v0.2.0 // indirect - github.com/k0sproject/rig v0.15.1 // indirect + github.com/k0sproject/rig v0.17.3 // indirect github.com/k0sproject/version v0.4.2 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786 // indirect - github.com/masterzen/winrm v0.0.0-20220917170901-b07f6cb0598d // indirect + github.com/masterzen/winrm v0.0.0-20231227165926-e811dad5ac77 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-shellwords v1.0.12 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -73,25 +76,26 @@ require ( github.com/sergi/go-diff v1.3.1 // indirect github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect github.com/sirupsen/logrus v1.9.3 // indirect + github.com/tidwall/transform v0.0.0-20201103190739-32f242e2dbde // indirect github.com/urfave/cli/v2 v2.27.1 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect github.com/zclconf/go-cty v1.14.1 // indirect - golang.org/x/crypto v0.17.0 // indirect + golang.org/x/crypto v0.18.0 // indirect golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.18.0 // indirect + golang.org/x/net v0.20.0 // indirect golang.org/x/oauth2 v0.10.0 // indirect - golang.org/x/sys v0.15.0 // indirect - golang.org/x/term v0.15.0 // indirect + golang.org/x/sys v0.16.0 // indirect + golang.org/x/term v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.13.0 // indirect + golang.org/x/tools v0.16.1 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/apimachinery v0.29.0 // indirect - k8s.io/client-go v0.29.0 // indirect + k8s.io/apimachinery v0.29.1 // indirect + k8s.io/client-go v0.29.1 // indirect k8s.io/klog/v2 v2.110.1 // indirect k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect diff --git a/hack/tool/go.sum b/hack/tool/go.sum index c091c196e240..6c98ef8576f3 100644 --- a/hack/tool/go.sum +++ b/hack/tool/go.sum @@ -2,7 +2,6 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= -github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/ChrisTrenkamp/goxpath v0.0.0-20210404020558-97928f7e12b6 h1:w0E0fgc1YafGEh5cROhlROMWXiNoZqApk2PDN0M1+Ns= @@ -29,6 +28,10 @@ github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwN github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/bodgit/ntlmssp v0.0.0-20231224131242-ee0981b06f47 h1:ZMj2BlouavwQqsJuHbsANI76eD4IU4dAU2ZRJAmAx4M= +github.com/bodgit/ntlmssp v0.0.0-20231224131242-ee0981b06f47/go.mod h1:Ue2cLc2yLbk7D139BcYcmVP3DHsRuB5P4JfMTtAa24o= +github.com/bodgit/windows v1.0.1 h1:tF7K6KOluPYygXa3Z2594zxlkbKPAOvqr97etrGNIz4= +github.com/bodgit/windows v1.0.1/go.mod h1:a6JLwrB4KrTR5hBpp8FI9/9W9jJfeQ2h4XDXU74ZCdM= github.com/carlmjohnson/versioninfo v0.22.5 h1:O00sjOLUAFxYQjlN/bzYTuZiS0y6fWDQjMRvwtKgwwc= github.com/carlmjohnson/versioninfo v0.22.5/go.mod h1:QT9mph3wcVfISUKd0i9sZfVrPviHuSF+cUtLjm2WSf8= github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= @@ -60,8 +63,9 @@ github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+ github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= github.com/go-git/go-git/v5 v5.10.1 h1:tu8/D8i+TWxgKpzQ3Vc43e+kkhXqtsZCKI/egajKnxk= github.com/go-git/go-git/v5 v5.10.1/go.mod h1:uEuHjxkHap8kAl//V5F/nNWwqIYtP/402ddd05mp0wg= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= @@ -76,7 +80,6 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.16.0 h1:x+plE831WK4vaKHO/jpgUGsvLKIqRRkz6M78GuJAfGE= github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -90,15 +93,12 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= @@ -130,12 +130,10 @@ github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFK github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= -github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= -github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8= github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= @@ -148,10 +146,10 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/k0sproject/dig v0.2.0 h1:cNxEIl96g9kqSMfPSZLhpnZ0P8bWXKv08nxvsMHop5w= github.com/k0sproject/dig v0.2.0/go.mod h1:rBcqaQlJpcKdt2x/OE/lPvhGU50u/e95CSm5g/r4s78= -github.com/k0sproject/k0sctl v0.17.1 h1:1rvqYyx08SlY86MHdPkw1ZYFPB/uDlFAAlE3hVB92wg= -github.com/k0sproject/k0sctl v0.17.1/go.mod h1:RjaK3EqFK9UWDTcNutcAnS3JvOkprOfgNFqh5hNfKos= -github.com/k0sproject/rig v0.15.1 h1:QjEBSgDDMk24NB6vLozIilUGPn0nOGEz/AFkPOZkYWw= -github.com/k0sproject/rig v0.15.1/go.mod h1:EQQjrgGbRY6MpbuZRpzMaymJJ86RJVxIuGsPGsVNfZg= +github.com/k0sproject/k0sctl v0.17.4 h1:CNfCriE6GPwCDTaXLO41113x1e3YQCXxdrsNLEYkTCc= +github.com/k0sproject/k0sctl v0.17.4/go.mod h1:ovmA+UEzXwg20bP2NdIx26ZbGc2PIK8Q/14zWreeXBg= +github.com/k0sproject/rig v0.17.3 h1:acrPjbhKA4FC17DoqGdXoH9PixI1oAw4WT+Iv5k+Ji4= +github.com/k0sproject/rig v0.17.3/go.mod h1:6i71zLJjUZuMp3gfLtd+oXoW+yUmq1+BQhe7nHaAmZw= github.com/k0sproject/version v0.4.2 h1:zrbT5xRv1ai4N102ZaHTTq9Zqf6pAGFm9WCxHaC9QHY= github.com/k0sproject/version v0.4.2/go.mod h1:oEjuz2ItQQtAnGyRgwEV9m5R6/9rjoFC6EiEEzbkFdI= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= @@ -174,8 +172,8 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786 h1:2ZKn+w/BJeL43sCxI2jhPLRv73oVVOjEKZjKkflyqxg= github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc= -github.com/masterzen/winrm v0.0.0-20220917170901-b07f6cb0598d h1:GXlX1g/AjI3/izilmeMvP/aHWYCuwOZXpJsS0XdGVls= -github.com/masterzen/winrm v0.0.0-20220917170901-b07f6cb0598d/go.mod h1:Iju3u6NzoTAvjuhsGCZc+7fReNnr/Bd6DsWj3WTokIU= +github.com/masterzen/winrm v0.0.0-20231227165926-e811dad5ac77 h1:psY7rHKhnfqjTEgkleIYpF1vVxVfYsUYFTO/cL5Z6xM= +github.com/masterzen/winrm v0.0.0-20231227165926-e811dad5ac77/go.mod h1:otHfftEJdo9JWGoq9GcJRaeNLp/uhqNq8JOk5lL+8Ks= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -183,6 +181,8 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= +github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= @@ -232,6 +232,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/tidwall/transform v0.0.0-20201103190739-32f242e2dbde h1:AMNpJRc7P+GTwVbl8DkK2I9I8BBUzNiHuH/tlxrpan0= +github.com/tidwall/transform v0.0.0-20201103190739-32f242e2dbde/go.mod h1:MvrEmduDUz4ST5pGZ7CABCnOU5f3ZiOAZzT6b1A6nX8= github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= @@ -248,13 +250,11 @@ github.com/zclconf/go-cty v1.14.1/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgr golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -267,27 +267,24 @@ golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= -golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -296,17 +293,16 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= @@ -319,8 +315,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -332,7 +328,6 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= @@ -347,12 +342,12 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= -k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= -k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= -k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= -k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8= -k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38= +k8s.io/api v0.29.1 h1:DAjwWX/9YT7NQD4INu49ROJuZAAAP/Ijki48GUPzxqw= +k8s.io/api v0.29.1/go.mod h1:7Kl10vBRUXhnQQI8YR/R327zXC8eJ7887/+Ybta+RoQ= +k8s.io/apimachinery v0.29.1 h1:KY4/E6km/wLBguvCZv8cKTeOwwOBqFNjwJIdMkMbbRc= +k8s.io/apimachinery v0.29.1/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= +k8s.io/client-go v0.29.1 h1:19B/+2NGEwnFLzt0uB5kNJnfTsbV8w6TgQRz9l7ti7A= +k8s.io/client-go v0.29.1/go.mod h1:TDG/psL9hdet0TI9mGyHJSgRkW3H9JZk2dNEUS7bRks= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= diff --git a/hack/tools/Makefile.variables b/hack/tools/Makefile.variables index a00d8cc64c94..35076e553b99 100644 --- a/hack/tools/Makefile.variables +++ b/hack/tools/Makefile.variables @@ -1,3 +1,3 @@ -controller-gen_version = 0.13.0 +controller-gen_version = 0.14.0 go-bindata_version = 3.23.0+incompatible golangci-lint_version = 1.55.2 diff --git a/hack/tools/gen-matrix.sh b/hack/tools/gen-matrix.sh index 534fa4a159e8..95a09925dc3f 100755 --- a/hack/tools/gen-matrix.sh +++ b/hack/tools/gen-matrix.sh @@ -5,7 +5,7 @@ # ./gen-matrix.sh 1.24.2 1.24.3 # Output: ["v1.24.2+k0s.0", "v1.24.3+k0s.0"] -set -e -o pipefail +set -euo pipefail list_k0s_releases() { # shellcheck disable=SC2016 @@ -13,12 +13,8 @@ list_k0s_releases() { VERSION_PREFIX="v$1" gh api -X GET /repos/k0sproject/k0s/releases -F per_page=100 --paginate --jq "$query" } -k0s_sort() { - go run github.com/k0sproject/version/cmd/k0s_sort@v0.4.2 -} - latest_release() { - list_k0s_releases "$1" | k0s_sort | tail -1 + list_k0s_releases "$1" | k0s_sort -l } json_print_latest_releases() { diff --git a/hack/tools/run-autopilot-matrix-tests.sh b/hack/tools/run-autopilot-matrix-tests.sh index 6060d52e454c..2c458e939ce7 100755 --- a/hack/tools/run-autopilot-matrix-tests.sh +++ b/hack/tools/run-autopilot-matrix-tests.sh @@ -10,11 +10,8 @@ TESTS=${1:-check-ap-ha3x3} VERSIONS="$2" ARCH=${TARGET_ARCH:-amd64} -go install github.com/k0sproject/version/cmd/k0s_sort@v0.4.2 -GOBIN="$(go env GOPATH)/bin" - if [[ -z "$VERSIONS" ]]; then - RELEASE=$(gh release list -L 100 -R k0sproject/k0s | grep "+k0s." | grep -v Draft | cut -f 1 | $GOBIN/k0s_sort | tail -1) + RELEASE=$(gh release list -L 100 -R k0sproject/k0s | grep "+k0s." | grep -v Draft | cut -f 1 | k0s_sort -l) VERSIONS=$RELEASE fi diff --git a/hack/validate-images/main.go b/hack/validate-images/main.go deleted file mode 100644 index ef433c944149..000000000000 --- a/hack/validate-images/main.go +++ /dev/null @@ -1,122 +0,0 @@ -//go:build hack - -/* -Copyright 2021 k0s authors - -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. -*/ - -package main - -import ( - "encoding/json" - "flag" - "fmt" - "os" - "strings" - - "github.com/k0sproject/k0s/pkg/airgap" - "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1" - - "k8s.io/utils/strings/slices" - - "github.com/estesp/manifest-tool/v2/pkg/registry" - "github.com/estesp/manifest-tool/v2/pkg/store" - "github.com/estesp/manifest-tool/v2/pkg/types" - "github.com/estesp/manifest-tool/v2/pkg/util" - - ocispec "github.com/opencontainers/image-spec/specs-go/v1" -) - -func check(e error) { - if e != nil { - panic(e) - } -} - -func main() { - var architectures []string - var architecturesString string - flag.StringVar(&architecturesString, "architectures", "amd64,arm64,arm", "which architectures to search for") - flag.Parse() - architectures = strings.Split(architecturesString, ",") - if len(architectures) < 1 { - panic("No architectures given") - } - cfg := v1beta1.DefaultClusterConfig() - uris := airgap.GetImageURIs(cfg.Spec, false) - - var errs []error - errs = append(errs, validateImages(uris, architectures)...) - - // Envoy doesn't have an official ARMv7 image! - architectures = slices.Filter(nil, architectures, func(s string) bool { return s != "arm" }) - errs = append(errs, validateImages([]string{v1beta1.DefaultEnvoyProxyImage().URI()}, architectures)...) - - if len(errs) > 0 { - fmt.Fprintln(os.Stderr, "Not all images were valid.") - for _, err := range errs { - fmt.Fprintln(os.Stderr, "Error: ", err) - } - os.Exit(1) - } -} - -func validateImages(uris []string, architectures []string) (errs []error) { - for _, name := range uris { - fmt.Println("validating image", name, "to have architectures: ", architectures) - imageRef, err := util.ParseName(name) - check(err) - memoryStore := store.NewMemoryStore() - err = util.CreateRegistryHost(imageRef, "", "", true, true, "", false) - check(err) - descriptor, err := registry.FetchDescriptor(util.GetResolver(), memoryStore, imageRef) - check(err) - _, db, _ := memoryStore.Get(descriptor) - switch descriptor.MediaType { - case ocispec.MediaTypeImageIndex, types.MediaTypeDockerSchema2ManifestList: - // this is a multi-platform image descriptor; marshal to Index type - var idx ocispec.Index - check(json.Unmarshal(db, &idx)) - if validationErrs := validateList(name, architectures, idx); validationErrs != nil { - errs = append(errs, validationErrs...) - } - case ocispec.MediaTypeImageManifest, types.MediaTypeDockerSchema2Manifest: - errs = append(errs, fmt.Errorf("image %s has single manifest, but we need multiarch manifests", name)) - default: - errs = append(errs, fmt.Errorf("image %s has unknown manifest type, can't validate architectures", name)) - } - } - return -} - -func validateList(name string, architectures []string, index ocispec.Index) (errs []error) { - searchFor := map[string]bool{} - - for _, m := range index.Manifests { - for _, platformToCheck := range architectures { - if m.Platform.Architecture == platformToCheck { - searchFor[platformToCheck] = true - } - } - } - - for _, platform := range architectures { - _, found := searchFor[platform] - if !found { - errs = append(errs, fmt.Errorf("platform %s not found for image %s", platform, name)) - } - } - - return -} diff --git a/inttest/Makefile b/inttest/Makefile index 889e49c80480..42568d1dd48a 100644 --- a/inttest/Makefile +++ b/inttest/Makefile @@ -111,6 +111,8 @@ check-network-conformance-calico: TEST_PACKAGE=network-conformance check-nllb: TIMEOUT=15m +check-openebs: TIMEOUT=7m + .PHONY: $(smoketests) include Makefile.variables diff --git a/inttest/Makefile.variables b/inttest/Makefile.variables index ac5c579d84b1..4357bd1046ee 100644 --- a/inttest/Makefile.variables +++ b/inttest/Makefile.variables @@ -38,7 +38,6 @@ smoketests := \ check-hacontrolplane \ check-hostnameoverride \ check-k0scloudprovider \ - check-k0sctl \ check-kine \ check-kubectl \ check-kubeletcertrotate \ @@ -52,6 +51,7 @@ smoketests := \ check-noderole \ check-noderole-no-taints \ check-noderole-single \ + check-openebs\ check-psp \ check-singlenode \ check-statussocket \ diff --git a/inttest/airgap/airgap_test.go b/inttest/airgap/airgap_test.go index e000233d764b..2bfb0b852cd4 100644 --- a/inttest/airgap/airgap_test.go +++ b/inttest/airgap/airgap_test.go @@ -21,12 +21,14 @@ import ( "strings" "testing" - "github.com/stretchr/testify/suite" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/k0sproject/k0s/inttest/common" "github.com/k0sproject/k0s/pkg/airgap" "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + + "github.com/stretchr/testify/suite" ) const k0sConfig = ` @@ -40,10 +42,11 @@ type AirgapSuite struct { } func (s *AirgapSuite) TestK0sGetsUp() { + ctx := s.Context() err := (&common.Airgap{ SSH: s.SSH, Logf: s.T().Logf, - }).LockdownMachines(s.Context(), + }).LockdownMachines(ctx, s.ControllerNode(0), s.WorkerNode(0), ) s.Require().NoError(err) @@ -62,47 +65,37 @@ func (s *AirgapSuite) TestK0sGetsUp() { s.Equal("bar", labels["k0sproject.io/foo"]) } - s.AssertSomeKubeSystemPods(kc) - - s.T().Log("waiting to see kube-router pods ready") - s.NoError(common.WaitForKubeRouterReady(s.Context(), kc), "kube-router did not start") - - // at that moment we can assume that all pods has at least started - events, err := kc.CoreV1().Events("kube-system").List(s.Context(), v1.ListOptions{ - Limit: 100, + s.Require().NoError(common.WaitForKubeRouterReady(ctx, kc), "While waiting for kube-router to become ready") + s.Require().NoError(common.WaitForCoreDNSReady(ctx, kc), "While waiting for CoreDNS to become ready") + s.Require().NoError(common.WaitForPodLogs(ctx, kc, "kube-system"), "While waiting for some pod logs") + + // At that moment we can assume that all pods have at least started + // We're interested only in image pull events + events, err := kc.CoreV1().Events("").List(ctx, metav1.ListOptions{ + FieldSelector: fields.AndSelectors( + fields.OneTermEqualSelector("involvedObject.kind", "Pod"), + fields.OneTermEqualSelector("reason", "Pulled"), + ).String(), }) s.Require().NoError(err) - imagesUsed := 0 - var pulledImagesMessages []string + for _, event := range events.Items { - if event.Source.Component == "kubelet" && event.Reason == "Pulled" { - // We're interested only in image pull events - s.T().Logf(event.Message) - if strings.Contains(event.Message, "already present on machine") { - imagesUsed++ - } - if strings.Contains(event.Message, "Pulling image") { - pulledImagesMessages = append(pulledImagesMessages, event.Message) - } - } - } - s.T().Logf("Used %d images from airgap bundle", imagesUsed) - if len(pulledImagesMessages) > 0 { - s.T().Logf("Image pulls messages") - for _, message := range pulledImagesMessages { - s.T().Logf(message) + if !strings.HasSuffix(event.Message, "already present on machine") { + s.Fail("Unexpected Pulled event", event.Message) + } else { + s.T().Log("Observed Pulled event:", event.Message) } - s.Fail("Require all images be installed from bundle") } + // Check that all the images have io.cri-containerd.pinned=pinned label - ssh, err := s.SSH(s.Context(), s.WorkerNode(0)) + ssh, err := s.SSH(ctx, s.WorkerNode(0)) s.Require().NoError(err) + defer ssh.Disconnect() for _, i := range airgap.GetImageURIs(v1beta1.DefaultClusterSpec(), true) { - output, err := ssh.ExecWithOutput(s.Context(), fmt.Sprintf(`k0s ctr i ls "name==%s"`, i)) + output, err := ssh.ExecWithOutput(ctx, fmt.Sprintf(`k0s ctr i ls "name==%s"`, i)) s.Require().NoError(err) s.Require().Contains(output, "io.cri-containerd.pinned=pinned", "expected %s image to have io.cri-containerd.pinned=pinned label", i) } - } func TestAirgapSuite(t *testing.T) { diff --git a/inttest/ap-airgap/airgap_test.go b/inttest/ap-airgap/airgap_test.go index 3ebf72a4bf7c..44d31686a46f 100644 --- a/inttest/ap-airgap/airgap_test.go +++ b/inttest/ap-airgap/airgap_test.go @@ -16,10 +16,18 @@ package airgap import ( "fmt" + "strings" "testing" + "time" + "github.com/k0sproject/k0s/pkg/airgap" + "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1" apconst "github.com/k0sproject/k0s/pkg/autopilot/constant" appc "github.com/k0sproject/k0s/pkg/autopilot/controller/plans/core" + "github.com/k0sproject/k0s/pkg/constant" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" "github.com/k0sproject/k0s/inttest/common" aptest "github.com/k0sproject/k0s/inttest/common/autopilot" @@ -46,6 +54,9 @@ func (s *airgapSuite) SetupTest() { s.Require().NoError(aptest.WaitForCRDByName(ctx, cClient, "plans")) s.Require().NoError(aptest.WaitForCRDByName(ctx, cClient, "controlnodes")) + wClient, err := s.KubeClient(s.ControllerNode(0)) + s.Require().NoError(err) + // Create a worker join token workerJoinToken, err := s.GetJoinToken("worker") s.Require().NoError(err) @@ -53,21 +64,30 @@ func (s *airgapSuite) SetupTest() { // Start the workers using the join token s.Require().NoError(s.RunWorkersWithToken(workerJoinToken)) - wClient, err := s.KubeClient(s.ControllerNode(0)) - s.Require().NoError(err) - s.Require().NoError(s.WaitForNodeReady(s.WorkerNode(0), wClient)) -} -func (s *airgapSuite) TestApply() { - err := (&common.Airgap{ - SSH: s.SSH, - Logf: s.T().Logf, - }).LockdownMachines(s.Context(), - s.ControllerNode(0), s.WorkerNode(0), - ) + // Wait until all the cluster components are up. + s.Require().NoError(common.WaitForKubeRouterReady(ctx, wClient), "While waiting for kube-router to become ready") + s.Require().NoError(common.WaitForCoreDNSReady(ctx, wClient), "While waiting for CoreDNS to become ready") + s.Require().NoError(common.WaitForPodLogs(ctx, wClient, "kube-system"), "While waiting for some pod logs") + + // Check that none of the images in the airgap bundle are pinned. + // This will happen as soon as k0s imports them after the Autopilot update. + ssh, err := s.SSH(ctx, s.WorkerNode(0)) s.Require().NoError(err) + defer ssh.Disconnect() + for _, i := range airgap.GetImageURIs(v1beta1.DefaultClusterSpec(), true) { + if strings.HasPrefix(i, constant.KubePauseContainerImage+":") { + continue // The pause image is pinned by containerd itself + } + output, err := ssh.ExecWithOutput(ctx, fmt.Sprintf(`k0s ctr i ls "name==%s"`, i)) + if s.NoError(err, "Failed to check %s", i) { + s.NotContains(output, "io.cri-containerd.pinned=pinned", "%s is already pinned", i) + } + } +} +func (s *airgapSuite) TestApply() { planTemplate := ` apiVersion: autopilot.k0sproject.io/v1beta2 kind: Plan @@ -110,9 +130,23 @@ spec: - worker0 ` + ctx := s.Context() + + // The container images have already been pulled by the cluster. + // Airgapping is kind of cosmetic here. + err := (&common.Airgap{ + SSH: s.SSH, + Logf: s.T().Logf, + }).LockdownMachines(ctx, + s.ControllerNode(0), s.WorkerNode(0), + ) + s.Require().NoError(err) + manifestFile := "/tmp/happy.yaml" s.PutFileTemplate(s.ControllerNode(0), manifestFile, planTemplate, nil) + updateStart := time.Now() + out, err := s.RunCommandController(0, fmt.Sprintf("/usr/local/bin/k0s kubectl apply -f %s", manifestFile)) s.T().Logf("kubectl apply output: '%s'", out) s.Require().NoError(err) @@ -122,15 +156,52 @@ spec: s.NotEmpty(client) // The plan has enough information to perform a successful update of k0s, so wait for it. - _, err = aptest.WaitForPlanState(s.Context(), client, apconst.AutopilotName, appc.PlanCompleted) + _, err = aptest.WaitForPlanState(ctx, client, apconst.AutopilotName, appc.PlanCompleted) s.Require().NoError(err) - // We are not confirming the image importing functionality of k0s, but we can get a pretty good idea if it worked. - // Does the bundle exist on the worker, in the proper directory? lsout, err := s.RunCommandWorker(0, "ls /var/lib/k0s/images/bundle.tar") s.NoError(err) s.NotEmpty(lsout) + + // Wait until all the cluster components are up. + kc, err := s.KubeClient(s.ControllerNode(0)) + s.Require().NoError(err) + s.Require().NoError(common.WaitForKubeRouterReady(ctx, kc), "While waiting for kube-router to become ready") + s.Require().NoError(common.WaitForCoreDNSReady(ctx, kc), "While waiting for CoreDNS to become ready") + s.Require().NoError(common.WaitForPodLogs(ctx, kc, "kube-system"), "While waiting for some pod logs") + + // At that moment we can assume that all pods have at least started. + // Inspect the Pulled events if there are some unexpected image pulls. + events, err := kc.CoreV1().Events("").List(ctx, metav1.ListOptions{ + FieldSelector: fields.AndSelectors( + fields.OneTermEqualSelector("involvedObject.kind", "Pod"), + fields.OneTermEqualSelector("reason", "Pulled"), + ).String(), + }) + s.Require().NoError(err) + + for _, event := range events.Items { + if event.LastTimestamp.After(updateStart) { + if !strings.HasSuffix(event.Message, "already present on machine") { + s.Fail("Unexpected Pulled event", event.Message) + } else { + s.T().Log("Observed Pulled event:", event.Message) + } + } + } + + // Check that all the images in the airgap bundle have been pinned by k0s. + // This proves that k0s has processed the image bundle. + ssh, err := s.SSH(ctx, s.WorkerNode(0)) + s.Require().NoError(err) + defer ssh.Disconnect() + for _, i := range airgap.GetImageURIs(v1beta1.DefaultClusterSpec(), true) { + output, err := ssh.ExecWithOutput(ctx, fmt.Sprintf(`k0s ctr i ls "name==%s"`, i)) + if s.NoError(err, "Failed to check %s", i) { + s.Contains(output, "io.cri-containerd.pinned=pinned", "%s is not pinned", i) + } + } } // TestAirgapSuite sets up a suite using 3 controllers for quorum, and runs various diff --git a/inttest/ap-ha3x3/ha3x3_test.go b/inttest/ap-ha3x3/ha3x3_test.go index 7d07ebb09b3a..723a084af4cd 100644 --- a/inttest/ap-ha3x3/ha3x3_test.go +++ b/inttest/ap-ha3x3/ha3x3_test.go @@ -15,24 +15,29 @@ package ha3x3 import ( + "bytes" + "context" "fmt" "os" + "path/filepath" "strings" "testing" "time" - apv1beta2 "github.com/k0sproject/k0s/pkg/apis/autopilot/v1beta2" apconst "github.com/k0sproject/k0s/pkg/autopilot/constant" appc "github.com/k0sproject/k0s/pkg/autopilot/controller/plans/core" "github.com/k0sproject/k0s/inttest/common" aptest "github.com/k0sproject/k0s/inttest/common/autopilot" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "golang.org/x/exp/slices" ) type ha3x3Suite struct { common.BootlooseSuite + k0sUpdateVersion string } const haControllerConfig = ` @@ -93,9 +98,6 @@ func (s *ha3x3Suite) SetupTest() { // TestApply applies a well-formed `plan` yaml, and asserts that // all of the correct values across different objects + controllers are correct. func (s *ha3x3Suite) TestApply() { - k0sUpdateVersion := os.Getenv("K0S_UPDATE_TO_VERSION") - s.Require().NotEmpty(k0sUpdateVersion, "env var not set or empty: K0S_UPDATE_TO_VERSION") - planTemplate := ` apiVersion: autopilot.k0sproject.io/v1beta2 kind: Plan @@ -106,7 +108,7 @@ spec: timestamp: now commands: - k0supdate: - version: ` + k0sUpdateVersion + ` + version: ` + s.k0sUpdateVersion + ` platforms: linux-amd64: url: http://localhost/dist/k0s-new @@ -127,58 +129,151 @@ spec: - worker2 ` - manifestFile := "/tmp/happy.yaml" - s.PutFileTemplate(s.ControllerNode(0), manifestFile, planTemplate, nil) + ctx := s.Context() - out, err := s.RunCommandController(0, fmt.Sprintf("/usr/local/bin/k0s kubectl apply -f %s", manifestFile)) - s.T().Logf("kubectl apply output: '%s'", out) + sshController, err := s.SSH(ctx, s.ControllerNode(0)) s.Require().NoError(err) + defer sshController.Disconnect() + + if version, err := s.GetK0sVersion(s.ControllerNode(0)); s.NoError(err, "Failed to get the base k0s version") { + hasOldStack := version != s.k0sUpdateVersion && (strings.HasPrefix(version, "v1.27.") || strings.HasPrefix(version, "v1.28.")) + s.T().Logf("Base k0s version: %q, has old stack: %v", version, hasOldStack) + s.checkKubeletConfigStackResources(ctx, sshController, hasOldStack) + } - ssh, err := s.SSH(s.Context(), s.WorkerNode(0)) + sshWorker, err := s.SSH(ctx, s.WorkerNode(0)) s.Require().NoError(err) - defer ssh.Disconnect() - out, err = ssh.ExecWithOutput(s.Context(), "/var/lib/k0s/bin/iptables-save -V") + defer sshWorker.Disconnect() + + iptablesModeBeforeUpdate, err := getIPTablesMode(ctx, sshWorker) + if !s.NoError(err) { + iptablesModeBeforeUpdate = "" + } + + var createPlanOutput bytes.Buffer + err = sshController.Exec(ctx, "k0s kc create -f -", common.SSHStreams{ + In: strings.NewReader(planTemplate), + Out: &createPlanOutput, + }) s.Require().NoError(err) - iptablesVersionParts := strings.Split(out, " ") - iptablesModeBeforeUpdate := iptablesVersionParts[len(iptablesVersionParts)-1] + s.T().Log(strings.TrimSpace(createPlanOutput.String())) client, err := s.AutopilotClient(s.ControllerNode(0)) s.Require().NoError(err) - s.NotEmpty(client) // The plan has enough information to perform a successful update of k0s, so wait for it. - plan, err := aptest.WaitForPlanState(s.Context(), client, apconst.AutopilotName, appc.PlanCompleted) + s.T().Log("Waiting for autopilot plan to complete") + plan, err := aptest.WaitForPlanState(ctx, client, apconst.AutopilotName, appc.PlanCompleted) s.Require().NoError(err) + s.T().Log("Autopilot plan completed") // Ensure all state/status are completed - s.Equal(1, len(plan.Status.Commands)) - cmd := plan.Status.Commands[0] + if s.Len(plan.Status.Commands, 1) { + cmd := plan.Status.Commands[0] + s.Equal(appc.PlanCompleted, cmd.State) + s.NotNil(cmd.K0sUpdate) + s.NotNil(cmd.K0sUpdate.Controllers) + s.NotNil(cmd.K0sUpdate.Workers) + s.Equal(appc.PlanCompleted, cmd.State) + s.NotNil(cmd.K0sUpdate) + s.NotNil(cmd.K0sUpdate.Controllers) + s.NotNil(cmd.K0sUpdate.Workers) - s.Equal(appc.PlanCompleted, cmd.State) - s.NotNil(cmd.K0sUpdate) - s.NotNil(cmd.K0sUpdate.Controllers) - s.NotNil(cmd.K0sUpdate.Workers) + if s.NotNil(cmd.K0sUpdate) { + s.Len(cmd.K0sUpdate.Controllers, s.ControllerCount) + for idx, controller := range cmd.K0sUpdate.Controllers { + s.Equal(appc.SignalCompleted, controller.State, "For controller %d", idx) + } - for _, group := range [][]apv1beta2.PlanCommandTargetStatus{cmd.K0sUpdate.Controllers, cmd.K0sUpdate.Workers} { - for _, node := range group { - s.Equal(appc.SignalCompleted, node.State) + s.Len(cmd.K0sUpdate.Workers, s.WorkerCount) + for idx, worker := range cmd.K0sUpdate.Workers { + s.Equal(appc.SignalCompleted, worker.State, "For worker %d", idx) + } } } if version, err := s.GetK0sVersion(s.ControllerNode(0)); s.NoError(err) { - s.Equal(k0sUpdateVersion, version) + s.Equal(s.k0sUpdateVersion, version) } - out, err = ssh.ExecWithOutput(s.Context(), "/var/lib/k0s/bin/iptables-save -V") - s.Require().NoError(err) - iptablesVersionParts = strings.Split(out, " ") - iptablesModeAfterUpdate := iptablesVersionParts[len(iptablesVersionParts)-1] - s.Equal(iptablesModeBeforeUpdate, iptablesModeAfterUpdate) + if iptablesModeAfterUpdate, err := getIPTablesMode(ctx, sshWorker); s.NoError(err) { + s.Equal(iptablesModeBeforeUpdate, iptablesModeAfterUpdate) + } + + for idx := 0; idx < s.ControllerCount; idx++ { + func() { + ssh, err := s.SSH(ctx, s.ControllerNode(idx)) + s.Require().NoError(err) + defer ssh.Disconnect() + s.checkKubeletConfigComponentFolders(ctx, ssh) + }() + } + + s.checkKubeletConfigStackResources(ctx, sshController, false) +} + +func (s *ha3x3Suite) checkKubeletConfigComponentFolders(ctx context.Context, ssh *common.SSHConnection) { + var foundFiles bytes.Buffer + if !s.NoError( + ssh.Exec(ctx, "cd /var/lib/k0s/manifests/kubelet && find . -type f -print0", common.SSHStreams{Out: &foundFiles}), + "Failed to list kubelet manifest folder", + ) { + return + } + + files := strings.Split(strings.TrimSuffix(foundFiles.String(), "\x00"), "\x00") + + // Check that removed.txt is present + if idx := slices.Index(files, "./removed.txt"); idx < 0 { + s.Failf("No removed.txt in kubelet manifests folder", "%v", files) + } else { + files = slices.Delete(files, idx, idx+1) + } + + // Check that all other files are only disabled yaml files. + for _, file := range files { + match, err := filepath.Match("./kubelet-config.yaml.*.removed", file) + s.Require().NoError(err) + if !match { + s.Failf("Unknown file in kubelet manifest folder", "%s in %v", file, files) + } + } +} + +func (s *ha3x3Suite) checkKubeletConfigStackResources(ctx context.Context, ssh *common.SSHConnection, exist bool) { + var out bytes.Buffer + err := ssh.Exec(ctx, "k0s kc get configmaps,roles,rolebindings -A -l 'k0s.k0sproject.io/stack=kubelet' -oname", common.SSHStreams{Out: &out}) + + if s.NoError(err) { + if exist { + s.NotEmpty(out.String()) + } else { + s.Empty(out.String()) + } + } +} + +func getIPTablesMode(ctx context.Context, ssh *common.SSHConnection) (string, error) { + var out bytes.Buffer + err := ssh.Exec(ctx, "/var/lib/k0s/bin/iptables-save -V", common.SSHStreams{Out: &out}) + if err != nil { + return "", err + } + + version := out.String() + if parts := strings.Split(version, " "); len(parts) == 3 { + return parts[2], nil + } + + return "", fmt.Errorf("expected something like %q, got %q", "iptables-save v1.8.9 (nf_tables)", version) } // TestHA3x3Suite sets up a suite using 3 controllers for quorum, and runs various // autopilot upgrade scenarios against them. func TestHA3x3Suite(t *testing.T) { + k0sUpdateVersion := os.Getenv("K0S_UPDATE_TO_VERSION") + require.NotEmpty(t, k0sUpdateVersion, "env var not set or empty: K0S_UPDATE_TO_VERSION") + suite.Run(t, &ha3x3Suite{ common.BootlooseSuite{ ControllerCount: 3, @@ -186,5 +281,6 @@ func TestHA3x3Suite(t *testing.T) { WithLB: true, LaunchMode: common.LaunchModeOpenRC, }, + k0sUpdateVersion, }) } diff --git a/inttest/calico/calico_test.go b/inttest/calico/calico_test.go index 503edff899c8..1112cc6565ce 100644 --- a/inttest/calico/calico_test.go +++ b/inttest/calico/calico_test.go @@ -67,7 +67,7 @@ func (s *CalicoSuite) TestK0sGetsUp() { s.AssertSomeKubeSystemPods(kc) s.T().Log("waiting to see calico pods ready") - s.NoError(common.WaitForDaemonSet(s.Context(), kc, "calico-node"), "calico did not start") + s.NoError(common.WaitForDaemonSet(s.Context(), kc, "calico-node", "kube-system"), "calico did not start") s.NoError(common.WaitForPodLogs(s.Context(), kc, "kube-system")) createdTargetPod, err := kc.CoreV1().Pods("default").Create(s.Context(), &corev1.Pod{ diff --git a/inttest/cli/cli_test.go b/inttest/cli/cli_test.go index ed90a607a2b4..7ff368443658 100644 --- a/inttest/cli/cli_test.go +++ b/inttest/cli/cli_test.go @@ -108,7 +108,7 @@ func (s *CliSuite) TestK0sCliKubectlAndResetCommand() { s.AssertSomeKubeSystemPods(kc) // Wait till we see all pods running, otherwise we get into weird timing issues and high probability of leaked containerd shim processes - require.NoError(common.WaitForDaemonSet(s.Context(), kc, "kube-proxy")) + require.NoError(common.WaitForDaemonSet(s.Context(), kc, "kube-proxy", "kube-system")) require.NoError(common.WaitForKubeRouterReady(s.Context(), kc)) require.NoError(common.WaitForDeployment(s.Context(), kc, "coredns", "kube-system")) diff --git a/inttest/common/util.go b/inttest/common/util.go index 26a17b1b2f29..39ff3a84a4bc 100644 --- a/inttest/common/util.go +++ b/inttest/common/util.go @@ -60,7 +60,7 @@ func Poll(ctx context.Context, condition wait.ConditionWithContextFunc) error { // WaitForKubeRouterReady waits to see all kube-router pods healthy as long as // the context isn't canceled. func WaitForKubeRouterReady(ctx context.Context, kc *kubernetes.Clientset) error { - return WaitForDaemonSet(ctx, kc, "kube-router") + return WaitForDaemonSet(ctx, kc, "kube-router", "kube-system") } // WaitForCoreDNSReady waits to see all coredns pods healthy as long as the context isn't canceled. @@ -146,10 +146,10 @@ func WaitForNodeReadyStatus(ctx context.Context, clients kubernetes.Interface, n }) } -// WaitForDaemonset waits for the DaemonlSet with the given name to have +// WaitForDaemonSet waits for the DaemonlSet with the given name to have // as many ready replicas as defined in the spec. -func WaitForDaemonSet(ctx context.Context, kc *kubernetes.Clientset, name string) error { - return watch.DaemonSets(kc.AppsV1().DaemonSets("kube-system")). +func WaitForDaemonSet(ctx context.Context, kc *kubernetes.Clientset, name string, namespace string) error { + return watch.DaemonSets(kc.AppsV1().DaemonSets(namespace)). WithObjectName(name). WithErrorCallback(RetryWatchErrors(logfFrom(ctx))). Until(ctx, func(ds *appsv1.DaemonSet) (bool, error) { diff --git a/inttest/customports/customports_test.go b/inttest/customports/customports_test.go index 60cc476de28f..4493a573d73d 100644 --- a/inttest/customports/customports_test.go +++ b/inttest/customports/customports_test.go @@ -131,7 +131,7 @@ func (s *customPortsSuite) TestControllerJoinsWithCustomPort() { s.T().Log("waiting to see CNI pods ready") s.Require().NoError(common.WaitForKubeRouterReady(s.Context(), kc), "calico did not start") s.T().Log("waiting to see konnectivity-agent pods ready") - s.Require().NoError(common.WaitForDaemonSet(s.Context(), kc, "konnectivity-agent"), "konnectivity-agent did not start") + s.Require().NoError(common.WaitForDaemonSet(s.Context(), kc, "konnectivity-agent", "kube-system"), "konnectivity-agent did not start") s.T().Log("waiting to get logs from pods") s.Require().NoError(common.WaitForPodLogs(s.Context(), kc, "kube-system")) diff --git a/inttest/k0sctl/.gitignore b/inttest/k0sctl/.gitignore deleted file mode 100644 index b8fe557a745c..000000000000 --- a/inttest/k0sctl/.gitignore +++ /dev/null @@ -1 +0,0 @@ -k0sctl diff --git a/inttest/k0sctl/k0sctl_test.go b/inttest/k0sctl/k0sctl_test.go deleted file mode 100644 index 7dcc5d13d63e..000000000000 --- a/inttest/k0sctl/k0sctl_test.go +++ /dev/null @@ -1,229 +0,0 @@ -/* -Copyright 2022 k0s authors - -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. -*/ - -package k0sctl - -import ( - "bufio" - "bytes" - "fmt" - "io" - "net/http" - "os" - "os/exec" - "path/filepath" - "runtime" - "strings" - "sync" - "testing" - - "github.com/stretchr/testify/suite" - "golang.org/x/exp/slices" - "sigs.k8s.io/yaml" - - "github.com/k0sproject/k0s/inttest/common" -) - -const k0sctlVersion = "v0.17.1" - -type K0sctlSuite struct { - common.BootlooseSuite - k0sctlEnv []string -} - -func (s *K0sctlSuite) haveLatest() bool { - cmd := exec.Command("./k0sctl", "version") - cmd.Env = s.k0sctlEnv - out, err := cmd.Output() - if err != nil { - return false - } - return strings.Contains(string(out), fmt.Sprintf("%s\n", k0sctlVersion)) -} - -func k0sctlFilename() string { - var ext string - os := runtime.GOOS - if os == "windows" { - os = "win" - ext = ".exe" - } - - var arch string - switch runtime.GOARCH { - case "amd64": - arch = "x64" - case "arm64", "arm64be": - arch = "arm64" - case "amd64p32", "arm", "armbe": - arch = "arm" - default: - arch = runtime.GOARCH - } - return fmt.Sprintf("k0sctl-%s-%s%s", os, arch, ext) -} - -func (s *K0sctlSuite) downloadK0sctl() { - if s.haveLatest() { - s.T().Logf("Already have k0sctl %s", k0sctlVersion) - return - } - - s.T().Logf("Downloading k0sctl %s", k0sctlVersion) - - req, err := http.NewRequest("GET", fmt.Sprintf("https://github.com/k0sproject/k0sctl/releases/download/%s/%s", k0sctlVersion, k0sctlFilename()), nil) - s.Require().NoError(err) - resp, err := http.DefaultClient.Do(req) - s.Require().NoError(err) - - defer resp.Body.Close() - - f, err := os.OpenFile("k0sctl", os.O_CREATE|os.O_WRONLY, 0755) - s.Require().NoError(err) - defer f.Close() - - _, err = io.Copy(f, resp.Body) - s.Require().NoError(err) - s.T().Logf("Download of %s complete", f.Name()) -} - -func (s *K0sctlSuite) k0sctlInitConfig() map[string]interface{} { - nodes := make([]string, s.ControllerCount+s.WorkerCount) - addresses := make([]string, s.ControllerCount+s.WorkerCount) - for i := 0; i < s.ControllerCount; i++ { - nodes[i] = s.ControllerNode(i) - } - for i := 0; i < s.WorkerCount; i++ { - nodes[i+s.ControllerCount] = s.WorkerNode(i) - } - - machines, err := s.InspectMachines(nodes) - s.Require().NoError(err) - - for _, m := range machines { - port, err := m.HostPort(22) - s.Require().NoError(err) - addresses = append(addresses, fmt.Sprintf("127.0.0.1:%d", port)) - } - - ssh, err := s.SSH(s.Context(), nodes[0]) - if err != nil { - s.FailNow("ssh connection failed", "%s", err) - } - ssh.Disconnect() - args := []string{"init", "--controller-count", fmt.Sprintf("%d", s.ControllerCount), "--key-path", ssh.KeyPath, "--user", ssh.User} - args = append(args, addresses...) - cmd := exec.Command("./k0sctl", args...) - cmd.Env = s.k0sctlEnv - out, err := cmd.Output() - s.Require().NoError(err) - - cfg := map[string]interface{}{} - err = yaml.Unmarshal(out, &cfg) - - s.Require().NoError(err) - return cfg -} - -func (s *K0sctlSuite) k0sctlApply(cfg map[string]interface{}) { - plain, err := yaml.Marshal(cfg) - s.Require().NoError(err) - - cacheHome := s.T().TempDir() - s.T().Logf("Applying k0sctl config:\n%s", plain) - cmd := exec.Command("./k0sctl", "apply", "--config", "-") - cmd.Env = append(slices.Clone(s.k0sctlEnv), fmt.Sprintf("XDG_CACHE_HOME=%s", cacheHome)) - cmd.Stdin = bytes.NewReader(plain) - - stdout, err := cmd.StdoutPipe() - s.Require().NoError(err) - stderr, err := cmd.StderrPipe() - s.Require().NoError(err) - - var wg sync.WaitGroup - - wg.Add(1) - go func() { - defer wg.Done() - scanner := bufio.NewScanner(stdout) - for scanner.Scan() { - s.T().Log(scanner.Text()) - } - }() - - wg.Add(1) - go func() { - defer wg.Done() - scanner := bufio.NewScanner(stderr) - for scanner.Scan() { - s.T().Log("STDERR", scanner.Text()) - } - }() - - s.Require().NoError(cmd.Start()) - - err = cmd.Wait() - wg.Wait() - log, logErr := os.ReadFile(filepath.Join(cacheHome, "k0sctl", "k0sctl.log")) - if !s.NoError(logErr) { - log = []byte{} - } - - s.Require().NoError(err, string(log)) -} - -func (s *K0sctlSuite) TestK0sGetsUp() { - k0sBinaryPath := os.Getenv("K0S_PATH") - k0sVersion, err := exec.Command(k0sBinaryPath, "version").Output() - s.Require().NoError(err, "failed to get k0s version") - - s.downloadK0sctl() - cfg := s.k0sctlInitConfig() - - spec, ok := cfg["spec"].(map[string]interface{}) - s.Require().True(ok, "could not find spec in generated k0sctl.yaml") - hosts, ok := spec["hosts"].([]interface{}) - s.Require().True(ok, "could not find spec.hosts in generated k0sctl.yaml") - - for _, host := range hosts { - h, ok := host.(map[string]interface{}) - s.Require().True(ok, "host not what was expected") - h["uploadBinary"] = true - h["k0sBinaryPath"] = k0sBinaryPath - } - - k0s, ok := spec["k0s"].(map[string]interface{}) - s.Require().True(ok, "could not find spec.k0s in generated k0sctl.yaml") - - k0s["version"] = strings.TrimSpace(string(k0sVersion)) - - s.k0sctlApply(cfg) -} - -func TestK0sctlSuite(t *testing.T) { - s := K0sctlSuite{ - common.BootlooseSuite{ - ControllerCount: 1, - WorkerCount: 1, - }, - []string{ - fmt.Sprintf("USER=%s", t.Name()), - fmt.Sprintf("HOME=%s", t.TempDir()), - fmt.Sprintf("TMPDIR=%s", t.TempDir()), - }, - } - suite.Run(t, &s) -} diff --git a/inttest/network-conformance/network_test.go b/inttest/network-conformance/network_test.go index 04f38b81a8ed..9a08e2538de6 100644 --- a/inttest/network-conformance/network_test.go +++ b/inttest/network-conformance/network_test.go @@ -70,7 +70,7 @@ func (s *networkSuite) TestK0sGetsUp() { daemonSetName = "kube-router" } s.T().Log("waiting to see CNI pods ready") - s.NoError(common.WaitForDaemonSet(s.Context(), kc, daemonSetName), fmt.Sprintf("%s did not start", daemonSetName)) + s.NoError(common.WaitForDaemonSet(s.Context(), kc, daemonSetName, "kube-system"), fmt.Sprintf("%s did not start", daemonSetName)) restConfig, err := s.GetKubeConfig("controller0") s.Require().NoError(err) diff --git a/inttest/nllb/nllb_test.go b/inttest/nllb/nllb_test.go index 536792c29628..1c1a8db5bd91 100644 --- a/inttest/nllb/nllb_test.go +++ b/inttest/nllb/nllb_test.go @@ -195,7 +195,7 @@ func (s *suite) TestNodeLocalLoadBalancing() { _, err = clients.AppsV1().DaemonSets("kube-system").Create(ctx, &dummyDaemons, metav1.CreateOptions{}) s.Require().NoError(err) - s.NoError(common.WaitForDaemonSet(s.Context(), clients, name)) + s.NoError(common.WaitForDaemonSet(s.Context(), clients, name, "kube-system")) s.T().Logf("Dummy DaemonSet %s is ready", name) }) @@ -303,7 +303,7 @@ func (s *suite) checkClusterReadiness(ctx context.Context, clients *kubernetes.C for _, daemonSet := range []string{"kube-proxy", "konnectivity-agent"} { daemonSet := daemonSet eg.Go(func() error { - if err := common.WaitForDaemonSet(ctx, clients, daemonSet); err != nil { + if err := common.WaitForDaemonSet(ctx, clients, daemonSet, "kube-system"); err != nil { return fmt.Errorf("%s is not ready: %w", daemonSet, err) } s.T().Log(daemonSet, "is ready") diff --git a/inttest/openebs/openebs_test.go b/inttest/openebs/openebs_test.go new file mode 100644 index 000000000000..cc1333c6a989 --- /dev/null +++ b/inttest/openebs/openebs_test.go @@ -0,0 +1,211 @@ +/* +Copyright 2024 k0s authors + +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. +*/ + +package openebs + +import ( + "context" + "testing" + "time" + + "github.com/k0sproject/bootloose/pkg/config" + "github.com/k0sproject/k0s/inttest/common" + "github.com/k0sproject/k0s/pkg/kubernetes/watch" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/client-go/kubernetes" + + helmv1beta1 "github.com/k0sproject/k0s/pkg/apis/helm/v1beta1" + helmclient "github.com/k0sproject/k0s/pkg/client/clientset/typed/helm/v1beta1" + "github.com/stretchr/testify/suite" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type OpenEBSSuite struct { + common.BootlooseSuite +} + +func (s *OpenEBSSuite) TestK0sGetsUp() { + ctx := s.Context() + + s.T().Log("Start k0s with both storage and helm extensions enabled") + s.PutFile(s.ControllerNode(0), "/tmp/k0s.yaml", k0sConfigWithBoth) + s.Require().NoError(s.InitController(0, "--config=/tmp/k0s.yaml", "--disable-components=konnectivity-server,metrics-server")) + s.Require().NoError(s.RunWorkers()) + + kc, err := s.KubeClient(s.ControllerNode(0), "") + s.Require().NoError(err) + + s.Require().NoError(s.WaitForNodeReady(s.WorkerNode(0), kc)) + + // When both storage and helm are enabled, there should be no action. + // Unfortunately to check that, the best we can do is seeing that it's not + // created after a grace period + s.T().Log("Waiting 30 additional seconds of grace period to see if charts are created") + s.sleep(ctx, 30*time.Second) + + s.T().Log("Checking that the chart isn't created") + hc, err := s.HelmClient(s.ControllerNode(0), "") + s.Require().NoError(err) + _, err = hc.Charts("kube-system").Get(ctx, openEBSChart, metav1.GetOptions{}) + s.Require().True(errors.IsNotFound(err), "Chart was created when it shouldn't have been") + + // Verify Test as a storage extension + s.T().Log("Retarting k0s with only storage extension enabled") + s.Require().NoError(s.StopController(s.ControllerNode(0))) + s.PutFile(s.ControllerNode(0), "/tmp/k0s.yaml", k0sConfigWithStorage) + s.Require().NoError(s.StartController(s.ControllerNode(0))) + s.Require().NoError(s.WaitForNodeReady(s.WorkerNode(0), kc)) + + s.T().Log("Checking that the chart is created and ready") + s.Require().NoError(s.waitForChartUpdated(ctx, "3.3.0")) + s.waitForOpenEBSReady(ctx, kc) + + // Migrate to helm chart + s.T().Log("Restarting k0s without applier-manager and without extension") + s.Require().NoError(s.StopController(s.ControllerNode(0))) + s.PutFile(s.ControllerNode(0), "/tmp/k0s.yaml", k0sConfigNoExtension) + s.Require().NoError(s.InitController(0, "--config=/tmp/k0s.yaml", "--disable-components=konnectivity-server,metrics-server,applier-manager")) + s.Require().NoError(s.WaitForNodeReady(s.WorkerNode(0), kc)) + + s.T().Log("Removing Label and annotation") + c, err := hc.Charts("kube-system").Get(ctx, openEBSChart, metav1.GetOptions{}) + s.Require().NoError(err, "Error getting OpenEBS chart after removing the storage extension") + delete(c.Annotations, "k0s.k0sproject.io/stack-checksum") + delete(c.Labels, "k0s.k0sproject.io/stack") + _, err = hc.Charts("kube-system").Update(ctx, c, metav1.UpdateOptions{}) + s.Require().NoError(err, "Error removing stack applier information in OpenEBS chart") + + s.T().Log("Removing the manifest") + ssh, err := s.SSH(s.Context(), s.ControllerNode(0)) + s.Require().NoError(err) + defer ssh.Disconnect() + s.Require().NoError(ssh.Exec(ctx, "rm -f /var/lib/k0s/manifests/helm/0_helm_extension_openebs.yaml", common.SSHStreams{})) + + s.T().Log("Upgrading to 3.9.0") + c, err = hc.Charts("kube-system").Get(ctx, openEBSChart, metav1.GetOptions{}) + s.Require().NoError(err, "Error getting OpenEBS chart after removing the storage extension") + c.Spec.Version = "3.9.0" + _, err = hc.Charts("kube-system").Update(ctx, c, metav1.UpdateOptions{}) + s.Require().NoError(err, "Error upgrading OpenEBS chart") + + s.T().Log("Checking that the chart is upgrades to 3.9.0 and becomes ready") + s.Require().NoError(s.waitForChartUpdated(ctx, "3.9.0")) + s.waitForOpenEBSReady(ctx, kc) + + // Test that applier doesn't revert it back to 3.9.0 + s.T().Log("Restarting the controller with manifest applier") + s.Require().NoError(s.InitController(0, "--config=/tmp/k0s.yaml", "--disable-components=konnectivity-server,metrics-server")) + s.Require().NoError(s.WaitForNodeReady(s.WorkerNode(0), kc)) + + s.T().Log("Waiting 30 additional seconds of grace period to see if charts is deleted") + s.sleep(ctx, 30*time.Second) + + s.T().Log("Checking that the chart is still to 3.9.0 and ready") + s.Require().NoError(s.waitForChartUpdated(ctx, "3.9.0")) + s.waitForOpenEBSReady(ctx, kc) +} + +func TestOpenEBSSuite(t *testing.T) { + s := OpenEBSSuite{ + common.BootlooseSuite{ + ControllerCount: 1, + WorkerCount: 1, + ExtraVolumes: []config.Volume{{ + Type: "bind", + Source: "/run/udev", + Destination: "/run/udev", + ReadOnly: false, + }}, + }, + } + suite.Run(t, &s) +} + +func (s *OpenEBSSuite) waitForChartUpdated(ctx context.Context, version string) error { + hc, err := s.HelmClient(s.ControllerNode(0), "") + s.Require().NoError(err) + + return watch.Charts(hc.Charts("kube-system")). + WithObjectName(openEBSChart). + WithErrorCallback(common.RetryWatchErrors(s.T().Logf)). + Until(ctx, func(chart *helmv1beta1.Chart) (done bool, err error) { + // We don't need to actually deploy helm in this test + // we're just validation that the spec is correct + return chart.Spec.Version == version && + chart.Status.AppVersion == version && + chart.Status.Version == version, nil + }) + +} + +func (s *OpenEBSSuite) waitForOpenEBSReady(ctx context.Context, kc *kubernetes.Clientset) { + s.T().Log("Waiting for openEBS to be ready") + s.Require().NoError(common.WaitForDeployment(ctx, kc, "openebs-localpv-provisioner", "openebs")) + s.Require().NoError(common.WaitForDeployment(ctx, kc, "openebs-ndm-operator", "openebs")) + s.Require().NoError(common.WaitForDaemonSet(ctx, kc, "openebs-ndm", "openebs")) +} + +// HelmClient returns HelmV1beta1Client by loading the admin access config from given node +func (s *OpenEBSSuite) HelmClient(node string, k0sKubeconfigArgs ...string) (*helmclient.HelmV1beta1Client, error) { + cfg, err := s.GetKubeConfig(node, k0sKubeconfigArgs...) + if err != nil { + return nil, err + } + return helmclient.NewForConfig(cfg) +} + +func (s *OpenEBSSuite) sleep(ctx context.Context, d time.Duration) { + select { + case <-ctx.Done(): + s.Require().NoError(ctx.Err()) + case <-time.After(30 * time.Second): + } +} + +const k0sConfigWithBoth = ` +spec: + extensions: + storage: + type: openebs_local_storage + helm: + repositories: + - name: openebs-internal + url: https://openebs.github.io/charts + charts: + - name: openebs + chartname: openebs-internal/openebs + version: "3.9.0" + namespace: openebs + order: 1 + values: | + localprovisioner: + hostpathClass: + enabled: true + isDefaultClass: false +` + +const k0sConfigWithStorage = ` +spec: + extensions: + storage: + type: openebs_local_storage +` + +const k0sConfigNoExtension = ` +spec: + extensions: {} +` +const openEBSChart = "k0s-addon-chart-openebs" diff --git a/inttest/sonobuoy/README.md b/inttest/sonobuoy/README.md index 8ac01be5b058..0ce84392902b 100644 --- a/inttest/sonobuoy/README.md +++ b/inttest/sonobuoy/README.md @@ -61,7 +61,7 @@ spec: user: "ubuntu" uploadBinary: true k0s: - version: "1.29.0+k0s.0" + version: "1.29.1+k0s.0" ``` To deploy a k0s cluster on the AWS machine, run: @@ -98,9 +98,9 @@ INFO ==> Running phase: Gather host facts . . . -INFO [ssh] 3.250.52.147:22: uploading k0s binary from /home/ubuntu/.cache/k0sctl/k0s/linux/amd64/k0s-v1.29.0+k0s.0 -INFO [ssh] 63.32.21.232:22: uploading k0s binary from /home/ubuntu/.cache/k0sctl/k0s/linux/amd64/k0s-v1.29.0+k0s.0 -INFO [ssh] 54.216.71.108:22: uploading k0s binary from /home/ubuntu/.cache/k0sctl/k0s/linux/amd64/k0s-v1.29.0+k0s.0 +INFO [ssh] 3.250.52.147:22: uploading k0s binary from /home/ubuntu/.cache/k0sctl/k0s/linux/amd64/k0s-v1.29.1+k0s.0 +INFO [ssh] 63.32.21.232:22: uploading k0s binary from /home/ubuntu/.cache/k0sctl/k0s/linux/amd64/k0s-v1.29.1+k0s.0 +INFO [ssh] 54.216.71.108:22: uploading k0s binary from /home/ubuntu/.cache/k0sctl/k0s/linux/amd64/k0s-v1.29.1+k0s.0 INFO ==> Running phase: Configure k0s WARN [ssh] 63.32.21.232:22: generating default configuration INFO [ssh] 63.32.21.232:22: validating configuration @@ -124,7 +124,7 @@ INFO [ssh] 3.250.52.147:22: waiting for node to become ready INFO ==> Running phase: Release exclusive host lock INFO ==> Running phase: Disconnect from hosts INFO ==> Finished in 1m42s -INFO k0s cluster version v1.29.0+k0s.0 is now installed +INFO k0s cluster version v1.29.1+k0s.0 is now installed INFO Tip: To access the cluster you can now fetch the admin kubeconfig using: INFO k0sctl kubeconfig ``` @@ -152,7 +152,7 @@ Example Output: /home/ubuntu/k0s/inttest/bin/sonobuoy run --wait=1200 \ --mode=certified-conformance \ --plugin-env=e2e.E2E_EXTRA_ARGS="--ginkgo.v" \ - --kubernetes-version=v1.29.0 + --kubernetes-version=v1.29.1 INFO[0000] create request issued name=sonobuoy namespace= resource=namespaces INFO[0000] create request issued name=sonobuoy-serviceaccount namespace=sonobuoy resource=serviceaccounts INFO[0000] create request issued name=sonobuoy-serviceaccount-sonobuoy namespace= resource=clusterrolebindings diff --git a/inttest/update-server/html/unstable/index.yaml b/inttest/update-server/html/unstable/index.yaml index 14f08867faf0..b5311c04a48d 100644 --- a/inttest/update-server/html/unstable/index.yaml +++ b/inttest/update-server/html/unstable/index.yaml @@ -1,5 +1,5 @@ name: unstable -version: v1.29.0+k0s.0 +version: v1.29.1+k0s.0 downloadURLs: k0s: linux-amd64: ..../k0s-amd64 diff --git a/mkdocs.yml b/mkdocs.yml index b9a64756f9a6..29ec1f8be191 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -62,6 +62,7 @@ nav: - Ambassador API Gateway: examples/ambassador-ingress.md - Ceph Storage with Rook: examples/rook-ceph.md - GitOps with Flux: examples/gitops-flux.md + - OpenEBS storage: examples/openebs.md - Troubleshooting: - FAQ: FAQ.md - Common Pitfalls: troubleshooting.md diff --git a/pkg/apis/helm/v1beta1/chart_types.go b/pkg/apis/helm/v1beta1/chart_types.go index 8f2b9814e18f..b94004bc5993 100644 --- a/pkg/apis/helm/v1beta1/chart_types.go +++ b/pkg/apis/helm/v1beta1/chart_types.go @@ -70,6 +70,9 @@ type ChartStatus struct { // +kubebuilder:object:root=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +kubebuilder:subresource:status +// +genclient +// +genclient:onlyVerbs=create,delete,list,get,watch,update +// +groupName=helm.k0sproject.io // Chart is the Schema for the charts API type Chart struct { metav1.TypeMeta `json:",inline"` diff --git a/pkg/apis/helm/v1beta1/groupversion_info.go b/pkg/apis/helm/v1beta1/groupversion_info.go index d33dad9513af..3e74dd98341d 100644 --- a/pkg/apis/helm/v1beta1/groupversion_info.go +++ b/pkg/apis/helm/v1beta1/groupversion_info.go @@ -27,6 +27,9 @@ var ( // GroupVersion is group version used to register these objects GroupVersion = schema.GroupVersion{Group: helm.GroupName, Version: Version} + // SchemeGroupVersion is group version used to register these objects + SchemeGroupVersion = schema.GroupVersion{Group: helm.GroupName, Version: Version} + // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} diff --git a/pkg/apis/k0s/v1beta1/api.go b/pkg/apis/k0s/v1beta1/api.go index c70f25bc1565..b1cd075854a2 100644 --- a/pkg/apis/k0s/v1beta1/api.go +++ b/pkg/apis/k0s/v1beta1/api.go @@ -35,6 +35,9 @@ type APISpec struct { // Local address on which to bind an API Address string `json:"address"` + // The IP address for the Kubernetes API server to listen on. + BindAddress string `json:"bindAddress,omitempty"` + // The loadbalancer address (for k0s controllers running behind a loadbalancer) ExternalAddress string `json:"externalAddress,omitempty"` // Map of key-values (strings) for any extra arguments to pass down to Kubernetes api-server process @@ -57,11 +60,12 @@ func DefaultAPISpec() *APISpec { addresses, _ := iface.AllAddresses() publicAddress, _ := iface.FirstPublicAddress() return &APISpec{ - Port: defaultKasPort, - K0sAPIPort: 9443, - SANs: addresses, - Address: publicAddress, - ExtraArgs: make(map[string]string), + Port: defaultKasPort, + K0sAPIPort: 9443, + BindAddress: "0.0.0.0", + SANs: addresses, + Address: publicAddress, + ExtraArgs: make(map[string]string), } } @@ -100,10 +104,21 @@ func (a *APISpec) getExternalURIForPort(port int) string { return fmt.Sprintf("https://%s:%d", addr, port) } +// APIServerAddress returns the address the API is listening on +func (a *APISpec) APIServerAddress() string { + if a.BindAddress == "" { + return "localhost" + } + return a.BindAddress +} + // Sans return the given SANS plus all local adresses and externalAddress if given func (a *APISpec) Sans() []string { sans, _ := iface.AllAddresses() sans = append(sans, a.Address) + if a.BindAddress != "" { + sans = append(sans, a.BindAddress) + } sans = append(sans, a.SANs...) if a.ExternalAddress != "" { sans = append(sans, a.ExternalAddress) @@ -139,5 +154,10 @@ func (a *APISpec) Validate() []error { if a.ExternalAddress != "" { validateIPAddressOrDNSName(field.NewPath("externalAddress"), a.ExternalAddress) } + + if a.BindAddress != "" && !govalidator.IsIP(a.BindAddress) { + errors = append(errors, field.Invalid(field.NewPath("bindAddress"), a.BindAddress, "invalid IP address")) + } + return errors } diff --git a/pkg/apis/k0s/v1beta1/api_test.go b/pkg/apis/k0s/v1beta1/api_test.go index d7551d14baaf..52a2a3585266 100644 --- a/pkg/apis/k0s/v1beta1/api_test.go +++ b/pkg/apis/k0s/v1beta1/api_test.go @@ -35,7 +35,8 @@ func (s *APISuite) TestValidation() { s.T().Run("accepts_ipv6_as_address", func(t *testing.T) { a := APISpec{ - Address: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + Address: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + BindAddress: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", } s.Nil(a.Validate()) @@ -44,7 +45,8 @@ func (s *APISuite) TestValidation() { s.T().Run("invalid_api_address", func(t *testing.T) { a := APISpec{ - Address: "something.that.is.not.valid//(())", + Address: "something.that.is.not.valid//(())", + BindAddress: "0.0.0.0", } errors := a.Validate() @@ -56,7 +58,8 @@ func (s *APISuite) TestValidation() { s.T().Run("invalid_sans_address", func(t *testing.T) { a := APISpec{ - Address: "1.2.3.4", + Address: "1.2.3.4", + BindAddress: "0.0.0.0", SANs: []string{ "something.that.is.not.valid//(())", }, @@ -68,6 +71,18 @@ func (s *APISuite) TestValidation() { s.ErrorContains(errors[0], `sans[0]: Invalid value: "something.that.is.not.valid//(())": invalid IP address / DNS name`) } }) + + s.T().Run("invalid_api_bind_address", func(t *testing.T) { + a := APISpec{ + Address: "1.2.3.4", + BindAddress: "somehting.that.is.not.valid//(())", + } + + errors := a.Validate() + s.NotNil(errors) + s.Len(errors, 1) + s.Contains(errors[0].Error(), "invalid IP address") + }) } func TestApiSuite(t *testing.T) { diff --git a/pkg/apis/k0s/v1beta1/extensions.go b/pkg/apis/k0s/v1beta1/extensions.go index 5212d9f420ff..0ef163466fe4 100644 --- a/pkg/apis/k0s/v1beta1/extensions.go +++ b/pkg/apis/k0s/v1beta1/extensions.go @@ -28,6 +28,7 @@ var _ Validateable = (*ClusterExtensions)(nil) // ClusterExtensions specifies cluster extensions type ClusterExtensions struct { + //+kubebuilder:deprecatedversion:warning="storage is deprecated and will be ignored in 1.30. https://docs.k0sproject.io/stable/examples/openebs". Storage *StorageExtension `json:"storage"` Helm *HelmExtensions `json:"helm"` } diff --git a/pkg/apis/k0s/v1beta1/kuberouter.go b/pkg/apis/k0s/v1beta1/kuberouter.go index d3dfea6f005a..f867187ee8b5 100644 --- a/pkg/apis/k0s/v1beta1/kuberouter.go +++ b/pkg/apis/k0s/v1beta1/kuberouter.go @@ -33,9 +33,14 @@ type KubeRouter struct { // IP masquerade for traffic originating from the pod network, and destined outside of it (default: false) IPMasq bool `json:"ipMasq"` // Comma-separated list of global peer addresses + // DEPRECATED: Use extraArgs with peerRouterASNs instead PeerRouterASNs string `json:"peerRouterASNs"` // Comma-separated list of global peer ASNs + // DEPRECATED: Use extraArgs with peerRouterIPs instead PeerRouterIPs string `json:"peerRouterIPs"` + // ExtraArgs are extra arguments to pass to kube-router + // Can be also used to override the default k0s managed kube-router arguments + ExtraArgs map[string]string `json:"extraArgs,omitempty"` } // +kubebuilder:validation:Enum=Enabled;Allowed;Disabled diff --git a/pkg/apis/k0s/v1beta1/network.go b/pkg/apis/k0s/v1beta1/network.go index 506157d1da78..5244d2104bc2 100644 --- a/pkg/apis/k0s/v1beta1/network.go +++ b/pkg/apis/k0s/v1beta1/network.go @@ -36,9 +36,9 @@ type Network struct { KubeProxy *KubeProxy `json:"kubeProxy"` KubeRouter *KubeRouter `json:"kuberouter"` - // nodeLocalLoadBalancing defines the configuration options related to k0s's + // NodeLocalLoadBalancing defines the configuration options related to k0s's // node-local load balancing feature. - // NOTE: This feature is experimental, and currently unsupported on ARMv7! + // NOTE: This feature is currently unsupported on ARMv7! // +optional NodeLocalLoadBalancing *NodeLocalLoadBalancing `json:"nodeLocalLoadBalancing,omitempty"` diff --git a/pkg/apis/k0s/v1beta1/nllb.go b/pkg/apis/k0s/v1beta1/nllb.go index c93bb1b9d3e8..e5495af73c41 100644 --- a/pkg/apis/k0s/v1beta1/nllb.go +++ b/pkg/apis/k0s/v1beta1/nllb.go @@ -29,7 +29,7 @@ import ( // NodeLocalLoadBalancing defines the configuration options related to k0s's // node-local load balancing feature. -// NOTE: This feature is experimental, and currently unsupported on ARMv7! +// NOTE: This feature is currently unsupported on ARMv7! type NodeLocalLoadBalancing struct { // enabled indicates if node-local load balancing should be used to access // Kubernetes API servers from worker nodes. diff --git a/pkg/apis/k0s/v1beta1/zz_generated.deepcopy.go b/pkg/apis/k0s/v1beta1/zz_generated.deepcopy.go index 5b5e4677c447..b705f1162a96 100644 --- a/pkg/apis/k0s/v1beta1/zz_generated.deepcopy.go +++ b/pkg/apis/k0s/v1beta1/zz_generated.deepcopy.go @@ -745,6 +745,13 @@ func (in *KubeProxyIPVSConfiguration) DeepCopy() *KubeProxyIPVSConfiguration { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KubeRouter) DeepCopyInto(out *KubeRouter) { *out = *in + if in.ExtraArgs != nil { + in, out := &in.ExtraArgs, &out.ExtraArgs + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeRouter. @@ -791,7 +798,7 @@ func (in *Network) DeepCopyInto(out *Network) { if in.KubeRouter != nil { in, out := &in.KubeRouter, &out.KubeRouter *out = new(KubeRouter) - **out = **in + (*in).DeepCopyInto(*out) } if in.NodeLocalLoadBalancing != nil { in, out := &in.NodeLocalLoadBalancing, &out.NodeLocalLoadBalancing diff --git a/pkg/applier/applier.go b/pkg/applier/applier.go index 1e38474d866f..a0239070917a 100644 --- a/pkg/applier/applier.go +++ b/pkg/applier/applier.go @@ -19,7 +19,6 @@ package applier import ( "context" "fmt" - "path" "path/filepath" "github.com/k0sproject/k0s/pkg/kubernetes" @@ -35,6 +34,10 @@ import ( // manifestFilePattern is the glob pattern that all applicable manifest files need to match. const manifestFilePattern = "*.yaml" +func FindManifestFilesInDir(dir string) ([]string, error) { + return filepath.Glob(filepath.Join(dir, manifestFilePattern)) +} + // Applier manages all the "static" manifests and applies them on the k8s API type Applier struct { Name string @@ -96,7 +99,7 @@ func (a *Applier) Apply(ctx context.Context) error { return err } - files, err := filepath.Glob(path.Join(a.Dir, manifestFilePattern)) + files, err := FindManifestFilesInDir(a.Dir) if err != nil { return err } diff --git a/pkg/applier/manager.go b/pkg/applier/manager.go index 5192990b6f50..4774b75fdf44 100644 --- a/pkg/applier/manager.go +++ b/pkg/applier/manager.go @@ -61,7 +61,7 @@ func (m *Manager) Init(ctx context.Context) error { if err != nil { return fmt.Errorf("failed to create manifest bundle dir %s: %w", m.K0sVars.ManifestsDir, err) } - m.log = logrus.WithField("component", "applier-manager") + m.log = logrus.WithField("component", constant.ApplierManagerComponentName) m.stacks = make(map[string]stack) m.bundlePath = m.K0sVars.ManifestsDir @@ -97,7 +97,7 @@ func (m *Manager) Stop() error { } func (m *Manager) runWatchers(ctx context.Context) error { - log := logrus.WithField("component", "applier-manager") + log := logrus.WithField("component", constant.ApplierManagerComponentName) watcher, err := fsnotify.NewWatcher() if err != nil { diff --git a/pkg/assets/offsets_other.go b/pkg/assets/offsets_other.go new file mode 100644 index 000000000000..d1380651b709 --- /dev/null +++ b/pkg/assets/offsets_other.go @@ -0,0 +1,22 @@ +//go:build noembedbins || (!linux && !windows) + +/* +Copyright 2024 k0s authors + +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. +*/ + +package assets + +var BinData = map[string]struct{ offset, size, originalSize int64 }{} +var BinDataSize int64 diff --git a/pkg/client/clientset/clientset.go b/pkg/client/clientset/clientset.go index 9fc93d83be8e..beb51fece218 100644 --- a/pkg/client/clientset/clientset.go +++ b/pkg/client/clientset/clientset.go @@ -23,6 +23,7 @@ import ( "net/http" autopilotv1beta2 "github.com/k0sproject/k0s/pkg/client/clientset/typed/autopilot/v1beta2" + helmv1beta1 "github.com/k0sproject/k0s/pkg/client/clientset/typed/helm/v1beta1" k0sv1beta1 "github.com/k0sproject/k0s/pkg/client/clientset/typed/k0s/v1beta1" discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" @@ -32,6 +33,7 @@ import ( type Interface interface { Discovery() discovery.DiscoveryInterface AutopilotV1beta2() autopilotv1beta2.AutopilotV1beta2Interface + HelmV1beta1() helmv1beta1.HelmV1beta1Interface K0sV1beta1() k0sv1beta1.K0sV1beta1Interface } @@ -39,6 +41,7 @@ type Interface interface { type Clientset struct { *discovery.DiscoveryClient autopilotV1beta2 *autopilotv1beta2.AutopilotV1beta2Client + helmV1beta1 *helmv1beta1.HelmV1beta1Client k0sV1beta1 *k0sv1beta1.K0sV1beta1Client } @@ -47,6 +50,11 @@ func (c *Clientset) AutopilotV1beta2() autopilotv1beta2.AutopilotV1beta2Interfac return c.autopilotV1beta2 } +// HelmV1beta1 retrieves the HelmV1beta1Client +func (c *Clientset) HelmV1beta1() helmv1beta1.HelmV1beta1Interface { + return c.helmV1beta1 +} + // K0sV1beta1 retrieves the K0sV1beta1Client func (c *Clientset) K0sV1beta1() k0sv1beta1.K0sV1beta1Interface { return c.k0sV1beta1 @@ -100,6 +108,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } + cs.helmV1beta1, err = helmv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.k0sV1beta1, err = k0sv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err @@ -126,6 +138,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset { func New(c rest.Interface) *Clientset { var cs Clientset cs.autopilotV1beta2 = autopilotv1beta2.New(c) + cs.helmV1beta1 = helmv1beta1.New(c) cs.k0sV1beta1 = k0sv1beta1.New(c) cs.DiscoveryClient = discovery.NewDiscoveryClient(c) diff --git a/pkg/client/clientset/fake/clientset_generated.go b/pkg/client/clientset/fake/clientset_generated.go index c3c679a595c5..d7006bde0172 100644 --- a/pkg/client/clientset/fake/clientset_generated.go +++ b/pkg/client/clientset/fake/clientset_generated.go @@ -22,6 +22,8 @@ import ( clientset "github.com/k0sproject/k0s/pkg/client/clientset" autopilotv1beta2 "github.com/k0sproject/k0s/pkg/client/clientset/typed/autopilot/v1beta2" fakeautopilotv1beta2 "github.com/k0sproject/k0s/pkg/client/clientset/typed/autopilot/v1beta2/fake" + helmv1beta1 "github.com/k0sproject/k0s/pkg/client/clientset/typed/helm/v1beta1" + fakehelmv1beta1 "github.com/k0sproject/k0s/pkg/client/clientset/typed/helm/v1beta1/fake" k0sv1beta1 "github.com/k0sproject/k0s/pkg/client/clientset/typed/k0s/v1beta1" fakek0sv1beta1 "github.com/k0sproject/k0s/pkg/client/clientset/typed/k0s/v1beta1/fake" "k8s.io/apimachinery/pkg/runtime" @@ -86,6 +88,11 @@ func (c *Clientset) AutopilotV1beta2() autopilotv1beta2.AutopilotV1beta2Interfac return &fakeautopilotv1beta2.FakeAutopilotV1beta2{Fake: &c.Fake} } +// HelmV1beta1 retrieves the HelmV1beta1Client +func (c *Clientset) HelmV1beta1() helmv1beta1.HelmV1beta1Interface { + return &fakehelmv1beta1.FakeHelmV1beta1{Fake: &c.Fake} +} + // K0sV1beta1 retrieves the K0sV1beta1Client func (c *Clientset) K0sV1beta1() k0sv1beta1.K0sV1beta1Interface { return &fakek0sv1beta1.FakeK0sV1beta1{Fake: &c.Fake} diff --git a/pkg/client/clientset/fake/register.go b/pkg/client/clientset/fake/register.go index c8c806e50682..6a20e119b37f 100644 --- a/pkg/client/clientset/fake/register.go +++ b/pkg/client/clientset/fake/register.go @@ -20,6 +20,7 @@ package fake import ( autopilotv1beta2 "github.com/k0sproject/k0s/pkg/apis/autopilot/v1beta2" + helmv1beta1 "github.com/k0sproject/k0s/pkg/apis/helm/v1beta1" k0sv1beta1 "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" @@ -33,6 +34,7 @@ var codecs = serializer.NewCodecFactory(scheme) var localSchemeBuilder = runtime.SchemeBuilder{ autopilotv1beta2.AddToScheme, + helmv1beta1.AddToScheme, k0sv1beta1.AddToScheme, } diff --git a/pkg/client/clientset/scheme/register.go b/pkg/client/clientset/scheme/register.go index 905a4c5a426e..48310aaf7f30 100644 --- a/pkg/client/clientset/scheme/register.go +++ b/pkg/client/clientset/scheme/register.go @@ -20,6 +20,7 @@ package scheme import ( autopilotv1beta2 "github.com/k0sproject/k0s/pkg/apis/autopilot/v1beta2" + helmv1beta1 "github.com/k0sproject/k0s/pkg/apis/helm/v1beta1" k0sv1beta1 "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" @@ -33,6 +34,7 @@ var Codecs = serializer.NewCodecFactory(Scheme) var ParameterCodec = runtime.NewParameterCodec(Scheme) var localSchemeBuilder = runtime.SchemeBuilder{ autopilotv1beta2.AddToScheme, + helmv1beta1.AddToScheme, k0sv1beta1.AddToScheme, } diff --git a/pkg/client/clientset/typed/helm/v1beta1/chart.go b/pkg/client/clientset/typed/helm/v1beta1/chart.go new file mode 100644 index 000000000000..fd42e40a8478 --- /dev/null +++ b/pkg/client/clientset/typed/helm/v1beta1/chart.go @@ -0,0 +1,144 @@ +/* +Copyright k0s authors + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + "time" + + v1beta1 "github.com/k0sproject/k0s/pkg/apis/helm/v1beta1" + scheme "github.com/k0sproject/k0s/pkg/client/clientset/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ChartsGetter has a method to return a ChartInterface. +// A group's client should implement this interface. +type ChartsGetter interface { + Charts(namespace string) ChartInterface +} + +// ChartInterface has methods to work with Chart resources. +type ChartInterface interface { + Create(ctx context.Context, chart *v1beta1.Chart, opts v1.CreateOptions) (*v1beta1.Chart, error) + Update(ctx context.Context, chart *v1beta1.Chart, opts v1.UpdateOptions) (*v1beta1.Chart, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.Chart, error) + List(ctx context.Context, opts v1.ListOptions) (*v1beta1.ChartList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + ChartExpansion +} + +// charts implements ChartInterface +type charts struct { + client rest.Interface + ns string +} + +// newCharts returns a Charts +func newCharts(c *HelmV1beta1Client, namespace string) *charts { + return &charts{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the chart, and returns the corresponding chart object, and an error if there is any. +func (c *charts) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Chart, err error) { + result = &v1beta1.Chart{} + err = c.client.Get(). + Namespace(c.ns). + Resource("charts"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of Charts that match those selectors. +func (c *charts) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ChartList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta1.ChartList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("charts"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested charts. +func (c *charts) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("charts"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a chart and creates it. Returns the server's representation of the chart, and an error, if there is any. +func (c *charts) Create(ctx context.Context, chart *v1beta1.Chart, opts v1.CreateOptions) (result *v1beta1.Chart, err error) { + result = &v1beta1.Chart{} + err = c.client.Post(). + Namespace(c.ns). + Resource("charts"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(chart). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a chart and updates it. Returns the server's representation of the chart, and an error, if there is any. +func (c *charts) Update(ctx context.Context, chart *v1beta1.Chart, opts v1.UpdateOptions) (result *v1beta1.Chart, err error) { + result = &v1beta1.Chart{} + err = c.client.Put(). + Namespace(c.ns). + Resource("charts"). + Name(chart.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(chart). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the chart and deletes it. Returns an error if one occurs. +func (c *charts) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("charts"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} diff --git a/pkg/client/clientset/typed/helm/v1beta1/doc.go b/pkg/client/clientset/typed/helm/v1beta1/doc.go new file mode 100644 index 000000000000..f6d3c8a5f3fc --- /dev/null +++ b/pkg/client/clientset/typed/helm/v1beta1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright k0s authors + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1beta1 diff --git a/pkg/client/clientset/typed/helm/v1beta1/fake/doc.go b/pkg/client/clientset/typed/helm/v1beta1/fake/doc.go new file mode 100644 index 000000000000..f7926ec7323e --- /dev/null +++ b/pkg/client/clientset/typed/helm/v1beta1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright k0s authors + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/pkg/client/clientset/typed/helm/v1beta1/fake/fake_chart.go b/pkg/client/clientset/typed/helm/v1beta1/fake/fake_chart.go new file mode 100644 index 000000000000..04a9a2d08bb3 --- /dev/null +++ b/pkg/client/clientset/typed/helm/v1beta1/fake/fake_chart.go @@ -0,0 +1,109 @@ +/* +Copyright k0s authors + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1beta1 "github.com/k0sproject/k0s/pkg/apis/helm/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeCharts implements ChartInterface +type FakeCharts struct { + Fake *FakeHelmV1beta1 + ns string +} + +var chartsResource = v1beta1.SchemeGroupVersion.WithResource("charts") + +var chartsKind = v1beta1.SchemeGroupVersion.WithKind("Chart") + +// Get takes name of the chart, and returns the corresponding chart object, and an error if there is any. +func (c *FakeCharts) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.Chart, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(chartsResource, c.ns, name), &v1beta1.Chart{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Chart), err +} + +// List takes label and field selectors, and returns the list of Charts that match those selectors. +func (c *FakeCharts) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ChartList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(chartsResource, chartsKind, c.ns, opts), &v1beta1.ChartList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1beta1.ChartList{ListMeta: obj.(*v1beta1.ChartList).ListMeta} + for _, item := range obj.(*v1beta1.ChartList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested charts. +func (c *FakeCharts) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(chartsResource, c.ns, opts)) + +} + +// Create takes the representation of a chart and creates it. Returns the server's representation of the chart, and an error, if there is any. +func (c *FakeCharts) Create(ctx context.Context, chart *v1beta1.Chart, opts v1.CreateOptions) (result *v1beta1.Chart, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(chartsResource, c.ns, chart), &v1beta1.Chart{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Chart), err +} + +// Update takes the representation of a chart and updates it. Returns the server's representation of the chart, and an error, if there is any. +func (c *FakeCharts) Update(ctx context.Context, chart *v1beta1.Chart, opts v1.UpdateOptions) (result *v1beta1.Chart, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(chartsResource, c.ns, chart), &v1beta1.Chart{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.Chart), err +} + +// Delete takes name of the chart and deletes it. Returns an error if one occurs. +func (c *FakeCharts) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(chartsResource, c.ns, name, opts), &v1beta1.Chart{}) + + return err +} diff --git a/pkg/client/clientset/typed/helm/v1beta1/fake/fake_helm_client.go b/pkg/client/clientset/typed/helm/v1beta1/fake/fake_helm_client.go new file mode 100644 index 000000000000..e666ba463d8c --- /dev/null +++ b/pkg/client/clientset/typed/helm/v1beta1/fake/fake_helm_client.go @@ -0,0 +1,40 @@ +/* +Copyright k0s authors + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1beta1 "github.com/k0sproject/k0s/pkg/client/clientset/typed/helm/v1beta1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeHelmV1beta1 struct { + *testing.Fake +} + +func (c *FakeHelmV1beta1) Charts(namespace string) v1beta1.ChartInterface { + return &FakeCharts{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeHelmV1beta1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/client/clientset/typed/helm/v1beta1/generated_expansion.go b/pkg/client/clientset/typed/helm/v1beta1/generated_expansion.go new file mode 100644 index 000000000000..2af6a91299bd --- /dev/null +++ b/pkg/client/clientset/typed/helm/v1beta1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +Copyright k0s authors + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +type ChartExpansion interface{} diff --git a/pkg/client/clientset/typed/helm/v1beta1/helm_client.go b/pkg/client/clientset/typed/helm/v1beta1/helm_client.go new file mode 100644 index 000000000000..e72993bbb8fd --- /dev/null +++ b/pkg/client/clientset/typed/helm/v1beta1/helm_client.go @@ -0,0 +1,107 @@ +/* +Copyright k0s authors + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "net/http" + + v1beta1 "github.com/k0sproject/k0s/pkg/apis/helm/v1beta1" + "github.com/k0sproject/k0s/pkg/client/clientset/scheme" + rest "k8s.io/client-go/rest" +) + +type HelmV1beta1Interface interface { + RESTClient() rest.Interface + ChartsGetter +} + +// HelmV1beta1Client is used to interact with features provided by the helm.k0sproject.io group. +type HelmV1beta1Client struct { + restClient rest.Interface +} + +func (c *HelmV1beta1Client) Charts(namespace string) ChartInterface { + return newCharts(c, namespace) +} + +// NewForConfig creates a new HelmV1beta1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*HelmV1beta1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new HelmV1beta1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*HelmV1beta1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &HelmV1beta1Client{client}, nil +} + +// NewForConfigOrDie creates a new HelmV1beta1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *HelmV1beta1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new HelmV1beta1Client for the given RESTClient. +func New(c rest.Interface) *HelmV1beta1Client { + return &HelmV1beta1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1beta1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *HelmV1beta1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/component/controller/apiserver.go b/pkg/component/controller/apiserver.go index 9d2824170106..7adbc3105add 100644 --- a/pkg/component/controller/apiserver.go +++ b/pkg/component/controller/apiserver.go @@ -125,6 +125,10 @@ func (a *APIServer) Start(_ context.Context) error { "enable-admission-plugins": "NodeRestriction", } + if a.ClusterConfig.Spec.API.BindAddress != "" { + args["bind-address"] = a.ClusterConfig.Spec.API.BindAddress + } + apiAudiences := []string{"https://kubernetes.default.svc"} if a.EnableKonnectivity { @@ -229,7 +233,7 @@ func (a *APIServer) Ready() error { TLSClientConfig: tlsConfig, } client := &http.Client{Transport: tr} - resp, err := client.Get(fmt.Sprintf("https://localhost:%d/readyz?verbose", a.ClusterConfig.Spec.API.Port)) + resp, err := client.Get(fmt.Sprintf("https://%s:%d/readyz?verbose", a.ClusterConfig.Spec.API.APIServerAddress(), a.ClusterConfig.Spec.API.Port)) if err != nil { return err } diff --git a/pkg/component/controller/extensions_controller.go b/pkg/component/controller/extensions_controller.go index 41bd99f3987d..74726f7e31bb 100644 --- a/pkg/component/controller/extensions_controller.go +++ b/pkg/component/controller/extensions_controller.go @@ -86,15 +86,9 @@ func (ec *ExtensionsController) Reconcile(ctx context.Context, clusterConfig *k0 ec.L.Info("Extensions reconciliation started") defer ec.L.Info("Extensions reconciliation finished") - helmSettings := clusterConfig.Spec.Extensions.Helm - var err error - switch clusterConfig.Spec.Extensions.Storage.Type { - case k0sAPI.OpenEBSLocal: - helmSettings, err = addOpenEBSHelmExtension(helmSettings, clusterConfig.Spec.Extensions.Storage) - if err != nil { - ec.L.WithError(err).Error("Can't add openebs helm extension") - } - default: + helmSettings, err := ec.configureStorage(clusterConfig) + if err != nil { + return fmt.Errorf("cannot configure storage: %w", err) } if err := ec.reconcileHelmExtensions(helmSettings); err != nil { @@ -104,6 +98,24 @@ func (ec *ExtensionsController) Reconcile(ctx context.Context, clusterConfig *k0 return nil } +func (ec *ExtensionsController) configureStorage(clusterConfig *k0sAPI.ClusterConfig) (*k0sAPI.HelmExtensions, error) { + helmSettings := clusterConfig.Spec.Extensions.Helm + if clusterConfig.Spec.Extensions.Storage.Type != k0sAPI.OpenEBSLocal { + return helmSettings, nil + } + + for _, chart := range helmSettings.Charts { + if chart.ChartName == "openebs-internal/openebs" { + return nil, fmt.Errorf("openebs-internal/openebs is defined in spec.extensions.helm.charts and spec.extensions.storage.type is set to openebs_local_storage. https://docs.k0sproject.io/stable/examples/openebs") + } + } + helmSettings, err := addOpenEBSHelmExtension(helmSettings, clusterConfig.Spec.Extensions.Storage) + if err != nil { + return nil, fmt.Errorf("can't add openebs helm extension") + } + return helmSettings, nil +} + func addOpenEBSHelmExtension(helmSpec *k0sAPI.HelmExtensions, storageExtension *k0sAPI.StorageExtension) (*k0sAPI.HelmExtensions, error) { openEBSValues := map[string]interface{}{ "localprovisioner": map[string]interface{}{ diff --git a/pkg/component/controller/extensions_controller_test.go b/pkg/component/controller/extensions_controller_test.go index 9027da4c579e..44cbd4388b25 100644 --- a/pkg/component/controller/extensions_controller_test.go +++ b/pkg/component/controller/extensions_controller_test.go @@ -20,6 +20,7 @@ import ( "testing" "github.com/k0sproject/k0s/pkg/apis/helm/v1beta1" + k0sv1beta1 "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1" "github.com/stretchr/testify/assert" ) @@ -128,9 +129,72 @@ func TestChartNeedsUpgrade(t *testing.T) { cr := new(ChartReconciler) for _, tc := range testCases { - t.Run("", func(t *testing.T) { + t.Run(tc.description, func(t *testing.T) { actual := cr.chartNeedsUpgrade(tc.chart) assert.Equal(t, tc.expected, actual) }) } } + +func addHelmExtension(config *k0sv1beta1.ClusterConfig) *k0sv1beta1.ClusterConfig { + config.Spec.Extensions.Storage.Type = k0sv1beta1.OpenEBSLocal + return config +} + +func addStorageExtension(config *k0sv1beta1.ClusterConfig) *k0sv1beta1.ClusterConfig { + config.Spec.Extensions.Helm, _ = addOpenEBSHelmExtension(config.Spec.Extensions.Helm, config.Spec.Extensions.Storage) + return config +} + +func TestConfigureStorage(t *testing.T) { + var testCases = []struct { + description string + clusterConfig *k0sv1beta1.ClusterConfig + expectedErr bool + expectedOpenEBS bool + }{ + { + "no_openebs", + k0sv1beta1.DefaultClusterConfig(), + false, + false, + }, + { + "openebs_helm_extension", + addHelmExtension(k0sv1beta1.DefaultClusterConfig()), + false, + true, + }, + { + "openebs_storage_extension", + addStorageExtension(k0sv1beta1.DefaultClusterConfig()), + false, + true, + }, + { + "openebs_both", + addStorageExtension(addHelmExtension(k0sv1beta1.DefaultClusterConfig())), + true, + false, + }, + } + + for _, tc := range testCases { + t.Run(tc.description, func(t *testing.T) { + ec := ExtensionsController{} + helmSettings, err := ec.configureStorage(tc.clusterConfig) + + if tc.expectedErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + + if tc.expectedOpenEBS { + assert.Equal(t, 1, len(helmSettings.Charts)) + assert.Equal(t, "openebs", helmSettings.Charts[0].Name) + } + }) + } + +} diff --git a/pkg/component/controller/kubeletconfig.go b/pkg/component/controller/kubeletconfig.go index 449093613d2c..44b2532c58ee 100644 --- a/pkg/component/controller/kubeletconfig.go +++ b/pkg/component/controller/kubeletconfig.go @@ -17,315 +17,77 @@ limitations under the License. package controller import ( - "bytes" "context" - "crypto/tls" - "encoding/json" - "fmt" - "io" - "path" + "errors" + "os" "path/filepath" - "reflect" - - "github.com/imdario/mergo" - "github.com/k0sproject/k0s/pkg/component/manager" - "github.com/k0sproject/k0s/pkg/config" - k8sutil "github.com/k0sproject/k0s/pkg/kubernetes" - "github.com/sirupsen/logrus" - "k8s.io/apimachinery/pkg/api/errors" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/yaml" "github.com/k0sproject/k0s/internal/pkg/dir" "github.com/k0sproject/k0s/internal/pkg/file" - "github.com/k0sproject/k0s/internal/pkg/templatewriter" - "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1" + "github.com/k0sproject/k0s/pkg/applier" + "github.com/k0sproject/k0s/pkg/component/manager" + "github.com/k0sproject/k0s/pkg/config" "github.com/k0sproject/k0s/pkg/constant" + + "github.com/sirupsen/logrus" ) // Dummy checks so we catch easily if we miss some interface implementation -var _ manager.Reconciler = (*KubeletConfig)(nil) var _ manager.Component = (*KubeletConfig)(nil) -// KubeletConfig is the reconciler for generic kubelet configs +// KubeletConfig is the old, replaced reconciler for generic kubelet configs. type KubeletConfig struct { - log logrus.FieldLogger - - kubeClientFactory k8sutil.ClientFactoryInterface - k0sVars *config.CfgVars - previousProfiles v1beta1.WorkerProfiles - nodeConfig *v1beta1.ClusterConfig -} - -// NewKubeletConfig creates new KubeletConfig reconciler -func NewKubeletConfig(k0sVars *config.CfgVars, clientFactory k8sutil.ClientFactoryInterface, nodeConfig *v1beta1.ClusterConfig) *KubeletConfig { - return &KubeletConfig{ - log: logrus.WithFields(logrus.Fields{"component": "kubeletconfig"}), - - kubeClientFactory: clientFactory, - k0sVars: k0sVars, - nodeConfig: nodeConfig, - } -} - -// Init does nothing -func (k *KubeletConfig) Init(_ context.Context) error { - return nil -} - -// Stop does nothign, nothing actually running -func (k *KubeletConfig) Stop() error { - return nil -} - -// Run dumps the needed manifest objects -func (k *KubeletConfig) Start(_ context.Context) error { - - return nil + k0sVars *config.CfgVars } -// Reconcile detects changes in configuration and applies them to the component -func (k *KubeletConfig) Reconcile(ctx context.Context, clusterSpec *v1beta1.ClusterConfig) error { - k.log.Debug("reconcile method called for: KubeletConfig") - // Check if we actually need to reconcile anything - defaultProfilesExist, err := k.defaultProfilesExist(ctx) - if err != nil { - return err - } - if defaultProfilesExist && reflect.DeepEqual(k.previousProfiles, clusterSpec.Spec.WorkerProfiles) { - k.log.Debugf("default profiles exist and no change in user specified profiles, nothing to reconcile") - return nil - } - - manifest, err := k.createProfiles(clusterSpec) - if err != nil { - return fmt.Errorf("failed to build final manifest: %v", err) - } - - if err := k.save(manifest.Bytes()); err != nil { - return fmt.Errorf("can't write manifest with config maps: %v", err) - } - k.previousProfiles = clusterSpec.Spec.WorkerProfiles - - return nil +// NewKubeletConfig creates a new KubeletConfig reconciler that merely +// uninstalls itself, if it still exists. +func NewKubeletConfig(k0sVars *config.CfgVars) *KubeletConfig { + return &KubeletConfig{k0sVars} } -func (k *KubeletConfig) defaultProfilesExist(ctx context.Context) (bool, error) { - c, err := k.kubeClientFactory.GetClient() - if err != nil { - return false, err - } - defaultProfileName := formatProfileName("default") - _, err = c.CoreV1().ConfigMaps("kube-system").Get(ctx, defaultProfileName, v1.GetOptions{}) - if err != nil && errors.IsNotFound(err) { - return false, nil - } else if err != nil { - return false, err - } - return true, nil -} - -func (k *KubeletConfig) createProfiles(clusterSpec *v1beta1.ClusterConfig) (*bytes.Buffer, error) { - dnsAddress, err := k.nodeConfig.Spec.Network.DNSAddress() - if err != nil { - return nil, fmt.Errorf("failed to get DNS address for kubelet config: %v", err) - } - manifest := bytes.NewBuffer([]byte{}) - defaultProfile := getDefaultProfile(dnsAddress, clusterSpec.Spec.Network.ClusterDomain) - defaultProfile["cgroupsPerQOS"] = true - - winDefaultProfile := getDefaultProfile(dnsAddress, clusterSpec.Spec.Network.ClusterDomain) - winDefaultProfile["cgroupsPerQOS"] = false +func (k *KubeletConfig) Init(context.Context) error { + kubeletDir := filepath.Join(k.k0sVars.ManifestsDir, "kubelet") - if err := k.writeConfigMapWithProfile(manifest, "default", defaultProfile); err != nil { - return nil, fmt.Errorf("can't write manifest for default profile config map: %v", err) - } - if err := k.writeConfigMapWithProfile(manifest, "default-windows", winDefaultProfile); err != nil { - return nil, fmt.Errorf("can't write manifest for default profile config map: %v", err) - } - configMapNames := []string{ - formatProfileName("default"), - formatProfileName("default-windows"), - } - for _, profile := range clusterSpec.Spec.WorkerProfiles { - profileConfig := getDefaultProfile(dnsAddress, clusterSpec.Spec.Network.ClusterDomain) - - var workerValues unstructuredYamlObject - err := json.Unmarshal(profile.Config.Raw, &workerValues) - if err != nil { - return nil, fmt.Errorf("failed to decode worker profile values: %v", err) - } - merged, err := mergeProfiles(&profileConfig, workerValues) - if err != nil { - return nil, fmt.Errorf("can't merge profile `%s` with default profile: %v", profile.Name, err) - } - - if err := k.writeConfigMapWithProfile(manifest, - profile.Name, - merged); err != nil { - return nil, fmt.Errorf("can't write manifest for profile config map: %v", err) - } - configMapNames = append(configMapNames, formatProfileName(profile.Name)) - } - if err := k.writeRbacRoleBindings(manifest, configMapNames); err != nil { - return nil, fmt.Errorf("can't write manifest for rbac bindings: %v", err) - } - return manifest, nil -} - -func (k *KubeletConfig) save(data []byte) error { - kubeletDir := path.Join(k.k0sVars.ManifestsDir, "kubelet") err := dir.Init(kubeletDir, constant.ManifestsDirMode) if err != nil { return err } - filePath := filepath.Join(kubeletDir, "kubelet-config.yaml") - if err := file.WriteContentAtomically(filePath, data, constant.CertMode); err != nil { - return fmt.Errorf("can't write kubelet configuration config map: %v", err) - } - - deprecationNotice := []byte(`The kubelet-config component has been replaced by the worker-config component in k0s 1.26. -It is scheduled for removal in k0s 1.27. -`) - - if err := file.WriteContentAtomically(filepath.Join(kubeletDir, "deprecated.txt"), deprecationNotice, constant.CertMode); err != nil { - k.log.WithError(err).Warn("Failed to write deprecation notice") - } - - return nil -} - -type unstructuredYamlObject map[string]interface{} - -func (k *KubeletConfig) writeConfigMapWithProfile(w io.Writer, name string, profile unstructuredYamlObject) error { - profileYaml, err := yaml.Marshal(profile) - if err != nil { - return err - } - tw := templatewriter.TemplateWriter{ - Name: "kubelet-config", - Template: kubeletConfigsManifestTemplate, - Data: struct { - Name string - KubeletConfigYAML string - }{ - Name: formatProfileName(name), - KubeletConfigYAML: string(profileYaml), - }, - } - return tw.WriteToBuffer(w) -} - -func formatProfileName(name string) string { - return fmt.Sprintf("kubelet-config-%s-%s", name, constant.KubernetesMajorMinorVersion) -} - -func (k *KubeletConfig) writeRbacRoleBindings(w io.Writer, configMapNames []string) error { - tw := templatewriter.TemplateWriter{ - Name: "kubelet-config-rbac", - Template: rbacRoleAndBindingsManifestTemplate, - Data: struct { - ConfigMapNames []string - }{ - ConfigMapNames: configMapNames, - }, + var errs []error + + // Iterate over all files that would be read by the manifest applier and + // rename them, so they won't be applied anymore. + if manifests, err := applier.FindManifestFilesInDir(kubeletDir); err != nil { + errs = append(errs, err) + } else { + for _, manifest := range manifests { + // Reserve a new unique file name to preserve the file's contents. + f, err := os.CreateTemp(filepath.Dir(manifest), filepath.Base(manifest)+".*.removed") + if err != nil { + errs = append(errs, err) + continue + } + errs = append(errs, f.Close()) + + // Rename the file, overwriting the target. + errs = append(errs, os.Rename(manifest, f.Name())) + } } - return tw.WriteToBuffer(w) -} + const removalNotice = `The kubelet-config component has been replaced by the worker-config component in k0s 1.26. +It has been removed in k0s 1.29. +` -func getDefaultProfile(dnsAddress string, clusterDomain string) unstructuredYamlObject { - // the motivation to keep it like this instead of the yaml template: - // - it's easier to merge programatically defined structure - // - apart from map[string]interface there is no good way to define free-form mapping + errs = append(errs, file.WriteContentAtomically(filepath.Join(kubeletDir, "removed.txt"), []byte(removalNotice), constant.CertMode)) - cipherSuites := make([]string, len(constant.AllowedTLS12CipherSuiteIDs)) - for i, cipherSuite := range constant.AllowedTLS12CipherSuiteIDs { - cipherSuites[i] = tls.CipherSuiteName(cipherSuite) + // Remove a potential deprecation notice + if err := os.Remove(filepath.Join(kubeletDir, "deprecated.txt")); err != nil && !errors.Is(err, os.ErrNotExist) { + logrus.WithField("component", "kubelet-config").WithError(err).Warn("Failed to delete deprecation notice") } - // for the authentication.x509.clientCAFile and volumePluginDir we want to use later binding so we put template placeholder instead of actual value there - profile := unstructuredYamlObject{ - "apiVersion": "kubelet.config.k8s.io/v1beta1", - "kind": "KubeletConfiguration", - "clusterDNS": []string{dnsAddress}, - "clusterDomain": clusterDomain, - "tlsCipherSuites": cipherSuites, - "failSwapOn": false, - "rotateCertificates": true, - "serverTLSBootstrap": true, - "eventRecordQPS": 0, - } - return profile + return errors.Join(errs...) } -const kubeletConfigsManifestTemplate = `--- -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{.Name}} - namespace: kube-system - labels: - k0s.k0sproject.io/deprecated-since: "1.26" - annotations: - k0s.k0sproject.io/deprecated: | - The kubelet-config component has been replaced by the worker-config component in k0s 1.26. - It is scheduled for removal in k0s 1.27. -data: - kubelet: | -{{ .KubeletConfigYAML | nindent 4 }} -` - -const rbacRoleAndBindingsManifestTemplate = `--- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: system:bootstrappers:kubelet-configmaps - namespace: kube-system - labels: - k0s.k0sproject.io/deprecated-since: "1.26" - annotations: - k0s.k0sproject.io/deprecated: | - The kubelet-config component has been replaced by the worker-config component in k0s 1.26. - It is scheduled for removal in k0s 1.27. -rules: -- apiGroups: [""] - resources: ["configmaps"] - resourceNames: -{{- range .ConfigMapNames }} - - "{{ . -}}" -{{ end }} - verbs: ["get"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: system:bootstrappers:kubelet-configmaps - namespace: kube-system - labels: - k0s.k0sproject.io/deprecated-since: "1.26" - annotations: - k0s.k0sproject.io/deprecated: | - The kubelet-config component has been replaced by the worker-config component in k0s 1.26. - It is scheduled for removal in k0s 1.27. -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: system:bootstrappers:kubelet-configmaps -subjects: - - apiGroup: rbac.authorization.k8s.io - kind: Group - name: system:bootstrappers - - apiGroup: rbac.authorization.k8s.io - kind: Group - name: system:nodes -` - -// mergeInto merges b to the a, a is modified inplace -func mergeProfiles(a *unstructuredYamlObject, b unstructuredYamlObject) (unstructuredYamlObject, error) { - if err := mergo.Merge(a, b, mergo.WithOverride); err != nil { - return nil, err - } - return *a, nil -} +func (k *KubeletConfig) Start(context.Context) error { return nil } +func (k *KubeletConfig) Stop() error { return nil } diff --git a/pkg/component/controller/kubeletconfig_test.go b/pkg/component/controller/kubeletconfig_test.go index fa337b01a04d..7a9d80c3e7e5 100644 --- a/pkg/component/controller/kubeletconfig_test.go +++ b/pkg/component/controller/kubeletconfig_test.go @@ -14,186 +14,80 @@ See the License for the specific language governing permissions and limitations under the License. */ -package controller +package controller_test import ( - "encoding/json" - "strings" + "context" + "os" + "path/filepath" + "syscall" "testing" - "github.com/k0sproject/k0s/internal/testutil" - "k8s.io/apimachinery/pkg/runtime" - - helmv1beta1 "github.com/k0sproject/k0s/pkg/apis/helm/v1beta1" - "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1" + "github.com/k0sproject/k0s/pkg/applier" + "github.com/k0sproject/k0s/pkg/component/controller" "github.com/k0sproject/k0s/pkg/config" - + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "sigs.k8s.io/yaml" ) -func Test_KubeletConfig(t *testing.T) { - cfg := v1beta1.DefaultClusterConfig() - k0sVars, err := config.NewCfgVars(nil, t.TempDir()) +func Test_KubeletConfig_Nonexistent(t *testing.T) { + tmp := t.TempDir() + dir := filepath.Join(tmp, "manifests", "kubelet") + + k0sVars, err := config.NewCfgVars(nil, tmp) require.NoError(t, err) - dnsAddr, _ := cfg.Spec.Network.DNSAddress() - t.Run("default_profile_only", func(t *testing.T) { - k := NewKubeletConfig(k0sVars, testutil.NewFakeClientFactory(), cfg) - - t.Log("starting to run...") - buf, err := k.createProfiles(cfg) - require.NoError(t, err) - if err != nil { - t.FailNow() - } - manifestYamls := strings.Split(strings.TrimSuffix(buf.String(), "---"), "---")[1:] - t.Run("output_must_have_3_manifests", func(t *testing.T) { - require.Len(t, manifestYamls, 4, "Must have exactly 4 generated manifests per profile") - requireConfigMap(t, manifestYamls[0], "kubelet-config-default-1.29") - requireConfigMap(t, manifestYamls[1], "kubelet-config-default-windows-1.29") - requireRole(t, manifestYamls[2], []string{ - formatProfileName("default"), - formatProfileName("default-windows"), - }) - requireRoleBinding(t, manifestYamls[3]) - }) - }) - t.Run("default_profile_must_pass_down_cluster_domain", func(t *testing.T) { - profile := getDefaultProfile(dnsAddr, "cluster.local.custom") - require.Equal(t, string( - "cluster.local.custom", - ), profile["clusterDomain"]) - }) - t.Run("with_user_provided_profiles", func(t *testing.T) { - k, cfgWithUserProvidedProfiles := defaultConfigWithUserProvidedProfiles(t) - buf, err := k.createProfiles(cfgWithUserProvidedProfiles) - require.NoError(t, err) - manifestYamls := strings.Split(strings.TrimSuffix(buf.String(), "---"), "---")[1:] - expectedManifestsCount := 6 - require.Len(t, manifestYamls, expectedManifestsCount, "Must have exactly 6 generated manifests per profile") - - t.Run("final_output_must_have_manifests_for_profiles", func(t *testing.T) { - // check that each profile has config map, role and role binding - var resourceNamesForRole []string - for idx, profileName := range []string{"default", "default-windows", "profile_XXX", "profile_YYY"} { - fullName := "kubelet-config-" + profileName + "-1.29" - resourceNamesForRole = append(resourceNamesForRole, formatProfileName(profileName)) - requireConfigMap(t, manifestYamls[idx], fullName) - } - requireRole(t, manifestYamls[len(resourceNamesForRole)], resourceNamesForRole) - }) - t.Run("user_profile_X_must_be_merged_with_default_profile", func(t *testing.T) { - profileXXX := struct { - Data map[string]string `yaml:"data"` - }{} - - profileYYY := struct { - Data map[string]string `yaml:"data"` - }{} - - require.NoError(t, yaml.Unmarshal([]byte(manifestYamls[2]), &profileXXX)) - require.NoError(t, yaml.Unmarshal([]byte(manifestYamls[3]), &profileYYY)) - - // manually apple the same changes to default config and check that there is no diff - defaultProfileKubeletConfig := getDefaultProfile(dnsAddr, "cluster.local") - defaultProfileKubeletConfig["authentication"] = map[string]interface{}{ - "anonymous": map[string]interface{}{ - "enabled": false, - }, - } - defaultWithChangesXXX, err := yaml.Marshal(defaultProfileKubeletConfig) - require.NoError(t, err) - - defaultProfileKubeletConfig = getDefaultProfile(dnsAddr, "cluster.local") - defaultProfileKubeletConfig["authentication"] = map[string]interface{}{ - "webhook": map[string]interface{}{ - "cacheTTL": "15s", - }, - } - defaultWithChangesYYY, err := yaml.Marshal(defaultProfileKubeletConfig) - - require.NoError(t, err) - - require.YAMLEq(t, string(defaultWithChangesXXX), profileXXX.Data["kubelet"]) - require.YAMLEq(t, string(defaultWithChangesYYY), profileYYY.Data["kubelet"]) - }) - }) + + underTest := controller.NewKubeletConfig(k0sVars) + assert.NoError(t, underTest.Init(context.TODO())) + assert.DirExists(t, dir, "Kubelet manifest directory wasn't created") } -func defaultConfigWithUserProvidedProfiles(t *testing.T) (*KubeletConfig, *v1beta1.ClusterConfig) { - cfg := v1beta1.DefaultClusterConfig() - k0sVars, err := config.NewCfgVars(nil, t.TempDir()) +func Test_KubeletConfig_ManifestDirObstructed(t *testing.T) { + tmp := t.TempDir() + dir := filepath.Join(tmp, "manifests") + require.NoError(t, os.WriteFile(dir, []byte("obstructed"), 0644)) + + k0sVars, err := config.NewCfgVars(nil, tmp) require.NoError(t, err) - k := NewKubeletConfig(k0sVars, testutil.NewFakeClientFactory(), cfg) - - cfgProfileX := map[string]interface{}{ - "authentication": map[string]interface{}{ - "anonymous": map[string]interface{}{ - "enabled": false, - }, - }, - } - wcx, err := json.Marshal(cfgProfileX) - if err != nil { - t.Fatal(err) - } - cfg.Spec.WorkerProfiles = append(cfg.Spec.WorkerProfiles, - v1beta1.WorkerProfile{ - Name: "profile_XXX", - Config: &runtime.RawExtension{Raw: wcx}, - }, - ) - - cfgProfileY := map[string]interface{}{ - "authentication": map[string]interface{}{ - "webhook": map[string]interface{}{ - "cacheTTL": "15s", - }, - }, - } - wcy, err := json.Marshal(cfgProfileY) - if err != nil { - t.Fatal(err) - } + underTest := controller.NewKubeletConfig(k0sVars) + err = underTest.Init(context.TODO()) - cfg.Spec.WorkerProfiles = append(cfg.Spec.WorkerProfiles, - v1beta1.WorkerProfile{ - Name: "profile_YYY", - Config: &runtime.RawExtension{Raw: wcy}, - }, - ) - return k, cfg + if pathErr := (*os.PathError)(nil); assert.ErrorAs(t, err, &pathErr) { + assert.Equal(t, pathErr.Path, dir) + assert.Equal(t, pathErr.Op, "mkdir") + assert.Equal(t, pathErr.Err, syscall.ENOTDIR) + } } -func requireConfigMap(t *testing.T, spec string, name string) { - dst := map[string]interface{}{} - require.NoError(t, yaml.Unmarshal([]byte(spec), &dst)) - dst = helmv1beta1.CleanUpGenericMap(dst) - require.Equal(t, "ConfigMap", dst["kind"]) - require.Equal(t, name, dst["metadata"].(map[string]interface{})["name"]) - spec, foundSpec := dst["data"].(map[string]interface{})["kubelet"].(string) - require.True(t, foundSpec, "kubelet config map must have embedded kubelet config") - require.True(t, strings.TrimSpace(spec) != "", "kubelet config map must have non-empty embedded kubelet config") -} +func Test_KubeletConfig_RenamesManifestFiles(t *testing.T) { + tmp := t.TempDir() + dir := filepath.Join(tmp, "manifests", "kubelet") + require.NoError(t, os.MkdirAll(dir, 0755)) + require.NoError(t, os.WriteFile(filepath.Join(dir, "deprecated.txt"), nil, 0644)) + require.NoError(t, os.WriteFile(filepath.Join(dir, "manifest.yaml"), nil, 0644)) + + foundFiles, err := applier.FindManifestFilesInDir(dir) + require.NoError(t, err, "Failed to find manifests in kubelet dir") + require.NotEmpty(t, foundFiles, "No manifests in kubelet dir; did the applier change its file patterns?") + + k0sVars, err := config.NewCfgVars(nil, tmp) + require.NoError(t, err) -func requireRole(t *testing.T, spec string, expectedResourceNames []string) { - dst := map[string]interface{}{} - require.NoError(t, yaml.Unmarshal([]byte(spec), &dst)) - dst = helmv1beta1.CleanUpGenericMap(dst) - require.Equal(t, "Role", dst["kind"]) - require.Equal(t, "system:bootstrappers:kubelet-configmaps", dst["metadata"].(map[string]interface{})["name"]) - var currentResourceNames []string - for _, el := range dst["rules"].([]interface{})[0].(map[string]interface{})["resourceNames"].([]interface{}) { - currentResourceNames = append(currentResourceNames, el.(string)) + underTest := controller.NewKubeletConfig(k0sVars) + assert.NoError(t, underTest.Init(context.TODO())) + + assert.NoFileExists(t, filepath.Join(dir, "deprecated.txt")) + assert.FileExists(t, filepath.Join(dir, "removed.txt")) + if matches, err := filepath.Glob(filepath.Join(dir, "manifest.yaml.*.removed")); assert.NoError(t, err) { + assert.Len(t, matches, 1, "Expected a single removed manifest file") + } + if entries, err := os.ReadDir(dir); assert.NoError(t, err) { + assert.Len(t, entries, 2, "Expected exactly two files in kubelet folder") } - require.Equal(t, expectedResourceNames, currentResourceNames) -} -func requireRoleBinding(t *testing.T, spec string) { - dst := map[string]interface{}{} - require.NoError(t, yaml.Unmarshal([]byte(spec), &dst)) - dst = helmv1beta1.CleanUpGenericMap(dst) - require.Equal(t, "RoleBinding", dst["kind"]) - require.Equal(t, "system:bootstrappers:kubelet-configmaps", dst["metadata"].(map[string]interface{})["name"]) + foundFiles, err = applier.FindManifestFilesInDir(dir) + if assert.NoError(t, err, "Failed to find manifests in kubelet dir") { + assert.Empty(t, foundFiles, "Some manifests were still found in kubelet dir") + } } diff --git a/pkg/component/controller/kuberouter.go b/pkg/component/controller/kuberouter.go index 4c9de39f1023..83c0331202ed 100644 --- a/pkg/component/controller/kuberouter.go +++ b/pkg/component/controller/kuberouter.go @@ -20,7 +20,9 @@ import ( "bytes" "context" "fmt" + "reflect" + "github.com/k0sproject/k0s/internal/pkg/stringmap" "github.com/k0sproject/k0s/internal/pkg/templatewriter" "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1" "github.com/k0sproject/k0s/pkg/component/manager" @@ -49,12 +51,12 @@ type kubeRouterConfig struct { MetricsPort int CNIInstallerImage string CNIImage string - GlobalHairpin bool CNIHairpin bool IPMasq bool PeerRouterIPs string PeerRouterASNs string PullPolicy string + Args []string } // NewKubeRouter creates new KubeRouter reconciler component @@ -73,25 +75,26 @@ func (k *KubeRouter) Init(_ context.Context) error { return nil } // Stop no-op as nothing running func (k *KubeRouter) Stop() error { return nil } -func getHairpinConfig(cfg *kubeRouterConfig, krc *v1beta1.KubeRouter) { +func getHairpinConfig(krc *v1beta1.KubeRouter) (cniHairpin bool, globalHairpin bool) { // Configure hairpin switch krc.Hairpin { case v1beta1.HairpinUndefined: // If Hairpin is undefined, then we honor HairpinMode if krc.HairpinMode { - cfg.CNIHairpin = true - cfg.GlobalHairpin = true + cniHairpin = true + globalHairpin = true } case v1beta1.HairpinDisabled: - cfg.CNIHairpin = false - cfg.GlobalHairpin = false + cniHairpin = false + globalHairpin = false case v1beta1.HairpinAllowed: - cfg.CNIHairpin = true - cfg.GlobalHairpin = false + cniHairpin = true + globalHairpin = false case v1beta1.HairpinEnabled: - cfg.CNIHairpin = true - cfg.GlobalHairpin = true + cniHairpin = true + globalHairpin = true } + return } // Reconcile detects changes in configuration and applies them to the component @@ -106,20 +109,44 @@ func (k *KubeRouter) Reconcile(_ context.Context, clusterConfig *v1beta1.Cluster return fmt.Errorf("cannot change CNI provider from %s to %s", existingCNI, constant.CNIProviderKubeRouter) } + cniHairpin, globalHairpin := getHairpinConfig(clusterConfig.Spec.Network.KubeRouter) + + args := stringmap.StringMap{ + // k0s set default args + "run-router": "true", + "run-firewall": "true", + "run-service-proxy": "false", + "bgp-graceful-restart": "true", + // Args from config values + "auto-mtu": fmt.Sprintf("%t", clusterConfig.Spec.Network.KubeRouter.AutoMTU), + "metrics-port": fmt.Sprintf("%d", clusterConfig.Spec.Network.KubeRouter.MetricsPort), + "hairpin-mode": fmt.Sprintf("%t", globalHairpin), + } + + // We should not add peering flags if the values are empty + if clusterConfig.Spec.Network.KubeRouter.PeerRouterASNs != "" { + args["peer-router-asns"] = clusterConfig.Spec.Network.KubeRouter.PeerRouterASNs + } + if clusterConfig.Spec.Network.KubeRouter.PeerRouterIPs != "" { + args["peer-router-ips"] = clusterConfig.Spec.Network.KubeRouter.PeerRouterIPs + } + + // Override or add args from config + args.Merge(clusterConfig.Spec.Network.KubeRouter.ExtraArgs) + cfg := kubeRouterConfig{ AutoMTU: clusterConfig.Spec.Network.KubeRouter.AutoMTU, MTU: clusterConfig.Spec.Network.KubeRouter.MTU, MetricsPort: clusterConfig.Spec.Network.KubeRouter.MetricsPort, - PeerRouterIPs: clusterConfig.Spec.Network.KubeRouter.PeerRouterIPs, - PeerRouterASNs: clusterConfig.Spec.Network.KubeRouter.PeerRouterASNs, IPMasq: clusterConfig.Spec.Network.KubeRouter.IPMasq, + CNIHairpin: cniHairpin, CNIImage: clusterConfig.Spec.Images.KubeRouter.CNI.URI(), CNIInstallerImage: clusterConfig.Spec.Images.KubeRouter.CNIInstaller.URI(), PullPolicy: clusterConfig.Spec.Images.DefaultPullPolicy, + Args: args.ToDashedArgs(), } - getHairpinConfig(&cfg, clusterConfig.Spec.Network.KubeRouter) - if cfg == k.previousConfig { + if reflect.DeepEqual(k.previousConfig, cfg) { k.log.Info("config matches with previous, not reconciling anything") return nil } @@ -278,20 +305,8 @@ spec: image: {{ .CNIImage }} imagePullPolicy: {{ .PullPolicy }} args: - - "--run-router=true" - - "--run-firewall=true" - - "--run-service-proxy=false" - - "--bgp-graceful-restart=true" - - "--metrics-port={{ .MetricsPort }}" - - "--hairpin-mode={{ .GlobalHairpin }}" - {{- if not .AutoMTU }} - - "--auto-mtu=false" - {{- end }} - {{- if .PeerRouterIPs }} - - "--peer-router-ips={{ .PeerRouterIPs }}" - {{- end }} - {{- if .PeerRouterASNs }} - - "--peer-router-asns={{ .PeerRouterASNs }}" + {{- range .Args }} + - {{ . | printf "%q" }} {{- end }} env: - name: NODE_NAME diff --git a/pkg/component/controller/kuberouter_test.go b/pkg/component/controller/kuberouter_test.go index ac5f15e2ad3b..0d254aff2684 100644 --- a/pkg/component/controller/kuberouter_test.go +++ b/pkg/component/controller/kuberouter_test.go @@ -77,40 +77,50 @@ func TestKubeRouterConfig(t *testing.T) { } type hairpinTest struct { - krc *v1beta1.KubeRouter - result kubeRouterConfig + krc *v1beta1.KubeRouter + resultCNIHairpin bool + resultGlobalHairpin bool } func TestGetHairpinConfig(t *testing.T) { hairpinTests := []hairpinTest{ { - krc: &v1beta1.KubeRouter{Hairpin: v1beta1.HairpinUndefined, HairpinMode: true}, - result: kubeRouterConfig{CNIHairpin: true, GlobalHairpin: true}, + krc: &v1beta1.KubeRouter{Hairpin: v1beta1.HairpinUndefined, HairpinMode: true}, + resultCNIHairpin: true, + resultGlobalHairpin: true, }, { - krc: &v1beta1.KubeRouter{Hairpin: v1beta1.HairpinUndefined, HairpinMode: false}, - result: kubeRouterConfig{CNIHairpin: false, GlobalHairpin: false}, + krc: &v1beta1.KubeRouter{Hairpin: v1beta1.HairpinUndefined, HairpinMode: false}, + resultCNIHairpin: false, + resultGlobalHairpin: false, }, { - krc: &v1beta1.KubeRouter{Hairpin: v1beta1.HairpinAllowed, HairpinMode: true}, - result: kubeRouterConfig{CNIHairpin: true, GlobalHairpin: false}, + krc: &v1beta1.KubeRouter{Hairpin: v1beta1.HairpinAllowed, HairpinMode: true}, + resultCNIHairpin: true, + resultGlobalHairpin: false, }, { - krc: &v1beta1.KubeRouter{Hairpin: v1beta1.HairpinDisabled, HairpinMode: true}, - result: kubeRouterConfig{CNIHairpin: false, GlobalHairpin: false}, + krc: &v1beta1.KubeRouter{Hairpin: v1beta1.HairpinDisabled, HairpinMode: true}, + resultCNIHairpin: false, + resultGlobalHairpin: false, }, { - krc: &v1beta1.KubeRouter{Hairpin: v1beta1.HairpinEnabled, HairpinMode: false}, - result: kubeRouterConfig{CNIHairpin: true, GlobalHairpin: true}, + krc: &v1beta1.KubeRouter{Hairpin: v1beta1.HairpinEnabled, HairpinMode: false}, + resultCNIHairpin: true, + resultGlobalHairpin: true, }, } for _, test := range hairpinTests { cfg := &kubeRouterConfig{} - getHairpinConfig(cfg, test.krc) - if cfg.CNIHairpin != test.result.CNIHairpin || cfg.GlobalHairpin != test.result.GlobalHairpin { - t.Fatalf("Hairpin configuration (%#v) does not match exepected output (%#v) ", cfg, test.result) + cniHairpin, globalHairpin := getHairpinConfig(test.krc) + if cniHairpin != test.resultCNIHairpin { + t.Fatalf("CNI hairpin configuration (%#v) does not match exepected output (%#v) ", cfg, test.resultCNIHairpin) } + if globalHairpin != test.resultGlobalHairpin { + t.Fatalf("Global hairpin configuration (%#v) does not match exepected output (%#v) ", cfg, test.resultGlobalHairpin) + } + } } @@ -182,6 +192,38 @@ func TestKubeRouterManualMTUManifests(t *testing.T) { require.Equal(t, float64(1234), p.Dig("mtu")) } +func TestExtraArgs(t *testing.T) { + k0sVars, err := config.NewCfgVars(nil, t.TempDir()) + require.NoError(t, err) + cfg := v1beta1.DefaultClusterConfig() + cfg.Spec.Network.Calico = nil + cfg.Spec.Network.Provider = "kuberouter" + cfg.Spec.Network.KubeRouter = v1beta1.DefaultKubeRouter() + cfg.Spec.Network.KubeRouter.ExtraArgs = map[string]string{ + // Add some random arg + "foo": "bar", + // Override the default arg + "run-firewall": "false", + } + + saver := inMemorySaver{} + kr := NewKubeRouter(k0sVars, saver) + require.NoError(t, kr.Reconcile(context.Background(), cfg)) + require.NoError(t, kr.Stop()) + + manifestData, foundRaw := saver["kube-router.yaml"] + require.True(t, foundRaw, "must have manifests for kube-router") + + resources, err := testutil.ParseManifests(manifestData) + require.NoError(t, err) + ds, err := findDaemonset(resources) + require.NoError(t, err) + require.NotNil(t, ds) + + assert.Contains(t, ds.Spec.Template.Spec.Containers[0].Args, "--run-firewall=false") + assert.Contains(t, ds.Spec.Template.Spec.Containers[0].Args, "--foo=bar") +} + func findConfig(resources []*unstructured.Unstructured) (corev1.ConfigMap, error) { var cm corev1.ConfigMap for _, r := range resources { diff --git a/pkg/config/cli.go b/pkg/config/cli.go index c91b4210879e..06452519e521 100644 --- a/pkg/config/cli.go +++ b/pkg/config/cli.go @@ -27,7 +27,6 @@ import ( "github.com/k0sproject/k0s/pkg/constant" "github.com/k0sproject/k0s/pkg/k0scloudprovider" - "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/pflag" "golang.org/x/exp/slices" @@ -95,24 +94,6 @@ func (o *ControllerOptions) Normalize() error { // Normalize component names var disabledComponents []string for _, disabledComponent := range o.DisableComponents { - switch disabledComponent { - case constant.APIConfigComponentName: - logrus.Warnf("Usage of deprecated component name %q, please switch to %q", - constant.APIConfigComponentName, "--enable-dynamic-config=false", - ) - if o.EnableDynamicConfig { - logrus.Warnf("Cannot disable component %q, because %q is selected", - constant.APIConfigComponentName, "--enable-dynamic-config", - ) - } - - case constant.KubeletConfigComponentName: - logrus.Warnf("Usage of deprecated component name %q, please switch to %q", - constant.KubeletConfigComponentName, constant.WorkerConfigComponentName, - ) - disabledComponent = constant.WorkerConfigComponentName - } - if !slices.Contains(availableComponents, disabledComponent) { return fmt.Errorf("unknown component %s", disabledComponent) } @@ -187,6 +168,7 @@ func GetWorkerFlags() *pflag.FlagSet { } var availableComponents = []string{ + constant.ApplierManagerComponentName, constant.AutopilotComponentName, constant.ControlAPIComponentName, constant.CoreDNSComponentname, diff --git a/pkg/config/cli_test.go b/pkg/config/cli_test.go index b4e724404f54..4d9e2c4eba3a 100644 --- a/pkg/config/cli_test.go +++ b/pkg/config/cli_test.go @@ -44,30 +44,14 @@ func TestControllerOptions_Normalize(t *testing.T) { assert.ErrorContains(t, err, "unknown component i-dont-exist") }) - for _, test := range []struct { - name string - disabled, expected []string - }{ - { - "removesDuplicateComponents", - []string{"helm", "kube-proxy", "coredns", "kube-proxy", "autopilot"}, - []string{"helm", "kube-proxy", "coredns", "autopilot"}, - }, - { - "replacesDeprecation", - []string{"helm", "kubelet-config", "coredns", "kubelet-config", "autopilot"}, - []string{"helm", "worker-config", "coredns", "autopilot"}, - }, - { - "replacesDeprecationAvoidingDuplicates", - []string{"helm", "kubelet-config", "coredns", "kubelet-config", "worker-config", "autopilot"}, - []string{"helm", "worker-config", "coredns", "autopilot"}, - }, - } { - underTest := ControllerOptions{DisableComponents: test.disabled} + t.Run("removesDuplicateComponents", func(t *testing.T) { + disabled := []string{"helm", "kube-proxy", "coredns", "kube-proxy", "autopilot"} + expected := []string{"helm", "kube-proxy", "coredns", "autopilot"} + + underTest := ControllerOptions{DisableComponents: disabled} err := underTest.Normalize() require.NoError(t, err) - assert.Equal(t, test.expected, underTest.DisableComponents) - } + assert.Equal(t, expected, underTest.DisableComponents) + }) } diff --git a/pkg/constant/constant_shared.go b/pkg/constant/constant_shared.go index 1c91a4f968da..3406b95991cf 100644 --- a/pkg/constant/constant_shared.go +++ b/pkg/constant/constant_shared.go @@ -78,11 +78,11 @@ const ( MetricsImage = "registry.k8s.io/metrics-server/metrics-server" MetricsImageVersion = "v0.6.4" KubeProxyImage = "quay.io/k0sproject/kube-proxy" - KubeProxyImageVersion = "v1.29.0" + KubeProxyImageVersion = "v1.29.1" CoreDNSImage = "quay.io/k0sproject/coredns" CoreDNSImageVersion = "1.11.1" EnvoyProxyImage = "quay.io/k0sproject/envoy-distroless" - EnvoyProxyImageVersion = "v1.27.1" + EnvoyProxyImageVersion = "v1.29.0" CalicoImage = "quay.io/k0sproject/calico-cni" CalicoComponentImagesVersion = "v3.26.1-1" CalicoNodeImage = "quay.io/k0sproject/calico-node" @@ -96,8 +96,8 @@ const ( /* Controller component names */ - APIConfigComponentName = "api-config" // Deprecated: just don't use dynamic config APIEndpointReconcilerComponentName = "endpoint-reconciler" + ApplierManagerComponentName = "applier-manager" ControlAPIComponentName = "control-api" CoreDNSComponentname = "coredns" CsrApproverComponentName = "csr-approver" @@ -106,7 +106,6 @@ const ( KubeControllerManagerComponentName = "kube-controller-manager" KubeProxyComponentName = "kube-proxy" KubeSchedulerComponentName = "kube-scheduler" - KubeletConfigComponentName = "kubelet-config" // Deprecated: replaced by worker-config WorkerConfigComponentName = "worker-config" MetricsServerComponentName = "metrics-server" NetworkProviderComponentName = "network-provider" diff --git a/pkg/constant/constant_shared_test.go b/pkg/constant/constant_shared_test.go index 71b4a67454a5..38e5590b235c 100644 --- a/pkg/constant/constant_shared_test.go +++ b/pkg/constant/constant_shared_test.go @@ -126,22 +126,6 @@ func TestContainerdModuleVersions(t *testing.T) { ) } -func TestRuncModuleVersions(t *testing.T) { - runcVersion := getVersion(t, "runc") - - checkPackageModules(t, - func(modulePath string) bool { - return modulePath == "github.com/opencontainers/runc" - }, - func(t *testing.T, pkgPath string, module *packages.Module) bool { - return !assert.Equal(t, "v"+runcVersion, module.Version, - "Module version for package %s doesn't match: %+#v", - pkgPath, module, - ) - }, - ) -} - func getVersion(t *testing.T, component string) string { cmd := exec.Command("sh", "./vars.sh", component+"_version") cmd.Dir = filepath.Join("..", "..") diff --git a/pkg/kubernetes/watch/k0s.go b/pkg/kubernetes/watch/k0s.go index 2cf7e3681e2b..fb9ac3236503 100644 --- a/pkg/kubernetes/watch/k0s.go +++ b/pkg/kubernetes/watch/k0s.go @@ -18,6 +18,7 @@ package watch import ( autopilotv1beta2 "github.com/k0sproject/k0s/pkg/apis/autopilot/v1beta2" + helmv1beta1 "github.com/k0sproject/k0s/pkg/apis/helm/v1beta1" k0sv1beta1 "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1" ) @@ -28,3 +29,7 @@ func ClusterConfigs(client Provider[*k0sv1beta1.ClusterConfigList]) *Watcher[k0s func Plans(client Provider[*autopilotv1beta2.PlanList]) *Watcher[autopilotv1beta2.Plan] { return FromClient[*autopilotv1beta2.PlanList, autopilotv1beta2.Plan](client) } + +func Charts(client Provider[*helmv1beta1.ChartList]) *Watcher[helmv1beta1.Chart] { + return FromClient[*helmv1beta1.ChartList, helmv1beta1.Chart](client) +} diff --git a/static/manifests/autopilot/CustomResourceDefinition/autopilot.k0sproject.io_controlnodes.yaml b/static/manifests/autopilot/CustomResourceDefinition/autopilot.k0sproject.io_controlnodes.yaml index cd62a04308fa..6381d4ed078f 100644 --- a/static/manifests/autopilot/CustomResourceDefinition/autopilot.k0sproject.io_controlnodes.yaml +++ b/static/manifests/autopilot/CustomResourceDefinition/autopilot.k0sproject.io_controlnodes.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.13.0 + controller-gen.kubebuilder.io/version: v0.14.0 name: controlnodes.autopilot.k0sproject.io spec: group: autopilot.k0sproject.io @@ -17,18 +17,24 @@ spec: - name: v1beta2 schema: openAPIV3Schema: - description: ControlNode is a node which behaves as a controller, able to - receive autopilot signaling updates. + description: |- + ControlNode is a node which behaves as a controller, able to receive autopilot + signaling updates. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object diff --git a/static/manifests/autopilot/CustomResourceDefinition/autopilot.k0sproject.io_plans.yaml b/static/manifests/autopilot/CustomResourceDefinition/autopilot.k0sproject.io_plans.yaml index 0c3f5262b6e7..2a9ed65b1801 100644 --- a/static/manifests/autopilot/CustomResourceDefinition/autopilot.k0sproject.io_plans.yaml +++ b/static/manifests/autopilot/CustomResourceDefinition/autopilot.k0sproject.io_plans.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.13.0 + controller-gen.kubebuilder.io/version: v0.14.0 name: plans.autopilot.k0sproject.io spec: group: autopilot.k0sproject.io @@ -24,18 +24,24 @@ spec: name: v1beta2 schema: openAPIV3Schema: - description: Plan provides all details of what to execute as a part of the - plan, and the current status of its execution. + description: |- + Plan provides all details of what to execute as a part of the plan, and + the current status of its execution. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -43,8 +49,9 @@ spec: description: Spec defines how the plan behaves. properties: commands: - description: Commands are a collection of all of the commands that - need to be executed in order for this plan to transition to Completed. + description: |- + Commands are a collection of all of the commands that need to be executed + in order for this plan to transition to Completed. items: description: PlanCommand is a command that can be run within a `Plan` properties: @@ -66,9 +73,9 @@ spec: required: - url type: object - description: Platforms is a map of PlanResourceUrls to platform - identifiers, allowing a single k0s airgap version to have - multiple Url resources based on platform. + description: |- + Platforms is a map of PlanResourceUrls to platform identifiers, allowing a single k0s airgap + version to have multiple Url resources based on platform. type: object version: description: Version is the version that `AirgapUpdate` @@ -115,10 +122,9 @@ spec: properties: concurrent: default: 1 - description: Concurrent specifies the number of - concurrent target executions that can be performed - within this target. (ie. '2' == at most have 2 - execute at the same time) + description: |- + Concurrent specifies the number of concurrent target executions that can be performed + within this target. (ie. '2' == at most have 2 execute at the same time) type: integer type: object required: @@ -151,9 +157,9 @@ spec: required: - url type: object - description: Platforms is a map of PlanResourceUrls to platform - identifiers, allowing a single k0s version to have multiple - URL resources based on platform. + description: |- + Platforms is a map of PlanResourceUrls to platform identifiers, allowing a single k0s version + to have multiple URL resources based on platform. type: object targets: description: Targets defines how the controllers/workers @@ -201,10 +207,9 @@ spec: properties: concurrent: default: 1 - description: Concurrent specifies the number - of concurrent target executions that can be - performed within this target. (ie. '2' == - at most have 2 execute at the same time) + description: |- + Concurrent specifies the number of concurrent target executions that can be performed + within this target. (ie. '2' == at most have 2 execute at the same time) type: integer type: object required: @@ -252,10 +257,9 @@ spec: properties: concurrent: default: 1 - description: Concurrent specifies the number - of concurrent target executions that can be - performed within this target. (ie. '2' == - at most have 2 execute at the same time) + description: |- + Concurrent specifies the number of concurrent target executions that can be performed + within this target. (ie. '2' == at most have 2 execute at the same time) type: integer type: object required: @@ -288,8 +292,9 @@ spec: description: Status is the most recently observed status of the plan. properties: commands: - description: Commands are a collection of status's for each of the - commands defined in the plan, maintained in their index order. + description: |- + Commands are a collection of status's for each of the commands defined in the plan, + maintained in their index order. items: description: PlanCommandStatus is the status of a known command. properties: @@ -394,9 +399,10 @@ spec: type: object type: array state: - description: State is the current state of the plan. This value typically - mirrors the status of the current command execution to allow for - querying a single field to determine the plan status. + description: |- + State is the current state of the plan. This value typically mirrors the status + of the current command execution to allow for querying a single field to determine + the plan status. type: string required: - commands diff --git a/static/manifests/autopilot/CustomResourceDefinition/autopilot.k0sproject.io_updateconfigs.yaml b/static/manifests/autopilot/CustomResourceDefinition/autopilot.k0sproject.io_updateconfigs.yaml index 3090adcb8cc9..7102b58f382c 100644 --- a/static/manifests/autopilot/CustomResourceDefinition/autopilot.k0sproject.io_updateconfigs.yaml +++ b/static/manifests/autopilot/CustomResourceDefinition/autopilot.k0sproject.io_updateconfigs.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.13.0 + controller-gen.kubebuilder.io/version: v0.14.0 name: updateconfigs.autopilot.k0sproject.io spec: group: autopilot.k0sproject.io @@ -19,14 +19,19 @@ spec: openAPIV3Schema: properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -42,9 +47,9 @@ spec: config properties: commands: - description: Commands are a collection of all of the commands - that need to be executed in order for this plan to transition - to Completed. + description: |- + Commands are a collection of all of the commands that need to be executed + in order for this plan to transition to Completed. items: description: AutopilotPlanCommand is a command that can be run within a `Plan` @@ -95,10 +100,9 @@ spec: properties: concurrent: default: 1 - description: Concurrent specifies the number - of concurrent target executions that can be - performed within this target. (ie. '2' == - at most have 2 execute at the same time) + description: |- + Concurrent specifies the number of concurrent target executions that can be performed + within this target. (ie. '2' == at most have 2 execute at the same time) type: integer type: object required: @@ -162,11 +166,9 @@ spec: properties: concurrent: default: 1 - description: Concurrent specifies the number - of concurrent target executions that can - be performed within this target. (ie. - '2' == at most have 2 execute at the same - time) + description: |- + Concurrent specifies the number of concurrent target executions that can be performed + within this target. (ie. '2' == at most have 2 execute at the same time) type: integer type: object required: @@ -215,11 +217,9 @@ spec: properties: concurrent: default: 1 - description: Concurrent specifies the number - of concurrent target executions that can - be performed within this target. (ie. - '2' == at most have 2 execute at the same - time) + description: |- + Concurrent specifies the number of concurrent target executions that can be performed + within this target. (ie. '2' == at most have 2 execute at the same time) type: integer type: object required: diff --git a/static/manifests/helm/CustomResourceDefinition/helm.k0sproject.io_charts.yaml b/static/manifests/helm/CustomResourceDefinition/helm.k0sproject.io_charts.yaml index e0e59e60adb3..f467b42c39cf 100644 --- a/static/manifests/helm/CustomResourceDefinition/helm.k0sproject.io_charts.yaml +++ b/static/manifests/helm/CustomResourceDefinition/helm.k0sproject.io_charts.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.13.0 + controller-gen.kubebuilder.io/version: v0.14.0 name: charts.helm.k0sproject.io spec: group: helm.k0sproject.io @@ -20,14 +20,19 @@ spec: description: Chart is the Schema for the charts API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object diff --git a/static/manifests/v1beta1/CustomResourceDefinition/k0s.k0sproject.io_clusterconfigs.yaml b/static/manifests/v1beta1/CustomResourceDefinition/k0s.k0sproject.io_clusterconfigs.yaml index ded8bd9df4f2..075b82082ca9 100644 --- a/static/manifests/v1beta1/CustomResourceDefinition/k0s.k0sproject.io_clusterconfigs.yaml +++ b/static/manifests/v1beta1/CustomResourceDefinition/k0s.k0sproject.io_clusterconfigs.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.13.0 + controller-gen.kubebuilder.io/version: v0.14.0 name: clusterconfigs.k0s.k0sproject.io spec: group: k0s.k0sproject.io @@ -20,14 +20,19 @@ spec: description: ClusterConfig is the Schema for the clusterconfigs API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -40,6 +45,10 @@ spec: address: description: Local address on which to bind an API type: string + bindAddress: + description: The IP address for the Kubernetes API server to listen + on. + type: string externalAddress: description: The loadbalancer address (for k0s controllers running behind a loadbalancer) @@ -96,10 +105,10 @@ spec: order: type: integer timeout: - description: A Duration represents the elapsed time - between two instants as an int64 nanosecond count. - The representation limits the largest representable - duration to approximately 290 years. + description: |- + A Duration represents the elapsed time between two instants + as an int64 nanosecond count. The representation limits the + largest representable duration to approximately 290 years. format: int64 type: integer values: @@ -374,8 +383,9 @@ spec: disabled: type: boolean iptables: - description: KubeProxyIPTablesConfiguration contains iptables-related - kube-proxy configuration @see https://github.com/kubernetes/kube-proxy/blob/v0.29.0/config/v1alpha1/types.go#L27-L48 + description: |- + KubeProxyIPTablesConfiguration contains iptables-related kube-proxy configuration + @see https://github.com/kubernetes/kube-proxy/blob/v0.29.0/config/v1alpha1/types.go#L27-L48 properties: localhostNodePorts: type: boolean @@ -390,8 +400,9 @@ spec: type: string type: object ipvs: - description: KubeProxyIPVSConfiguration contains ipvs-related - kube-proxy configuration @see https://github.com/kubernetes/kube-proxy/blob/v0.29.0/config/v1alpha1/types.go#L52-L78 + description: |- + KubeProxyIPVSConfiguration contains ipvs-related kube-proxy configuration + @see https://github.com/kubernetes/kube-proxy/blob/v0.29.0/config/v1alpha1/types.go#L52-L78 properties: excludeCIDRs: items: @@ -428,11 +439,18 @@ spec: autoMTU: description: 'Auto-detection of used MTU (default: true)' type: boolean + extraArgs: + additionalProperties: + type: string + description: |- + ExtraArgs are extra arguments to pass to kube-router + Can be also used to override the default k0s managed kube-router arguments + type: object hairpin: default: Enabled - description: 'Admits three values: "Enabled" enables it globally, - "Allowed" allows but services must be annotated explicitly - and "Disabled" Defaults to "Enabled"' + description: |- + Admits three values: "Enabled" enables it globally, "Allowed" allows but services must be annotated explicitly and "Disabled" + Defaults to "Enabled" enum: - Enabled - Allowed @@ -456,34 +474,40 @@ spec: false) type: integer peerRouterASNs: - description: Comma-separated list of global peer addresses + description: |- + Comma-separated list of global peer addresses + DEPRECATED: Use extraArgs with peerRouterASNs instead type: string peerRouterIPs: - description: Comma-separated list of global peer ASNs + description: |- + Comma-separated list of global peer ASNs + DEPRECATED: Use extraArgs with peerRouterIPs instead type: string type: object nodeLocalLoadBalancing: - description: 'nodeLocalLoadBalancing defines the configuration - options related to k0s''s node-local load balancing feature. - NOTE: This feature is experimental, and currently unsupported - on ARMv7!' + description: |- + NodeLocalLoadBalancing defines the configuration options related to k0s's + node-local load balancing feature. + NOTE: This feature is currently unsupported on ARMv7! properties: enabled: - description: 'enabled indicates if node-local load balancing - should be used to access Kubernetes API servers from worker - nodes. Default: false' + description: |- + enabled indicates if node-local load balancing should be used to access + Kubernetes API servers from worker nodes. + Default: false type: boolean envoyProxy: - description: envoyProxy contains configuration options related - to the "EnvoyProxy" type of load balancing. + description: |- + envoyProxy contains configuration options related to the "EnvoyProxy" type + of load balancing. properties: apiServerBindPort: default: 7443 - description: 'apiServerBindPort is the port number on - which to bind the Envoy load balancer for the Kubernetes - API server to on a worker''s loopback interface. This - must be a valid port number, 0 < x < 65536. Default: - 7443' + description: |- + apiServerBindPort is the port number on which to bind the Envoy load + balancer for the Kubernetes API server to on a worker's loopback + interface. This must be a valid port number, 0 < x < 65536. + Default: 7443 format: int32 maximum: 65535 minimum: 1 @@ -498,9 +522,9 @@ spec: type: string type: object imagePullPolicy: - description: imagePullPolicy specifies the pull policy - being used for the Envoy Pod. Defaults to the default - image pull policy. + description: |- + imagePullPolicy specifies the pull policy being used for the Envoy Pod. + Defaults to the default image pull policy. enum: - Always - Never @@ -508,10 +532,11 @@ spec: type: string konnectivityServerBindPort: default: 7132 - description: 'konnectivityServerBindPort is the port number - on which to bind the Envoy load balancer for the konnectivity - server to on a worker''s loopback interface. This must - be a valid port number, 0 < x < 65536. Default: 7132' + description: |- + konnectivityServerBindPort is the port number on which to bind the Envoy + load balancer for the konnectivity server to on a worker's loopback + interface. This must be a valid port number, 0 < x < 65536. + Default: 7132 format: int32 maximum: 65535 minimum: 1 @@ -519,9 +544,9 @@ spec: type: object type: default: EnvoyProxy - description: type indicates the type of the node-local load - balancer to deploy on worker nodes. Currently, the only - supported type is "EnvoyProxy". + description: |- + type indicates the type of the node-local load balancer to deploy on + worker nodes. Currently, the only supported type is "EnvoyProxy". enum: - EnvoyProxy type: string diff --git a/vars.sh b/vars.sh index 28d189c32902..240a3158fbb8 100755 --- a/vars.sh +++ b/vars.sh @@ -1,4 +1,5 @@ #!/usr/bin/env sh +#shellcheck disable=SC3043 set -eu @@ -12,6 +13,18 @@ print_usage() { echo " $0 FROM=docs python_version" } +version_from_go_mod() { + local pkg version rest + while read -r pkg version rest; do + if [ "$pkg" = "$1" ]; then + printf %s "$version" + return 0 + fi + done + + return 1 +} + fail() { echo "$@" >&2 print_usage >&2 @@ -41,6 +54,17 @@ done [ -n "$var" ] || fail Makefile variable not given [ -n "$from" ] || from=embedded-bins +case "$var" in +k0sctl_version) pkg=github.com/k0sproject/k0sctl ;; +k0s_sort_version) pkg=github.com/k0sproject/version ;; +*) pkg='' ;; +esac + +if [ -n "$pkg" ]; then + version_from_go_mod "$pkg" <"$from"/go.mod + exit 0 +fi + exec make --no-print-directory -r -s -f - <