diff --git a/.github/workflows/airgap.yaml b/.github/workflows/airgap.yaml index 8e622080ac45..97175d676de7 100644 --- a/.github/workflows/airgap.yaml +++ b/.github/workflows/airgap.yaml @@ -20,7 +20,7 @@ jobs: uses: actions/checkout@v6 - name: Set up Docker - uses: docker/setup-docker-action@v4 + uses: docker/setup-docker-action@v5 with: version: type=image,tag=28 daemon-config: '{"features":{"containerd-snapshotter":true}}' diff --git a/.github/workflows/build-k3s.yaml b/.github/workflows/build-k3s.yaml index eeef200cc744..90389737aa7f 100644 --- a/.github/workflows/build-k3s.yaml +++ b/.github/workflows/build-k3s.yaml @@ -38,12 +38,12 @@ jobs: - name: Set up QEMU if: inputs.arch == 'arm' - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v4 with: cache-image: false - name: Set up Docker - uses: docker/setup-docker-action@v4 + uses: docker/setup-docker-action@v5 with: version: type=image,tag=28 daemon-config: '{"features":{"containerd-snapshotter":true}}' @@ -67,7 +67,7 @@ jobs: if: inputs.arch == 'arm64' || inputs.arch == 'amd64' env: DOCKER_BUILD_SUMMARY: false - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: . file: ./Dockerfile.local @@ -89,7 +89,7 @@ jobs: env: PLATFORM: ${{ inputs.arch == 'arm' && 'linux/arm/v7' || format('linux/{0}', inputs.arch) }} DOCKER_BUILD_SUMMARY: false - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: . file: ./Dockerfile.local diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index f69c70eb4537..c843c9044558 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -77,7 +77,7 @@ jobs: uses: actions/checkout@v6 with: {fetch-depth: 1} - name: Set up Docker - uses: docker/setup-docker-action@v4 + uses: docker/setup-docker-action@v5 with: version: type=image,tag=28 daemon-config: '{"features":{"containerd-snapshotter":true}}' @@ -108,7 +108,7 @@ jobs: curl -LO "https://dl.k8s.io/release/${STABLE_VERSION}/bin/linux/amd64/kubectl" sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl - name: "Download k3s binary" - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: k3s-amd64 path: ./dist/artifacts @@ -187,13 +187,15 @@ jobs: strategy: fail-fast: false matrix: - dtest: [autoimport, basics, bootstraptoken, cacerts, dualstack, etcd, hardened, lazypull, skew, secretsencryption, snapshotrestore, svcpoliciesandfirewall, token, upgrade] + dtest: [autoimport, basics, bootstraptoken, cacerts, dualstack, etcd, hardened, lazypull, nixsnapshotter, skew, secretsencryption, snapshotrestore, svcpoliciesandfirewall, token, upgrade] arch: [amd64, arm64] exclude: - dtest: autoimport arch: arm64 - dtest: dualstack arch: arm64 + - dtest: nixsnapshotter + arch: arm64 - dtest: secretsencryption arch: arm64 - dtest: snapshotrestore @@ -226,12 +228,12 @@ jobs: - name: Checkout uses: actions/checkout@v6 - name: "Download K3s image" - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: k3s-${{ matrix.arch }} path: ./dist/artifacts - name: Set up Docker - uses: docker/setup-docker-action@v4 + uses: docker/setup-docker-action@v5 with: version: type=image,tag=28 daemon-config: '{"features":{"containerd-snapshotter":true}}' @@ -245,8 +247,16 @@ jobs: docker image load -i ./dist/artifacts/k3s-image.tar IMAGE_TAG=$(docker image ls --format '{{.Repository}}:{{.Tag}}' | grep 'rancher/k3s') echo "K3S_IMAGE=$IMAGE_TAG" >> $GITHUB_ENV + - name: Install Nix + if: matrix.dtest == 'nixsnapshotter' + uses: DeterminateSystems/nix-installer-action@v21 + - name: Build nix test image + if: matrix.dtest == 'nixsnapshotter' + run: | + nix build github:pdtpartners/nix-snapshotter#image-hello + cp result ./tests/docker/resources/nix-hello-image.tar - name: Download Go Tests - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: docker-go-tests-${{ matrix.arch }} path: ./dist/artifacts diff --git a/.github/workflows/install.yaml b/.github/workflows/install.yaml index 83758a361b2b..42f8edf10bd5 100644 --- a/.github/workflows/install.yaml +++ b/.github/workflows/install.yaml @@ -71,7 +71,7 @@ jobs: - name: "Vagrant Plugin(s)" run: vagrant plugin install vagrant-k3s vagrant-reload vagrant-scp - name: "Download k3s binary" - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: k3s-amd64 path: tests/install/${{ matrix.vm }} diff --git a/.github/workflows/integration.yaml b/.github/workflows/integration.yaml index af820d1422a4..0345d1f9f124 100644 --- a/.github/workflows/integration.yaml +++ b/.github/workflows/integration.yaml @@ -74,7 +74,7 @@ jobs: - name: Install Go uses: ./.github/actions/setup-go - name: "Download k3s binary" - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: k3s-amd64 path: ./dist/artifacts @@ -120,7 +120,7 @@ jobs: - name: Install Go uses: ./.github/actions/setup-go - name: Download k3s binary - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: k3s-windows path: dist/artifacts/ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 14a4e9df4b2f..780d2819951b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,7 +42,7 @@ jobs: uses: actions/checkout@v6 - name: Set up Docker - uses: docker/setup-docker-action@v4 + uses: docker/setup-docker-action@v5 with: version: type=image,tag=28 daemon-config: '{"features":{"containerd-snapshotter":true}}' @@ -154,7 +154,7 @@ jobs: tags: ${{ steps.tag_config.outputs.tag_spec }} - name: "Download K3s build" - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: pattern: k3s* path: ./dist/artifacts @@ -166,7 +166,7 @@ jobs: cp ./dist/artifacts/data-* ./build/out - name: Build and push K3s runtime image - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: . file: ./package/Dockerfile @@ -215,14 +215,14 @@ jobs: secret/data/github/repo/${{ github.repository }}/k3s-suse-registry/credentials registry | REGISTRY - name: Configure AWS Credentials (s3) - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@v6 with: aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} aws-region: us-east-1 - name: "Download Artifacts" - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: pattern: "*" path: ./dist/artifacts @@ -249,7 +249,7 @@ jobs: ./scripts/validate-artifacts - name: Upload Assets to Release - uses: softprops/action-gh-release@v2.2.1 + uses: softprops/action-gh-release@v2.5.0 with: files: | dist/artifacts/k3s* diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 0085612bd035..77c21436eb07 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -13,7 +13,7 @@ jobs: contents: write steps: - name: Close Stale Issues - uses: actions/stale@v9.1.0 + uses: actions/stale@v10.2.0 with: # ensure PRs are exempt days-before-pr-stale: -1 diff --git a/.github/workflows/trivy-scan.yml b/.github/workflows/trivy-scan.yml index bf5b920cda13..01c9cd7bba2c 100644 --- a/.github/workflows/trivy-scan.yml +++ b/.github/workflows/trivy-scan.yml @@ -58,7 +58,7 @@ jobs: run: curl -fsSO https://raw.githubusercontent.com/rancher/vexhub/refs/heads/main/reports/rancher.openvex.json - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@0.32.0 + uses: aquasecurity/trivy-action@0.34.1 with: image-ref: 'rancher/k3s:latest' format: 'table' @@ -85,7 +85,7 @@ jobs: steps: - name: Download Trivy Report artifact - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 if: needs.trivy_scan.result == 'success' with: name: trivy-report diff --git a/Dockerfile.manifest b/Dockerfile.manifest index 709f1c6e66c5..24573ec8abdd 100644 --- a/Dockerfile.manifest +++ b/Dockerfile.manifest @@ -1,4 +1,4 @@ -ARG GOLANG=golang:1.24.13-alpine3.22 +ARG GOLANG=golang:1.24.13-alpine3.23 FROM ${GOLANG} COPY --from=plugins/manifest:1.2.3 /bin/* /bin/ diff --git a/Dockerfile.test b/Dockerfile.test index 0639ef4c317a..e318b3c48657 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -1,4 +1,4 @@ -ARG GOLANG=golang:1.24.13-alpine3.22 +ARG GOLANG=golang:1.24.13-alpine3.23 FROM ${GOLANG} AS test-base RUN apk -U --no-cache add bash jq diff --git a/cmd/containerd/main.go b/cmd/containerd/main.go index aaf76513e350..9e0300f2fb18 100644 --- a/cmd/containerd/main.go +++ b/cmd/containerd/main.go @@ -7,5 +7,6 @@ import ( func main() { klog.InitFlags(nil) + klog.EnableContextualLogging(true) containerd.Main() } diff --git a/cmd/k3s/main.go b/cmd/k3s/main.go index 098b9a47dfc5..07960289d82f 100644 --- a/cmd/k3s/main.go +++ b/cmd/k3s/main.go @@ -3,7 +3,6 @@ package main import ( "bytes" "context" - "errors" "io" "io/fs" "os" @@ -20,9 +19,9 @@ import ( "github.com/k3s-io/k3s/pkg/dataverify" "github.com/k3s-io/k3s/pkg/flock" "github.com/k3s-io/k3s/pkg/untar" + "github.com/k3s-io/k3s/pkg/util/errors" + "github.com/k3s-io/k3s/pkg/util/home" "github.com/k3s-io/k3s/pkg/version" - pkgerrors "github.com/pkg/errors" - "github.com/rancher/wrangler/v3/pkg/resolvehome" "github.com/sirupsen/logrus" "github.com/spf13/pflag" "github.com/urfave/cli/v2" @@ -212,7 +211,7 @@ func stageAndRunCLI(cli *cli.Context, cmd string, dataDir string, args []string) func stageAndRun(dataDir, cmd string, args []string, calledAsInternal bool) error { dir, err := extract(dataDir) if err != nil { - return pkgerrors.WithMessage(err, "extracting data") + return errors.WithMessage(err, "extracting data") } logrus.Debugf("Asset dir %s", dir) @@ -386,7 +385,7 @@ func extract(dataDir string) (string, error) { func findCriConfig(dataDir string) string { searchList := []string{filepath.Join(dataDir, "agent", criDefaultConfigPath)} - if homeDataDir, err := resolvehome.Resolve(datadir.DefaultHomeDataDir); err == nil { + if homeDataDir, err := home.Resolve(datadir.DefaultHomeDataDir); err == nil { searchList = append(searchList, filepath.Join(homeDataDir, "agent", criDefaultConfigPath)) } else { logrus.Warnf("Failed to resolve user home directory: %s", err) diff --git a/cmd/k3s/main_linux.go b/cmd/k3s/main_linux.go index 21247bfb3728..d7ce37e980e8 100644 --- a/cmd/k3s/main_linux.go +++ b/cmd/k3s/main_linux.go @@ -6,14 +6,14 @@ import ( "os" "syscall" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" ) const programPostfix = "" func runExec(cmd string, args []string, calledAsInternal bool) (err error) { if err := syscall.Exec(cmd, args, os.Environ()); err != nil { - return pkgerrors.WithMessagef(err, "exec %s failed", cmd) + return errors.WithMessagef(err, "exec %s failed", cmd) } return nil } diff --git a/go.mod b/go.mod index 97e094ba8dac..92d018375aa6 100644 --- a/go.mod +++ b/go.mod @@ -3,21 +3,19 @@ module github.com/k3s-io/k3s go 1.24.13 replace ( - github.com/Microsoft/hcsshim => github.com/Microsoft/hcsshim v0.13.0 + github.com/Microsoft/hcsshim => github.com/Microsoft/hcsshim v0.14.0-rc.1 github.com/Mirantis/cri-dockerd => github.com/k3s-io/cri-dockerd v0.3.19-k3s3 github.com/cilium/ebpf => github.com/cilium/ebpf v0.12.3 github.com/cloudnativelabs/kube-router/v2 => github.com/k3s-io/kube-router/v2 v2.6.3-k3s1 - github.com/containerd/containerd/api => github.com/containerd/containerd/api v1.9.0 - github.com/containerd/containerd/v2 => github.com/k3s-io/containerd/v2 v2.1.5-k3s1 + github.com/containerd/containerd/api => github.com/containerd/containerd/api v1.10.0 + github.com/containerd/containerd/v2 => github.com/brandond/containerd/v2 v2.2.2-bd1.34 github.com/containerd/imgcrypt => github.com/containerd/imgcrypt v1.1.11 - github.com/containerd/stargz-snapshotter => github.com/k3s-io/stargz-snapshotter v0.17.0-k3s1 github.com/docker/distribution => github.com/docker/distribution v2.8.3+incompatible github.com/docker/docker => github.com/docker/docker v25.0.8+incompatible github.com/emicklei/go-restful/v3 => github.com/emicklei/go-restful/v3 v3.11.0 github.com/golang/protobuf => github.com/golang/protobuf v1.5.4 github.com/google/cadvisor => github.com/k3s-io/cadvisor v0.52.1 github.com/googleapis/gax-go/v2 => github.com/googleapis/gax-go/v2 v2.12.0 - github.com/open-policy-agent/opa => github.com/open-policy-agent/opa v0.59.0 // github.com/Microsoft/hcsshim using bad version v0.42.2 github.com/opencontainers/runc => github.com/opencontainers/runc v1.4.0 github.com/opencontainers/selinux => github.com/opencontainers/selinux v1.13.0 github.com/prometheus/client_golang => github.com/prometheus/client_golang v1.22.0 @@ -54,7 +52,7 @@ replace ( k8s.io/endpointslice => github.com/k3s-io/kubernetes/staging/src/k8s.io/endpointslice v1.34.5-k3s1 k8s.io/externaljwt => github.com/k3s-io/kubernetes/staging/src/k8s.io/externaljwt v1.34.5-k3s1 k8s.io/klog => github.com/k3s-io/klog v1.0.0-k3s2 // k3s-release-1.x - k8s.io/klog/v2 => github.com/k3s-io/klog/v2 v2.120.1-k3s1 // k3s-main + k8s.io/klog/v2 => github.com/k3s-io/klog/v2 v2.140.0-k3s1 // k3s-main k8s.io/kms => github.com/k3s-io/kubernetes/staging/src/k8s.io/kms v1.34.5-k3s1 k8s.io/kube-aggregator => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-aggregator v1.34.5-k3s1 k8s.io/kube-controller-manager => github.com/k3s-io/kubernetes/staging/src/k8s.io/kube-controller-manager v1.34.5-k3s1 @@ -80,13 +78,13 @@ require ( github.com/Mirantis/cri-dockerd v0.0.0-00010101000000-000000000000 github.com/blang/semver/v4 v4.0.0 github.com/cloudnativelabs/kube-router/v2 v2.0.0-00010101000000-000000000000 - github.com/containerd/cgroups/v3 v3.1.0 + github.com/containerd/cgroups/v3 v3.1.2 github.com/containerd/containerd/api v1.10.0 github.com/containerd/containerd/v2 v2.2.0 github.com/containerd/errdefs v1.0.0 - github.com/containerd/fuse-overlayfs-snapshotter/v2 v2.1.6 - github.com/containerd/stargz-snapshotter v0.17.0 - github.com/containerd/zfs/v2 v2.0.0-rc.0 + github.com/containerd/fuse-overlayfs-snapshotter/v2 v2.1.7 + github.com/containerd/stargz-snapshotter v0.18.1 + github.com/containerd/zfs/v2 v2.0.0 github.com/coreos/go-iptables v0.8.0 github.com/coreos/go-systemd/v22 v22.6.0 github.com/distribution/reference v0.6.0 @@ -100,7 +98,6 @@ require ( github.com/google/cadvisor v0.53.0 github.com/google/go-containerregistry v0.20.2 github.com/google/uuid v1.6.0 - github.com/gorilla/mux v1.8.1 github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 github.com/inetaf/tcpproxy v0.0.0-20240214030015-3ce58045626c github.com/ipfs/go-ds-leveldb v0.5.0 @@ -109,7 +106,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/k3s-io/api v0.1.4 github.com/k3s-io/helm-controller v0.16.17 - github.com/k3s-io/kine v0.14.12 + github.com/k3s-io/kine v0.14.14 github.com/klauspost/compress v1.18.4 github.com/libp2p/go-libp2p v0.46.0 github.com/minio/minio-go/v7 v7.0.91 @@ -124,15 +121,15 @@ require ( github.com/opencontainers/image-spec v1.1.1 github.com/opencontainers/selinux v1.13.1 github.com/otiai10/copy v1.14.1 - github.com/pkg/errors v0.9.1 + github.com/pdtpartners/nix-snapshotter v0.4.0 github.com/prometheus/client_golang v1.23.2 github.com/prometheus/common v0.66.1 - github.com/rancher/dynamiclistener v0.7.1 - github.com/rancher/lasso v0.2.3 + github.com/rancher/dynamiclistener v0.7.5 + github.com/rancher/lasso v0.2.5 github.com/rancher/permissions v0.0.0-20240523180510-4001d3d637f7 github.com/rancher/remotedialer v0.6.0-rc.1.0.20250916111157-f160aa32568d - github.com/rancher/wharfie v0.7.0 - github.com/rancher/wrangler/v3 v3.2.3 + github.com/rancher/wharfie v0.7.1 + github.com/rancher/wrangler/v3 v3.3.4 github.com/robfig/cron/v3 v3.0.1 github.com/rootless-containers/rootlesskit v1.1.1 github.com/sirupsen/logrus v1.9.4 @@ -148,13 +145,13 @@ require ( go.etcd.io/etcd/client/v3 v3.6.8 go.etcd.io/etcd/etcdutl/v3 v3.6.6 go.etcd.io/etcd/server/v3 v3.6.8 - go.uber.org/mock v0.5.2 + go.uber.org/mock v0.6.0 go.uber.org/zap v1.27.1 golang.org/x/crypto v0.46.0 golang.org/x/mod v0.30.0 golang.org/x/net v0.48.0 golang.org/x/sync v0.19.0 - golang.org/x/sys v0.39.0 + golang.org/x/sys v0.40.0 google.golang.org/grpc v1.79.1 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.34.5 @@ -174,7 +171,7 @@ require ( k8s.io/kubectl v0.34.5 k8s.io/kubelet v0.34.5 k8s.io/kubernetes v1.34.5 - k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 sigs.k8s.io/cri-tools v0.34.0 sigs.k8s.io/yaml v1.6.0 ) @@ -205,6 +202,7 @@ require ( github.com/Microsoft/hnslib v0.1.1 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/Rican7/retry v0.3.1 // indirect + github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect github.com/antithesishq/antithesis-sdk-go v0.5.0 // indirect github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 // indirect github.com/avast/retry-go/v4 v4.7.0 // indirect @@ -215,7 +213,7 @@ require ( github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect - github.com/checkpoint-restore/checkpointctl v1.3.0 // indirect + github.com/checkpoint-restore/checkpointctl v1.4.0 // indirect github.com/checkpoint-restore/go-criu/v7 v7.2.0 // indirect github.com/cilium/ebpf v0.17.3 // indirect github.com/container-storage-interface/spec v1.9.0 // indirect @@ -224,15 +222,15 @@ require ( github.com/containerd/continuity v0.4.5 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/containerd/fifo v1.1.0 // indirect - github.com/containerd/go-cni v1.1.12 // indirect + github.com/containerd/go-cni v1.1.13 // indirect github.com/containerd/go-runc v1.1.0 // indirect github.com/containerd/imgcrypt/v2 v2.0.1 // indirect github.com/containerd/log v0.1.0 // indirect - github.com/containerd/nri v0.8.0 // indirect + github.com/containerd/nri v0.11.0 // indirect github.com/containerd/otelttrpc v0.1.0 // indirect github.com/containerd/platforms v1.0.0-rc.2 // indirect github.com/containerd/plugin v1.0.0 // indirect - github.com/containerd/stargz-snapshotter/estargz v0.17.0 // indirect + github.com/containerd/stargz-snapshotter/estargz v0.18.1 // indirect github.com/containerd/ttrpc v1.2.7 // indirect github.com/containerd/typeurl/v2 v2.2.3 // indirect github.com/containernetworking/cni v1.3.0 // indirect @@ -245,7 +243,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect - github.com/docker/cli v28.3.2+incompatible // indirect + github.com/docker/cli v29.2.0+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/go-connections v0.6.0 // indirect @@ -266,8 +264,9 @@ require ( github.com/ghodss/yaml v1.0.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-ini/ini v1.67.0 // indirect - github.com/go-jose/go-jose/v4 v4.0.5 // indirect + github.com/go-jose/go-jose/v4 v4.1.3 // indirect github.com/go-logr/stdr v1.2.3-0.20220714215716-96bad1d688c5 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/jsonpointer v0.22.0 // indirect github.com/go-openapi/jsonreference v0.21.1 // indirect github.com/go-openapi/swag v0.24.1 // indirect @@ -293,19 +292,21 @@ require ( github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e // indirect github.com/google/btree v1.1.3 // indirect github.com/google/cel-go v0.26.1 // indirect + github.com/google/certtostore v1.0.6 // indirect + github.com/google/deck v0.0.0-20230104221208-105ad94aa8ae // indirect github.com/google/gnostic-models v0.7.0 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-tpm v0.9.6 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 // indirect + github.com/gorilla/mux v1.8.1 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect github.com/guillaumemichel/reservedpool v0.3.0 // indirect - github.com/hanwen/go-fuse/v2 v2.8.0 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hanwen/go-fuse/v2 v2.9.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-retryablehttp v0.7.8 // indirect github.com/hashicorp/go-version v1.7.0 // indirect @@ -314,7 +315,7 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/intel/goresctrl v0.8.0 // indirect + github.com/intel/goresctrl v0.10.0 // indirect github.com/ipfs/boxo v0.35.2 // indirect github.com/ipfs/go-block-format v0.2.3 // indirect github.com/ipfs/go-cid v0.6.0 // indirect @@ -333,6 +334,7 @@ require ( github.com/josharian/native v1.1.0 // indirect github.com/karrick/godirwalk v1.17.0 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/knqyf263/go-plugin v0.9.0 // indirect github.com/koron/go-ssdp v0.0.6 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/libopenstorage/openstorage v1.0.0 // indirect @@ -373,6 +375,7 @@ require ( github.com/moby/ipvs v1.1.0 // indirect github.com/moby/locker v1.0.1 // indirect github.com/moby/spdystream v0.5.0 // indirect + github.com/moby/sys/capability v0.4.0 // indirect github.com/moby/sys/mountinfo v0.7.2 // indirect github.com/moby/sys/sequential v0.6.0 // indirect github.com/moby/sys/signal v0.7.1 // indirect @@ -400,11 +403,11 @@ require ( github.com/nats-io/jsm.go v0.3.0 // indirect github.com/nats-io/jwt/v2 v2.8.0 // indirect github.com/nats-io/nats-server/v2 v2.12.2 // indirect - github.com/nats-io/nats.go v1.48.0 // indirect - github.com/nats-io/nkeys v0.4.11 // indirect + github.com/nats-io/nats.go v1.49.0 // indirect + github.com/nats-io/nkeys v0.4.12 // indirect github.com/nats-io/nuid v1.0.1 // indirect - github.com/opencontainers/runtime-spec v1.2.1 // indirect - github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 // indirect + github.com/opencontainers/runtime-spec v1.3.0 // indirect + github.com/opencontainers/runtime-tools v0.9.1-0.20251114084447-edf4cb3d2116 // indirect github.com/otiai10/mint v1.6.3 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect @@ -413,10 +416,10 @@ require ( github.com/pierrec/lz4 v2.6.0+incompatible // indirect github.com/pion/datachannel v1.5.10 // indirect github.com/pion/dtls/v2 v2.2.12 // indirect - github.com/pion/dtls/v3 v3.0.6 // indirect + github.com/pion/dtls/v3 v3.0.11 // indirect github.com/pion/ice/v4 v4.0.10 // indirect github.com/pion/interceptor v0.1.40 // indirect - github.com/pion/logging v0.2.3 // indirect + github.com/pion/logging v0.2.4 // indirect github.com/pion/mdns/v2 v2.0.7 // indirect github.com/pion/randutil v0.1.0 // indirect github.com/pion/rtcp v1.2.15 // indirect @@ -428,8 +431,10 @@ require ( github.com/pion/stun/v3 v3.0.0 // indirect github.com/pion/transport/v2 v2.2.10 // indirect github.com/pion/transport/v3 v3.0.7 // indirect + github.com/pion/transport/v4 v4.0.1 // indirect github.com/pion/turn/v4 v4.0.2 // indirect github.com/pion/webrtc/v4 v4.1.2 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/pquerna/cachecontrol v0.1.0 // indirect @@ -449,12 +454,12 @@ require ( github.com/spf13/cobra v1.9.1 // indirect github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 // indirect github.com/stoewer/go-strcase v1.3.1 // indirect - github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect github.com/syndtr/goleveldb v1.0.0 // indirect - github.com/tchap/go-patricia/v2 v2.3.2 // indirect + github.com/tchap/go-patricia/v2 v2.3.3 // indirect + github.com/tetratelabs/wazero v1.10.1 // indirect github.com/tidwall/btree v1.8.1 // indirect github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 // indirect - github.com/vbatts/tar-split v0.12.1 // indirect + github.com/vbatts/tar-split v0.12.2 // indirect github.com/vishvananda/netns v0.0.5 // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/wlynxg/anet v0.0.5 // indirect @@ -469,12 +474,12 @@ require ( go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.44.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect - go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel v1.40.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.39.0 // indirect - go.opentelemetry.io/otel/sdk v1.39.0 // indirect - go.opentelemetry.io/otel/trace v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/otel/sdk v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.40.0 // indirect go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/dig v1.19.0 // indirect @@ -500,18 +505,18 @@ require ( gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/controller-manager v0.34.5 // indirect - k8s.io/csi-translation-lib v0.0.0 // indirect - k8s.io/dynamic-resource-allocation v0.0.0 // indirect - k8s.io/endpointslice v0.0.0 // indirect + k8s.io/csi-translation-lib v0.34.5 // indirect + k8s.io/dynamic-resource-allocation v0.34.5 // indirect + k8s.io/endpointslice v0.34.5 // indirect k8s.io/externaljwt v1.32.0 // indirect - k8s.io/kms v0.0.0 // indirect + k8s.io/kms v0.34.5 // indirect k8s.io/kube-aggregator v0.34.5 // indirect - k8s.io/kube-controller-manager v0.0.0 // indirect - k8s.io/kube-openapi v0.0.0-20250814151709-d7b6acb124c3 // indirect - k8s.io/kube-scheduler v0.0.0 // indirect - k8s.io/metrics v0.0.0 // indirect - k8s.io/mount-utils v0.32.4 // indirect - k8s.io/pod-security-admission v0.0.0 // indirect + k8s.io/kube-controller-manager v0.34.5 // indirect + k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect + k8s.io/kube-scheduler v0.34.5 // indirect + k8s.io/metrics v0.34.5 // indirect + k8s.io/mount-utils v0.34.5 // indirect + k8s.io/pod-security-admission v0.34.5 // indirect lukechampine.com/blake3 v1.4.1 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect @@ -521,6 +526,6 @@ require ( sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect - tags.cncf.io/container-device-interface v1.0.1 // indirect - tags.cncf.io/container-device-interface/specs-go v1.0.0 // indirect + tags.cncf.io/container-device-interface v1.1.0 // indirect + tags.cncf.io/container-device-interface/specs-go v1.1.0 // indirect ) diff --git a/go.sum b/go.sum index ee4b0c3d52e5..5620ad8e8f3d 100644 --- a/go.sum +++ b/go.sum @@ -246,8 +246,8 @@ github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1 github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Microsoft/hcsshim v0.13.0 h1:/BcXOiS6Qi7N9XqUcv27vkIuVOkBEcWstd2pMlWSeaA= -github.com/Microsoft/hcsshim v0.13.0/go.mod h1:9KWJ/8DgU+QzYGupX4tzMhRQE8h6w90lH6HAaclpEok= +github.com/Microsoft/hcsshim v0.14.0-rc.1 h1:qAPXKwGOkVn8LlqgBN8GS0bxZ83hOJpcjxzmlQKxKsQ= +github.com/Microsoft/hcsshim v0.14.0-rc.1/go.mod h1:hTKFGbnDtQb1wHiOWv4v0eN+7boSWAHyK/tNAaYZL0c= github.com/Microsoft/hnslib v0.1.1 h1:JsZy681SnvSOUAfCZVAxkX4LgQGp+CZZwPbLV0/pdF8= github.com/Microsoft/hnslib v0.1.1/go.mod h1:DRQR4IjLae6WHYVhW7uqe44hmFUiNhmaWA+jwMbz5tM= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= @@ -258,6 +258,8 @@ github.com/RaduBerinde/btreemap v0.0.0-20250419174037-3d62b7205d54 h1:bsU8Tzxr/P github.com/RaduBerinde/btreemap v0.0.0-20250419174037-3d62b7205d54/go.mod h1:0tr7FllbE9gJkHq7CVeeDDFAFKQVy5RnCSSNBOvdqbc= github.com/Rican7/retry v0.3.1 h1:scY4IbO8swckzoA/11HgBwaZRJEyY9vaNJshcdhp1Mc= github.com/Rican7/retry v0.3.1/go.mod h1:CxSDrhAyXmTMeEuRAnArMu1FHu48vtfjLREWqVl7Vw0= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= +github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= @@ -291,6 +293,8 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/brandond/containerd/v2 v2.2.2-bd1.34 h1:WFkfwuK/VzmIst+6AaVMq2P47L3ZKkONGHZiY3TMpJ4= +github.com/brandond/containerd/v2 v2.2.2-bd1.34/go.mod h1:CxjFDF0QbFWazWGg1oDrFf87FKCoe1tYFvDGuuL7NsI= github.com/bronze1man/goStrongswanVici v0.0.0-20231128135937-211cef3b0b20 h1:JMoL5xJSYxo1QVJ3c+4FutWQnks3gZX9DYkgAnvg+5g= github.com/bronze1man/goStrongswanVici v0.0.0-20231128135937-211cef3b0b20/go.mod h1:fWUtBEPt2yjrr3WFhOqvajM8JSEU8bEeBcoeSCsKRpc= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= @@ -304,8 +308,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= -github.com/checkpoint-restore/checkpointctl v1.3.0 h1:bNz5b6s+lxFdG5ZGDba3qSkBtXDDTCG2494dfAbQJ4E= -github.com/checkpoint-restore/checkpointctl v1.3.0/go.mod h1:dqZH4wDvbjnsqFGK2LdUDk21yFQ1dCAtzgRMlG44KDM= +github.com/checkpoint-restore/checkpointctl v1.4.0 h1:3kRns56TArwiyHOMakaumUgSZZlB1hZBkjVgR6IeZ3E= +github.com/checkpoint-restore/checkpointctl v1.4.0/go.mod h1:ynQ52zQBazgcTZuxpwTFzRinIcAf0haDTC1X1LA/FKA= github.com/checkpoint-restore/go-criu/v7 v7.2.0 h1:qGiWA4App1gGlEfIJ68WR9jbezV9J7yZdjzglezcqKo= github.com/checkpoint-restore/go-criu/v7 v7.2.0/go.mod h1:u0LCWLg0w4yqqu14aXhiB4YD3a1qd8EcCEg7vda5dwo= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -340,12 +344,12 @@ github.com/container-storage-interface/spec v1.9.0 h1:zKtX4STsq31Knz3gciCYCi1SXt github.com/container-storage-interface/spec v1.9.0/go.mod h1:ZfDu+3ZRyeVqxZM0Ds19MVLkN2d1XJ5MAfi1L3VjlT0= github.com/containerd/btrfs/v2 v2.0.0 h1:FN4wsx7KQrYoLXN7uLP0vBV4oVWHOIKDRQ1G2Z0oL5M= github.com/containerd/btrfs/v2 v2.0.0/go.mod h1:swkD/7j9HApWpzl8OHfrHNxppPd9l44DFZdF94BUj9k= -github.com/containerd/cgroups/v3 v3.1.0 h1:azxYVj+91ZgSnIBp2eI3k9y2iYQSR/ZQIgh9vKO+HSY= -github.com/containerd/cgroups/v3 v3.1.0/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins= +github.com/containerd/cgroups/v3 v3.1.2 h1:OSosXMtkhI6Qove637tg1XgK4q+DhR0mX8Wi8EhrHa4= +github.com/containerd/cgroups/v3 v3.1.2/go.mod h1:PKZ2AcWmSBsY/tJUVhtS/rluX0b1uq1GmPO1ElCmbOw= github.com/containerd/console v1.0.5 h1:R0ymNeydRqH2DmakFNdmjR2k0t7UPuiOV/N/27/qqsc= github.com/containerd/console v1.0.5/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= -github.com/containerd/containerd/api v1.9.0 h1:HZ/licowTRazus+wt9fM6r/9BQO7S0vD5lMcWspGIg0= -github.com/containerd/containerd/api v1.9.0/go.mod h1:GhghKFmTR3hNtyznBoQ0EMWr9ju5AqHjcZPsSpTKutI= +github.com/containerd/containerd/api v1.10.0 h1:5n0oHYVBwN4VhoX9fFykCV9dF1/BvAXeg2F8W6UYq1o= +github.com/containerd/containerd/api v1.10.0/go.mod h1:NBm1OAk8ZL+LG8R0ceObGxT5hbUYj7CzTmR3xh0DlMM= github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4= github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= @@ -354,32 +358,34 @@ github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151X github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY= github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o= -github.com/containerd/fuse-overlayfs-snapshotter/v2 v2.1.6 h1:gfW1JsN//B97zhsQ84Kkar7WJqod1fmWf8zKHmz+ieY= -github.com/containerd/fuse-overlayfs-snapshotter/v2 v2.1.6/go.mod h1:Mau9LZ7ZnyKCIgcNT7sMG5fjaZ9YCOHU5RuolUikhBQ= -github.com/containerd/go-cni v1.1.12 h1:wm/5VD/i255hjM4uIZjBRiEQ7y98W9ACy/mHeLi4+94= -github.com/containerd/go-cni v1.1.12/go.mod h1:+jaqRBdtW5faJxj2Qwg1Of7GsV66xcvnCx4mSJtUlxU= +github.com/containerd/fuse-overlayfs-snapshotter/v2 v2.1.7 h1:pD+wZQE81lBgjiQRaDMJYd9k9k/Xc90eKNpZho1r2tI= +github.com/containerd/fuse-overlayfs-snapshotter/v2 v2.1.7/go.mod h1:gzkTvoDZmX6hLuNn6qQ8s3wkTJ+Va9SbT76v07GzVK0= +github.com/containerd/go-cni v1.1.13 h1:eFSGOKlhoYNxpJ51KRIMHZNlg5UgocXEIEBGkY7Hnis= +github.com/containerd/go-cni v1.1.13/go.mod h1:nTieub0XDRmvCZ9VI/SBG6PyqT95N4FIhxsauF1vSBI= github.com/containerd/go-runc v1.1.0 h1:OX4f+/i2y5sUT7LhmcJH7GYrjjhHa1QI4e8yO0gGleA= github.com/containerd/go-runc v1.1.0/go.mod h1:xJv2hFF7GvHtTJd9JqTS2UVxMkULUYw4JN5XAUZqH5U= github.com/containerd/imgcrypt/v2 v2.0.1 h1:gQcmeCKA97fAl0wlpq0itSY/PagFBsn4/mlKUy6kOio= github.com/containerd/imgcrypt/v2 v2.0.1/go.mod h1:/qIJL8nxzdzMA2n5iYyyuIY36KfoVQWmgTWdfVtyebM= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/containerd/nri v0.8.0 h1:n1S753B9lX8RFrHYeSgwVvS1yaUcHjxbB+f+xzEncRI= -github.com/containerd/nri v0.8.0/go.mod h1:uSkgBrCdEtAiEz4vnrq8gmAC4EnVAM5Klt0OuK5rZYQ= +github.com/containerd/nri v0.11.0 h1:26mcQwNG58AZn0YkOrlJQ0yxQVmyZooflnVWJTqQrqQ= +github.com/containerd/nri v0.11.0/go.mod h1:bjGTLdUA58WgghKHg8azFMGXr05n1wDHrt3NSVBHiGI= github.com/containerd/otelttrpc v0.1.0 h1:UOX68eVTE8H/T45JveIg+I22Ev2aFj4qPITCmXsskjw= github.com/containerd/otelttrpc v0.1.0/go.mod h1:XhoA2VvaGPW1clB2ULwrBZfXVuEWuyOd2NUD1IM0yTg= github.com/containerd/platforms v1.0.0-rc.2 h1:0SPgaNZPVWGEi4grZdV8VRYQn78y+nm6acgLGv/QzE4= github.com/containerd/platforms v1.0.0-rc.2/go.mod h1:J71L7B+aiM5SdIEqmd9wp6THLVRzJGXfNuWCZCllLA4= github.com/containerd/plugin v1.0.0 h1:c8Kf1TNl6+e2TtMHZt+39yAPDbouRH9WAToRjex483Y= github.com/containerd/plugin v1.0.0/go.mod h1:hQfJe5nmWfImiqT1q8Si3jLv3ynMUIBB47bQ+KexvO8= -github.com/containerd/stargz-snapshotter/estargz v0.17.0 h1:+TyQIsR/zSFI1Rm31EQBwpAA1ovYgIKHy7kctL3sLcE= -github.com/containerd/stargz-snapshotter/estargz v0.17.0/go.mod h1:s06tWAiJcXQo9/8AReBCIo/QxcXFZ2n4qfsRnpl71SM= +github.com/containerd/stargz-snapshotter v0.18.1 h1:eIkwsafohSWas5YmhxoumrI7elmb2EZJcW8eu7goyOY= +github.com/containerd/stargz-snapshotter v0.18.1/go.mod h1:HPC+XHGIxkjWfAONMvXepQyOs8iGApP2e5A3fOv2TCU= +github.com/containerd/stargz-snapshotter/estargz v0.18.1 h1:cy2/lpgBXDA3cDKSyEfNOFMA/c10O1axL69EU7iirO8= +github.com/containerd/stargz-snapshotter/estargz v0.18.1/go.mod h1:ALIEqa7B6oVDsrF37GkGN20SuvG/pIMm7FwP7ZmRb0Q= github.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRqQ= github.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40= github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk= -github.com/containerd/zfs/v2 v2.0.0-rc.0 h1:0dRlgpoaepW7HuovtcvYQMF7NlpceQVdn7+3Udeth4M= -github.com/containerd/zfs/v2 v2.0.0-rc.0/go.mod h1:g36g/XCEGDRxUXIFdM3oWAEvmTvhfz/eKWElqg4Secw= +github.com/containerd/zfs/v2 v2.0.0 h1:sI0wKwWNQXR9G4jnPPrXmMSetm6PGAwgqBRTQtFUY/o= +github.com/containerd/zfs/v2 v2.0.0/go.mod h1:fnUDKF98iYuQqLvNdoXs9MXjtfhRWp1nxSgRf7VZH8s= github.com/containernetworking/cni v1.3.0 h1:v6EpN8RznAZj9765HhXQrtXgX+ECGebEYEmnuFjskwo= github.com/containernetworking/cni v1.3.0/go.mod h1:Bs8glZjjFfGPHMw6hQu82RUgEPNGEaBb9KS5KtNMnJ4= github.com/containernetworking/plugins v1.9.0 h1:Mg3SXBdRGkdXyFC4lcwr6u2ZB2SDeL6LC3U+QrEANuQ= @@ -415,8 +421,8 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvw github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/cli v28.3.2+incompatible h1:mOt9fcLE7zaACbxW1GeS65RI67wIJrTnqS3hP2huFsY= -github.com/docker/cli v28.3.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v29.2.0+incompatible h1:9oBd9+YM7rxjZLfyMGxjraKBKE4/nVyvVfN4qNl9XRM= +github.com/docker/cli v29.2.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v25.0.8+incompatible h1:FSKbeS2aCyKqNymmbPnq6qM8EQkxOpLK7gth1cpy4g4= @@ -501,8 +507,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= -github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= -github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= +github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= +github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -514,6 +520,8 @@ github.com/go-logr/stdr v1.2.3-0.20220714215716-96bad1d688c5 h1:aj5xnNwNY2GCk38V github.com/go-logr/stdr v1.2.3-0.20220714215716-96bad1d688c5/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= 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-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.22.0 h1:TmMhghgNef9YXxTu1tOopo+0BGEytxA+okbry0HjZsM= github.com/go-openapi/jsonpointer v0.22.0/go.mod h1:xt3jV88UtExdIkkL7NloURjRQjbeUgcxFblMjq2iaiU= github.com/go-openapi/jsonreference v0.21.1 h1:bSKrcl8819zKiOgxkbVNRUBIr6Wwj9KYrDbMjRs0cDA= @@ -594,6 +602,10 @@ github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/cel-go v0.26.1 h1:iPbVVEdkhTX++hpe3lzSk7D3G3QSYqLGoHOcEio+UXQ= github.com/google/cel-go v0.26.1/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM= +github.com/google/certtostore v1.0.6 h1:LlCIgyTvDxTlcncMPTSYZGo6lCsiHzO6Dy7ff6ltk/0= +github.com/google/certtostore v1.0.6/go.mod h1:2N0ZPLkGvQWhYvXaiBGq02r71fnSLfq78VKIWQHr1wo= +github.com/google/deck v0.0.0-20230104221208-105ad94aa8ae h1:Iy1Ad7L9qPtNAFJad+Ch2kwDXrcwu7QUBR0bfChjnEM= +github.com/google/deck v0.0.0-20230104221208-105ad94aa8ae/go.mod h1:DoDv8G58DuLNZF0KysYn0bA/6ZWhmRW3fZE2VnGEH0w= github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= @@ -685,9 +697,8 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnV github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/guillaumemichel/reservedpool v0.3.0 h1:eqqO/QvTllLBrit7LVtVJBqw4cD0WdV9ajUe7WNTajw= github.com/guillaumemichel/reservedpool v0.3.0/go.mod h1:sXSDIaef81TFdAJglsCFCMfgF5E5Z5xK1tFhjDhvbUc= -github.com/hanwen/go-fuse/v2 v2.8.0 h1:wV8rG7rmCz8XHSOwBZhG5YcVqcYjkzivjmbaMafPlAs= -github.com/hanwen/go-fuse/v2 v2.8.0/go.mod h1:yE6D2PqWwm3CbYRxFXV9xUd8Md5d6NG0WBs5spCswmI= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hanwen/go-fuse/v2 v2.9.0 h1:0AOGUkHtbOVeyGLr0tXupiid1Vg7QB7M6YUcdmVdC58= +github.com/hanwen/go-fuse/v2 v2.9.0/go.mod h1:yE6D2PqWwm3CbYRxFXV9xUd8Md5d6NG0WBs5spCswmI= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= @@ -719,8 +730,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inetaf/tcpproxy v0.0.0-20240214030015-3ce58045626c h1:gYfYE403/nlrGNYj6BEOs9ucLCAGB9gstlSk92DttTg= github.com/inetaf/tcpproxy v0.0.0-20240214030015-3ce58045626c/go.mod h1:Di7LXRyUcnvAcLicFhtM9/MlZl/TNgRSDHORM2c6CMI= -github.com/intel/goresctrl v0.8.0 h1:N3shVbS3kA1Hk2AmcbHv8805Hjbv+zqsCIZCGktxx50= -github.com/intel/goresctrl v0.8.0/go.mod h1:T3ZZnuHSNouwELB5wvOoUJaB7l/4Rm23rJy/wuWJlr0= +github.com/intel/goresctrl v0.10.0 h1:Q94PBhLtQM/aVxVTKzB1j/ooMuV+9XleTN1fq2OGsSo= +github.com/intel/goresctrl v0.10.0/go.mod h1:1S8GDqL46GuKb525bxNhIEEkhf4rhVcbSf9DuKhp7mw= github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/ipfs/boxo v0.35.2 h1:0QZJJh6qrak28abENOi5OA8NjBnZM4p52SxeuIDqNf8= @@ -783,8 +794,6 @@ github.com/k3s-io/api v0.1.4 h1:mnu1pgtEEwplvDHgjeyekbC96wykUWsq0E5ouJoRkM4= github.com/k3s-io/api v0.1.4/go.mod h1:9aQAaTKBFWO+BpGrMFJk9uZaUhZRrL9aahobcOQQm64= github.com/k3s-io/cadvisor v0.52.1 h1:KeeADD5no2159ICWnTRTJfExlNbVfhqbo9ohixQ74GM= github.com/k3s-io/cadvisor v0.52.1/go.mod h1:OAhPcx1nOm5YwMh/JhpUOMKyv1YKLRtS9KgzWPndHmA= -github.com/k3s-io/containerd/v2 v2.1.5-k3s1 h1:P3rmxzZP5+UAxwdpUv6G4tkyJYirMEeTXqWbDpit3go= -github.com/k3s-io/containerd/v2 v2.1.5-k3s1/go.mod h1:ZFOeMOvrvPVVxAAYWIBlEtTTcbH/Q7IM1kGNrooupIg= github.com/k3s-io/cri-dockerd v0.3.19-k3s3 h1:fZTPlYTPZaUwh6Z8RTN6jYFjC3gvyW/O4VFKhG03tf4= github.com/k3s-io/cri-dockerd v0.3.19-k3s3/go.mod h1:t9ANNTpfHRdsVoKuwd+/INWoGgjQQRHiBENk4yfumSc= github.com/k3s-io/cri-tools v1.34.0-k3s2 h1:6TZBGipv1T3dhJmgIJzmHX8VvB45j/uH48wnfCx5+6Y= @@ -803,10 +812,10 @@ github.com/k3s-io/etcd/server/v3 v3.6.7-k3s1 h1:ZBV6n9XhjGex9MIOaEAefbhNriH5Gxo4 github.com/k3s-io/etcd/server/v3 v3.6.7-k3s1/go.mod h1:LEM328bPA2uVMhN0+Ht/vAsADW127QS1oM7EuHrOTy0= github.com/k3s-io/helm-controller v0.16.17 h1:VXMmXQmmTB49x6bnN/PsJUTVKHb0r69b+SffIDUTMTM= github.com/k3s-io/helm-controller v0.16.17/go.mod h1:jmrgGttLQbh2yB1kcf9XFAigNW6U8oWCswCSuEjkxXU= -github.com/k3s-io/kine v0.14.12 h1:He4hfjkFnd6zV/mwO7WUIsMp7zHAU02J4ALlViY8pKA= -github.com/k3s-io/kine v0.14.12/go.mod h1:5C5dPvFbapdvyLurH1Ls4xGdgl/Gqn+73BunjDndXBU= -github.com/k3s-io/klog/v2 v2.120.1-k3s1 h1:7twAHPFpZA21KdMnMNnj68STQMPldAxF2Zsaol57dxw= -github.com/k3s-io/klog/v2 v2.120.1-k3s1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +github.com/k3s-io/kine v0.14.14 h1:DD1tAIfOIy51T784p46szjVVXq019Uv7Efn+5HguhTA= +github.com/k3s-io/kine v0.14.14/go.mod h1:6+xemLl2cJ7csY06UWfj3HpkAzQLNGAfjElQwhumjyk= +github.com/k3s-io/klog/v2 v2.140.0-k3s1 h1:Z6S9oqaxcKtLaTcQNgWsaZNE5a+qJmCrTI+Lahor4X8= +github.com/k3s-io/klog/v2 v2.140.0-k3s1/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= github.com/k3s-io/kube-router/v2 v2.6.3-k3s1 h1:RZjUBIuitXCuYoCzm1aM6p5EgQFC5k3N72j4pBIc2j4= github.com/k3s-io/kube-router/v2 v2.6.3-k3s1/go.mod h1:RaxDc+SBKB33+fjao+LeDue4CaUajk02eCHXVK/V4YE= github.com/k3s-io/kubernetes v1.34.5-k3s1 h1:jpYn37PqkJeJAmQKmTHnRYaFEWy6j1LxDHvNB4twja0= @@ -865,8 +874,6 @@ github.com/k3s-io/kubernetes/staging/src/k8s.io/pod-security-admission v1.34.5-k github.com/k3s-io/kubernetes/staging/src/k8s.io/pod-security-admission v1.34.5-k3s1/go.mod h1:3bwMqCfzs5exVFZydu9eBJkw5UbmNzDvxCYT7JWYVAo= github.com/k3s-io/spegel v0.6.0-k3s1 h1:GUdEnBaNrwXcl95vZLkXYvL5SacfVO+ps1QVanz04zI= github.com/k3s-io/spegel v0.6.0-k3s1/go.mod h1:x6yD3BfTF6zhhpjSWXPflm5QDtwCh2U6fIVE6Gt3hFM= -github.com/k3s-io/stargz-snapshotter v0.17.0-k3s1 h1:QkAk5A+As/MiFoknI6FJSpFVLQ7BuhcMvEwmWjwuq0Y= -github.com/k3s-io/stargz-snapshotter v0.17.0-k3s1/go.mod h1:UgxD0RRcEELdIwC+WoKBJ1saQZHoXPyoKpkFK/fiXdY= github.com/karrick/godirwalk v1.17.0 h1:b4kY7nqDdioR/6qnbHQyDvmA17u5G1cZ6J+CZXwSWoI= github.com/karrick/godirwalk v1.17.0/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= @@ -881,6 +888,8 @@ github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/knqyf263/go-plugin v0.9.0 h1:CQs2+lOPIlkZVtcb835ZYDEoyyWJWLbSTWeCs0EwTwI= +github.com/knqyf263/go-plugin v0.9.0/go.mod h1:2z5lCO1/pez6qGo8CvCxSlBFSEat4MEp1DrnA+f7w8Q= github.com/koron/go-ssdp v0.0.6 h1:Jb0h04599eq/CY7rB5YEqPS83HmRfHP2azkxMN2rFtU= github.com/koron/go-ssdp v0.0.6/go.mod h1:0R9LfRJGek1zWTjN3JUNlm5INCDYGpRDfAptnct63fI= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -993,13 +1002,14 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= -github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs= github.com/moby/ipvs v1.1.0 h1:ONN4pGaZQgAx+1Scz5RvWV4Q7Gb+mvfRh3NsPS+1XQQ= github.com/moby/ipvs v1.1.0/go.mod h1:4VJMWuf098bsUMmZEiD4Tjk/O7mOn3l1PTD3s4OoYAs= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= +github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk= +github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I= github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= github.com/moby/sys/reexec v0.1.0 h1:RrBi8e0EBTLEgfruBOFcxtElzRGTEUkeIFaVXgU7wok= @@ -1031,7 +1041,6 @@ github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7P github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= @@ -1069,10 +1078,10 @@ github.com/nats-io/jwt/v2 v2.8.0 h1:K7uzyz50+yGZDO5o772eRE7atlcSEENpL7P+b74JV1g= github.com/nats-io/jwt/v2 v2.8.0/go.mod h1:me11pOkwObtcBNR8AiMrUbtVOUGkqYjMQZ6jnSdVUIA= github.com/nats-io/nats-server/v2 v2.12.2 h1:4TEQd0Y4zvcW0IsVxjlXnRso1hBkQl3TS0BI+SxgPhE= github.com/nats-io/nats-server/v2 v2.12.2/go.mod h1:j1AAttYeu7WnvD8HLJ+WWKNMSyxsqmZ160pNtCQRMyE= -github.com/nats-io/nats.go v1.48.0 h1:pSFyXApG+yWU/TgbKCjmm5K4wrHu86231/w84qRVR+U= -github.com/nats-io/nats.go v1.48.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g= -github.com/nats-io/nkeys v0.4.11 h1:q44qGV008kYd9W1b1nEBkNzvnWxtRSQ7A8BoqRrcfa0= -github.com/nats-io/nkeys v0.4.11/go.mod h1:szDimtgmfOi9n25JpfIdGw12tZFYXqhGxjhVxsatHVE= +github.com/nats-io/nats.go v1.49.0 h1:yh/WvY59gXqYpgl33ZI+XoVPKyut/IcEaqtsiuTJpoE= +github.com/nats-io/nats.go v1.49.0/go.mod h1:fDCn3mN5cY8HooHwE2ukiLb4p4G4ImmzvXyJt+tGwdw= +github.com/nats-io/nkeys v0.4.12 h1:nssm7JKOG9/x4J8II47VWCL1Ds29avyiQDRn0ckMvDc= +github.com/nats-io/nkeys v0.4.12/go.mod h1:MT59A1HYcjIcyQDJStTfaOY6vhy9XTUjOFo+SVsvpBg= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= @@ -1092,11 +1101,10 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= -github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww= -github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 h1:DmNGcqH3WDbV5k8OJ+esPWbqUOX5rMLR2PMvziDMJi0= -github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626/go.mod h1:BRHJJd0E+cx42OybVYSgUvZmU0B8P9gZuRXlZUP7TKI= +github.com/opencontainers/runtime-spec v1.3.0 h1:YZupQUdctfhpZy3TM39nN9Ika5CBWT5diQ8ibYCRkxg= +github.com/opencontainers/runtime-spec v1.3.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-tools v0.9.1-0.20251114084447-edf4cb3d2116 h1:tAKu3NkKWZYpqBSOJKwTxT1wIGueiF7gcmcNgr5pNTY= +github.com/opencontainers/runtime-tools v0.9.1-0.20251114084447-edf4cb3d2116/go.mod h1:DKDEfzxvRkoQ6n9TGhxQgg2IM1lY4aM0eaQP4e3oElw= github.com/opencontainers/selinux v1.13.0 h1:Zza88GWezyT7RLql12URvoxsbLfjFx988+LGaWfbL84= github.com/opencontainers/selinux v1.13.0/go.mod h1:XxWTed+A/s5NNq4GmYScVy+9jzXhGBVEOAyucdRUY8s= github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8= @@ -1105,6 +1113,8 @@ github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs= github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= +github.com/pdtpartners/nix-snapshotter v0.4.0 h1:c9wxyxoJq/toKdUgoh704Tctl5bMgWksrP+fH1Trle4= +github.com/pdtpartners/nix-snapshotter v0.4.0/go.mod h1:AuH0d9eY9rOXnI3MCzIp4BKoQCy0eIyB6CLQCEtki7M= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= @@ -1122,15 +1132,15 @@ github.com/pion/datachannel v1.5.10/go.mod h1:p/jJfC9arb29W7WrxyKbepTU20CFgyx5oL github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/dtls/v3 v3.0.6 h1:7Hkd8WhAJNbRgq9RgdNh1aaWlZlGpYTzdqjy9x9sK2E= -github.com/pion/dtls/v3 v3.0.6/go.mod h1:iJxNQ3Uhn1NZWOMWlLxEEHAN5yX7GyPvvKw04v9bzYU= +github.com/pion/dtls/v3 v3.0.11 h1:zqn8YhoAU7d9whsWLhNiQlbB8QdpJj8XQVSc5ImUons= +github.com/pion/dtls/v3 v3.0.11/go.mod h1:YEmmBYIoBsY3jmG56dsziTv/Lca9y4Om83370CXfqJ8= github.com/pion/ice/v4 v4.0.10 h1:P59w1iauC/wPk9PdY8Vjl4fOFL5B+USq1+xbDcN6gT4= github.com/pion/ice/v4 v4.0.10/go.mod h1:y3M18aPhIxLlcO/4dn9X8LzLLSma84cx6emMSu14FGw= github.com/pion/interceptor v0.1.40 h1:e0BjnPcGpr2CFQgKhrQisBU7V3GXK6wrfYrGYaU6Jq4= github.com/pion/interceptor v0.1.40/go.mod h1:Z6kqH7M/FYirg3frjGJ21VLSRJGBXB/KqaTIrdqnOic= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= -github.com/pion/logging v0.2.3 h1:gHuf0zpoh1GW67Nr6Gj4cv5Z9ZscU7g/EaoC/Ke/igI= -github.com/pion/logging v0.2.3/go.mod h1:z8YfknkquMe1csOrxK5kc+5/ZPAzMxbKLX5aXpbpC90= +github.com/pion/logging v0.2.4 h1:tTew+7cmQ+Mc1pTBLKH2puKsOvhm32dROumOZ655zB8= +github.com/pion/logging v0.2.4/go.mod h1:DffhXTKYdNZU+KtJ5pyQDjvOAh/GsNSyv1lbkFbe3so= github.com/pion/mdns/v2 v2.0.7 h1:c9kM8ewCgjslaAmicYMFQIde2H9/lrZpjBkN8VwoVtM= github.com/pion/mdns/v2 v2.0.7/go.mod h1:vAdSYNAT0Jy3Ru0zl2YiW3Rm/fJCwIeM0nToenfOJKA= github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= @@ -1155,6 +1165,8 @@ github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQp github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0= github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo= +github.com/pion/transport/v4 v4.0.1 h1:sdROELU6BZ63Ab7FrOLn13M6YdJLY20wldXW2Cu2k8o= +github.com/pion/transport/v4 v4.0.1/go.mod h1:nEuEA4AD5lPdcIegQDpVLgNoDGreqM/YqmEx3ovP4jM= github.com/pion/turn/v4 v4.0.2 h1:ZqgQ3+MjP32ug30xAbD6Mn+/K4Sxi3SdNOTFf+7mpps= github.com/pion/turn/v4 v4.0.2/go.mod h1:pMMKP/ieNAG/fN5cZiN4SDuyKsXtNTr0ccN7IToA1zs= github.com/pion/webrtc/v4 v4.1.2 h1:mpuUo/EJ1zMNKGE79fAdYNFZBX790KE7kQQpLMjjR54= @@ -1195,18 +1207,18 @@ github.com/quic-go/quic-go v0.57.1 h1:25KAAR9QR8KZrCZRThWMKVAwGoiHIrNbT72ULHTuI1 github.com/quic-go/quic-go v0.57.1/go.mod h1:ly4QBAjHA2VhdnxhojRsCUOeJwKYg+taDlos92xb1+s= github.com/quic-go/webtransport-go v0.9.0 h1:jgys+7/wm6JarGDrW+lD/r9BGqBAmqY/ssklE09bA70= github.com/quic-go/webtransport-go v0.9.0/go.mod h1:4FUYIiUc75XSsF6HShcLeXXYZJ9AGwo/xh3L8M/P1ao= -github.com/rancher/dynamiclistener v0.7.1 h1:vt4AGDw/s19qFCfpyYSQS8HcRc6THcTD7PIAPAK2R1o= -github.com/rancher/dynamiclistener v0.7.1/go.mod h1:kq+3QHceIpW3f2xVpYgok7ILn1JcS8+O2utC42y8ZNY= -github.com/rancher/lasso v0.2.3 h1:74/z/C/O3ykhyMrRuEgc9kVyYiSoS7kp5BAijlcyXDg= -github.com/rancher/lasso v0.2.3/go.mod h1:G+KeeOaKRjp+qGp0bV6VbLhYrq1vHbJPbDh40ejg5yE= +github.com/rancher/dynamiclistener v0.7.5 h1:C8Aqefrwo18Z6//CNXt7Wf2gwajMOpVmWEcSU/dJRE8= +github.com/rancher/dynamiclistener v0.7.5/go.mod h1:eL7NEC7+bmHgjwRxJ2vddmgnTe0nGatIyz5aXHHbZ60= +github.com/rancher/lasso v0.2.5 h1:K++lWDDdfeN98Ixc1kCfUq0/q6tLjoHN++Np6QntXw0= +github.com/rancher/lasso v0.2.5/go.mod h1:71rWfv+KkdSmSxZ9Ly5QYhxAu0nEUcaq9N2ByjcHqAM= github.com/rancher/permissions v0.0.0-20240523180510-4001d3d637f7 h1:0Kg2SGoMeU1ll4xPi4DE0+qNHLFO/U5MwtK0WrIdK+o= github.com/rancher/permissions v0.0.0-20240523180510-4001d3d637f7/go.mod h1:fsbs0YOsGn1ofPD5p+BuI4qDhbMbSJtTegKt6Ucna+c= github.com/rancher/remotedialer v0.6.0-rc.1.0.20250916111157-f160aa32568d h1:0ckbeLz9EFnLznH3+ywtQ3UaMbCaJbyaHc5ut/wzqH8= github.com/rancher/remotedialer v0.6.0-rc.1.0.20250916111157-f160aa32568d/go.mod h1:CW6Q8F8IESN05/yl48OSwhVi54nDwVQQriV16zAiGkg= -github.com/rancher/wharfie v0.7.0 h1:M+OHMkE+tfafY59E5RuZ/Q4IorKNJGVqhtZRksTpOWo= -github.com/rancher/wharfie v0.7.0/go.mod h1:wSQoRNUM58z0Qb9kmAT1L6ia2ys0LWHRH+7Vix/rkD8= -github.com/rancher/wrangler/v3 v3.2.3 h1:s35Dpu/oIbXI1GV/FmYQaAex60+NXe67An3Z5zzzyEY= -github.com/rancher/wrangler/v3 v3.2.3/go.mod h1:TA1QuuQxrtn/kmJbBLW/l24IcfHBmSXBa9an3IRlqQQ= +github.com/rancher/wharfie v0.7.1 h1:/4MPrr71I7aXESB0C5DVf7an4H1TYOYv1yx6vA6eKko= +github.com/rancher/wharfie v0.7.1/go.mod h1:x/X8GGrrjBAdKHJuSF4ANqcljVQAhu3jBHoutVKeCE8= +github.com/rancher/wrangler/v3 v3.3.4 h1:Df+BlerYtTy5RDxEMZFG57kzz8KDe+Q4pJp/hyu5KcY= +github.com/rancher/wrangler/v3 v3.3.4/go.mod h1:6NaqLD16x/cH2kzwhF35v5TTQTdaiGoomVyz//Hc0TY= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= @@ -1285,22 +1297,21 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8 github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= -github.com/tchap/go-patricia/v2 v2.3.2 h1:xTHFutuitO2zqKAQ5rCROYgUb7Or/+IC3fts9/Yc7nM= -github.com/tchap/go-patricia/v2 v2.3.2/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= +github.com/tchap/go-patricia/v2 v2.3.3 h1:xfNEsODumaEcCcY3gI0hYPZ/PcpVv5ju6RMAhgwZDDc= +github.com/tchap/go-patricia/v2 v2.3.3/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= +github.com/tetratelabs/wazero v1.10.1 h1:2DugeJf6VVk58KTPszlNfeeN8AhhpwcZqkJj2wwFuH8= +github.com/tetratelabs/wazero v1.10.1/go.mod h1:DRm5twOQ5Gr1AoEdSi0CLjDQF1J9ZAuyqFIjl1KKfQU= github.com/tidwall/btree v1.8.1 h1:27ehoXvm5AG/g+1VxLS1SD3vRhp/H7LuEfwNvddEdmA= github.com/tidwall/btree v1.8.1/go.mod h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= -github.com/urfave/cli v1.19.1/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU= github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AOXUZjA4= -github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo= -github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA= +github.com/vbatts/tar-split v0.12.2 h1:w/Y6tjxpeiFMR47yzZPlPj/FcPLpXbTUi/9H7d3CPa4= +github.com/vbatts/tar-split v0.12.2/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA= github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0= github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4= github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= @@ -1316,7 +1327,6 @@ github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= @@ -1369,8 +1379,8 @@ go.opentelemetry.io/contrib/propagators/b3 v1.19.0 h1:ulz44cpm6V5oAeg5Aw9HyqGFMS go.opentelemetry.io/contrib/propagators/b3 v1.19.0/go.mod h1:OzCmE2IVS+asTI+odXQstRGVfXQ4bXv9nMBRK0nNyqQ= go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= -go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= -go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= +go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= @@ -1379,18 +1389,18 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= -go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= -go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= +go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= -go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= -go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= +go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= -go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= -go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= +go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= -go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= -go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= +go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= @@ -1404,8 +1414,8 @@ go.uber.org/fx v1.24.0 h1:wE8mruvpg2kiiL1Vqd0CC+tr0/24XIB10Iwp2lLWzkg= go.uber.org/fx v1.24.0/go.mod h1:AmDeGyS+ZARGKM4tlH4FY2Jr63VjbEDJHtqXTGP5hbo= 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/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko= -go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o= +go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= @@ -1802,8 +1812,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= -gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= -gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1816,8 +1826,8 @@ k8s.io/cri-client v0.34.5 h1:p/ikiLX2OSElhtdcUWvlsDislz92TghzJJUqpGWynDE= k8s.io/cri-client v0.34.5/go.mod h1:d/746g/YRAiDqaYVeznmkltmeP6a0bwTX1cT49+EVfg= k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA= k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= -k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d h1:wAhiDyZ4Tdtt7e46e9M5ZSAJ/MnPGPs+Ki1gHw4w1R0= -k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg= lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= @@ -1876,7 +1886,7 @@ sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/ sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= -tags.cncf.io/container-device-interface v1.0.1 h1:KqQDr4vIlxwfYh0Ed/uJGVgX+CHAkahrgabg6Q8GYxc= -tags.cncf.io/container-device-interface v1.0.1/go.mod h1:JojJIOeW3hNbcnOH2q0NrWNha/JuHoDZcmYxAZwb2i0= -tags.cncf.io/container-device-interface/specs-go v1.0.0 h1:8gLw29hH1ZQP9K1YtAzpvkHCjjyIxHZYzBAvlQ+0vD8= -tags.cncf.io/container-device-interface/specs-go v1.0.0/go.mod h1:u86hoFWqnh3hWz3esofRFKbI261bUlvUfLKGrDhJkgQ= +tags.cncf.io/container-device-interface v1.1.0 h1:RnxNhxF1JOu6CJUVpetTYvrXHdxw9j9jFYgZpI+anSY= +tags.cncf.io/container-device-interface v1.1.0/go.mod h1:76Oj0Yqp9FwTx/pySDc8Bxjpg+VqXfDb50cKAXVJ34Q= +tags.cncf.io/container-device-interface/specs-go v1.1.0 h1:QRZVeAceQM+zTZe12eyfuJuuzp524EKYwhmvLd+h+yQ= +tags.cncf.io/container-device-interface/specs-go v1.1.0/go.mod h1:u86hoFWqnh3hWz3esofRFKbI261bUlvUfLKGrDhJkgQ= diff --git a/manifests/local-storage.yaml b/manifests/local-storage.yaml index a55586c825d7..83dc448945c8 100644 --- a/manifests/local-storage.yaml +++ b/manifests/local-storage.yaml @@ -66,7 +66,7 @@ spec: kubernetes.io/os: linux containers: - name: local-path-provisioner - image: "%{SYSTEM_DEFAULT_REGISTRY}%rancher/local-path-provisioner:v0.0.34" + image: "%{SYSTEM_DEFAULT_REGISTRY}%rancher/local-path-provisioner:v0.0.35" imagePullPolicy: IfNotPresent command: - local-path-provisioner diff --git a/manifests/traefik.yaml b/manifests/traefik.yaml index eac0113421e1..b98bee4d2931 100644 --- a/manifests/traefik.yaml +++ b/manifests/traefik.yaml @@ -28,7 +28,7 @@ spec: priorityClassName: "system-cluster-critical" image: repository: "rancher/mirrored-library-traefik" - tag: "3.6.9" + tag: "3.6.10" tolerations: - key: "CriticalAddonsOnly" operator: "Exists" diff --git a/pkg/agent/config/config.go b/pkg/agent/config/config.go index 75d9d225cd62..f074cbd104a7 100644 --- a/pkg/agent/config/config.go +++ b/pkg/agent/config/config.go @@ -9,7 +9,6 @@ import ( "crypto/x509" "encoding/hex" "encoding/pem" - "errors" "fmt" "io" "net" @@ -30,8 +29,8 @@ import ( "github.com/k3s-io/k3s/pkg/daemons/control/deps" "github.com/k3s-io/k3s/pkg/spegel" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" - pkgerrors "github.com/pkg/errors" certutil "github.com/rancher/dynamiclistener/cert" "github.com/rancher/wharfie/pkg/registries" "github.com/rancher/wrangler/v3/pkg/slice" @@ -248,7 +247,7 @@ func upgradeOldNodePasswordPath(oldNodePasswordFile, newNodePasswordFile string) func getKubeletServingCert(nodeName string, nodeIPs []net.IP, certFile, keyFile, nodePasswordFile string, info *clientaccess.Info) error { csr, err := getCSRBytes(keyFile) if err != nil { - return pkgerrors.WithMessagef(err, "failed to create certificate request %s", certFile) + return errors.WithMessagef(err, "failed to create certificate request %s", certFile) } basename := filepath.Base(certFile) @@ -262,11 +261,11 @@ func getKubeletServingCert(nodeName string, nodeIPs []net.IP, certFile, keyFile, // must be used instead of the one we signed the CSR with. certBytes, keyBytes := splitCertKeyPEM(body) if err := os.WriteFile(certFile, certBytes, 0600); err != nil { - return pkgerrors.WithMessagef(err, "failed to write cert %s", certFile) + return errors.WithMessagef(err, "failed to write cert %s", certFile) } if len(keyBytes) > 0 { if err := os.WriteFile(keyFile, keyBytes, 0600); err != nil { - return pkgerrors.WithMessagef(err, "failed to write key %s", keyFile) + return errors.WithMessagef(err, "failed to write key %s", keyFile) } } return nil @@ -280,7 +279,7 @@ func getHostFile(filename string, info *clientaccess.Info) error { return err } if err := os.WriteFile(filename, fileBytes, 0600); err != nil { - return pkgerrors.WithMessagef(err, "failed to write cert %s", filename) + return errors.WithMessagef(err, "failed to write cert %s", filename) } return nil } @@ -292,7 +291,7 @@ func getHostFile(filename string, info *clientaccess.Info) error { func getClientCert(certFile, keyFile string, info *clientaccess.Info) error { csr, err := getCSRBytes(keyFile) if err != nil { - return pkgerrors.WithMessagef(err, "failed to create certificate request %s", certFile) + return errors.WithMessagef(err, "failed to create certificate request %s", certFile) } basename := filepath.Base(certFile) @@ -306,11 +305,11 @@ func getClientCert(certFile, keyFile string, info *clientaccess.Info) error { // must be used instead of the one we signed the CSR with. certBytes, keyBytes := splitCertKeyPEM(fileBytes) if err := os.WriteFile(certFile, certBytes, 0600); err != nil { - return pkgerrors.WithMessagef(err, "failed to write cert %s", certFile) + return errors.WithMessagef(err, "failed to write cert %s", certFile) } if len(keyBytes) > 0 { if err := os.WriteFile(keyFile, keyBytes, 0600); err != nil { - return pkgerrors.WithMessagef(err, "failed to write key %s", keyFile) + return errors.WithMessagef(err, "failed to write key %s", keyFile) } } return nil @@ -353,7 +352,7 @@ func splitCertKeyPEM(bytes []byte) (certPem []byte, keyPem []byte) { func getKubeletClientCert(certFile, keyFile, nodeName string, nodeIPs []net.IP, nodePasswordFile string, info *clientaccess.Info) error { csr, err := getCSRBytes(keyFile) if err != nil { - return pkgerrors.WithMessagef(err, "failed to create certificate request %s", certFile) + return errors.WithMessagef(err, "failed to create certificate request %s", certFile) } basename := filepath.Base(certFile) @@ -367,11 +366,11 @@ func getKubeletClientCert(certFile, keyFile, nodeName string, nodeIPs []net.IP, // must be used instead of the one we signed the CSR with. certBytes, keyBytes := splitCertKeyPEM(body) if err := os.WriteFile(certFile, certBytes, 0600); err != nil { - return pkgerrors.WithMessagef(err, "failed to write cert %s", certFile) + return errors.WithMessagef(err, "failed to write cert %s", certFile) } if len(keyBytes) > 0 { if err := os.WriteFile(keyFile, keyBytes, 0600); err != nil { - return pkgerrors.WithMessagef(err, "failed to write key %s", keyFile) + return errors.WithMessagef(err, "failed to write key %s", keyFile) } } return nil @@ -451,18 +450,18 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N controlConfig, err := getConfig(info) if err != nil { - return nil, pkgerrors.WithMessage(err, "failed to retrieve configuration from server") + return nil, errors.WithMessage(err, "failed to retrieve configuration from server") } nodeName, nodeIPs, err := util.GetHostnameAndIPs(envInfo.NodeName, envInfo.NodeIP.Value()) if err != nil { - return nil, pkgerrors.WithMessage(err, "failed to get node name and addresses") + return nil, errors.WithMessage(err, "failed to get node name and addresses") } // If the supervisor and externally-facing apiserver are not on the same port, tell the proxy where to find the apiserver. if controlConfig.SupervisorPort != controlConfig.HTTPSPort { if err := proxy.SetAPIServerPort(controlConfig.HTTPSPort, utilsnet.IsIPv6(nodeIPs[0])); err != nil { - return nil, pkgerrors.WithMessagef(err, "failed to set apiserver port to %d", controlConfig.HTTPSPort) + return nil, errors.WithMessagef(err, "failed to set apiserver port to %d", controlConfig.HTTPSPort) } } apiServerURL := proxy.APIServerURL() @@ -523,12 +522,12 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N // Ask the server to sign our kubelet server cert. if err := getKubeletServingCert(nodeName, nodeExternalAndInternalIPs, servingKubeletCert, servingKubeletKey, newNodePasswordFile, info); err != nil { - return nil, pkgerrors.WithMessage(err, servingKubeletCert) + return nil, errors.WithMessage(err, servingKubeletCert) } // Ask the server to sign our kubelet client cert. if err := getKubeletClientCert(clientKubeletCert, clientKubeletKey, nodeName, nodeIPs, newNodePasswordFile, info); err != nil { - return nil, pkgerrors.WithMessage(err, clientKubeletCert) + return nil, errors.WithMessage(err, clientKubeletCert) } // Generate a kubeconfig for the kubelet. @@ -542,7 +541,7 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N // Ask the server to sign our kube-proxy client cert. if err := getClientCert(clientKubeProxyCert, clientKubeProxyKey, info); err != nil { - return nil, pkgerrors.WithMessage(err, clientKubeProxyCert) + return nil, errors.WithMessage(err, clientKubeProxyCert) } // Generate a kubeconfig for kube-proxy. @@ -556,7 +555,7 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N // Ask the server to sign our agent controller client cert. if err := getClientCert(clientK3sControllerCert, clientK3sControllerKey, info); err != nil { - return nil, pkgerrors.WithMessage(err, clientK3sControllerCert) + return nil, errors.WithMessage(err, clientK3sControllerCert) } // Generate a kubeconfig for the agent controller. @@ -627,7 +626,7 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N } else { listenAddress, _, _, err := util.GetDefaultAddresses(nodeIPs[0]) if err != nil { - return nil, pkgerrors.WithMessage(err, "cannot configure IPv4/IPv6 node-ip") + return nil, errors.WithMessage(err, "cannot configure IPv4/IPv6 node-ip") } nodeConfig.AgentConfig.ListenAddress = listenAddress } @@ -802,7 +801,7 @@ func getKubeProxyDisabled(ctx context.Context, node *config.Node, proxy proxy.Pr controlConfig, err := getConfig(info) if err != nil { - return false, pkgerrors.WithMessage(err, "failed to retrieve configuration from server") + return false, errors.WithMessage(err, "failed to retrieve configuration from server") } return controlConfig.DisableKubeProxy, nil diff --git a/pkg/agent/config/config_linux.go b/pkg/agent/config/config_linux.go index 4f4a227dd18a..726d49463aa5 100644 --- a/pkg/agent/config/config_linux.go +++ b/pkg/agent/config/config_linux.go @@ -3,14 +3,13 @@ package config import ( - "errors" "os" "path/filepath" "github.com/k3s-io/k3s/pkg/agent/containerd" "github.com/k3s-io/k3s/pkg/cli/cmds" "github.com/k3s-io/k3s/pkg/daemons/config" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/sirupsen/logrus" ) @@ -20,24 +19,30 @@ func applyContainerdOSSpecificConfig(nodeConfig *config.Node) error { nodeConfig.Containerd.Address = filepath.Join(nodeConfig.Containerd.State, "containerd.sock") // validate that the selected snapshotter supports the filesystem at the root path. - // for stargz, also overrides the image service endpoint path. + // for stargz and nix, also overrides the image service endpoint path. switch nodeConfig.AgentConfig.Snapshotter { case "overlayfs": if err := containerd.OverlaySupported(nodeConfig.Containerd.Root); err != nil { - return pkgerrors.WithMessagef(err, "\"overlayfs\" snapshotter cannot be enabled for %q, try using \"fuse-overlayfs\" or \"native\"", + return errors.WithMessagef(err, "\"overlayfs\" snapshotter cannot be enabled for %q, try using \"fuse-overlayfs\" or \"native\"", nodeConfig.Containerd.Root) } case "fuse-overlayfs": if err := containerd.FuseoverlayfsSupported(nodeConfig.Containerd.Root); err != nil { - return pkgerrors.WithMessagef(err, "\"fuse-overlayfs\" snapshotter cannot be enabled for %q, try using \"native\"", + return errors.WithMessagef(err, "\"fuse-overlayfs\" snapshotter cannot be enabled for %q, try using \"native\"", nodeConfig.Containerd.Root) } case "stargz": if err := containerd.StargzSupported(nodeConfig.Containerd.Root); err != nil { - return pkgerrors.WithMessagef(err, "\"stargz\" snapshotter cannot be enabled for %q, try using \"overlayfs\" or \"native\"", + return errors.WithMessagef(err, "\"stargz\" snapshotter cannot be enabled for %q, try using \"overlayfs\" or \"native\"", nodeConfig.Containerd.Root) } nodeConfig.AgentConfig.ImageServiceSocket = "/run/containerd-stargz-grpc/containerd-stargz-grpc.sock" + case "nix": + if err := containerd.NixSupported(nodeConfig.Containerd.Root); err != nil { + return errors.WithMessagef(err, "\"nix\" snapshotter cannot be enabled for %q, try using \"overlayfs\" or \"native\"", + nodeConfig.Containerd.Root) + } + nodeConfig.AgentConfig.ImageServiceSocket = filepath.Join(nodeConfig.Containerd.State, "nix-snapshotter.sock") } return nil diff --git a/pkg/agent/config/config_windows.go b/pkg/agent/config/config_windows.go index 65a0cf060f17..4b0486c4db17 100644 --- a/pkg/agent/config/config_windows.go +++ b/pkg/agent/config/config_windows.go @@ -7,7 +7,7 @@ import ( "github.com/k3s-io/k3s/pkg/cli/cmds" "github.com/k3s-io/k3s/pkg/daemons/config" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/rancher/permissions/pkg/access" "github.com/rancher/permissions/pkg/acl" "github.com/rancher/permissions/pkg/sid" @@ -45,7 +45,7 @@ func configureACL(file string) error { access.GrantSid(windows.GENERIC_ALL, sid.LocalSystem()), access.GrantSid(windows.GENERIC_ALL, sid.BuiltinAdministrators()), }...); err != nil { - return pkgerrors.WithMessagef(err, "failed to configure Access Control List For %s", file) + return errors.WithMessagef(err, "failed to configure Access Control List For %s", file) } return nil diff --git a/pkg/agent/containerd/config_linux.go b/pkg/agent/containerd/config_linux.go index 7a34ad7bb3bd..ad37820054a6 100644 --- a/pkg/agent/containerd/config_linux.go +++ b/pkg/agent/containerd/config_linux.go @@ -3,8 +3,10 @@ package containerd import ( + "errors" "fmt" "os" + "os/exec" containerd "github.com/containerd/containerd/v2/client" "github.com/containerd/containerd/v2/plugins/snapshots/overlay/overlayutils" @@ -16,7 +18,7 @@ import ( "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/version" "github.com/moby/sys/userns" - pkgerrors "github.com/pkg/errors" + "github.com/pdtpartners/nix-snapshotter/pkg/nix" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" "k8s.io/cri-client/pkg/util" @@ -96,7 +98,7 @@ func SetupContainerdConfig(cfg *config.Node) error { selEnabled, selConfigured, err := selinuxStatus() if err != nil { - return pkgerrors.WithMessage(err, "failed to detect selinux") + return fmt.Errorf("failed to detect selinux: %w", err) } switch { case !cfg.SELinux && selEnabled: @@ -132,3 +134,10 @@ func FuseoverlayfsSupported(root string) error { func StargzSupported(root string) error { return stargz.Supported(root) } + +func NixSupported(root string) error { + if _, err := exec.LookPath("nix-store"); err != nil { + return errors.New("nix-store not found in PATH: install nix (https://nixos.org/download) to use the nix snapshotter") + } + return nix.Supported(root) +} diff --git a/pkg/agent/containerd/config_windows.go b/pkg/agent/containerd/config_windows.go index 6e5ebcdf6ac8..90a04b0cc2db 100644 --- a/pkg/agent/containerd/config_windows.go +++ b/pkg/agent/containerd/config_windows.go @@ -8,8 +8,7 @@ import ( containerd "github.com/containerd/containerd/v2/client" "github.com/k3s-io/k3s/pkg/agent/templates" "github.com/k3s-io/k3s/pkg/daemons/config" - util3 "github.com/k3s-io/k3s/pkg/util" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/sirupsen/logrus" "k8s.io/cri-client/pkg/util" ) @@ -67,13 +66,17 @@ func Client(address string) (*containerd.Client, error) { } func OverlaySupported(root string) error { - return pkgerrors.WithMessagef(util3.ErrUnsupportedPlatform, "overlayfs is not supported") + return errors.WithMessagef(errors.ErrUnsupportedPlatform, "overlayfs is not supported") } func FuseoverlayfsSupported(root string) error { - return pkgerrors.WithMessagef(util3.ErrUnsupportedPlatform, "fuse-overlayfs is not supported") + return errors.WithMessagef(errors.ErrUnsupportedPlatform, "fuse-overlayfs is not supported") } func StargzSupported(root string) error { - return pkgerrors.WithMessagef(util3.ErrUnsupportedPlatform, "stargz is not supported") + return errors.WithMessagef(errors.ErrUnsupportedPlatform, "stargz is not supported") +} + +func NixSupported(root string) error { + return errors.WithMessagef(errors.ErrUnsupportedPlatform, "nix is not supported") } diff --git a/pkg/agent/containerd/containerd.go b/pkg/agent/containerd/containerd.go index 87ecdc85fc9a..fe64b96e509c 100644 --- a/pkg/agent/containerd/containerd.go +++ b/pkg/agent/containerd/containerd.go @@ -4,7 +4,6 @@ import ( "bufio" "context" "encoding/json" - "errors" "fmt" "io" "os" @@ -24,13 +23,12 @@ import ( util2 "github.com/k3s-io/k3s/pkg/agent/util" "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/signals" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" "github.com/natefinch/lumberjack" "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - pkgerrors "github.com/pkg/errors" "github.com/rancher/wharfie/pkg/tarfile" - "github.com/rancher/wrangler/v3/pkg/merr" "github.com/sirupsen/logrus" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" ) @@ -112,7 +110,7 @@ func Run(ctx context.Context, cfg *config.Node) error { addDeathSig(cmd) err := cmd.Run() if err != nil && !errors.Is(err, context.Canceled) { - signals.RequestShutdown(pkgerrors.WithMessage(err, "containerd exited")) + signals.RequestShutdown(errors.WithMessage(err, "containerd exited")) } signals.RequestShutdown(nil) }() @@ -149,12 +147,12 @@ func PreloadImages(ctx context.Context, cfg *config.Node) error { // At startup all leases from k3s are cleared; we no longer use leases to lock content if err := clearLeases(ctx, client); err != nil { - return pkgerrors.WithMessage(err, "failed to clear leases") + return errors.WithMessage(err, "failed to clear leases") } // Clear the pinned labels on all images previously pinned by k3s if err := clearLabels(ctx, client); err != nil { - return pkgerrors.WithMessage(err, "failed to clear pinned labels") + return errors.WithMessage(err, "failed to clear pinned labels") } return importAndWatchImages(ctx, cfg) @@ -174,7 +172,7 @@ func preloadFile(ctx context.Context, cfg *config.Node, client *containerd.Clien logrus.Infof("Pulling images from %s", filePath) images, err = prePullImages(ctx, client, imageClient, file) if err != nil { - return pkgerrors.WithMessage(err, "failed to pull images from "+filePath) + return errors.WithMessage(err, "failed to pull images from "+filePath) } } else { opener, err := tarfile.GetOpener(filePath) @@ -191,18 +189,18 @@ func preloadFile(ctx context.Context, cfg *config.Node, client *containerd.Clien logrus.Infof("Importing images from %s", filePath) images, err = client.Import(ctx, imageReader, containerd.WithAllPlatforms(true), containerd.WithSkipMissing()) if err != nil { - return pkgerrors.WithMessage(err, "failed to import images from "+filePath) + return errors.WithMessage(err, "failed to import images from "+filePath) } } if err := labelImages(ctx, client, images, filepath.Base(filePath)); err != nil { - return pkgerrors.WithMessage(err, "failed to add pinned label to images") + return errors.WithMessage(err, "failed to add pinned label to images") } if err := retagImages(ctx, client, images, cfg.AgentConfig.AirgapExtraRegistry); err != nil { - return pkgerrors.WithMessage(err, "failed to retag images") + return errors.WithMessage(err, "failed to retag images") } if err := labelContent(ctx, client, images, cfg.AgentConfig.AirgapExtraRegistry); err != nil { - return pkgerrors.WithMessage(err, "failed to add source labels to layer content") + return errors.WithMessage(err, "failed to add source labels to layer content") } return nil @@ -238,10 +236,10 @@ func clearLabels(ctx context.Context, client *containerd.Client) error { delete(image.Labels, k3sPinnedImageLabelKey) delete(image.Labels, criPinnedImageLabelKey) if _, err := imageService.Update(ctx, image, "labels"); err != nil { - errs = append(errs, pkgerrors.WithMessage(err, "failed to delete labels from image "+image.Name)) + errs = append(errs, errors.WithMessage(err, "failed to delete labels from image "+image.Name)) } } - return merr.NewErrors(errs...) + return errors.Join(errs...) } // labelImages adds labels to the listed images, indicating that they @@ -263,12 +261,12 @@ func labelImages(ctx context.Context, client *containerd.Client, images []images image.Labels[criPinnedImageLabelKey] = criPinnedImageLabelValue updatedImage, err := imageService.Update(ctx, image, "labels") if err != nil { - errs = append(errs, pkgerrors.WithMessage(err, "failed to add labels to image "+image.Name)) + errs = append(errs, errors.WithMessage(err, "failed to add labels to image "+image.Name)) } else { images[i] = updatedImage } } - return merr.NewErrors(errs...) + return errors.Join(errs...) } // retagImages retags all listed images as having been pulled from the given remote registries. @@ -280,7 +278,7 @@ func retagImages(ctx context.Context, client *containerd.Client, images []images for _, image := range images { name, err := parseNamedTagged(image.Name) if err != nil { - errs = append(errs, pkgerrors.WithMessage(err, "failed to parse tag for image "+image.Name)) + errs = append(errs, errors.WithMessage(err, "failed to parse tag for image "+image.Name)) continue } logrus.Infof("Imported %s", image.Name) @@ -302,7 +300,7 @@ func retagImages(ctx context.Context, client *containerd.Client, images []images } } } - return merr.NewErrors(errs...) + return errors.Join(errs...) } // forceCreateTag retags an image with the provided reference. @@ -311,13 +309,13 @@ func forceCreateTag(ctx context.Context, imageService images.Store, image images if _, err := imageService.Create(ctx, image); err != nil { if errdefs.IsAlreadyExists(err) { if err = imageService.Delete(ctx, image.Name); err != nil { - return pkgerrors.WithMessage(err, "failed to delete existing image "+image.Name) + return errors.WithMessage(err, "failed to delete existing image "+image.Name) } if _, err = imageService.Create(ctx, image); err != nil { - return pkgerrors.WithMessage(err, "failed to tag after deleting existing image "+image.Name) + return errors.WithMessage(err, "failed to tag after deleting existing image "+image.Name) } } else { - return pkgerrors.WithMessage(err, "failed to tag image "+image.Name) + return errors.WithMessage(err, "failed to tag image "+image.Name) } } return nil @@ -332,13 +330,13 @@ func labelContent(ctx context.Context, client *containerd.Client, images []image for _, image := range images { name, err := parseNamedTagged(image.Name) if err != nil { - errs = append(errs, pkgerrors.WithMessage(err, "failed to parse tags for image "+image.Name)) + errs = append(errs, errors.WithMessage(err, "failed to parse tags for image "+image.Name)) continue } registries := append(registries, docker.Domain(name)) digests, err := getDigests(ctx, contentStore, image.Target) if err != nil { - errs = append(errs, pkgerrors.WithMessage(err, "failed to get content digests for image "+image.Name)) + errs = append(errs, errors.WithMessage(err, "failed to get content digests for image "+image.Name)) continue } for _, digest := range digests { @@ -354,13 +352,13 @@ func labelContent(ctx context.Context, client *containerd.Client, images []image if _, err := contentStore.Update(ctx, info, paths...); err != nil { if !errdefs.IsNotFound(err) { - errs = append(errs, pkgerrors.WithMessage(err, "failed to add source labels to content with digest "+digest.String())) + errs = append(errs, errors.WithMessage(err, "failed to add source labels to content with digest "+digest.String())) } continue } } } - return merr.NewErrors(errs...) + return errors.Join(errs...) } // getDigests returns layer and config digests for the provided descriptor @@ -467,5 +465,5 @@ func prePullImages(ctx context.Context, client *containerd.Client, imageClient r } } } - return images, merr.NewErrors(errs...) + return images, errors.Join(errs...) } diff --git a/pkg/agent/containerd/watcher.go b/pkg/agent/containerd/watcher.go index 5cc310a839a0..2fe71f5e1818 100644 --- a/pkg/agent/containerd/watcher.go +++ b/pkg/agent/containerd/watcher.go @@ -13,7 +13,7 @@ import ( "github.com/fsnotify/fsnotify" "github.com/k3s-io/k3s/pkg/agent/cri" "github.com/k3s-io/k3s/pkg/daemons/config" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/rancher/wharfie/pkg/tarfile" "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -137,18 +137,18 @@ func (w *watchqueue) processImageEvent(ctx context.Context, key string, client * defer w.syncCache() return nil } else if err != nil { - return pkgerrors.Wrapf(err, "failed to get fileinfo for image event %s", key) + return errors.WithMessagef(err, "failed to get fileinfo for image event %s", key) } if file.IsDir() { // Add to watch and list+enqueue directory contents, as notify is not recursive if err := w.watcher.Add(key); err != nil { - return pkgerrors.Wrapf(err, "failed to add watch of %s", key) + return errors.WithMessagef(err, "failed to add watch of %s", key) } fileInfos, err := os.ReadDir(key) if err != nil { - return pkgerrors.Wrapf(err, "unable to list contents of %s", key) + return errors.WithMessagef(err, "unable to list contents of %s", key) } for _, fileInfo := range fileInfos { @@ -164,7 +164,7 @@ func (w *watchqueue) processImageEvent(ctx context.Context, key string, client * if lastFileState := w.filesCache[key]; lastFileState == nil || (file.Size() != lastFileState.Size && file.ModTime().After(lastFileState.ModTime.Time)) { start := time.Now() if err := preloadFile(ctx, w.cfg, client, imageClient, key); err != nil { - return pkgerrors.Wrapf(err, "failed to import %s", key) + return errors.WithMessagef(err, "failed to import %s", key) } logrus.Infof("Imported images from %s in %s", key, time.Since(start)) w.filesCache[key] = &fileInfo{Size: file.Size(), ModTime: metav1.NewTime(file.ModTime()), seen: true} @@ -274,7 +274,7 @@ func watchImages(ctx context.Context, cfg *config.Node) (*watchqueue, error) { // watch the directory above the images dir, as it may not exist yet when the watch is started. watcher, err := createWatcher(filepath.Dir(cfg.Images)) if err != nil { - return nil, pkgerrors.Wrapf(err, "failed to create image import watcher for %s", filepath.Dir(cfg.Images)) + return nil, errors.WithMessagef(err, "failed to create image import watcher for %s", filepath.Dir(cfg.Images)) } w := &watchqueue{ diff --git a/pkg/agent/cridockerd/config_linux.go b/pkg/agent/cridockerd/config_linux.go index b49ed87cd9bc..afee44baa966 100644 --- a/pkg/agent/cridockerd/config_linux.go +++ b/pkg/agent/cridockerd/config_linux.go @@ -8,7 +8,7 @@ import ( "github.com/docker/docker/client" "github.com/k3s-io/k3s/pkg/daemons/config" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" ) const socketPrefix = "unix://" @@ -24,11 +24,11 @@ func setupDockerCRIConfig(ctx context.Context, cfg *config.Node) error { } c, err := client.NewClientWithOpts(clientOpts...) if err != nil { - return pkgerrors.WithMessage(err, "failed to create docker client") + return errors.WithMessage(err, "failed to create docker client") } i, err := c.Info(ctx) if err != nil { - return pkgerrors.WithMessage(err, "failed to get docker runtime info") + return errors.WithMessage(err, "failed to get docker runtime info") } // note: this mutatation of the passed agent.Config is later used to set the // kubelet's cgroup-driver flag. This may merit moving to somewhere else in order diff --git a/pkg/agent/cridockerd/cridockerd.go b/pkg/agent/cridockerd/cridockerd.go index 46bb9df29da6..27869a66f8f4 100644 --- a/pkg/agent/cridockerd/cridockerd.go +++ b/pkg/agent/cridockerd/cridockerd.go @@ -4,20 +4,18 @@ package cridockerd import ( "context" - "errors" "os" "runtime/debug" "strings" "github.com/Mirantis/cri-dockerd/cmd" "github.com/Mirantis/cri-dockerd/cmd/version" - pkgerrors "github.com/pkg/errors" - "github.com/k3s-io/k3s/pkg/agent/cri" "github.com/k3s-io/k3s/pkg/cgroups" "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/signals" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/sirupsen/logrus" utilsnet "k8s.io/utils/net" @@ -42,7 +40,7 @@ func Run(ctx context.Context, cfg *config.Node) error { }() err := command.ExecuteContext(ctx) if err != nil && !errors.Is(err, context.Canceled) { - signals.RequestShutdown(pkgerrors.WithMessage(err, "cri-dockerd exited")) + signals.RequestShutdown(errors.WithMessage(err, "cri-dockerd exited")) } signals.RequestShutdown(nil) }() diff --git a/pkg/agent/flannel/flannel.go b/pkg/agent/flannel/flannel.go index 158165cb2676..ee95cac22a87 100644 --- a/pkg/agent/flannel/flannel.go +++ b/pkg/agent/flannel/flannel.go @@ -15,7 +15,6 @@ package flannel import ( - "errors" "fmt" "math/big" "net" @@ -29,8 +28,7 @@ import ( "github.com/flannel-io/flannel/pkg/subnet/kube" "github.com/flannel-io/flannel/pkg/trafficmngr/iptables" "github.com/joho/godotenv" - pkgerrors "github.com/pkg/errors" - "github.com/rancher/wrangler/v3/pkg/merr" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/sirupsen/logrus" "golang.org/x/net/context" @@ -61,7 +59,7 @@ var ( func flannel(ctx context.Context, wg *sync.WaitGroup, flannelIface *net.Interface, flannelConf, kubeConfigFile string, flannelIPv6Masq bool, nm netMode) error { extIface, err := LookupExtInterface(flannelIface, nm) if err != nil { - return pkgerrors.WithMessage(err, "failed to find the interface") + return errors.WithMessage(err, "failed to find the interface") } sm, err := kube.NewSubnetManager(ctx, @@ -71,12 +69,12 @@ func flannel(ctx context.Context, wg *sync.WaitGroup, flannelIface *net.Interfac flannelConf, false) if err != nil { - return pkgerrors.WithMessage(err, "failed to create the SubnetManager") + return errors.WithMessage(err, "failed to create the SubnetManager") } config, err := sm.GetNetworkConfig(ctx) if err != nil { - return pkgerrors.WithMessage(err, "failed to get the network config") + return errors.WithMessage(err, "failed to get the network config") } // Create a backend manager then use it to create the backend and register the network with it. @@ -84,17 +82,17 @@ func flannel(ctx context.Context, wg *sync.WaitGroup, flannelIface *net.Interfac be, err := bm.GetBackend(config.BackendType) if err != nil { - return pkgerrors.WithMessage(err, "failed to create the flannel backend") + return errors.WithMessage(err, "failed to create the flannel backend") } bn, err := be.RegisterNetwork(ctx, wg, config) if err != nil { - return pkgerrors.WithMessage(err, "failed to register flannel network") + return errors.WithMessage(err, "failed to register flannel network") } trafficMngr := &iptables.IPTablesManager{} err = trafficMngr.Init(ctx) if err != nil { - return pkgerrors.WithMessage(err, "failed to initialize flannel ipTables manager") + return errors.WithMessage(err, "failed to initialize flannel ipTables manager") } if nm.IPv4Enabled() && config.Network.Empty() { @@ -114,7 +112,7 @@ func flannel(ctx context.Context, wg *sync.WaitGroup, flannelIface *net.Interfac err = trafficMngr.SetupAndEnsureMasqRules(ctx, config.Network, prevSubnet, prevNetwork, ip.IP6Net{}, prevIPv6Subnet, prevIPv6Network, bn.Lease(), 60, false) } if err != nil { - return pkgerrors.WithMessage(err, "failed to setup masq rules") + return errors.WithMessage(err, "failed to setup masq rules") } // setup forward rules @@ -142,11 +140,11 @@ func LookupExtInterface(iface *net.Interface, nm netMode) (*backend.ExternalInte logrus.Debug("No interface defined for flannel in the config. Fetching the default gateway interface") if nm.IPv4Enabled() { if iface, err = ip.GetDefaultGatewayInterface(); err != nil { - return nil, pkgerrors.WithMessage(err, "failed to get default interface") + return nil, errors.WithMessage(err, "failed to get default interface") } } else { if iface, err = ip.GetDefaultV6GatewayInterface(); err != nil { - return nil, pkgerrors.WithMessage(err, "failed to get default interface") + return nil, errors.WithMessage(err, "failed to get default interface") } } } @@ -155,7 +153,7 @@ func LookupExtInterface(iface *net.Interface, nm netMode) (*backend.ExternalInte if nm.IPv4Enabled() { ifaceAddr, err = ip.GetInterfaceIP4Addrs(iface) if err != nil { - return nil, pkgerrors.WithMessagef(err, "failed to find IPv4 address for interface %s", iface.Name) + return nil, errors.WithMessagef(err, "failed to find IPv4 address for interface %s", iface.Name) } logrus.Infof("The interface %s with ipv4 address %s will be used by flannel", iface.Name, ifaceAddr[0]) } else { @@ -164,7 +162,7 @@ func LookupExtInterface(iface *net.Interface, nm netMode) (*backend.ExternalInte if nm.IPv6Enabled() { ifacev6Addr, err = ip.GetInterfaceIP6Addrs(iface) if err != nil { - return nil, pkgerrors.WithMessagef(err, "failed to find IPv6 address for interface %s", iface.Name) + return nil, errors.WithMessagef(err, "failed to find IPv6 address for interface %s", iface.Name) } logrus.Infof("The interface %s with ipv6 address %s will be used by flannel", iface.Name, ifacev6Addr[0]) } else { @@ -209,10 +207,10 @@ func WriteSubnetFile(path string, nw ip.IP4Net, nwv6 ip.IP6Net, ipMasq bool, bn } tempFile := f.Name() cleanupNoClose := func(err error) error { - return merr.NewErrors(err, os.Remove(tempFile)) + return errors.Join(err, os.Remove(tempFile)) } cleanup := func(err error) error { - return merr.NewErrors(err, f.Close(), os.Remove(tempFile)) + return errors.Join(err, f.Close(), os.Remove(tempFile)) } if err := f.Chmod(perm); err != nil { return cleanup(err) diff --git a/pkg/agent/flannel/setup.go b/pkg/agent/flannel/setup.go index 59d0fd65bfea..d84f8da2861d 100644 --- a/pkg/agent/flannel/setup.go +++ b/pkg/agent/flannel/setup.go @@ -2,7 +2,6 @@ package flannel import ( "context" - "errors" "fmt" "net" "path/filepath" @@ -13,9 +12,9 @@ import ( agentutil "github.com/k3s-io/k3s/pkg/agent/util" "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/signals" - "github.com/k3s-io/k3s/pkg/vpn" "github.com/k3s-io/k3s/pkg/util" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" + "github.com/k3s-io/k3s/pkg/vpn" "github.com/sirupsen/logrus" authorizationv1 "k8s.io/api/authorization/v1" v1 "k8s.io/api/core/v1" @@ -86,7 +85,7 @@ func Run(ctx context.Context, wg *sync.WaitGroup, nodeConfig *config.Node) error // use the kubelet kubeconfig to sync node annotations, as the k3s-controller // rbac does not allow create or update of nodes. if err := syncAnnotations(ctx, nodeConfig, coreClient); err != nil { - return pkgerrors.WithMessage(err, "flannel failed to sync address annotations") + return errors.WithMessage(err, "flannel failed to sync address annotations") } resourceAttrs := authorizationv1.ResourceAttributes{Verb: "list", Resource: "nodes"} @@ -95,7 +94,7 @@ func Run(ctx context.Context, wg *sync.WaitGroup, nodeConfig *config.Node) error // Flannel needs to watch all nodes in the cluster, which the kubelet is not allowed to do on recent versions of Kubernetes. // If the kubelet cannot list nodes, then wait for the k3s-controller RBAC to become ready, and use that kubeconfig instead. if canListNodes, err := util.CheckRBAC(ctx, kubeConfig, resourceAttrs, ""); err != nil { - return pkgerrors.WithMessage(err, "failed to check if RBAC allows node list") + return errors.WithMessage(err, "failed to check if RBAC allows node list") } else if !canListNodes { kubeConfig = nodeConfig.AgentConfig.KubeConfigK3sController coreClient, err = util.GetClientSet(kubeConfig) @@ -103,22 +102,22 @@ func Run(ctx context.Context, wg *sync.WaitGroup, nodeConfig *config.Node) error return err } if err := util.WaitForRBACReady(ctx, kubeConfig, util.DefaultAPIServerReadyTimeout, resourceAttrs, ""); err != nil { - return pkgerrors.WithMessage(err, "flannel failed to wait for RBAC") + return errors.WithMessage(err, "flannel failed to wait for RBAC") } } if err := waitForPodCIDR(ctx, nodeConfig.AgentConfig.NodeName, coreClient); err != nil { - return pkgerrors.WithMessage(err, "flannel failed to wait for PodCIDR assignment") + return errors.WithMessage(err, "flannel failed to wait for PodCIDR assignment") } nm, err := findNetMode(nodeConfig.AgentConfig.ClusterCIDRs) if err != nil { - return pkgerrors.WithMessage(err, "failed to check netMode for flannel") + return errors.WithMessage(err, "failed to check netMode for flannel") } go func() { err := flannel(ctx, wg, nodeConfig.Flannel.Iface, nodeConfig.Flannel.ConfFile, kubeConfig, nodeConfig.Flannel.IPv6Masq, nm) if err != nil && !errors.Is(err, context.Canceled) { - signals.RequestShutdown(pkgerrors.WithMessage(err, "flannel exited")) + signals.RequestShutdown(errors.WithMessage(err, "flannel exited")) } signals.RequestShutdown(nil) }() @@ -137,7 +136,7 @@ func waitForPodCIDR(ctx context.Context, nodeName string, coreClient kubernetes. } if _, err := toolswatch.UntilWithSync(ctx, lw, &v1.Node{}, nil, condition); err != nil { - return pkgerrors.WithMessage(err, "failed to wait for PodCIDR assignment") + return errors.WithMessage(err, "failed to wait for PodCIDR assignment") } logrus.Info("Flannel found PodCIDR assigned for node " + nodeName) diff --git a/pkg/agent/https/https.go b/pkg/agent/https/https.go index a688cca00dd1..703cf6b8bfd9 100644 --- a/pkg/agent/https/https.go +++ b/pkg/agent/https/https.go @@ -5,10 +5,10 @@ import ( "strconv" "sync" - "github.com/gorilla/mux" "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/server/auth" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/mux" "k8s.io/apiserver/pkg/server" "k8s.io/apiserver/pkg/server/options" ) @@ -25,7 +25,7 @@ var err error // Subsequent calls will return the same router. func Start(ctx context.Context, nodeConfig *config.Node, runtime *config.ControlRuntime) (*mux.Router, error) { once.Do(func() { - router = mux.NewRouter().SkipClean(true) + router = mux.NewRouter() config := &server.Config{} if runtime == nil { diff --git a/pkg/agent/loadbalancer/httpproxy.go b/pkg/agent/loadbalancer/httpproxy.go index 685060a1c03d..075139771cea 100644 --- a/pkg/agent/loadbalancer/httpproxy.go +++ b/pkg/agent/loadbalancer/httpproxy.go @@ -8,9 +8,9 @@ import ( "strconv" "time" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" httpdialer "github.com/mwitkow/go-http-dialer" - pkgerrors "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/net/http/httpproxy" "golang.org/x/net/proxy" @@ -32,14 +32,14 @@ func SetHTTPProxy(address string) error { serverURL, err := url.Parse(address) if err != nil { - return pkgerrors.WithMessagef(err, "failed to parse address %s", address) + return errors.WithMessagef(err, "failed to parse address %s", address) } // Call this directly instead of using the cached environment used by http.ProxyFromEnvironment to allow for testing proxyFromEnvironment := httpproxy.FromEnvironment().ProxyFunc() proxyURL, err := proxyFromEnvironment(serverURL) if err != nil { - return pkgerrors.WithMessagef(err, "failed to get proxy for address %s", address) + return errors.WithMessagef(err, "failed to get proxy for address %s", address) } if proxyURL == nil { logrus.Debug(version.ProgramUpper + "_AGENT_HTTP_PROXY_ALLOWED is true but no proxy is configured for URL " + serverURL.String()) @@ -48,7 +48,7 @@ func SetHTTPProxy(address string) error { dialer, err := proxyDialer(proxyURL, defaultDialer) if err != nil { - return pkgerrors.WithMessagef(err, "failed to create proxy dialer for %s", proxyURL) + return errors.WithMessagef(err, "failed to create proxy dialer for %s", proxyURL) } defaultDialer = dialer diff --git a/pkg/agent/netpol/netpol.go b/pkg/agent/netpol/netpol.go index f8b1f0f3a921..ad7ccbe2758e 100644 --- a/pkg/agent/netpol/netpol.go +++ b/pkg/agent/netpol/netpol.go @@ -26,7 +26,7 @@ import ( "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/metrics" "github.com/k3s-io/k3s/pkg/util" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/sirupsen/logrus" v1 "k8s.io/api/core/v1" "k8s.io/client-go/informers" @@ -96,7 +96,7 @@ func Run(ctx context.Context, wg *sync.WaitGroup, nodeConfig *config.Node) error } return true, nil }); err != nil { - return pkgerrors.WithMessagef(err, "network policy controller failed to wait for %s taint to be removed from Node %s", cloudproviderapi.TaintExternalCloudProvider, nodeConfig.AgentConfig.NodeName) + return errors.WithMessagef(err, "network policy controller failed to wait for %s taint to be removed from Node %s", cloudproviderapi.TaintExternalCloudProvider, nodeConfig.AgentConfig.NodeName) } krConfig := options.NewKubeRouterConfig() @@ -130,13 +130,13 @@ func Run(ctx context.Context, wg *sync.WaitGroup, nodeConfig *config.Node) error if nodeConfig.AgentConfig.EnableIPv4 { iptHandler, err := iptables.NewWithProtocol(iptables.ProtocolIPv4) if err != nil { - return pkgerrors.WithMessage(err, "failed to create iptables handler") + return errors.WithMessage(err, "failed to create iptables handler") } iptablesCmdHandlers[v1.IPv4Protocol] = iptHandler ipset, err := utils.NewIPSet(false) if err != nil { - return pkgerrors.WithMessage(err, "failed to create ipset handler") + return errors.WithMessage(err, "failed to create ipset handler") } ipSetHandlers[v1.IPv4Protocol] = ipset } @@ -144,13 +144,13 @@ func Run(ctx context.Context, wg *sync.WaitGroup, nodeConfig *config.Node) error if nodeConfig.AgentConfig.EnableIPv6 { ipt6Handler, err := iptables.NewWithProtocol(iptables.ProtocolIPv6) if err != nil { - return pkgerrors.WithMessage(err, "failed to create iptables handler") + return errors.WithMessage(err, "failed to create iptables handler") } iptablesCmdHandlers[v1.IPv6Protocol] = ipt6Handler ipset, err := utils.NewIPSet(true) if err != nil { - return pkgerrors.WithMessage(err, "failed to create ipset handler") + return errors.WithMessage(err, "failed to create ipset handler") } ipSetHandlers[v1.IPv6Protocol] = ipset } @@ -179,7 +179,7 @@ func Run(ctx context.Context, wg *sync.WaitGroup, nodeConfig *config.Node) error npc, err := netpol.NewNetworkPolicyController(client, krConfig, podInformer, npInformer, nsInformer, &sync.Mutex{}, nil, iptablesCmdHandlers, ipSetHandlers) if err != nil { - return pkgerrors.WithMessage(err, "unable to initialize network policy controller") + return errors.WithMessage(err, "unable to initialize network policy controller") } podInformer.AddEventHandler(npc.PodEventHandler) diff --git a/pkg/agent/proxy/apiproxy.go b/pkg/agent/proxy/apiproxy.go index 3f521ae4bab7..c5f11b745102 100644 --- a/pkg/agent/proxy/apiproxy.go +++ b/pkg/agent/proxy/apiproxy.go @@ -9,7 +9,7 @@ import ( "github.com/sirupsen/logrus" "github.com/k3s-io/k3s/pkg/agent/loadbalancer" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" ) type Proxy interface { @@ -57,7 +57,7 @@ func NewSupervisorProxy(ctx context.Context, lbEnabled bool, dataDir, supervisor u, err := url.Parse(p.initialSupervisorURL) if err != nil { - return nil, pkgerrors.WithMessagef(err, "failed to parse %s", p.initialSupervisorURL) + return nil, errors.WithMessagef(err, "failed to parse %s", p.initialSupervisorURL) } p.fallbackSupervisorAddress = u.Host p.supervisorPort = u.Port() @@ -139,7 +139,7 @@ func (p *proxy) SetAPIServerPort(port int, isIPv6 bool) error { u, err := url.Parse(p.initialSupervisorURL) if err != nil { - return pkgerrors.WithMessagef(err, "failed to parse server URL %s", p.initialSupervisorURL) + return errors.WithMessagef(err, "failed to parse server URL %s", p.initialSupervisorURL) } p.apiServerPort = strconv.Itoa(port) u.Host = net.JoinHostPort(u.Hostname(), p.apiServerPort) diff --git a/pkg/agent/run.go b/pkg/agent/run.go index 4c0347b20a13..3d2436198dc8 100644 --- a/pkg/agent/run.go +++ b/pkg/agent/run.go @@ -2,7 +2,6 @@ package agent import ( "context" - "errors" "fmt" "net" "os" @@ -34,8 +33,8 @@ import ( "github.com/k3s-io/k3s/pkg/signals" "github.com/k3s-io/k3s/pkg/spegel" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" - pkgerrors "github.com/pkg/errors" "github.com/sirupsen/logrus" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -56,20 +55,20 @@ import ( func run(ctx context.Context, cfg cmds.Agent, proxy proxy.Proxy) error { nodeConfig, err := config.Get(ctx, cfg, proxy) if err != nil { - return pkgerrors.WithMessage(err, "failed to retrieve agent configuration") + return errors.WithMessage(err, "failed to retrieve agent configuration") } dualCluster, err := utilsnet.IsDualStackCIDRs(nodeConfig.AgentConfig.ClusterCIDRs) if err != nil { - return pkgerrors.WithMessage(err, "failed to validate cluster-cidr") + return errors.WithMessage(err, "failed to validate cluster-cidr") } dualService, err := utilsnet.IsDualStackCIDRs(nodeConfig.AgentConfig.ServiceCIDRs) if err != nil { - return pkgerrors.WithMessage(err, "failed to validate service-cidr") + return errors.WithMessage(err, "failed to validate service-cidr") } dualNode, err := utilsnet.IsDualStackIPs(nodeConfig.AgentConfig.NodeIPs) if err != nil { - return pkgerrors.WithMessage(err, "failed to validate node-ip") + return errors.WithMessage(err, "failed to validate node-ip") } serviceIPv4 := utilsnet.IsIPv4CIDR(nodeConfig.AgentConfig.ServiceCIDR) clusterIPv4 := utilsnet.IsIPv4CIDR(nodeConfig.AgentConfig.ClusterCIDR) @@ -98,7 +97,7 @@ func run(ctx context.Context, cfg cmds.Agent, proxy proxy.Proxy) error { conntrackConfig, err := getConntrackConfig(nodeConfig) if err != nil { - return pkgerrors.WithMessage(err, "failed to validate kube-proxy conntrack configuration") + return errors.WithMessage(err, "failed to validate kube-proxy conntrack configuration") } syssetup.Configure(enableIPv6, conntrackConfig) nodeConfig.AgentConfig.EnableIPv4 = enableIPv4 @@ -114,19 +113,19 @@ func run(ctx context.Context, cfg cmds.Agent, proxy proxy.Proxy) error { } if err := spegel.DefaultRegistry.Start(ctx, nodeConfig, executor.CRIReadyChan()); err != nil { - return pkgerrors.WithMessage(err, "failed to start embedded registry") + return errors.WithMessage(err, "failed to start embedded registry") } } if nodeConfig.SupervisorMetrics { if err := metrics.DefaultMetrics.Start(ctx, nodeConfig); err != nil { - return pkgerrors.WithMessage(err, "failed to serve metrics") + return errors.WithMessage(err, "failed to serve metrics") } } if nodeConfig.EnablePProf { if err := profile.DefaultProfiler.Start(ctx, nodeConfig); err != nil { - return pkgerrors.WithMessage(err, "failed to serve pprof") + return errors.WithMessage(err, "failed to serve pprof") } } @@ -144,7 +143,7 @@ func run(ctx context.Context, cfg cmds.Agent, proxy proxy.Proxy) error { go func() { if err := startCRI(ctx, nodeConfig); err != nil { - signals.RequestShutdown(pkgerrors.WithMessage(err, "failed to start container runtime")) + signals.RequestShutdown(errors.WithMessage(err, "failed to start container runtime")) } }() @@ -155,7 +154,7 @@ func run(ctx context.Context, cfg cmds.Agent, proxy proxy.Proxy) error { go func() { <-executor.APIServerReadyChan() if err := startNetwork(ctx, &sync.WaitGroup{}, nodeConfig); err != nil { - signals.RequestShutdown(pkgerrors.WithMessage(err, "failed to start networking")) + signals.RequestShutdown(errors.WithMessage(err, "failed to start networking")) return } @@ -254,7 +253,7 @@ func RunStandalone(ctx context.Context, wg *sync.WaitGroup, cfg cmds.Agent) erro nodeConfig, err := config.Get(ctx, cfg, proxy) if err != nil { - return pkgerrors.WithMessage(err, "failed to retrieve agent configuration") + return errors.WithMessage(err, "failed to retrieve agent configuration") } if err := executor.Bootstrap(ctx, nodeConfig, cfg); err != nil { @@ -275,13 +274,13 @@ func RunStandalone(ctx context.Context, wg *sync.WaitGroup, cfg cmds.Agent) erro if nodeConfig.SupervisorMetrics { if err := metrics.DefaultMetrics.Start(ctx, nodeConfig); err != nil { - return pkgerrors.WithMessage(err, "failed to serve metrics") + return errors.WithMessage(err, "failed to serve metrics") } } if nodeConfig.EnablePProf { if err := profile.DefaultProfiler.Start(ctx, nodeConfig); err != nil { - return pkgerrors.WithMessage(err, "failed to serve pprof") + return errors.WithMessage(err, "failed to serve pprof") } } @@ -324,7 +323,7 @@ func createProxyAndValidateToken(ctx context.Context, cfg *cmds.Agent) (proxy.Pr _, nodeIPs, err := util.GetHostnameAndIPs(cfg.NodeName, cfg.NodeIP.Value()) if err != nil { - return nil, pkgerrors.WithMessage(err, "failed to get node name and addresses") + return nil, errors.WithMessage(err, "failed to get node name and addresses") } proxy, err := proxy.NewSupervisorProxy(ctx, !cfg.DisableLoadBalancer, agentDir, cfg.ServerURL, cfg.LBServerPort, utilsnet.IsIPv6(nodeIPs[0])) @@ -388,7 +387,7 @@ func configureNode(ctx context.Context, nodeConfig *daemonconfig.Node, coreClien return true, nil } if _, err := toolswatch.UntilWithSync(ctx, lw, &v1.Node{}, nil, condition); err != nil { - return pkgerrors.WithMessage(err, "failed to configure node") + return errors.WithMessage(err, "failed to configure node") } return nil } diff --git a/pkg/agent/templates/templates.go b/pkg/agent/templates/templates.go index aadf6c0112eb..8dbd96ffdcf3 100644 --- a/pkg/agent/templates/templates.go +++ b/pkg/agent/templates/templates.go @@ -50,6 +50,7 @@ const ContainerdConfigTemplate = ` {{- /* */ -}} # File generated by {{ .Program }}. DO NOT EDIT. Use config.toml.tmpl instead. version = 2 +imports = [{{ filepathjoin .NodeConfig.Containerd.Template "config.toml.d" "*.toml" | printf "%q" }}] root = {{ printf "%q" .NodeConfig.Containerd.Root }} state = {{ printf "%q" .NodeConfig.Containerd.State }} @@ -82,7 +83,7 @@ state = {{ printf "%q" .NodeConfig.Containerd.State }} {{- if .NodeConfig.AgentConfig.Snapshotter }} [plugins."io.containerd.grpc.v1.cri".containerd] snapshotter = "{{ .NodeConfig.AgentConfig.Snapshotter }}" - disable_snapshot_annotations = {{ if eq .NodeConfig.AgentConfig.Snapshotter "stargz" }}false{{else}}true{{end}} + disable_snapshot_annotations = {{ if or (eq .NodeConfig.AgentConfig.Snapshotter "stargz") (eq .NodeConfig.AgentConfig.Snapshotter "nix") }}false{{else}}true{{end}} {{ if .NodeConfig.DefaultRuntime }}default_runtime_name = "{{ .NodeConfig.DefaultRuntime }}"{{end}} {{ if eq .NodeConfig.AgentConfig.Snapshotter "stargz" }} {{ if .NodeConfig.AgentConfig.ImageServiceSocket }} @@ -109,6 +110,27 @@ enable_keychain = true {{end}} {{end}} +{{ if eq .NodeConfig.AgentConfig.Snapshotter "nix" }} +{{ if .NodeConfig.AgentConfig.ImageServiceSocket }} +[plugins."io.containerd.snapshotter.v1.nix"] + address = "{{ .NodeConfig.AgentConfig.ImageServiceSocket }}" + +[plugins."io.containerd.snapshotter.v1.nix".image_service] + enable = true + containerd_address = {{ deschemify .NodeConfig.Containerd.Address | printf "%q" }} + +[[plugins."io.containerd.transfer.v1.local".unpack_config]] + platform = "linux/amd64" + snapshotter = "nix" + differ = "walking" + +[[plugins."io.containerd.transfer.v1.local".unpack_config]] + platform = "linux/arm64" + snapshotter = "nix" + differ = "walking" +{{end}} +{{end}} + {{- if or .NodeConfig.AgentConfig.CNIBinDir .NodeConfig.AgentConfig.CNIConfDir }} [plugins."io.containerd.grpc.v1.cri".cni] {{ if .NodeConfig.AgentConfig.CNIBinDir }}bin_dir = {{ printf "%q" .NodeConfig.AgentConfig.CNIBinDir }}{{end}} @@ -157,8 +179,9 @@ enable_keychain = true // This version 3 config template is used by both Linux and Windows nodes const ContainerdConfigTemplateV3 = ` {{- /* */ -}} -# File generated by {{ .Program }}. DO NOT EDIT. Use config.toml.tmpl instead. +# File generated by {{ .Program }}. DO NOT EDIT. Use config-v3.toml.tmpl instead. version = 3 +imports = [{{ filepathjoin .NodeConfig.Containerd.Template "config-v3.toml.d" "*.toml" | printf "%q" }}] root = {{ printf "%q" .NodeConfig.Containerd.Root }} state = {{ printf "%q" .NodeConfig.Containerd.State }} @@ -190,7 +213,7 @@ state = {{ printf "%q" .NodeConfig.Containerd.State }} {{ with .NodeConfig.AgentConfig.Snapshotter }} [plugins.'io.containerd.cri.v1.images'] snapshotter = "{{ . }}" - disable_snapshot_annotations = {{ if eq . "stargz" }}false{{else}}true{{end}} + disable_snapshot_annotations = {{ if or (eq . "stargz") (eq . "nix") }}false{{else}}true{{end}} use_local_image_pull = true {{ end }} @@ -274,6 +297,32 @@ state = {{ printf "%q" .NodeConfig.Containerd.State }} {{ end }} {{ end }} {{ end }} + +{{ if eq .NodeConfig.AgentConfig.Snapshotter "nix" }} +{{ with .NodeConfig.AgentConfig.ImageServiceSocket }} +[plugins.'io.containerd.snapshotter.v1.nix'] + address = {{ printf "%q" . }} + +[plugins.'io.containerd.snapshotter.v1.nix'.image_service] + enable = true + containerd_address = {{ deschemify $.NodeConfig.Containerd.Address | printf "%q" }} + +[[plugins.'io.containerd.transfer.v1.local'.unpack_config]] + platform = "linux/amd64" + snapshotter = "nix" + differ = "walking" + +[[plugins.'io.containerd.transfer.v1.local'.unpack_config]] + platform = "linux/arm64" + snapshotter = "nix" + differ = "walking" +{{ end }} +{{ end }} + +{{ if .IsRunningInUserNS }} +[plugins.'io.containerd.nri.v1.nri'] + disable = true +{{ end }} ` var HostsTomlHeader = "# File generated by " + version.Program + ". DO NOT EDIT.\n" diff --git a/pkg/agent/templates/templates_linux.go b/pkg/agent/templates/templates_linux.go index bf302be6f5e4..034920404264 100644 --- a/pkg/agent/templates/templates_linux.go +++ b/pkg/agent/templates/templates_linux.go @@ -4,6 +4,7 @@ package templates import ( "encoding/json" + "path/filepath" "text/template" ) @@ -16,4 +17,5 @@ var templateFuncs = template.FuncMap{ output, _ := json.Marshal(v) return string(output) }, + "filepathjoin": filepath.Join, } diff --git a/pkg/agent/templates/templates_windows.go b/pkg/agent/templates/templates_windows.go index 300df300e3e6..67c8b3cb5a81 100644 --- a/pkg/agent/templates/templates_windows.go +++ b/pkg/agent/templates/templates_windows.go @@ -5,6 +5,7 @@ package templates import ( "encoding/json" "net/url" + "path/filepath" "strings" "text/template" ) @@ -25,4 +26,5 @@ var templateFuncs = template.FuncMap{ output, _ := json.Marshal(v) return string(output) }, + "filepathjoin": filepath.Join, } diff --git a/pkg/agent/tunnel/tunnel.go b/pkg/agent/tunnel/tunnel.go index 45d3c87505eb..41aafeb8812d 100644 --- a/pkg/agent/tunnel/tunnel.go +++ b/pkg/agent/tunnel/tunnel.go @@ -3,7 +3,6 @@ package tunnel import ( "context" "crypto/tls" - "errors" "fmt" "net" "os" @@ -19,8 +18,8 @@ import ( "github.com/k3s-io/k3s/pkg/daemons/executor" "github.com/k3s-io/k3s/pkg/signals" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" - pkgerrors "github.com/pkg/errors" "github.com/rancher/remotedialer" "github.com/sirupsen/logrus" "github.com/yl2chen/cidranger" @@ -118,7 +117,7 @@ func (a *agentTunnel) startWatches(ctx context.Context, config *daemonconfig.Nod Group: "discovery.k8s.io", Resource: "endpointslices", }, ""); err != nil { - signals.RequestShutdown(pkgerrors.WithMessage(err, "tunnel watches failed to wait for RBAC")) + signals.RequestShutdown(errors.WithMessage(err, "tunnel watches failed to wait for RBAC")) return } diff --git a/pkg/agent/util/file.go b/pkg/agent/util/file.go index 9485c6ba31b5..c47e42785420 100644 --- a/pkg/agent/util/file.go +++ b/pkg/agent/util/file.go @@ -1,18 +1,17 @@ package util import ( - "errors" "os" "path/filepath" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" ) func WriteFile(name string, content string) error { os.MkdirAll(filepath.Dir(name), 0755) err := os.WriteFile(name, []byte(content), 0644) if err != nil { - return pkgerrors.WithMessagef(err, "writing %s", name) + return errors.WithMessagef(err, "writing %s", name) } return nil } @@ -23,11 +22,11 @@ func CopyFile(sourceFile string, destinationFile string, ignoreNotExist bool) er if errors.Is(err, os.ErrNotExist) && ignoreNotExist { return nil } else if err != nil { - return pkgerrors.WithMessagef(err, "copying %s to %s", sourceFile, destinationFile) + return errors.WithMessagef(err, "copying %s to %s", sourceFile, destinationFile) } err = os.WriteFile(destinationFile, input, 0644) if err != nil { - return pkgerrors.WithMessagef(err, "copying %s to %s", sourceFile, destinationFile) + return errors.WithMessagef(err, "copying %s to %s", sourceFile, destinationFile) } return nil } diff --git a/pkg/bootstrap/bootstrap.go b/pkg/bootstrap/bootstrap.go index 40b2a95dc28b..37d62edb9222 100644 --- a/pkg/bootstrap/bootstrap.go +++ b/pkg/bootstrap/bootstrap.go @@ -8,7 +8,7 @@ import ( "time" "github.com/k3s-io/k3s/pkg/daemons/config" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/sirupsen/logrus" ) @@ -71,13 +71,13 @@ func WriteToDiskFromStorage(files PathsDataformat, bootstrap *config.ControlRunt } if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil { - return pkgerrors.WithMessagef(err, "failed to mkdir %s", filepath.Dir(path)) + return errors.WithMessagef(err, "failed to mkdir %s", filepath.Dir(path)) } if err := os.WriteFile(path, bsf.Content, 0600); err != nil { - return pkgerrors.WithMessagef(err, "failed to write to %s", path) + return errors.WithMessagef(err, "failed to write to %s", path) } if err := os.Chtimes(path, bsf.Timestamp, bsf.Timestamp); err != nil { - return pkgerrors.WithMessagef(err, "failed to update modified time on %s", path) + return errors.WithMessagef(err, "failed to update modified time on %s", path) } } diff --git a/pkg/certmonitor/certmonitor.go b/pkg/certmonitor/certmonitor.go index 63b82b3e4e60..9b17fc15d62c 100644 --- a/pkg/certmonitor/certmonitor.go +++ b/pkg/certmonitor/certmonitor.go @@ -2,6 +2,7 @@ package certmonitor import ( "context" + "errors" "fmt" "os" "path/filepath" @@ -18,7 +19,6 @@ import ( "github.com/k3s-io/k3s/pkg/version" "github.com/prometheus/client_golang/prometheus" certutil "github.com/rancher/dynamiclistener/cert" - "github.com/rancher/wrangler/v3/pkg/merr" "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -113,7 +113,7 @@ func Setup(ctx context.Context, nodeConfig *daemonconfig.Node, dataDir string) e } func checkCerts(fileMap map[string][]string, warningPeriod time.Duration) error { - errs := merr.Errors{} + errs := []error{} now := time.Now() warn := now.Add(warningPeriod) @@ -139,5 +139,5 @@ func checkCerts(fileMap map[string][]string, warningPeriod time.Duration) error } } - return merr.NewErrors(errs...) + return errors.Join(errs...) } diff --git a/pkg/cli/agent/agent.go b/pkg/cli/agent/agent.go index 7fd2ef06a3a5..cb89e47141f7 100644 --- a/pkg/cli/agent/agent.go +++ b/pkg/cli/agent/agent.go @@ -3,12 +3,10 @@ package agent import ( "context" "crypto/tls" - "errors" "os" "path/filepath" "sync" - "github.com/gorilla/mux" "github.com/k3s-io/k3s/pkg/agent" "github.com/k3s-io/k3s/pkg/agent/https" "github.com/k3s-io/k3s/pkg/cli/cmds" @@ -20,12 +18,15 @@ import ( "github.com/k3s-io/k3s/pkg/signals" "github.com/k3s-io/k3s/pkg/spegel" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" + "github.com/k3s-io/k3s/pkg/util/logger" + "github.com/k3s-io/k3s/pkg/util/mux" "github.com/k3s-io/k3s/pkg/util/permissions" "github.com/k3s-io/k3s/pkg/version" "github.com/k3s-io/k3s/pkg/vpn" - pkgerrors "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" + "k8s.io/klog/v2" ) func Run(clx *cli.Context) (rerr error) { @@ -47,7 +48,8 @@ func Run(clx *cli.Context) (rerr error) { return err } - ctx := signals.SetupSignalContext() + klog.EnableContextualLogging(true) + ctx := klog.NewContext(signals.SetupSignalContext(), logger.NewLogrusSink(nil).AsLogr()) wg := &sync.WaitGroup{} // If exiting due to an error, ensure that contexts are cancelled so that the @@ -65,7 +67,7 @@ func Run(clx *cli.Context) (rerr error) { if !cmds.AgentConfig.Rootless { if err := permissions.IsPrivileged(); err != nil { - return pkgerrors.WithMessage(err, "agent requires additional privilege if not run with --rootless") + return errors.WithMessage(err, "agent requires additional privilege if not run with --rootless") } } diff --git a/pkg/cli/cert/cert.go b/pkg/cli/cert/cert.go index 8e2a840ce5a0..ceae41a64dea 100644 --- a/pkg/cli/cert/cert.go +++ b/pkg/cli/cert/cert.go @@ -3,7 +3,6 @@ package cert import ( "bytes" "encoding/json" - "errors" "fmt" "io" "os" @@ -23,10 +22,10 @@ import ( "github.com/k3s-io/k3s/pkg/proctitle" "github.com/k3s-io/k3s/pkg/server" k3sutil "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/util/services" "github.com/k3s-io/k3s/pkg/version" "github.com/otiai10/copy" - pkgerrors "github.com/pkg/errors" certutil "github.com/rancher/dynamiclistener/cert" "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" @@ -401,7 +400,7 @@ func rotateCA(app *cli.Context, cfg *cmds.Server, sync *cmds.CertRotateCA) error url := fmt.Sprintf("/v1-%s/cert/cacerts?force=%t", version.Program, sync.Force) if err = info.Put(url, buf.Bytes()); err != nil { - return pkgerrors.WithMessage(err, "see server log for details") + return errors.WithMessage(err, "see server log for details") } fmt.Println("certificates saved to datastore") diff --git a/pkg/cli/cmds/init_linux.go b/pkg/cli/cmds/init_linux.go index a33a4508f9c9..5f203fd91b43 100644 --- a/pkg/cli/cmds/init_linux.go +++ b/pkg/cli/cmds/init_linux.go @@ -5,8 +5,8 @@ package cmds import ( "os" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/moby/sys/userns" - pkgerrors "github.com/pkg/errors" "github.com/rootless-containers/rootlesskit/pkg/parent/cgrouputil" ) @@ -17,7 +17,7 @@ func EvacuateCgroup2() error { // The root cgroup has to be empty to enable subtree_control, so evacuate it by placing // ourselves in the init cgroup. if err := cgrouputil.EvacuateCgroup2("init"); err != nil { - return pkgerrors.WithMessage(err, "failed to evacuate root cgroup") + return errors.WithMessage(err, "failed to evacuate root cgroup") } } return nil diff --git a/pkg/cli/cmds/log_linux.go b/pkg/cli/cmds/log_linux.go index cd742b729f50..513e94db05df 100644 --- a/pkg/cli/cmds/log_linux.go +++ b/pkg/cli/cmds/log_linux.go @@ -12,9 +12,9 @@ import ( systemd "github.com/coreos/go-systemd/v22/daemon" "github.com/k3s-io/k3s/pkg/proctitle" "github.com/k3s-io/k3s/pkg/signals" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" "github.com/natefinch/lumberjack" - pkgerrors "github.com/pkg/errors" "golang.org/x/sys/unix" ) @@ -46,7 +46,7 @@ func forkIfLoggingOrReaping() error { pwd, err := os.Getwd() if err != nil { - return pkgerrors.WithMessage(err, "failed to get working directory") + return errors.WithMessage(err, "failed to get working directory") } if enableReaping { diff --git a/pkg/cli/cmds/server.go b/pkg/cli/cmds/server.go index 11a22f0dcde3..f90d73f5ffcb 100644 --- a/pkg/cli/cmds/server.go +++ b/pkg/cli/cmds/server.go @@ -150,7 +150,7 @@ var ( } ClusterDNS = &cli.StringSliceFlag{ Name: "cluster-dns", - Usage: "(networking) IPv4/IPv6 Cluster IP for coredns service. Should be in your service-cidr range (default: 10.43.0.10)", + Usage: "(networking) IPv4 Cluster IP for coredns service. Should be in your service-cidr range (default: 10.43.0.10)", Destination: &ServerConfig.ClusterDNS, } ClusterDomain = &cli.StringFlag{ diff --git a/pkg/cli/etcdsnapshot/etcd_snapshot.go b/pkg/cli/etcdsnapshot/etcd_snapshot.go index 2bcca5923674..90c4ae67df12 100644 --- a/pkg/cli/etcdsnapshot/etcd_snapshot.go +++ b/pkg/cli/etcdsnapshot/etcd_snapshot.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "encoding/json" - "errors" "fmt" "os" "path/filepath" @@ -21,8 +20,7 @@ import ( "github.com/k3s-io/k3s/pkg/etcd" "github.com/k3s-io/k3s/pkg/proctitle" "github.com/k3s-io/k3s/pkg/server" - util2 "github.com/k3s-io/k3s/pkg/util" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -50,8 +48,12 @@ func commandSetup(app *cli.Context, cfg *cmds.Server) (*etcd.SnapshotRequest, *c if app.IsSet("etcd-snapshot-retention") { sr.Retention = &cfg.EtcdSnapshotRetention } - if cfg.EtcdS3 { + // set default s3 retention from local snapshot retention + // preserves legacy behavior of local snapshot retention also affecting s3 + if !app.IsSet("etcd-s3-retention") && app.IsSet("etcd-snapshot-retention") { + cfg.EtcdS3Retention = cfg.EtcdSnapshotRetention + } sr.S3 = &config.EtcdS3{ AccessKey: cfg.EtcdS3AccessKey, Bucket: cfg.EtcdS3BucketName, @@ -95,7 +97,7 @@ func wrapServerError(err error) error { // since the operation may have actualy succeeded despite the client timing out the request. return err } - return pkgerrors.WithMessage(err, "see server log for details") + return errors.WithMessage(err, "see server log for details") } // Save triggers an on-demand etcd snapshot operation @@ -108,7 +110,7 @@ func Save(app *cli.Context) error { func save(app *cli.Context, cfg *cmds.Server) error { if app.Args().Len() > 0 { - return util2.ErrCommandNoArgs + return errors.ErrCommandNoArgs } // Save always sets retention to 0 to disable automatic pruning. diff --git a/pkg/cli/secretsencrypt/secrets_encrypt.go b/pkg/cli/secretsencrypt/secrets_encrypt.go index a49e14edc330..8c55fd7a6755 100644 --- a/pkg/cli/secretsencrypt/secrets_encrypt.go +++ b/pkg/cli/secretsencrypt/secrets_encrypt.go @@ -16,8 +16,8 @@ import ( "github.com/k3s-io/k3s/pkg/secretsencrypt" "github.com/k3s-io/k3s/pkg/server" "github.com/k3s-io/k3s/pkg/server/handlers" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" - pkgerrors "github.com/pkg/errors" "github.com/urfave/cli/v2" "k8s.io/utils/ptr" ) @@ -44,7 +44,7 @@ func commandPrep(cfg *cmds.Server) (*clientaccess.Info, error) { } func wrapServerError(err error) error { - return pkgerrors.WithMessage(err, "see server log for details") + return errors.WithMessage(err, "see server log for details") } func Enable(app *cli.Context) error { diff --git a/pkg/cli/server/server.go b/pkg/cli/server/server.go index edb3de0f8d94..847a1d0c6d41 100644 --- a/pkg/cli/server/server.go +++ b/pkg/cli/server/server.go @@ -2,7 +2,6 @@ package server import ( "context" - "errors" "fmt" "net" "os" @@ -12,7 +11,7 @@ import ( "time" systemd "github.com/coreos/go-systemd/v22/daemon" - "github.com/gorilla/mux" + "github.com/go-logr/logr" "github.com/k3s-io/k3s/pkg/agent" "github.com/k3s-io/k3s/pkg/agent/https" "github.com/k3s-io/k3s/pkg/agent/loadbalancer" @@ -30,16 +29,19 @@ import ( "github.com/k3s-io/k3s/pkg/signals" "github.com/k3s-io/k3s/pkg/spegel" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" + "github.com/k3s-io/k3s/pkg/util/logger" + "github.com/k3s-io/k3s/pkg/util/mux" "github.com/k3s-io/k3s/pkg/util/permissions" "github.com/k3s-io/k3s/pkg/version" "github.com/k3s-io/k3s/pkg/vpn" - pkgerrors "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apimachinery/pkg/util/wait" kubeapiserverflag "k8s.io/component-base/cli/flag" + "k8s.io/klog/v2" "k8s.io/kubernetes/pkg/controlplane/apiserver/options" utilsnet "k8s.io/utils/net" ) @@ -76,7 +78,8 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont return err } - ctx := signals.SetupSignalContext() + klog.EnableContextualLogging(true) + ctx := logr.NewContext(signals.SetupSignalContext(), logger.NewLogrusSink(nil).AsLogr()) wg := &sync.WaitGroup{} // If exiting due to an error, ensure that contexts are cancelled so that the @@ -94,7 +97,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont if !cfg.DisableAgent && !cfg.Rootless { if err := permissions.IsPrivileged(); err != nil { - return pkgerrors.WithMessage(err, "server requires additional privilege when not run with --rootless and/or --disable-agent") + return errors.WithMessage(err, "server requires additional privilege when not run with --rootless and/or --disable-agent") } } @@ -214,6 +217,11 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont if cfg.EtcdS3Timeout <= 0 { return errors.New("etcd-s3-timeout must be greater than 0s") } + // set default s3 retention from local snapshot retention + // preserves legacy behavior of local snapshot retention also affecting s3 + if !app.IsSet("etcd-s3-retention") && app.IsSet("etcd-snapshot-retention") { + cfg.EtcdS3Retention = cfg.EtcdSnapshotRetention + } serverConfig.ControlConfig.EtcdS3 = &config.EtcdS3{ AccessKey: cfg.EtcdS3AccessKey, Bucket: cfg.EtcdS3BucketName, @@ -353,7 +361,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont for _, cidr := range util.SplitStringSlice(cmds.ServerConfig.ClusterCIDR.Value()) { _, parsed, err := net.ParseCIDR(cidr) if err != nil { - return pkgerrors.WithMessagef(err, "invalid cluster-cidr %s", cidr) + return errors.WithMessagef(err, "invalid cluster-cidr %s", cidr) } serverConfig.ControlConfig.ClusterIPRanges = append(serverConfig.ControlConfig.ClusterIPRanges, parsed) } @@ -368,7 +376,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont for _, cidr := range util.SplitStringSlice(cmds.ServerConfig.ServiceCIDR.Value()) { _, parsed, err := net.ParseCIDR(cidr) if err != nil { - return pkgerrors.WithMessagef(err, "invalid service-cidr %s", cidr) + return errors.WithMessagef(err, "invalid service-cidr %s", cidr) } serverConfig.ControlConfig.ServiceIPRanges = append(serverConfig.ControlConfig.ServiceIPRanges, parsed) } @@ -378,7 +386,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont serverConfig.ControlConfig.ServiceNodePortRange, err = utilnet.ParsePortRange(cfg.ServiceNodePortRange) if err != nil { - return pkgerrors.WithMessagef(err, "invalid port range %s", cfg.ServiceNodePortRange) + return errors.WithMessagef(err, "invalid port range %s", cfg.ServiceNodePortRange) } // the apiserver service does not yet support dual-stack operation @@ -396,7 +404,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont for _, svcCIDR := range serverConfig.ControlConfig.ServiceIPRanges { clusterDNS, err := utilsnet.GetIndexedIP(svcCIDR, 10) if err != nil { - return pkgerrors.WithMessage(err, "cannot configure default cluster-dns address") + return errors.WithMessage(err, "cannot configure default cluster-dns address") } serverConfig.ControlConfig.ClusterDNSs = append(serverConfig.ControlConfig.ClusterDNSs, clusterDNS) } @@ -446,7 +454,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont serverConfig.ControlConfig.MinTLSVersion = tlsMinVersionArg serverConfig.ControlConfig.TLSMinVersion, err = kubeapiserverflag.TLSVersion(tlsMinVersionArg) if err != nil { - return pkgerrors.WithMessage(err, "invalid tls-min-version") + return errors.WithMessage(err, "invalid tls-min-version") } serverConfig.StartupHooks = append(serverConfig.StartupHooks, cfg.StartupHooks...) @@ -476,7 +484,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont serverConfig.ControlConfig.CipherSuites = tlsCipherSuites serverConfig.ControlConfig.TLSCipherSuites, err = kubeapiserverflag.TLSCipherSuites(tlsCipherSuites) if err != nil { - return pkgerrors.WithMessage(err, "invalid tls-cipher-suites") + return errors.WithMessage(err, "invalid tls-cipher-suites") } // If performing a cluster reset, make sure control-plane components are diff --git a/pkg/cli/token/token.go b/pkg/cli/token/token.go index 4be197b537b3..5cc4a4414173 100644 --- a/pkg/cli/token/token.go +++ b/pkg/cli/token/token.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "encoding/json" - "errors" "fmt" "os" "path/filepath" @@ -19,8 +18,8 @@ import ( "github.com/k3s-io/k3s/pkg/server" "github.com/k3s-io/k3s/pkg/server/handlers" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" - pkgerrors "github.com/pkg/errors" "github.com/urfave/cli/v2" "gopkg.in/yaml.v2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -122,7 +121,7 @@ func deleteToken(app *cli.Context, cfg *cmds.Token) error { } secretName := bootstraputil.BootstrapTokenSecretName(token) if err := client.CoreV1().Secrets(metav1.NamespaceSystem).Delete(context.TODO(), secretName, metav1.DeleteOptions{}); err != nil { - return pkgerrors.WithMessagef(err, "failed to delete bootstrap token %q", err) + return errors.WithMessagef(err, "failed to delete bootstrap token %q", err) } fmt.Printf("bootstrap token %q deleted\n", token) @@ -219,7 +218,7 @@ func list(app *cli.Context, cfg *cmds.Token) error { secrets, err := client.CoreV1().Secrets(metav1.NamespaceSystem).List(context.TODO(), listOptions) if err != nil { - return pkgerrors.WithMessagef(err, "failed to list bootstrap tokens") + return errors.WithMessagef(err, "failed to list bootstrap tokens") } tokens := make([]*kubeadm.BootstrapToken, len(secrets.Items)) diff --git a/pkg/clientaccess/kubeconfig.go b/pkg/clientaccess/kubeconfig.go index 1039284f38a4..b82a025ecb98 100644 --- a/pkg/clientaccess/kubeconfig.go +++ b/pkg/clientaccess/kubeconfig.go @@ -3,7 +3,8 @@ package clientaccess import ( "os" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" + "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" ) @@ -12,17 +13,17 @@ import ( func WriteClientKubeConfig(destFile, url, serverCAFile, clientCertFile, clientKeyFile string) error { serverCA, err := os.ReadFile(serverCAFile) if err != nil { - return pkgerrors.WithMessagef(err, "failed to read %s", serverCAFile) + return errors.WithMessagef(err, "failed to read %s", serverCAFile) } clientCert, err := os.ReadFile(clientCertFile) if err != nil { - return pkgerrors.WithMessagef(err, "failed to read %s", clientCertFile) + return errors.WithMessagef(err, "failed to read %s", clientCertFile) } clientKey, err := os.ReadFile(clientKeyFile) if err != nil { - return pkgerrors.WithMessagef(err, "failed to read %s", clientKeyFile) + return errors.WithMessagef(err, "failed to read %s", clientKeyFile) } config := clientcmdapi.NewConfig() diff --git a/pkg/clientaccess/token.go b/pkg/clientaccess/token.go index b46afcd5014b..b6dd06191336 100644 --- a/pkg/clientaccess/token.go +++ b/pkg/clientaccess/token.go @@ -7,7 +7,6 @@ import ( "crypto/x509" "encoding/hex" "encoding/json" - "errors" "fmt" "io" "net/http" @@ -17,7 +16,7 @@ import ( "time" "github.com/k3s-io/k3s/pkg/kubeadm" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" certutil "github.com/rancher/dynamiclistener/cert" "github.com/sirupsen/logrus" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -365,7 +364,7 @@ func (i *Info) Post(path string, body []byte, options ...any) ([]byte, error) { func (i *Info) setServer(server string) error { url, err := url.Parse(server) if err != nil { - return pkgerrors.WithMessagef(err, "Invalid server url, failed to parse: %s", server) + return errors.WithMessagef(err, "Invalid server url, failed to parse: %s", server) } if url.Scheme != "https" { @@ -425,7 +424,7 @@ func getCACerts(u url.URL) ([]byte, error) { // Download the CA bundle using a client that does not validate certs. cacerts, err := get(url, insecureClient, "", "", "") if err != nil { - return nil, pkgerrors.WithMessage(err, "failed to get CA certs") + return nil, errors.WithMessage(err, "failed to get CA certs") } // Request the CA bundle again, validating that the CA bundle can be loaded @@ -433,7 +432,7 @@ func getCACerts(u url.URL) ([]byte, error) { // get an empty CA bundle. or if the dynamiclistener cert is incorrectly signed. _, err = get(url, GetHTTPClient(cacerts, "", ""), "", "", "") if err != nil { - return nil, pkgerrors.WithMessage(err, "CA cert validation failed") + return nil, errors.WithMessage(err, "CA cert validation failed") } return cacerts, nil diff --git a/pkg/cloudprovider/servicelb.go b/pkg/cloudprovider/servicelb.go index 1bec498870d9..a5288e55b9fd 100644 --- a/pkg/cloudprovider/servicelb.go +++ b/pkg/cloudprovider/servicelb.go @@ -17,7 +17,6 @@ import ( "github.com/rancher/wrangler/v3/pkg/condition" coreclient "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" discoveryclient "github.com/rancher/wrangler/v3/pkg/generated/controllers/discovery/v1" - "github.com/rancher/wrangler/v3/pkg/merr" "github.com/rancher/wrangler/v3/pkg/objectset" "github.com/sirupsen/logrus" apps "k8s.io/api/apps/v1" @@ -55,7 +54,7 @@ const ( ) var ( - DefaultLBImage = "rancher/klipper-lb:v0.4.14" + DefaultLBImage = "rancher/klipper-lb:v0.4.15" ) func (k *k3s) Register(ctx context.Context, @@ -659,7 +658,7 @@ func (k *k3s) removeServiceFinalizers(ctx context.Context) error { return err } - var errs merr.Errors + var errs []error for _, svc := range services.Items { if err := retry.RetryOnConflict(retry.DefaultRetry, func() error { s, err := k.removeFinalizer(ctx, &svc) @@ -670,10 +669,7 @@ func (k *k3s) removeServiceFinalizers(ctx context.Context) error { } } - if len(errs) > 0 { - return errs - } - return nil + return errors.Join(errs...) } // removeFinalizer ensures that there is not a finalizer for this controller on the Service diff --git a/pkg/cluster/bootstrap.go b/pkg/cluster/bootstrap.go index 46fb9970e2f1..51562e8eee3b 100644 --- a/pkg/cluster/bootstrap.go +++ b/pkg/cluster/bootstrap.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "encoding/json" - "errors" "fmt" "io" "net" @@ -23,11 +22,11 @@ import ( "github.com/k3s-io/k3s/pkg/daemons/executor" "github.com/k3s-io/k3s/pkg/etcd/store" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" "github.com/k3s-io/kine/pkg/endpoint" "github.com/k3s-io/kine/pkg/tls" "github.com/otiai10/copy" - pkgerrors "github.com/pkg/errors" "github.com/sirupsen/logrus" "go.etcd.io/etcd/api/v3/mvccpb" ) @@ -37,7 +36,7 @@ import ( // ControlRuntimeBootstrap struct, either via HTTP or from the datastore. func (c *Cluster) Bootstrap(ctx context.Context, clusterReset bool) error { if err := c.assignManagedDriver(ctx); err != nil { - return pkgerrors.WithMessage(err, "failed to set datastore driver") + return errors.WithMessage(err, "failed to set datastore driver") } // Check if we need to bootstrap, and whether or not the managed database has already @@ -46,7 +45,7 @@ func (c *Cluster) Bootstrap(ctx context.Context, clusterReset bool) error { // This also sets c.clientAccessInfo if c.config.JoinURL and c.config.Token are set. shouldBootstrap, isInitialized, err := c.shouldBootstrapLoad(ctx) if err != nil { - return pkgerrors.WithMessage(err, "failed to check if bootstrap data has been initialized") + return errors.WithMessage(err, "failed to check if bootstrap data has been initialized") } if c.managedDB != nil { @@ -54,7 +53,7 @@ func (c *Cluster) Bootstrap(ctx context.Context, clusterReset bool) error { // secondary server with etcd disabled, start the etcd proxy so that we can attempt to use it // when reconciling. if err := c.startEtcdProxy(ctx); err != nil { - return pkgerrors.WithMessage(err, "failed to start etcd proxy") + return errors.WithMessage(err, "failed to start etcd proxy") } } else if isInitialized && !clusterReset { // For secondary servers with etcd, first attempt to connect and reconcile using the join URL. @@ -71,7 +70,7 @@ func (c *Cluster) Bootstrap(ctx context.Context, clusterReset bool) error { // extract bootstrap data from a copy of the etcd mvcc store and reconcile // against that. if err := c.ReconcileBootstrapData(ctx, nil, &c.config.Runtime.ControlRuntimeBootstrap, false); err != nil { - return pkgerrors.WithMessage(err, "failed to reconcile with local datastore") + return errors.WithMessage(err, "failed to reconcile with local datastore") } logrus.Info("Successfully reconciled with local datastore") } @@ -129,7 +128,7 @@ func (c *Cluster) shouldBootstrapLoad(ctx context.Context) (bool, bool, error) { // the hash in the token. The password isn't actually checked until later when actually bootstrapping. info, err := clientaccess.ParseAndValidateToken(c.config.JoinURL, c.config.Token, opts...) if err != nil { - return false, false, pkgerrors.WithMessage(err, "failed to validate token") + return false, false, errors.WithMessage(err, "failed to validate token") } c.clientAccessInfo = info @@ -313,7 +312,7 @@ func (c *Cluster) ReconcileBootstrapData(ctx context.Context, buf io.ReadSeeker, if storageClient == nil { storageClient, err = store.NewTemporaryStore(filepath.Join(c.config.DataDir, "db", "etcd")) if err != nil { - return pkgerrors.WithMessage(err, "failed to create temporary datastore client") + return errors.WithMessage(err, "failed to create temporary datastore client") } } @@ -367,7 +366,7 @@ func (c *Cluster) ReconcileBootstrapData(ctx context.Context, buf io.ReadSeeker, updated, newer, err := isNewerFile(path, fileData) if err != nil { - return pkgerrors.WithMessagef(err, "failed to get update status of %s", pathKey) + return errors.WithMessagef(err, "failed to get update status of %s", pathKey) } if newer { newerOnDisk = append(newerOnDisk, path) @@ -384,10 +383,10 @@ func (c *Cluster) ReconcileBootstrapData(ctx context.Context, buf io.ReadSeeker, logrus.Infof("Cluster reset: backing up certificates directory to %s", tlsBackupDir) if _, err := os.Stat(serverTLSDir); err != nil { - return pkgerrors.WithMessage(err, "cluster reset failed to stat server TLS dir") + return errors.WithMessage(err, "cluster reset failed to stat server TLS dir") } if err := copy.Copy(serverTLSDir, tlsBackupDir); err != nil { - return pkgerrors.WithMessage(err, "cluster reset failed to back up server TLS dir") + return errors.WithMessage(err, "cluster reset failed to back up server TLS dir") } } else if len(newerOnDisk) > 0 { logrus.Fatal(strings.Join(newerOnDisk, ", ") + " newer than datastore and could cause a cluster outage. Remove the file(s) from disk and restart to be recreated from datastore.") @@ -410,13 +409,13 @@ func isNewerFile(path string, file bootstrap.File) (updated bool, newerOnDisk bo logrus.Warn(path + " doesn't exist. continuing...") return true, false, nil } - return false, false, pkgerrors.WithMessagef(err, "reconcile failed to open") + return false, false, errors.WithMessagef(err, "reconcile failed to open") } defer f.Close() data, err := io.ReadAll(f) if err != nil { - return false, false, pkgerrors.WithMessagef(err, "reconcile failed to read") + return false, false, errors.WithMessagef(err, "reconcile failed to read") } if bytes.Equal(file.Content, data) { @@ -425,7 +424,7 @@ func isNewerFile(path string, file bootstrap.File) (updated bool, newerOnDisk bo info, err := f.Stat() if err != nil { - return false, false, pkgerrors.WithMessagef(err, "reconcile failed to stat") + return false, false, errors.WithMessagef(err, "reconcile failed to stat") } if info.ModTime().Unix()-file.Timestamp.Unix() >= systemTimeSkew { @@ -486,7 +485,7 @@ func (c *Cluster) bootstrap(ctx context.Context) error { if c.managedDB != nil { // Try to compare local config against the server we're joining. if err := c.compareConfig(); err != nil { - return pkgerrors.WithMessage(err, "failed to validate server configuration") + return errors.WithMessage(err, "failed to validate server configuration") } // Try to bootstrap from the datastore using the local etcd proxy. if data, err := c.getBootstrapData(ctx, c.clientAccessInfo.Password); err != nil { diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go index 7226fdac4985..5c507da064b1 100644 --- a/pkg/cluster/cluster.go +++ b/pkg/cluster/cluster.go @@ -2,7 +2,6 @@ package cluster import ( "context" - "errors" "net" "net/url" "strings" @@ -18,8 +17,8 @@ import ( "github.com/k3s-io/k3s/pkg/metrics" "github.com/k3s-io/k3s/pkg/signals" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/kine/pkg/endpoint" - pkgerrors "github.com/pkg/errors" "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/util/wait" utilsnet "k8s.io/utils/net" @@ -60,7 +59,7 @@ func (c *Cluster) Start(ctx context.Context, wg *sync.WaitGroup) error { // start managed etcd database; when kine is in use this is a no-op. if err := c.start(ctx, wg); err != nil { - return pkgerrors.WithMessage(err, "start managed database") + return errors.WithMessage(err, "start managed database") } // set c.config.Datastore and c.config.Runtime.EtcdConfig with values @@ -85,7 +84,7 @@ func (c *Cluster) Start(ctx context.Context, wg *sync.WaitGroup) error { // always save to managed etcd, to ensure that any file modified locally are in sync with the datastore. // this will fail if multiple keys exist, to prevent nodes from running with different bootstrap data. if err := Save(ctx, c.config, false); err != nil && !errors.Is(err, context.Canceled) { - signals.RequestShutdown(pkgerrors.WithMessage(err, "failed to save bootstrap data")) + signals.RequestShutdown(errors.WithMessage(err, "failed to save bootstrap data")) return } @@ -127,7 +126,7 @@ func (c *Cluster) startEtcdProxy(ctx context.Context) error { } _, nodeIPs, err := util.GetHostnameAndIPs(cmds.AgentConfig.NodeName, cmds.AgentConfig.NodeIP.Value()) if err != nil { - pkgerrors.WithMessage(err, "failed to get node name and addresses") + errors.WithMessage(err, "failed to get node name and addresses") } defaultURL.Host = net.JoinHostPort(defaultURL.Hostname(), "2379") @@ -145,7 +144,7 @@ func (c *Cluster) startEtcdProxy(ctx context.Context) error { for i, c := range clientURLs { u, err := url.Parse(c) if err != nil { - return pkgerrors.WithMessage(err, "failed to parse etcd ClientURL") + return errors.WithMessage(err, "failed to parse etcd ClientURL") } clientURLs[i] = u.Host } @@ -196,7 +195,7 @@ func (c *Cluster) startStorage(ctx context.Context, bootstrap bool) error { // start listening on the kine socket as an etcd endpoint, or return the external etcd endpoints etcdConfig, err := endpoint.Listen(ctx, c.config.Datastore) if err != nil { - return pkgerrors.WithMessage(err, "creating storage endpoint") + return errors.WithMessage(err, "creating storage endpoint") } // Persist the returned etcd configuration. We decide if we're doing leader election for embedded controllers diff --git a/pkg/cluster/managed.go b/pkg/cluster/managed.go index d380eeeac743..6840788815e8 100644 --- a/pkg/cluster/managed.go +++ b/pkg/cluster/managed.go @@ -13,11 +13,11 @@ import ( "sync" "time" - "github.com/gorilla/mux" "github.com/k3s-io/k3s/pkg/cluster/managed" "github.com/k3s-io/k3s/pkg/etcd" "github.com/k3s-io/k3s/pkg/nodepassword" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/mux" "github.com/k3s-io/k3s/pkg/version" "github.com/sirupsen/logrus" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -144,10 +144,10 @@ func (c *Cluster) deleteNodePasswdSecret(ctx context.Context) { // handlerNoEtcd wraps a handler with an error message indicating that etcd is not deployed. func handlerNoEtcd(handler http.Handler) http.Handler { - r := mux.NewRouter().SkipClean(true) + r := mux.NewRouter() // Wildcard route for anything after /db/ - r.HandleFunc("/db/{_:.*}", func(resp http.ResponseWriter, r *http.Request) { + r.HandleFunc("/db/", func(resp http.ResponseWriter, r *http.Request) { util.SendError(errors.New("etcd datastore disabled"), resp, r, http.StatusBadRequest) }) diff --git a/pkg/containerd/builtins.go b/pkg/containerd/builtins.go index 24d83f3b448e..9599d3188fd6 100644 --- a/pkg/containerd/builtins.go +++ b/pkg/containerd/builtins.go @@ -27,6 +27,7 @@ import ( _ "github.com/containerd/containerd/v2/plugins/imageverifier" _ "github.com/containerd/containerd/v2/plugins/leases" _ "github.com/containerd/containerd/v2/plugins/metadata" + _ "github.com/containerd/containerd/v2/plugins/mount" _ "github.com/containerd/containerd/v2/plugins/nri" _ "github.com/containerd/containerd/v2/plugins/restart" _ "github.com/containerd/containerd/v2/plugins/sandbox" @@ -38,6 +39,7 @@ import ( _ "github.com/containerd/containerd/v2/plugins/services/images" _ "github.com/containerd/containerd/v2/plugins/services/introspection" _ "github.com/containerd/containerd/v2/plugins/services/leases" + _ "github.com/containerd/containerd/v2/plugins/services/mounts" _ "github.com/containerd/containerd/v2/plugins/services/namespaces" _ "github.com/containerd/containerd/v2/plugins/services/opt" _ "github.com/containerd/containerd/v2/plugins/services/sandbox" diff --git a/pkg/containerd/builtins_linux.go b/pkg/containerd/builtins_linux.go index c238899a884a..1f35022151e2 100644 --- a/pkg/containerd/builtins_linux.go +++ b/pkg/containerd/builtins_linux.go @@ -24,6 +24,7 @@ import ( _ "github.com/containerd/containerd/v2/core/metrics/cgroups/v2" _ "github.com/containerd/containerd/v2/plugins/diff/erofs/plugin" _ "github.com/containerd/containerd/v2/plugins/diff/walking/plugin" + _ "github.com/containerd/containerd/v2/plugins/mount/erofs" _ "github.com/containerd/containerd/v2/plugins/snapshots/blockfile/plugin" _ "github.com/containerd/containerd/v2/plugins/snapshots/btrfs/plugin" _ "github.com/containerd/containerd/v2/plugins/snapshots/devmapper/plugin" @@ -33,4 +34,5 @@ import ( _ "github.com/containerd/fuse-overlayfs-snapshotter/v2/plugin" _ "github.com/containerd/stargz-snapshotter/service/plugin" _ "github.com/containerd/zfs/v2/plugin" + _ "github.com/pdtpartners/nix-snapshotter/pkg/plugin" ) diff --git a/pkg/containerd/utility_linux.go b/pkg/containerd/utility_linux.go index 18eadecf24e3..925aecbbdbcc 100644 --- a/pkg/containerd/utility_linux.go +++ b/pkg/containerd/utility_linux.go @@ -3,9 +3,13 @@ package containerd import ( + "errors" + "os/exec" + "github.com/containerd/containerd/v2/plugins/snapshots/overlay/overlayutils" fuseoverlayfs "github.com/containerd/fuse-overlayfs-snapshotter/v2" stargz "github.com/containerd/stargz-snapshotter/service" + "github.com/pdtpartners/nix-snapshotter/pkg/nix" ) func OverlaySupported(root string) error { @@ -19,3 +23,10 @@ func FuseoverlayfsSupported(root string) error { func StargzSupported(root string) error { return stargz.Supported(root) } + +func NixSupported(root string) error { + if _, err := exec.LookPath("nix-store"); err != nil { + return errors.New("nix-store not found in PATH: install nix (https://nixos.org/download) to use the nix snapshotter") + } + return nix.Supported(root) +} diff --git a/pkg/containerd/utility_windows.go b/pkg/containerd/utility_windows.go index 3c26e2295a00..c5c1877412b7 100644 --- a/pkg/containerd/utility_windows.go +++ b/pkg/containerd/utility_windows.go @@ -3,18 +3,21 @@ package containerd import ( - util2 "github.com/k3s-io/k3s/pkg/util" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" ) func OverlaySupported(root string) error { - return pkgerrors.WithMessagef(util2.ErrUnsupportedPlatform, "overlayfs is not supported") + return errors.WithMessagef(errors.ErrUnsupportedPlatform, "overlayfs is not supported") } func FuseoverlayfsSupported(root string) error { - return pkgerrors.WithMessagef(util2.ErrUnsupportedPlatform, "fuse-overlayfs is not supported") + return errors.WithMessagef(errors.ErrUnsupportedPlatform, "fuse-overlayfs is not supported") } func StargzSupported(root string) error { - return pkgerrors.WithMessagef(util2.ErrUnsupportedPlatform, "stargz is not supported") + return errors.WithMessagef(errors.ErrUnsupportedPlatform, "stargz is not supported") +} + +func NixSupported(root string) error { + return errors.WithMessagef(errors.ErrUnsupportedPlatform, "nix is not supported") } diff --git a/pkg/daemons/agent/agent.go b/pkg/daemons/agent/agent.go index 88aed28f2112..9004e85b112d 100644 --- a/pkg/daemons/agent/agent.go +++ b/pkg/daemons/agent/agent.go @@ -16,9 +16,9 @@ import ( "github.com/k3s-io/k3s/pkg/daemons/executor" "github.com/k3s-io/k3s/pkg/signals" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" "github.com/otiai10/copy" - pkgerrors "github.com/pkg/errors" "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/component-base/logs" @@ -40,14 +40,14 @@ func Agent(ctx context.Context, nodeConfig *daemonconfig.Node, proxy proxy.Proxy go func() { <-executor.CRIReadyChan() if err := startKubelet(ctx, &nodeConfig.AgentConfig); err != nil { - signals.RequestShutdown(pkgerrors.WithMessage(err, "failed to start kubelet")) + signals.RequestShutdown(errors.WithMessage(err, "failed to start kubelet")) } }() go func() { if !config.KubeProxyDisabled(ctx, nodeConfig, proxy) { if err := startKubeProxy(ctx, &nodeConfig.AgentConfig); err != nil { - signals.RequestShutdown(pkgerrors.WithMessage(err, "failed to start kube-proxy")) + signals.RequestShutdown(errors.WithMessage(err, "failed to start kube-proxy")) } } }() @@ -65,16 +65,16 @@ func startKubeProxy(ctx context.Context, cfg *daemonconfig.Agent) error { func startKubelet(ctx context.Context, cfg *daemonconfig.Agent) error { argsMap, defaultConfig, err := kubeletArgsAndConfig(cfg) if err != nil { - return pkgerrors.WithMessage(err, "prepare default configuration drop-in") + return errors.WithMessage(err, "prepare default configuration drop-in") } extraArgs, err := extractConfigArgs(cfg.KubeletConfigDir, cfg.ExtraKubeletArgs, defaultConfig) if err != nil { - return pkgerrors.WithMessage(err, "prepare user configuration drop-ins") + return errors.WithMessage(err, "prepare user configuration drop-ins") } if err := writeKubeletConfig(cfg.KubeletConfigDir, defaultConfig); err != nil { - return pkgerrors.WithMessage(err, "generate default kubelet configuration drop-in") + return errors.WithMessage(err, "generate default kubelet configuration drop-in") } args := util.GetArgs(argsMap, extraArgs) @@ -138,7 +138,7 @@ func extractConfigArgs(path string, extraArgs []string, config *kubeletconfig.Ku src := strippedArgs["config"] dest := filepath.Join(path, "10-cli-config.conf") if err := agentutil.CopyFile(src, dest, false); err != nil { - return nil, pkgerrors.WithMessagef(err, "copy config %q into managed drop-in dir %q", src, dest) + return nil, errors.WithMessagef(err, "copy config %q into managed drop-in dir %q", src, dest) } } // copy the config-dir into our managed config dir, unless its already in there @@ -146,7 +146,7 @@ func extractConfigArgs(path string, extraArgs []string, config *kubeletconfig.Ku src := strippedArgs["config-dir"] dest := filepath.Join(path, "20-cli-config-dir") if err := copy.Copy(src, dest, copy.Options{PreserveOwner: true}); err != nil { - return nil, pkgerrors.WithMessagef(err, "copy config-dir %q into managed drop-in dir %q", src, dest) + return nil, errors.WithMessagef(err, "copy config-dir %q into managed drop-in dir %q", src, dest) } } return args, nil @@ -248,12 +248,12 @@ func defaultKubeletConfig(cfg *daemonconfig.Agent) (*kubeletconfig.KubeletConfig defaultConfig.StaticPodPath = cfg.PodManifests } if err := os.MkdirAll(defaultConfig.StaticPodPath, 0750); err != nil { - return nil, pkgerrors.WithMessagef(err, "failed to create static pod manifest dir %s", defaultConfig.StaticPodPath) + return nil, errors.WithMessagef(err, "failed to create static pod manifest dir %s", defaultConfig.StaticPodPath) } t, _, err := taints.ParseTaints(cfg.NodeTaints) if err != nil { - return nil, pkgerrors.WithMessage(err, "failed to parse node taints") + return nil, errors.WithMessage(err, "failed to parse node taints") } defaultConfig.RegisterWithTaints = t diff --git a/pkg/daemons/control/proxy/proxy.go b/pkg/daemons/control/proxy/proxy.go index 76665bed6ba6..4fef0bad0190 100644 --- a/pkg/daemons/control/proxy/proxy.go +++ b/pkg/daemons/control/proxy/proxy.go @@ -1,10 +1,10 @@ package proxy import ( - "errors" "io" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" + "github.com/sirupsen/logrus" ) @@ -44,12 +44,12 @@ func (p *proxy) pipe(src, dst io.ReadWriter) { for { n, err := src.Read(buff) if err != nil { - p.err(pkgerrors.WithMessage(err, "read failed")) + p.err(errors.WithMessage(err, "read failed")) return } _, err = dst.Write(buff[:n]) if err != nil { - p.err(pkgerrors.WithMessage(err, "write failed")) + p.err(errors.WithMessage(err, "write failed")) return } } diff --git a/pkg/daemons/control/server.go b/pkg/daemons/control/server.go index 41a482069175..f7ac15347405 100644 --- a/pkg/daemons/control/server.go +++ b/pkg/daemons/control/server.go @@ -2,7 +2,6 @@ package control import ( "context" - "errors" "os" "path/filepath" "strconv" @@ -17,8 +16,8 @@ import ( "github.com/k3s-io/k3s/pkg/daemons/executor" "github.com/k3s-io/k3s/pkg/signals" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" - pkgerrors "github.com/pkg/errors" "github.com/sirupsen/logrus" authorizationv1 "k8s.io/api/authorization/v1" v1 "k8s.io/api/core/v1" @@ -42,12 +41,12 @@ import ( func Prepare(ctx context.Context, wg *sync.WaitGroup, cfg *config.Control) error { logsapi.ReapplyHandling = logsapi.ReapplyHandlingIgnoreUnchanged if err := prepare(ctx, wg, cfg); err != nil { - return pkgerrors.WithMessage(err, "preparing server") + return errors.WithMessage(err, "preparing server") } tunnel, err := setupTunnel(ctx, cfg) if err != nil { - return pkgerrors.WithMessage(err, "setup tunnel server") + return errors.WithMessage(err, "setup tunnel server") } cfg.Runtime.Tunnel = tunnel @@ -70,7 +69,7 @@ func Prepare(ctx context.Context, wg *sync.WaitGroup, cfg *config.Control) error // not disabled on this node. func Server(ctx context.Context, wg *sync.WaitGroup, cfg *config.Control) error { if err := cfg.Cluster.Start(ctx, wg); err != nil { - return pkgerrors.WithMessage(err, "failed to start cluster") + return errors.WithMessage(err, "failed to start cluster") } // Create a new context to use for control-plane components that is @@ -194,7 +193,7 @@ func scheduler(ctx context.Context, cfg *config.Control) error { logrus.Infof("Waiting for untainted node") // this waits forever for an untainted node; if it returns ErrWaitTimeout the context has been cancelled, and it is not a fatal error if err := waitForUntaintedNode(ctx, runtime.KubeConfigScheduler); err != nil && !errors.Is(err, wait.ErrWaitTimeout) { - signals.RequestShutdown(pkgerrors.WithMessage(err, "failed to wait for untained node")) + signals.RequestShutdown(errors.WithMessage(err, "failed to wait for untained node")) } } }() @@ -325,15 +324,15 @@ func prepare(ctx context.Context, wg *sync.WaitGroup, config *config.Control) er config.Cluster = cluster.New(config) if err := config.Cluster.Bootstrap(ctx, config.ClusterReset); err != nil { - return pkgerrors.WithMessage(err, "failed to bootstrap cluster data") + return errors.WithMessage(err, "failed to bootstrap cluster data") } if err := deps.GenServerDeps(config); err != nil { - return pkgerrors.WithMessage(err, "failed to generate server dependencies") + return errors.WithMessage(err, "failed to generate server dependencies") } if err := config.Cluster.ListenAndServe(ctx); err != nil { - return pkgerrors.WithMessage(err, "failed to start supervisor listener") + return errors.WithMessage(err, "failed to start supervisor listener") } return nil @@ -470,7 +469,7 @@ func waitForUntaintedNode(ctx context.Context, kubeConfig string) error { } if _, err := toolswatch.UntilWithSync(ctx, lw, &v1.Node{}, nil, condition); err != nil { - return pkgerrors.WithMessage(err, "failed to wait for untainted node") + return errors.WithMessage(err, "failed to wait for untainted node") } return nil } diff --git a/pkg/daemons/control/server_test.go b/pkg/daemons/control/server_test.go index 4c248a0153ba..e09ac198ae81 100644 --- a/pkg/daemons/control/server_test.go +++ b/pkg/daemons/control/server_test.go @@ -2,6 +2,7 @@ package control import ( "context" + "fmt" "net/http" "os" "sync" @@ -15,12 +16,10 @@ import ( "github.com/k3s-io/k3s/pkg/cluster" "github.com/k3s-io/k3s/pkg/cluster/managed" "github.com/k3s-io/k3s/pkg/daemons/config" - "github.com/k3s-io/k3s/pkg/daemons/control/deps" "github.com/k3s-io/k3s/pkg/daemons/executor" "github.com/k3s-io/k3s/pkg/etcd" testutil "github.com/k3s-io/k3s/tests" "github.com/k3s-io/k3s/tests/mock" - pkgerrors "github.com/pkg/errors" "go.uber.org/mock/gomock" utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apiserver/pkg/authentication/authenticator" @@ -198,12 +197,8 @@ func mockControl(ctx context.Context, t *testing.T, clusterInit bool) (*config.C testutil.GenerateRuntime(control) control.Cluster = cluster.New(control) - if err := control.Cluster.Bootstrap(ctx, control.ClusterReset); err != nil { - return nil, pkgerrors.WithMessage(err, "failed to bootstrap cluster data") - } - - if err := deps.GenServerDeps(control); err != nil { - return nil, pkgerrors.WithMessage(err, "failed to generate server dependencies") + if err := prepare(ctx, nil, control); err != nil { + return nil, fmt.Errorf("failed to prepare cluster: %w", err) } return control, nil diff --git a/pkg/datadir/datadir.go b/pkg/datadir/datadir.go index cdcb529c24ff..350e67564114 100644 --- a/pkg/datadir/datadir.go +++ b/pkg/datadir/datadir.go @@ -3,10 +3,10 @@ package datadir import ( "path/filepath" + "github.com/k3s-io/k3s/pkg/util/errors" + "github.com/k3s-io/k3s/pkg/util/home" "github.com/k3s-io/k3s/pkg/util/permissions" "github.com/k3s-io/k3s/pkg/version" - pkgerrors "github.com/pkg/errors" - "github.com/rancher/wrangler/v3/pkg/resolvehome" ) var ( @@ -29,9 +29,9 @@ func LocalHome(dataDir string, forceLocal bool) (string, error) { } } - dataDir, err := resolvehome.Resolve(dataDir) + dataDir, err := home.Resolve(dataDir) if err != nil { - return "", pkgerrors.WithMessagef(err, "resolving %s", dataDir) + return "", errors.WithMessagef(err, "resolving %s", dataDir) } return filepath.Abs(dataDir) diff --git a/pkg/deploy/controller.go b/pkg/deploy/controller.go index 6dcbd4cce323..398273f49919 100644 --- a/pkg/deploy/controller.go +++ b/pkg/deploy/controller.go @@ -19,10 +19,9 @@ import ( controllersv1 "github.com/k3s-io/api/pkg/generated/controllers/k3s.cattle.io/v1" "github.com/k3s-io/k3s/pkg/agent/util" pkgutil "github.com/k3s-io/k3s/pkg/util" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/rancher/wrangler/v3/pkg/apply" "github.com/rancher/wrangler/v3/pkg/kv" - "github.com/rancher/wrangler/v3/pkg/merr" "github.com/rancher/wrangler/v3/pkg/objectset" "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" @@ -108,7 +107,7 @@ func (w *watcher) listFiles(force bool) error { errs = append(errs, err) } } - return merr.NewErrors(errs...) + return errors.Join(errs...) } // listFilesIn recursively processes all files within a path, and checks them against the disable and skip lists. Files found that @@ -165,7 +164,7 @@ func (w *watcher) listFilesIn(base string, force bool) error { // Disabled files are not just skipped, but actively deleted from the filesystem if shouldDisableFile(base, path, w.disables) { if err := w.delete(path); err != nil { - errs = append(errs, pkgerrors.WithMessagef(err, "failed to delete %s", path)) + errs = append(errs, errors.WithMessagef(err, "failed to delete %s", path)) } continue } @@ -178,13 +177,13 @@ func (w *watcher) listFilesIn(base string, force bool) error { continue } if err := w.deploy(path, !force); err != nil { - errs = append(errs, pkgerrors.WithMessagef(err, "failed to process %s", path)) + errs = append(errs, errors.WithMessagef(err, "failed to process %s", path)) } else { w.modTime[path] = modTime } } - return merr.NewErrors(errs...) + return errors.Join(errs...) } // deploy loads yaml from a manifest on disk, creates an AddOn resource to track its application, and then applies diff --git a/pkg/deploy/stage.go b/pkg/deploy/stage.go index 937190a7ca9e..72a5bef14b63 100644 --- a/pkg/deploy/stage.go +++ b/pkg/deploy/stage.go @@ -10,7 +10,7 @@ import ( "strings" "github.com/k3s-io/k3s/pkg/util/bindata" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/sirupsen/logrus" ) @@ -46,7 +46,7 @@ staging: os.MkdirAll(filepath.Dir(p), 0700) logrus.Info("Writing manifest: ", p) if err := os.WriteFile(p, content, 0600); err != nil { - return pkgerrors.WithMessagef(err, "failed to write to %s", name) + return errors.WithMessagef(err, "failed to write to %s", name) } } diff --git a/pkg/etcd/etcd.go b/pkg/etcd/etcd.go index 678486fcc6fd..ae1880790ae4 100644 --- a/pkg/etcd/etcd.go +++ b/pkg/etcd/etcd.go @@ -5,7 +5,6 @@ import ( "context" "crypto/tls" "encoding/json" - "errors" "fmt" "io/fs" "net" @@ -20,7 +19,6 @@ import ( "time" "github.com/google/uuid" - "github.com/gorilla/mux" "github.com/k3s-io/k3s/pkg/clientaccess" "github.com/k3s-io/k3s/pkg/cluster/managed" "github.com/k3s-io/k3s/pkg/daemons/config" @@ -31,11 +29,12 @@ import ( "github.com/k3s-io/k3s/pkg/server/auth" "github.com/k3s-io/k3s/pkg/signals" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" + "github.com/k3s-io/k3s/pkg/util/mux" "github.com/k3s-io/k3s/pkg/version" kine "github.com/k3s-io/kine/pkg/app" "github.com/k3s-io/kine/pkg/client" "github.com/k3s-io/kine/pkg/endpoint" - pkgerrors "github.com/pkg/errors" certutil "github.com/rancher/dynamiclistener/cert" controllerv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" "github.com/rancher/wrangler/v3/pkg/start" @@ -188,8 +187,7 @@ func (e *ETCD) SetControlConfig(config *config.Control) error { return err } e.address = address - - return e.setName(false) + return nil } // Test ensures that the local node is a voting member of the target cluster, @@ -207,7 +205,7 @@ func (e *ETCD) Test(ctx context.Context, enableMaintenance bool) error { status, err := e.status(ctx) if err != nil { - return pkgerrors.WithMessage(err, "failed to get etcd status") + return errors.WithMessage(err, "failed to get etcd status") } else if status.IsLearner { return errors.New("this server has not yet been promoted from learner to voting member") } else if status.Leader == 0 { @@ -226,19 +224,19 @@ func (e *ETCD) Test(ctx context.Context, enableMaintenance bool) error { // defrag this node to reclaim freed space from compacted revisions if err := e.defragment(ctx); err != nil { - return pkgerrors.WithMessage(err, "failed to defragment etcd database") + return errors.WithMessage(err, "failed to defragment etcd database") } // clear alarms on this node if err := e.clearAlarms(ctx, status.Header.MemberId); err != nil { - return pkgerrors.WithMessage(err, "failed to disarm etcd alarms") + return errors.WithMessage(err, "failed to disarm etcd alarms") } // refresh status - note that errors may remain on other nodes, but this // should not prevent us from continuing with startup. status, err = e.status(ctx) if err != nil { - return pkgerrors.WithMessage(err, "failed to get etcd status") + return errors.WithMessage(err, "failed to get etcd status") } logrus.Infof("Datastore using %d of %d bytes after defragment", status.DbSizeInUse, status.DbSize) @@ -332,7 +330,7 @@ func (e *ETCD) IsInitialized() (bool, error) { } else if os.IsNotExist(err) { return false, nil } - return false, pkgerrors.WithMessage(err, "invalid state for wal directory "+dir) + return false, errors.WithMessage(err, "invalid state for wal directory "+dir) } // Reset resets an etcd node to a single node cluster. @@ -412,15 +410,15 @@ func (e *ETCD) Reset(ctx context.Context, wg *sync.WaitGroup, rebootstrap func() if errors.Is(err, s3.ErrNoConfigSecret) { return errors.New("cannot use S3 config secret when restoring snapshot; configuration must be set in CLI or config file") } - return pkgerrors.WithMessage(err, "failed to initialize S3 client") + return errors.WithMessage(err, "failed to initialize S3 client") } dir, err := snapshotDir(e.config, true) if err != nil { - return pkgerrors.WithMessage(err, "failed to get the snapshot dir") + return errors.WithMessage(err, "failed to get the snapshot dir") } path, err := s3client.Download(ctx, e.config.ClusterResetRestorePath, dir) if err != nil { - return pkgerrors.WithMessage(err, "failed to download snapshot from S3") + return errors.WithMessage(err, "failed to download snapshot from S3") } e.config.ClusterResetRestorePath = path logrus.Infof("S3 download complete for %s", e.config.ClusterResetRestorePath) @@ -453,7 +451,7 @@ func (e *ETCD) Reset(ctx context.Context, wg *sync.WaitGroup, rebootstrap func() func (e *ETCD) Start(ctx context.Context, wg *sync.WaitGroup, clientAccessInfo *clientaccess.Info) error { isInitialized, err := e.IsInitialized() if err != nil { - return pkgerrors.WithMessagef(err, "failed to check for initialized etcd datastore") + return errors.WithMessagef(err, "failed to check for initialized etcd datastore") } if err := e.startClient(ctx); err != nil { @@ -533,7 +531,7 @@ func (e *ETCD) pollJoin(ctx context.Context, wg *sync.WaitGroup, clientAccessInf } return true, nil }); err != nil { - signals.RequestShutdown(pkgerrors.WithMessage(err, "etcd cluster join failed")) + signals.RequestShutdown(errors.WithMessage(err, "etcd cluster join failed")) } } @@ -680,7 +678,7 @@ func (e *ETCD) Register(handler http.Handler) (http.Handler, error) { // ensure client is started, as etcd startup may not have handled this if this is a control-plane-only node if e.client == nil { if err := e.startClient(ctx); err != nil { - panic(pkgerrors.WithMessage(err, "failed to start etcd client")) + panic(errors.WithMessage(err, "failed to start etcd client")) } } @@ -691,7 +689,7 @@ func (e *ETCD) Register(handler http.Handler) (http.Handler, error) { // Re-run informer factory startup after core and leader-elected controllers have started. // Additional caches may need to start for the newly added OnChange/OnRemove callbacks. if err := start.All(ctx, 5, e.config.Runtime.K3s, e.config.Runtime.Core); err != nil { - panic(pkgerrors.WithMessage(err, "failed to start wrangler controllers")) + panic(errors.WithMessage(err, "failed to start wrangler controllers")) } } } @@ -746,16 +744,16 @@ func (e *ETCD) setName(force bool) error { // handler wraps the handler with routes for database info func (e *ETCD) handler(next http.Handler) http.Handler { - r := mux.NewRouter().SkipClean(true) + r := mux.NewRouter() r.NotFoundHandler = next - ir := r.Path("/db/info").Subrouter() + ir := r.SubRouter("/db/info") ir.Use(auth.IsLocalOrHasRole(e.config, version.Program+":server")) - ir.Handle("", e.infoHandler()) + ir.Handle("/", e.infoHandler()) - sr := r.Path("/db/snapshot").Subrouter() + sr := r.SubRouter("/db/snapshot") sr.Use(auth.HasRole(e.config, version.Program+":server")) - sr.Handle("", e.snapshotHandler()) + sr.Handle("/", e.snapshotHandler()) return r } @@ -778,7 +776,7 @@ func (e *ETCD) infoHandler() http.Handler { members, err := e.client.MemberList(ctx) if err != nil { - util.SendError(pkgerrors.WithMessage(err, "failed to get etcd MemberList"), rw, req, http.StatusInternalServerError) + util.SendError(errors.WithMessage(err, "failed to get etcd MemberList"), rw, req, http.StatusInternalServerError) return } @@ -1323,7 +1321,7 @@ func (e *ETCD) trackLearnerProgress(ctx context.Context, progress *learnerProgre func (e *ETCD) getETCDStatus(ctx context.Context, url string) (*clientv3.StatusResponse, error) { resp, err := e.client.Status(ctx, url) if err != nil { - return resp, pkgerrors.WithMessage(err, "failed to check etcd member status") + return resp, errors.WithMessage(err, "failed to check etcd member status") } if len(resp.Errors) != 0 { return resp, errors.New("etcd member has status errors: " + strings.Join(resp.Errors, ",")) @@ -1552,7 +1550,7 @@ func (e *ETCD) Restore(ctx context.Context) error { if strings.HasSuffix(e.config.ClusterResetRestorePath, snapshot.CompressedExtension) { dir, err := snapshotDir(e.config, true) if err != nil { - return pkgerrors.WithMessage(err, "failed to get the snapshot dir") + return errors.WithMessage(err, "failed to get the snapshot dir") } decompressSnapshot, err := e.decompressSnapshot(dir, e.config.ClusterResetRestorePath) diff --git a/pkg/etcd/s3/s3.go b/pkg/etcd/s3/s3.go index e659b226deec..a8248977718a 100644 --- a/pkg/etcd/s3/s3.go +++ b/pkg/etcd/s3/s3.go @@ -5,7 +5,6 @@ import ( "crypto/tls" "crypto/x509" "encoding/base64" - "errors" "fmt" "io/ioutil" "net/http" @@ -24,10 +23,10 @@ import ( "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/etcd/snapshot" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" - pkgerrors "github.com/pkg/errors" "github.com/rancher/wrangler/v3/pkg/generated/controllers/core" "github.com/sirupsen/logrus" v1 "k8s.io/api/core/v1" @@ -100,13 +99,13 @@ func Start(ctx context.Context, config *config.Control) (*Controller, error) { // cluster id hack: see https://groups.google.com/forum/#!msg/kubernetes-sig-architecture/mVGobfD4TpY/nkdbkX1iBwAJ ns, err := c.core.V1().Namespace().Get(metav1.NamespaceSystem, metav1.GetOptions{}) if err != nil { - return false, pkgerrors.WithMessage(err, "failed to set S3 snapshot cluster ID") + return false, errors.WithMessage(err, "failed to set S3 snapshot cluster ID") } c.clusterID = string(ns.UID) tokenHash, err := util.GetTokenHash(config) if err != nil { - return false, pkgerrors.WithMessage(err, "failed to set S3 snapshot server token hash") + return false, errors.WithMessage(err, "failed to set S3 snapshot server token hash") } c.tokenHash = tokenHash @@ -130,6 +129,8 @@ func (c *Controller) GetClient(ctx context.Context, etcdS3 *config.EtcdS3) (*Cli // update ConfigSecret in defaults so that comparisons between current and default config // ignore ConfigSecret when deciding if CLI configuration is present. defaultEtcdS3.ConfigSecret = etcdS3.ConfigSecret + // also ignore retention, as it may have been defaulted from the etcd-snapshot-retention flag. + defaultEtcdS3.Retention = etcdS3.Retention // If config is default, try to load config from secret, and fail if it cannot be retrieved or if the secret name is not set. // If config is not default, and secret name is set, warn that the secret is being ignored @@ -138,7 +139,7 @@ func (c *Controller) GetClient(ctx context.Context, etcdS3 *config.EtcdS3) (*Cli if isDefault { e, err := c.getConfigFromSecret(etcdS3.ConfigSecret) if err != nil { - return nil, pkgerrors.WithMessagef(err, "failed to get config from etcd-s3-config-secret %q", etcdS3.ConfigSecret) + return nil, errors.WithMessagef(err, "failed to get config from etcd-s3-config-secret %q", etcdS3.ConfigSecret) } logrus.Infof("Using etcd s3 configuration from etcd-s3-config-secret %q", etcdS3.ConfigSecret) etcdS3 = e @@ -197,7 +198,7 @@ func (c *Controller) GetClient(ctx context.Context, etcdS3 *config.EtcdS3) (*Cli if etcdS3.Proxy != "none" { u, err = url.Parse(etcdS3.Proxy) if err != nil { - return nil, pkgerrors.WithMessage(err, "failed to parse etcd-s3-proxy value as URL") + return nil, errors.WithMessage(err, "failed to parse etcd-s3-proxy value as URL") } if u.Scheme == "" || u.Host == "" { return nil, errors.New("proxy URL must include scheme and host") @@ -220,7 +221,7 @@ func (c *Controller) GetClient(ctx context.Context, etcdS3 *config.EtcdS3) (*Cli }) if _, err := creds.Get(); err != nil { - return nil, pkgerrors.WithMessage(err, "failed to get credentials") + return nil, errors.WithMessage(err, "failed to get credentials") } opt := minio.Options{ @@ -242,7 +243,7 @@ func (c *Controller) GetClient(ctx context.Context, etcdS3 *config.EtcdS3) (*Cli exists, err := mc.BucketExists(ctx, etcdS3.Bucket) if err != nil { - return nil, pkgerrors.WithMessagef(err, "failed to test for existence of bucket %s", etcdS3.Bucket) + return nil, errors.WithMessagef(err, "failed to test for existence of bucket %s", etcdS3.Bucket) } if !exists { return nil, fmt.Errorf("bucket %s does not exist", etcdS3.Bucket) diff --git a/pkg/etcd/s3/s3_test.go b/pkg/etcd/s3/s3_test.go index 131757ced05a..0a0361dda767 100644 --- a/pkg/etcd/s3/s3_test.go +++ b/pkg/etcd/s3/s3_test.go @@ -14,10 +14,10 @@ import ( "text/template" "time" - "github.com/gorilla/mux" "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/etcd/snapshot" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/mux" "github.com/k3s-io/k3s/tests/mock" "github.com/rancher/dynamiclistener/cert" "github.com/rancher/wrangler/v3/pkg/generated/controllers/core" @@ -1554,65 +1554,72 @@ func s3Router(t *testing.T) http.Handler { // badbucket returns 404 for all requests // authbucket returns 200 for HeadBucket, 403 for all others // others return 200 for objects with name prefix snapshot, 404 for all others - router := mux.NewRouter().SkipClean(true) + router := mux.NewRouter() // HeadBucket - router.Path("/{bucket}/").Methods(http.MethodHead).HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - if vars["bucket"] == "badbucket" { - rw.WriteHeader(http.StatusNotFound) - } - }) // ListObjectsV2 - router.Path("/{bucket}/").Methods(http.MethodGet).HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - switch vars["bucket"] { - case "badbucket": - rw.WriteHeader(http.StatusNotFound) - case "authbucket": - rw.WriteHeader(http.StatusForbidden) - default: - prefix := r.URL.Query().Get("prefix") - filtered := []object{} - for _, object := range objects { - if strings.HasPrefix(object.Key, prefix) { - filtered = append(filtered, object) - } + router.HandleFunc("GET /{bucket}/{$}", func(rw http.ResponseWriter, r *http.Request) { + switch r.Method { + case http.MethodHead: + if r.PathValue("bucket") == "badbucket" { + rw.WriteHeader(http.StatusNotFound) } - if err := listResponse.Execute(rw, bucket{Name: vars["bucket"], Prefix: prefix, Objects: filtered}); err != nil { - t.Errorf("Failed to generate ListObjectsV2 response, error = %v", err) - rw.WriteHeader(http.StatusInternalServerError) + case http.MethodGet: + switch r.PathValue("bucket") { + case "badbucket": + rw.WriteHeader(http.StatusNotFound) + case "authbucket": + rw.WriteHeader(http.StatusForbidden) + default: + prefix := r.URL.Query().Get("prefix") + filtered := []object{} + for _, object := range objects { + if strings.HasPrefix(object.Key, prefix) { + filtered = append(filtered, object) + } + } + if err := listResponse.Execute(rw, bucket{Name: r.PathValue("bucket"), Prefix: prefix, Objects: filtered}); err != nil { + t.Errorf("Failed to generate ListObjectsV2 response, error = %v", err) + rw.WriteHeader(http.StatusInternalServerError) + } } } }) - // HeadObject - snapshot - router.Path("/{bucket}/{prefix:.*}snapshot-{snapshot}").Methods(http.MethodHead).HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - switch vars["bucket"] { - case "badbucket": - rw.WriteHeader(http.StatusNotFound) - case "authbucket": - rw.WriteHeader(http.StatusForbidden) - default: - rw.Header().Add("last-modified", time.Now().In(gmt).Format(time.RFC1123)) - } - }) - // GetObject - snapshot - router.Path("/{bucket}/{prefix:.*}snapshot-{snapshot}").Methods(http.MethodGet).HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - switch vars["bucket"] { - case "badbucket": - rw.WriteHeader(http.StatusNotFound) - case "authbucket": - rw.WriteHeader(http.StatusForbidden) - default: - rw.Header().Add("last-modified", time.Now().In(gmt).Format(time.RFC1123)) - rw.Write([]byte("test snapshot file\n")) + // HeadObject + // GetObject + router.HandleFunc("GET /{bucket}/{object...}", func(rw http.ResponseWriter, r *http.Request) { + switch r.Method { + case http.MethodHead: + switch r.PathValue("bucket") { + case "badbucket": + rw.WriteHeader(http.StatusNotFound) + case "authbucket": + rw.WriteHeader(http.StatusForbidden) + default: + if strings.Contains(r.PathValue("object"), "bad") { + rw.WriteHeader(http.StatusNotFound) + } else { + rw.Header().Add("last-modified", time.Now().In(gmt).Format(time.RFC1123)) + } + } + case http.MethodGet: + switch r.PathValue("bucket") { + case "badbucket": + rw.WriteHeader(http.StatusNotFound) + case "authbucket": + rw.WriteHeader(http.StatusForbidden) + default: + if strings.Contains(r.PathValue("object"), "bad") { + rw.WriteHeader(http.StatusNotFound) + } else { + rw.Header().Add("last-modified", time.Now().In(gmt).Format(time.RFC1123)) + rw.Write([]byte("test snapshot file\n")) + } + } } }) - // PutObject/DeleteObject - snapshot - router.Path("/{bucket}/{prefix:.*}snapshot-{snapshot}").Methods(http.MethodPut, http.MethodDelete).HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - switch vars["bucket"] { + // PutObject + router.HandleFunc("PUT /{bucket}/{object...}", func(rw http.ResponseWriter, r *http.Request) { + switch r.PathValue("bucket") { case "badbucket": rw.WriteHeader(http.StatusNotFound) case "authbucket": @@ -1623,45 +1630,27 @@ func s3Router(t *testing.T) http.Handler { } } }) - // HeadObject - snapshot metadata - router.Path("/{bucket}/{prefix:.*}.metadata/snapshot-{snapshot}").Methods(http.MethodHead).HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - switch vars["bucket"] { - case "badbucket": - rw.WriteHeader(http.StatusNotFound) - case "authbucket": - rw.WriteHeader(http.StatusForbidden) - default: - rw.Header().Add("last-modified", time.Now().In(gmt).Format(time.RFC1123)) - } - }) - // GetObject - snapshot metadata - router.Path("/{bucket}/{prefix:.*}.metadata/snapshot-{snapshot}").Methods(http.MethodGet).HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - switch vars["bucket"] { - case "badbucket": - rw.WriteHeader(http.StatusNotFound) - case "authbucket": - rw.WriteHeader(http.StatusForbidden) - default: - rw.Header().Add("last-modified", time.Now().In(gmt).Format(time.RFC1123)) - rw.Write([]byte("test snapshot metadata\n")) - } - }) - // PutObject/DeleteObject - snapshot metadata - router.Path("/{bucket}/{prefix:.*}.metadata/snapshot-{snapshot}").Methods(http.MethodPut, http.MethodDelete).HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - switch vars["bucket"] { + // DeleteObject + router.HandleFunc("DELETE /{bucket}/{object...}", func(rw http.ResponseWriter, r *http.Request) { + switch r.PathValue("bucket") { case "badbucket": rw.WriteHeader(http.StatusNotFound) case "authbucket": rw.WriteHeader(http.StatusForbidden) default: if r.Method == http.MethodDelete { - rw.WriteHeader(http.StatusNoContent) + if strings.Contains(r.PathValue("object"), "bad") { + rw.WriteHeader(http.StatusNotFound) + } else { + rw.WriteHeader(http.StatusNoContent) + } } } }) + router.NotFoundHandler = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + logrus.Errorf("Failed to match %q", r.URL) + rw.WriteHeader(http.StatusInternalServerError) + }) return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { scheme := "http" if r.TLS != nil { diff --git a/pkg/etcd/snapshot.go b/pkg/etcd/snapshot.go index 475af3e268c0..3bfcf88d0137 100644 --- a/pkg/etcd/snapshot.go +++ b/pkg/etcd/snapshot.go @@ -5,7 +5,6 @@ import ( "context" "encoding/base64" "encoding/json" - "errors" "fmt" "io" "math/rand" @@ -25,9 +24,9 @@ import ( "github.com/k3s-io/k3s/pkg/etcd/snapshot" "github.com/k3s-io/k3s/pkg/etcd/snapshotmetrics" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/util/metrics" "github.com/k3s-io/k3s/pkg/version" - pkgerrors "github.com/pkg/errors" "github.com/robfig/cron/v3" "github.com/sirupsen/logrus" snapshotv3 "go.etcd.io/etcd/client/v3/snapshot" @@ -232,7 +231,7 @@ func (e *ETCD) snapshot(ctx context.Context) (_ *managed.SnapshotResult, rerr er endpoints := getEndpoints(e.config) status, err := e.client.Status(ctx, endpoints[0]) if err != nil { - return nil, pkgerrors.WithMessage(err, "failed to check etcd status for snapshot") + return nil, errors.WithMessage(err, "failed to check etcd status for snapshot") } if status.IsLearner { @@ -242,17 +241,17 @@ func (e *ETCD) snapshot(ctx context.Context) (_ *managed.SnapshotResult, rerr er snapshotDir, err := snapshotDir(e.config, true) if err != nil { - return nil, pkgerrors.WithMessage(err, "failed to get etcd-snapshot-dir") + return nil, errors.WithMessage(err, "failed to get etcd-snapshot-dir") } cfg, err := getClientConfig(ctx, e.config) if err != nil { - return nil, pkgerrors.WithMessage(err, "failed to get config for etcd snapshot") + return nil, errors.WithMessage(err, "failed to get config for etcd snapshot") } tokenHash, err := util.GetTokenHash(e.config) if err != nil { - return nil, pkgerrors.WithMessage(err, "failed to get server token hash for etcd snapshot") + return nil, errors.WithMessage(err, "failed to get server token hash for etcd snapshot") } nodeName := os.Getenv("NODE_NAME") @@ -282,7 +281,7 @@ func (e *ETCD) snapshot(ctx context.Context) (_ *managed.SnapshotResult, rerr er } logrus.Errorf("Failed to take etcd snapshot: %v", err) if err := e.addSnapshotData(*sf); err != nil { - return nil, pkgerrors.WithMessage(err, "failed to sync ETCDSnapshotFile") + return nil, errors.WithMessage(err, "failed to sync ETCDSnapshotFile") } } @@ -298,7 +297,7 @@ func (e *ETCD) snapshot(ctx context.Context) (_ *managed.SnapshotResult, rerr er } if err != nil { - return nil, pkgerrors.WithMessage(err, "failed to compress snapshot") + return nil, errors.WithMessage(err, "failed to compress snapshot") } snapshotPath = zipPath logrus.Info("Compressed snapshot: " + snapshotPath) @@ -306,7 +305,7 @@ func (e *ETCD) snapshot(ctx context.Context) (_ *managed.SnapshotResult, rerr er f, err := os.Stat(snapshotPath) if err != nil { - return nil, pkgerrors.WithMessage(err, "unable to retrieve snapshot information from local snapshot") + return nil, errors.WithMessage(err, "unable to retrieve snapshot information from local snapshot") } sf = &snapshot.File{ @@ -348,7 +347,7 @@ func (e *ETCD) snapshot(ctx context.Context) (_ *managed.SnapshotResult, rerr er logrus.Warnf("Unable to initialize S3 client: %v", err) if !errors.Is(err, s3.ErrNoConfigSecret) { metrics.ObserveWithStatus(snapshotmetrics.SaveS3Count, s3Start, err) - err = pkgerrors.WithMessage(err, "failed to initialize S3 client") + err = errors.WithMessage(err, "failed to initialize S3 client") sf = &snapshot.File{ Name: f.Name(), NodeName: "s3", @@ -403,7 +402,7 @@ func (e *ETCD) listLocalSnapshots() (map[string]snapshot.File, error) { snapshots := make(map[string]snapshot.File) snapshotDir, err := snapshotDir(e.config, true) if err != nil { - return snapshots, pkgerrors.WithMessage(err, "failed to get etcd-snapshot-dir") + return snapshots, errors.WithMessage(err, "failed to get etcd-snapshot-dir") } if err := filepath.Walk(snapshotDir, func(path string, file os.FileInfo, err error) error { @@ -471,7 +470,7 @@ func (e *ETCD) getS3Client(ctx context.Context) (*s3.Client, error) { func (e *ETCD) PruneSnapshots(ctx context.Context) (*managed.SnapshotResult, error) { snapshotDir, err := snapshotDir(e.config, false) if err != nil { - return nil, pkgerrors.WithMessage(err, "failed to get etcd-snapshot-dir") + return nil, errors.WithMessage(err, "failed to get etcd-snapshot-dir") } res := &managed.SnapshotResult{} @@ -509,7 +508,7 @@ func (e *ETCD) ListSnapshots(ctx context.Context) (*k3s.ETCDSnapshotFileList, er if s3client, err := e.getS3Client(ctx); err != nil { logrus.Warnf("Unable to initialize S3 client: %v", err) if !errors.Is(err, s3.ErrNoConfigSecret) { - return nil, pkgerrors.WithMessage(err, "failed to initialize S3 client") + return nil, errors.WithMessage(err, "failed to initialize S3 client") } } else { sfs, err := s3client.ListSnapshots(ctx) @@ -543,7 +542,7 @@ func (e *ETCD) ListSnapshots(ctx context.Context) (*k3s.ETCDSnapshotFileList, er func (e *ETCD) DeleteSnapshots(ctx context.Context, snapshots []string) (*managed.SnapshotResult, error) { snapshotDir, err := snapshotDir(e.config, false) if err != nil { - return nil, pkgerrors.WithMessage(err, "failed to get etcd-snapshot-dir") + return nil, errors.WithMessage(err, "failed to get etcd-snapshot-dir") } var s3client *s3.Client @@ -552,7 +551,7 @@ func (e *ETCD) DeleteSnapshots(ctx context.Context, snapshots []string) (*manage if err != nil { logrus.Warnf("Unable to initialize S3 client: %v", err) if !errors.Is(err, s3.ErrNoConfigSecret) { - return nil, pkgerrors.WithMessage(err, "failed to initialize S3 client") + return nil, errors.WithMessage(err, "failed to initialize S3 client") } } } @@ -716,7 +715,7 @@ func (e *ETCD) reconcileSnapshotData(ctx context.Context, res *managed.SnapshotR logrus.Warnf("Unable to initialize S3 client: %v", err) if !errors.Is(err, s3.ErrNoConfigSecret) { metrics.ObserveWithStatus(snapshotmetrics.ReconcileS3Count, s3Start, err) - return pkgerrors.WithMessage(err, "failed to initialize S3 client") + return errors.WithMessage(err, "failed to initialize S3 client") } } else { s3Snapshots, err := s3client.ListSnapshots(ctx) diff --git a/pkg/etcd/snapshot_controller.go b/pkg/etcd/snapshot_controller.go index 9c9ef7cde7a1..0316f7d578d2 100644 --- a/pkg/etcd/snapshot_controller.go +++ b/pkg/etcd/snapshot_controller.go @@ -2,7 +2,6 @@ package etcd import ( "context" - "errors" "os" "sort" "strconv" @@ -13,8 +12,8 @@ import ( controllersv1 "github.com/k3s-io/api/pkg/generated/controllers/k3s.cattle.io/v1" "github.com/k3s-io/k3s/pkg/etcd/snapshot" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" - pkgerrors "github.com/pkg/errors" controllerv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/equality" @@ -90,14 +89,14 @@ func (e *etcdSnapshotHandler) sync(key string, esf *k3s.ETCDSnapshotFile) (*k3s. sfKey := sf.GenerateConfigMapKey() m, err := sf.Marshal() if err != nil { - return nil, pkgerrors.WithMessage(err, "failed to marshal snapshot ConfigMap data") + return nil, errors.WithMessage(err, "failed to marshal snapshot ConfigMap data") } marshalledSnapshot := string(m) snapshotConfigMap, err := e.configmaps.Get(metav1.NamespaceSystem, snapshotConfigMapName, metav1.GetOptions{}) if err != nil { if !apierrors.IsNotFound(err) { - return nil, pkgerrors.WithMessage(err, "failed to get snapshot ConfigMap") + return nil, errors.WithMessage(err, "failed to get snapshot ConfigMap") } snapshotConfigMap = &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ @@ -142,7 +141,7 @@ func (e *etcdSnapshotHandler) sync(key string, esf *k3s.ETCDSnapshotFile) (*k3s. } if err != nil { - err = pkgerrors.WithMessage(err, "failed to sync snapshot to ConfigMap") + err = errors.WithMessage(err, "failed to sync snapshot to ConfigMap") } return nil, err @@ -157,14 +156,14 @@ func (e *etcdSnapshotHandler) onRemove(key string, esf *k3s.ETCDSnapshotFile) (* if apierrors.IsNotFound(err) { return nil, nil } - return nil, pkgerrors.WithMessage(err, "failed to get snapshot ConfigMap") + return nil, errors.WithMessage(err, "failed to get snapshot ConfigMap") } sfKey := generateETCDSnapshotFileConfigMapKey(*esf) if _, ok := snapshotConfigMap.Data[sfKey]; ok { delete(snapshotConfigMap.Data, sfKey) if _, err := e.configmaps.Update(snapshotConfigMap); err != nil { - return nil, pkgerrors.WithMessage(err, "failed to remove snapshot from ConfigMap") + return nil, errors.WithMessage(err, "failed to remove snapshot from ConfigMap") } } e.etcd.emitEvent(esf) @@ -243,7 +242,7 @@ func (e *etcdSnapshotHandler) reconcile() error { snapshotConfigMap, err := e.configmaps.Get(metav1.NamespaceSystem, snapshotConfigMapName, metav1.GetOptions{}) if err != nil { if !apierrors.IsNotFound(err) { - return pkgerrors.WithMessage(err, "failed to get snapshot ConfigMap") + return errors.WithMessage(err, "failed to get snapshot ConfigMap") } snapshotConfigMap = &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ diff --git a/pkg/etcd/snapshot_handler.go b/pkg/etcd/snapshot_handler.go index 1d156bcdcdec..8439f47ce121 100644 --- a/pkg/etcd/snapshot_handler.go +++ b/pkg/etcd/snapshot_handler.go @@ -3,7 +3,6 @@ package etcd import ( "context" "encoding/json" - "errors" "io" "net/http" @@ -11,8 +10,9 @@ import ( "github.com/k3s-io/k3s/pkg/cluster/managed" "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/util" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" ) type SnapshotOperation string @@ -70,7 +70,7 @@ func (e *ETCD) snapshotHandler() http.Handler { func (e *ETCD) handleList(rw http.ResponseWriter, req *http.Request) error { if e.config.EtcdS3 != nil { if _, err := e.getS3Client(req.Context()); err != nil { - err = pkgerrors.WithMessage(err, "failed to initialize S3 client") + err = errors.WithMessage(err, "failed to initialize S3 client") util.SendError(err, rw, req, http.StatusBadRequest) return nil } @@ -87,7 +87,7 @@ func (e *ETCD) handleList(rw http.ResponseWriter, req *http.Request) error { func (e *ETCD) handleSave(rw http.ResponseWriter, req *http.Request) error { if e.config.EtcdS3 != nil { if _, err := e.getS3Client(req.Context()); err != nil { - err = pkgerrors.WithMessage(err, "failed to initialize S3 client") + err = errors.WithMessage(err, "failed to initialize S3 client") util.SendError(err, rw, req, http.StatusBadRequest) return nil } @@ -104,7 +104,7 @@ func (e *ETCD) handleSave(rw http.ResponseWriter, req *http.Request) error { func (e *ETCD) handlePrune(rw http.ResponseWriter, req *http.Request) error { if e.config.EtcdS3 != nil { if _, err := e.getS3Client(req.Context()); err != nil { - err = pkgerrors.WithMessage(err, "failed to initialize S3 client") + err = errors.WithMessage(err, "failed to initialize S3 client") util.SendError(err, rw, req, http.StatusBadRequest) return nil } @@ -121,7 +121,7 @@ func (e *ETCD) handlePrune(rw http.ResponseWriter, req *http.Request) error { func (e *ETCD) handleDelete(rw http.ResponseWriter, req *http.Request, snapshots []string) error { if e.config.EtcdS3 != nil { if _, err := e.getS3Client(req.Context()); err != nil { - err = pkgerrors.WithMessage(err, "failed to initialize S3 client") + err = errors.WithMessage(err, "failed to initialize S3 client") util.SendError(err, rw, req, http.StatusBadRequest) return nil } @@ -179,7 +179,7 @@ func (e *ETCD) withRequest(sr *SnapshotRequest) *ETCD { // getSnapshotRequest unmarshalls the snapshot operation request from a client. func getSnapshotRequest(req *http.Request) (*SnapshotRequest, error) { if req.Method != http.MethodPost { - return nil, http.ErrNotSupported + return nil, apierrors.NewMethodNotSupported(k3s.Resource("snapshot"), req.Method) } sr := &SnapshotRequest{} b, err := io.ReadAll(req.Body) diff --git a/pkg/etcd/store/store.go b/pkg/etcd/store/store.go index 9b9e51c23fae..431869eb6484 100644 --- a/pkg/etcd/store/store.go +++ b/pkg/etcd/store/store.go @@ -2,16 +2,14 @@ package store import ( "context" - "errors" "fmt" "os" "runtime/debug" "time" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/kine/pkg/endpoint" "github.com/otiai10/copy" - pkgerrors "github.com/pkg/errors" - "github.com/rancher/wrangler/v3/pkg/merr" "github.com/sirupsen/logrus" "go.etcd.io/etcd/api/v3/mvccpb" "go.etcd.io/etcd/client/pkg/v3/logutil" @@ -205,7 +203,7 @@ func (t *TemporaryStore) Get(ctx context.Context, key string) (mvccpb.KeyValue, } func (t *TemporaryStore) Close() error { - return merr.NewErrors(t.store.Close(), os.RemoveAll(t.dataDir)) + return errors.Join(t.store.Close(), os.RemoveAll(t.dataDir)) } // explicit interface check @@ -254,7 +252,7 @@ func NewStore(dataDir string) (store *Store, rerr error) { // need to check for backend path ourselves, as backend.New just creates // a new empty database if the file does not exist or is empty. if _, err := os.Stat(path); err != nil { - return nil, pkgerrors.WithMessage(err, "failed to stat MVCC KV store backend path") + return nil, errors.WithMessage(err, "failed to stat MVCC KV store backend path") } logrus.Infof("Opening etcd MVCC KV backend database at %s", path) @@ -307,7 +305,7 @@ func (s *Store) Close() error { if s.be != nil { errs = append(errs, s.be.Close()) } - return merr.NewErrors(errs...) + return errors.Join(errs...) } func (s *Store) List(ctx context.Context, key string, rev int64) ([]mvccpb.KeyValue, error) { diff --git a/pkg/executor/embed/embed.go b/pkg/executor/embed/embed.go index 992344a7f171..25c86bfd3ae6 100644 --- a/pkg/executor/embed/embed.go +++ b/pkg/executor/embed/embed.go @@ -4,7 +4,6 @@ package embed import ( "context" - "errors" "flag" "fmt" "net" @@ -27,9 +26,9 @@ import ( "github.com/k3s-io/k3s/pkg/executor/embed/etcd" "github.com/k3s-io/k3s/pkg/signals" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" "github.com/k3s-io/k3s/pkg/vpn" - pkgerrors "github.com/pkg/errors" "github.com/sirupsen/logrus" "k8s.io/apiserver/pkg/authentication/authenticator" cloudprovider "k8s.io/cloud-provider" @@ -97,7 +96,7 @@ func (e *Embedded) Bootstrap(ctx context.Context, nodeConfig *daemonconfig.Node, if len(cfg.FlannelIface) > 0 { nodeConfig.Flannel.Iface, err = net.InterfaceByName(cfg.FlannelIface) if err != nil { - return pkgerrors.WithMessagef(err, "unable to find interface %s", cfg.FlannelIface) + return errors.WithMessagef(err, "unable to find interface %s", cfg.FlannelIface) } } @@ -140,7 +139,7 @@ func (e *Embedded) Bootstrap(ctx context.Context, nodeConfig *daemonconfig.Node, nodeConfig.AgentConfig.NodeIP = vpnIPs[0].String() nodeConfig.Flannel.Iface, err = net.InterfaceByName(vpnInfo.Interface) if err != nil { - return pkgerrors.WithMessagef(err, "unable to find vpn interface: %s", vpnInfo.Interface) + return errors.WithMessagef(err, "unable to find vpn interface: %s", vpnInfo.Interface) } } } @@ -148,7 +147,7 @@ func (e *Embedded) Bootstrap(ctx context.Context, nodeConfig *daemonconfig.Node, // set paths for embedded flannel if enabled hostLocal, err := exec.LookPath("host-local") if err != nil { - return pkgerrors.WithMessagef(err, "failed to find host-local") + return errors.WithMessagef(err, "failed to find host-local") } if cfg.FlannelConf == "" { @@ -182,7 +181,7 @@ func (e *Embedded) Kubelet(ctx context.Context, args []string) error { }() err := command.ExecuteContext(ctx) if err != nil && !errors.Is(err, context.Canceled) { - signals.RequestShutdown(pkgerrors.WithMessage(err, "kubelet exited")) + signals.RequestShutdown(errors.WithMessage(err, "kubelet exited")) } signals.RequestShutdown(nil) }() @@ -203,7 +202,7 @@ func (e *Embedded) KubeProxy(ctx context.Context, args []string) error { }() err := command.ExecuteContext(ctx) if err != nil && !errors.Is(err, context.Canceled) { - signals.RequestShutdown(pkgerrors.WithMessage(err, "kube-proxy exited")) + signals.RequestShutdown(errors.WithMessage(err, "kube-proxy exited")) } signals.RequestShutdown(nil) }() @@ -229,7 +228,7 @@ func (e *Embedded) APIServer(ctx context.Context, args []string) error { }() err := command.ExecuteContext(ctx) if err != nil && !errors.Is(err, context.Canceled) { - signals.RequestShutdown(pkgerrors.WithMessage(err, "apiserver exited")) + signals.RequestShutdown(errors.WithMessage(err, "apiserver exited")) } signals.RequestShutdown(nil) }() @@ -251,7 +250,7 @@ func (e *Embedded) Scheduler(ctx context.Context, nodeReady <-chan struct{}, arg }() err := command.ExecuteContext(ctx) if err != nil && !errors.Is(err, context.Canceled) { - signals.RequestShutdown(pkgerrors.WithMessage(err, "scheduler exited")) + signals.RequestShutdown(errors.WithMessage(err, "scheduler exited")) } signals.RequestShutdown(nil) }() @@ -272,7 +271,7 @@ func (e *Embedded) ControllerManager(ctx context.Context, args []string) error { }() err := command.ExecuteContext(ctx) if err != nil && !errors.Is(err, context.Canceled) { - signals.RequestShutdown(pkgerrors.WithMessage(err, "controller-manager exited")) + signals.RequestShutdown(errors.WithMessage(err, "controller-manager exited")) } signals.RequestShutdown(nil) }() @@ -317,7 +316,7 @@ func (*Embedded) CloudControllerManager(ctx context.Context, ccmRBACReady <-chan }() err := command.ExecuteContext(ctx) if err != nil && !errors.Is(err, context.Canceled) { - signals.RequestShutdown(pkgerrors.WithMessage(err, "cloud-controller-manager exited")) + signals.RequestShutdown(errors.WithMessage(err, "cloud-controller-manager exited")) } signals.RequestShutdown(nil) }() diff --git a/pkg/kubeadm/utils.go b/pkg/kubeadm/utils.go index 18bd4d437ed7..b77bf6564284 100644 --- a/pkg/kubeadm/utils.go +++ b/pkg/kubeadm/utils.go @@ -6,7 +6,8 @@ import ( "strings" "time" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" bootstrapapi "k8s.io/cluster-bootstrap/token/api" @@ -117,7 +118,7 @@ func BootstrapTokenFromSecret(secret *v1.Secret) (*BootstrapToken, error) { // Create the BootstrapTokenString object based on the ID and Secret bts, err := NewBootstrapTokenStringFromIDAndSecret(tokenID, tokenSecret) if err != nil { - return nil, pkgerrors.WithMessage(err, "bootstrap Token Secret is invalid and couldn't be parsed") + return nil, errors.WithMessage(err, "bootstrap Token Secret is invalid and couldn't be parsed") } // Get the description (if any) from the Secret @@ -130,7 +131,7 @@ func BootstrapTokenFromSecret(secret *v1.Secret) (*BootstrapToken, error) { if len(secretExpiration) > 0 { expTime, err := time.Parse(time.RFC3339, secretExpiration) if err != nil { - return nil, pkgerrors.WithMessagef(err, "can't parse expiration time of bootstrap token %q", secret.Name) + return nil, errors.WithMessagef(err, "can't parse expiration time of bootstrap token %q", secret.Name) } expires = &metav1.Time{Time: expTime} } diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index c555312e0b1a..c4aa8fcdc8bd 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -4,11 +4,11 @@ import ( "context" "errors" - "github.com/gorilla/mux" "github.com/k3s-io/k3s/pkg/agent/https" "github.com/k3s-io/k3s/pkg/agent/loadbalancer" "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/etcd/snapshotmetrics" + "github.com/k3s-io/k3s/pkg/util/mux" "github.com/prometheus/client_golang/prometheus/promhttp" lassometrics "github.com/rancher/lasso/pkg/metrics" rdmetrics "github.com/rancher/remotedialer/metrics" diff --git a/pkg/nodeconfig/nodeconfig.go b/pkg/nodeconfig/nodeconfig.go index e9940ba86cb5..def62cddbcd6 100644 --- a/pkg/nodeconfig/nodeconfig.go +++ b/pkg/nodeconfig/nodeconfig.go @@ -11,8 +11,8 @@ import ( "github.com/k3s-io/k3s/pkg/configfilearg" "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" - pkgerrors "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" ) @@ -46,7 +46,7 @@ func getNodeArgs() (string, error) { } nodeArgs, err := json.Marshal(nodeArgsList) if err != nil { - return "", pkgerrors.WithMessage(err, "Failed to retrieve argument list for node") + return "", errors.WithMessage(err, "Failed to retrieve argument list for node") } return string(nodeArgs), nil } @@ -66,7 +66,7 @@ func getNodeEnv() (string, error) { } k3sEnvJSON, err := json.Marshal(k3sEnv) if err != nil { - return "", pkgerrors.WithMessage(err, "Failed to retrieve environment map for node") + return "", errors.WithMessage(err, "Failed to retrieve environment map for node") } return string(k3sEnvJSON), nil } diff --git a/pkg/nodepassword/nodepassword.go b/pkg/nodepassword/nodepassword.go index 577cfbcc82f7..ba477672fa6d 100644 --- a/pkg/nodepassword/nodepassword.go +++ b/pkg/nodepassword/nodepassword.go @@ -2,14 +2,13 @@ package nodepassword import ( "context" - "errors" "fmt" "strings" "github.com/k3s-io/k3s/pkg/authenticator/hash" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" - pkgerrors "github.com/pkg/errors" v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -92,7 +91,7 @@ func (npc *nodePasswordController) ensure(nodeName, pass string) error { func (npc *nodePasswordController) verifyNode(ctx context.Context, node *nodeInfo) error { if nodeName, isNodeAuth := identifier.NodeIdentity(node.User); isNodeAuth { if _, err := npc.nodes.Cache().Get(nodeName); err != nil { - return pkgerrors.WithMessage(err, "unable to verify node identity") + return errors.WithMessage(err, "unable to verify node identity") } } return nil diff --git a/pkg/nodepassword/validate.go b/pkg/nodepassword/validate.go index 598822448729..d9736371275a 100644 --- a/pkg/nodepassword/validate.go +++ b/pkg/nodepassword/validate.go @@ -2,7 +2,6 @@ package nodepassword import ( "context" - "errors" "net/http" "os" "path" @@ -11,10 +10,10 @@ import ( "sync" "time" - "github.com/gorilla/mux" "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/util" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" + "github.com/k3s-io/k3s/pkg/version" "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" @@ -106,13 +105,12 @@ func getNodeInfo(req *http.Request) (*nodeInfo, error) { return nil, errors.New("auth user not set") } - program := mux.Vars(req)["program"] - nodeName := req.Header.Get(program + "-Node-Name") + nodeName := req.Header.Get(version.Program + "-Node-Name") if nodeName == "" { return nil, errors.New("node name not set") } - nodePassword := req.Header.Get(program + "-Node-Password") + nodePassword := req.Header.Get(version.Program + "-Node-Password") if nodePassword == "" { return nil, errors.New("node password not set") } @@ -143,16 +141,16 @@ func verifyLocalPassword(ctx context.Context, control *config.Control, mu *sync. passBytes, err := os.ReadFile(nodePasswordFile) if err != nil { - return "", http.StatusInternalServerError, pkgerrors.WithMessage(err, "unable to read node password file") + return "", http.StatusInternalServerError, errors.WithMessage(err, "unable to read node password file") } passHash, err := Hasher.CreateHash(strings.TrimSpace(string(passBytes))) if err != nil { - return "", http.StatusInternalServerError, pkgerrors.WithMessage(err, "unable to hash node password file") + return "", http.StatusInternalServerError, errors.WithMessage(err, "unable to hash node password file") } if err := Hasher.VerifyHash(passHash, node.Password); err != nil { - return "", http.StatusForbidden, pkgerrors.WithMessage(err, "unable to verify local node password") + return "", http.StatusForbidden, errors.WithMessage(err, "unable to verify local node password") } mu.Lock() diff --git a/pkg/profile/profile.go b/pkg/profile/profile.go index 39c3929a580e..729453e2f6cc 100644 --- a/pkg/profile/profile.go +++ b/pkg/profile/profile.go @@ -5,9 +5,9 @@ import ( "errors" "net/http/pprof" - "github.com/gorilla/mux" "github.com/k3s-io/k3s/pkg/agent/https" "github.com/k3s-io/k3s/pkg/daemons/config" + "github.com/k3s-io/k3s/pkg/util/mux" ) // DefaultProfiler the default instance of a performance profiling server @@ -33,6 +33,6 @@ func (c *Config) Start(ctx context.Context, nodeConfig *config.Node) error { mRouter.HandleFunc("/debug/pprof/profile", pprof.Profile) mRouter.HandleFunc("/debug/pprof/symbol", pprof.Symbol) mRouter.HandleFunc("/debug/pprof/trace", pprof.Trace) - mRouter.PathPrefix("/debug/pprof/").HandlerFunc(pprof.Index) + mRouter.HandleFunc("/debug/pprof/", pprof.Index) return nil } diff --git a/pkg/rootless/mounts.go b/pkg/rootless/mounts.go index d17d1263efb8..ebb2c31296ea 100644 --- a/pkg/rootless/mounts.go +++ b/pkg/rootless/mounts.go @@ -9,7 +9,8 @@ import ( "path/filepath" "strings" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" + "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) @@ -40,7 +41,7 @@ func setupMounts(stateDir string) error { for _, v := range mountMap { if err := setupMount(v[0], v[1]); err != nil { - return pkgerrors.WithMessagef(err, "failed to setup mount %s => %s", v[0], v[1]) + return errors.WithMessagef(err, "failed to setup mount %s => %s", v[0], v[1]) } } @@ -74,16 +75,16 @@ func setupMount(target, dir string) error { } if err := os.MkdirAll(toCreate, 0700); err != nil { - return pkgerrors.WithMessagef(err, "failed to create directory %s", toCreate) + return errors.WithMessagef(err, "failed to create directory %s", toCreate) } logrus.Debug("Mounting none ", toCreate, " tmpfs") if err := unix.Mount("none", toCreate, "tmpfs", 0, ""); err != nil { - return pkgerrors.WithMessagef(err, "failed to mount tmpfs to %s", toCreate) + return errors.WithMessagef(err, "failed to mount tmpfs to %s", toCreate) } if err := os.MkdirAll(target, 0700); err != nil { - return pkgerrors.WithMessagef(err, "failed to create directory %s", target) + return errors.WithMessagef(err, "failed to create directory %s", target) } if dir == "" { @@ -91,7 +92,7 @@ func setupMount(target, dir string) error { } if err := os.MkdirAll(dir, 0700); err != nil { - return pkgerrors.WithMessagef(err, "failed to create directory %s", dir) + return errors.WithMessagef(err, "failed to create directory %s", dir) } logrus.Debug("Mounting ", dir, target, " none bind") diff --git a/pkg/rootless/rootless.go b/pkg/rootless/rootless.go index a59b3bda7727..b021499ba78e 100644 --- a/pkg/rootless/rootless.go +++ b/pkg/rootless/rootless.go @@ -3,7 +3,6 @@ package rootless import ( - "errors" "fmt" "net" "os" @@ -12,8 +11,8 @@ import ( "strconv" "strings" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/opencontainers/cgroups" - pkgerrors "github.com/pkg/errors" "github.com/rootless-containers/rootlesskit/pkg/child" "github.com/rootless-containers/rootlesskit/pkg/copyup/tmpfssymlink" "github.com/rootless-containers/rootlesskit/pkg/network/slirp4netns" @@ -133,7 +132,7 @@ func parseCIDR(s string) (*net.IPNet, error) { func createParentOpt(driver portDriver, stateDir string, enableIPv6 bool) (*parent.Opt, error) { if err := os.MkdirAll(stateDir, 0755); err != nil { - return nil, pkgerrors.WithMessagef(err, "failed to mkdir %s", stateDir) + return nil, errors.WithMessagef(err, "failed to mkdir %s", stateDir) } driver.SetStateDir(stateDir) diff --git a/pkg/server/auth/auth.go b/pkg/server/auth/auth.go index c125908c26b4..179b5387d0e5 100644 --- a/pkg/server/auth/auth.go +++ b/pkg/server/auth/auth.go @@ -5,9 +5,9 @@ import ( "net" "net/http" - "github.com/gorilla/mux" "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/mux" "github.com/k3s-io/k3s/pkg/version" "github.com/sirupsen/logrus" "k8s.io/apiserver/pkg/apis/apiserver" diff --git a/pkg/server/handlers/cert.go b/pkg/server/handlers/cert.go index 82e748e32f3f..9da62b036e18 100644 --- a/pkg/server/handlers/cert.go +++ b/pkg/server/handlers/cert.go @@ -6,7 +6,6 @@ import ( "crypto/tls" "crypto/x509" "encoding/json" - "errors" "fmt" "io" "io/fs" @@ -22,10 +21,9 @@ import ( "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/daemons/control/deps" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" - pkgerrors "github.com/pkg/errors" certutil "github.com/rancher/dynamiclistener/cert" - "github.com/rancher/wrangler/v3/pkg/merr" "github.com/sirupsen/logrus" "k8s.io/client-go/util/keyutil" ) @@ -78,12 +76,12 @@ func caCertReplace(control *config.Control, buf io.ReadCloser, force bool) error } if err := defaultBootstrap(control, tmpControl); err != nil { - return pkgerrors.WithMessage(err, "failed to set default bootstrap values") + return errors.WithMessage(err, "failed to set default bootstrap values") } if err := validateBootstrap(control, tmpControl); err != nil { if !force { - return pkgerrors.WithMessage(err, "failed to validate new CA certificates and keys") + return errors.WithMessage(err, "failed to validate new CA certificates and keys") } logrus.Warnf("Save of CA certificates and keys forced, ignoring validation errors: %v", err) } @@ -113,7 +111,7 @@ func defaultBootstrap(oldControl, newControl *config.Control) error { newVal := newMeta.FieldByName(field.Name) info, err := os.Stat(newVal.String()) if err != nil && !errors.Is(err, fs.ErrNotExist) { - errs = append(errs, pkgerrors.WithMessage(err, field.Name)) + errs = append(errs, errors.WithMessage(err, field.Name)) continue } @@ -127,7 +125,7 @@ func defaultBootstrap(oldControl, newControl *config.Control) error { } } } - return merr.NewErrors(errs...) + return errors.Join(errs...) } // validateBootstrap checks the new certs and keys to ensure that the cluster would function properly were they to be used. @@ -151,24 +149,24 @@ func validateBootstrap(oldControl, newControl *config.Control) error { // Check CA chain consistency and cert/key agreement if strings.HasSuffix(field.Name, "CA") { if err := validateCA(oldVal.String(), newVal.String()); err != nil { - errs = append(errs, pkgerrors.WithMessage(err, field.Name)) + errs = append(errs, errors.WithMessage(err, field.Name)) } newKeyVal := newMeta.FieldByName(field.Name + "Key") oldKeyVal := oldMeta.FieldByName(field.Name + "Key") if err := validateCAKey(oldVal.String(), oldKeyVal.String(), newVal.String(), newKeyVal.String()); err != nil { - errs = append(errs, pkgerrors.WithMessage(err, field.Name+"Key")) + errs = append(errs, errors.WithMessage(err, field.Name+"Key")) } } // Check signing key rotation if field.Name == "ServiceKey" { if err := validateServiceKey(oldVal.String(), newVal.String()); err != nil { - errs = append(errs, pkgerrors.WithMessage(err, field.Name)) + errs = append(errs, errors.WithMessage(err, field.Name)) } } } - return merr.NewErrors(errs...) + return errors.Join(errs...) } func validateCA(oldCAPath, newCAPath string) error { @@ -215,7 +213,7 @@ func validateCA(oldCAPath, newCAPath string) error { // Verify the first cert in the bundle, using the combined roots and intermediates _, err = newCerts[0].Verify(x509.VerifyOptions{Roots: roots, Intermediates: intermediates}) if err != nil { - err = pkgerrors.WithMessage(err, "new CA cert cannot be verified using old CA chain") + err = errors.WithMessage(err, "new CA cert cannot be verified using old CA chain") } return err } @@ -229,7 +227,7 @@ func validateCAKey(oldCAPath, oldCAKeyPath, newCAPath, newCAKeyPath string) erro _, err := tls.LoadX509KeyPair(newCAPath, newCAKeyPath) if err != nil { - err = pkgerrors.WithMessage(err, "new CA cert and key cannot be loaded as X590KeyPair") + err = errors.WithMessage(err, "new CA cert and key cannot be loaded as X590KeyPair") } return err } diff --git a/pkg/server/handlers/handlers.go b/pkg/server/handlers/handlers.go index c51c6ecc823c..e1326e79592e 100644 --- a/pkg/server/handlers/handlers.go +++ b/pkg/server/handlers/handlers.go @@ -4,7 +4,6 @@ import ( "context" "crypto" "crypto/x509" - "errors" "fmt" "io" "net" @@ -14,18 +13,20 @@ import ( "strings" "time" - "github.com/gorilla/mux" "github.com/k3s-io/k3s/pkg/cli/cmds" "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/etcd" "github.com/k3s-io/k3s/pkg/nodepassword" "github.com/k3s-io/k3s/pkg/util" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" + "github.com/k3s-io/k3s/pkg/version" certutil "github.com/rancher/dynamiclistener/cert" "github.com/sirupsen/logrus" discoveryv1 "k8s.io/api/discovery/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/json" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apiserver/pkg/authentication/user" @@ -67,8 +68,7 @@ func ServingKubeletCert(control *config.Control, auth nodepassword.NodeAuthValid } ips := []net.IP{net.ParseIP("127.0.0.1"), net.ParseIP("::1")} - program := mux.Vars(req)["program"] - if nodeIP := req.Header.Get(program + "-Node-IP"); nodeIP != "" { + if nodeIP := req.Header.Get(version.Program + "-Node-IP"); nodeIP != "" { for _, v := range strings.Split(nodeIP, ",") { ip := net.ParseIP(v) if ip == nil { @@ -116,9 +116,8 @@ func ClientKubeProxyCert(control *config.Control) http.Handler { func ClientControllerCert(control *config.Control) http.Handler { return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { - program := mux.Vars(req)["program"] signAndSend(resp, req, control.Runtime.ClientCA, control.Runtime.ClientCAKey, control.Runtime.ClientK3sControllerKey, certutil.Config{ - CommonName: "system:" + program + "-controller", + CommonName: "system:" + version.Program + "-controller", Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, }) }) @@ -136,7 +135,7 @@ func File(fileName ...string) http.Handler { for _, f := range fileName { bytes, err := os.ReadFile(f) if err != nil { - util.SendError(pkgerrors.WithMessagef(err, "failed to read %s", f), resp, req, http.StatusInternalServerError) + util.SendError(errors.WithMessagef(err, "failed to read %s", f), resp, req, http.StatusInternalServerError) return } resp.Write(bytes) @@ -167,7 +166,7 @@ func APIServers(control *config.Control) http.Handler { endpoints := collectAddresses(ctx) resp.Header().Set("content-type", "application/json") if err := json.NewEncoder(resp).Encode(endpoints); err != nil { - util.SendError(pkgerrors.WithMessage(err, "failed to encode apiserver endpoints"), resp, req, http.StatusInternalServerError) + util.SendError(errors.WithMessage(err, "failed to encode apiserver endpoints"), resp, req, http.StatusInternalServerError) } }) } @@ -181,7 +180,7 @@ func Config(control *config.Control, cfg *cmds.Server) http.Handler { control.DisableKubeProxy = cfg.DisableKubeProxy resp.Header().Set("content-type", "application/json") if err := json.NewEncoder(resp).Encode(control); err != nil { - util.SendError(pkgerrors.WithMessage(err, "failed to encode agent config"), resp, req, http.StatusInternalServerError) + util.SendError(errors.WithMessage(err, "failed to encode agent config"), resp, req, http.StatusInternalServerError) } }) } @@ -315,7 +314,7 @@ func getCACertAndKey(caCertFile, caKeyFile string) ([]*x509.Certificate, crypto. // If the request is not a POST, or cannot be parsed as a request, an error is returned. func getCSR(req *http.Request) (*x509.CertificateRequest, error) { if req.Method != http.MethodPost { - return nil, mux.ErrMethodMismatch + return nil, apierrors.NewMethodNotSupported(schema.GroupResource{}, req.Method) } csrBytes, err := io.ReadAll(req.Body) if err != nil { diff --git a/pkg/server/handlers/router.go b/pkg/server/handlers/router.go index 45abb7598dc7..4e2df6bf4934 100644 --- a/pkg/server/handlers/router.go +++ b/pkg/server/handlers/router.go @@ -5,11 +5,11 @@ import ( "net/http" "path/filepath" - "github.com/gorilla/mux" "github.com/k3s-io/k3s/pkg/cli/cmds" "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/nodepassword" "github.com/k3s-io/k3s/pkg/server/auth" + "github.com/k3s-io/k3s/pkg/util/mux" "github.com/k3s-io/k3s/pkg/version" "k8s.io/apiserver/pkg/authentication/user" bootstrapapi "k8s.io/cluster-bootstrap/token/api" @@ -30,26 +30,26 @@ var ( func NewHandler(ctx context.Context, control *config.Control, cfg *cmds.Server) http.Handler { nodeAuth := nodepassword.GetNodeAuthValidator(ctx, control) - prefix := "/v1-{program}" - authed := mux.NewRouter().SkipClean(true) + prefix := "/v1-" + version.Program + authed := mux.NewRouter() authed.NotFoundHandler = APIServer(control, cfg) authed.Use(auth.HasRole(control, version.Program+":agent", user.NodesGroup, bootstrapapi.BootstrapDefaultGroup), auth.RequestInfo(), auth.MaxInFlight(maxNonMutatingAgentRequests, maxMutatingAgentRequests)) authed.Handle(prefix+"/serving-kubelet.crt", ServingKubeletCert(control, nodeAuth)) authed.Handle(prefix+"/client-kubelet.crt", ClientKubeletCert(control, nodeAuth)) authed.Handle(prefix+"/client-kube-proxy.crt", ClientKubeProxyCert(control)) - authed.Handle(prefix+"/client-{program}-controller.crt", ClientControllerCert(control)) + authed.Handle(prefix+"/client-"+version.Program+"-controller.crt", ClientControllerCert(control)) authed.Handle(prefix+"/client-ca.crt", File(control.Runtime.ClientCA)) authed.Handle(prefix+"/server-ca.crt", File(control.Runtime.ServerCA)) authed.Handle(prefix+"/apiservers", APIServers(control)) authed.Handle(prefix+"/config", Config(control, cfg)) authed.Handle(prefix+"/readyz", Readyz(control)) - nodeAuthed := mux.NewRouter().SkipClean(true) + nodeAuthed := mux.NewRouter() nodeAuthed.NotFoundHandler = authed nodeAuthed.Use(auth.HasRole(control, user.NodesGroup)) nodeAuthed.Handle(prefix+"/connect", control.Runtime.Tunnel) - serverAuthed := mux.NewRouter().SkipClean(true) + serverAuthed := mux.NewRouter() serverAuthed.NotFoundHandler = nodeAuthed serverAuthed.Use(auth.HasRole(control, version.Program+":server")) serverAuthed.Handle(prefix+"/encrypt/status", EncryptionStatus(control)) @@ -58,15 +58,14 @@ func NewHandler(ctx context.Context, control *config.Control, cfg *cmds.Server) serverAuthed.Handle(prefix+"/server-bootstrap", Bootstrap(control)) serverAuthed.Handle(prefix+"/token", TokenRequest(ctx, control)) - systemAuthed := mux.NewRouter().SkipClean(true) + systemAuthed := mux.NewRouter() systemAuthed.NotFoundHandler = serverAuthed - systemAuthed.MethodNotAllowedHandler = serverAuthed systemAuthed.Use(auth.HasRole(control, user.SystemPrivilegedGroup)) - systemAuthed.Methods(http.MethodConnect).Handler(control.Runtime.Tunnel) + systemAuthed.Handle("CONNECT /", control.Runtime.Tunnel) - router := mux.NewRouter().SkipClean(true) + router := mux.NewRouter() router.NotFoundHandler = systemAuthed - router.PathPrefix(staticURL).Handler(Static(staticURL, filepath.Join(control.DataDir, "static"))) + router.Handle(staticURL, Static(staticURL, filepath.Join(control.DataDir, "static"))) router.Handle("/cacerts", CACerts(control)) router.Handle("/ping", Ping()) diff --git a/pkg/server/server.go b/pkg/server/server.go index b9df3bf0b685..6153d3575aeb 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -27,13 +27,13 @@ import ( "github.com/k3s-io/k3s/pkg/server/handlers" "github.com/k3s-io/k3s/pkg/static" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" + "github.com/k3s-io/k3s/pkg/util/home" "github.com/k3s-io/k3s/pkg/util/permissions" "github.com/k3s-io/k3s/pkg/version" - pkgerrors "github.com/pkg/errors" "github.com/rancher/wrangler/v3/pkg/apply" v1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" "github.com/rancher/wrangler/v3/pkg/leader" - "github.com/rancher/wrangler/v3/pkg/resolvehome" "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -72,7 +72,7 @@ func PrepareServer(ctx context.Context, wg *sync.WaitGroup, config *Config, cfg // and writes the admin kubeconfig. func StartServer(ctx context.Context, wg *sync.WaitGroup, config *Config, cfg *cmds.Server) error { if err := control.Server(ctx, wg, &config.ControlConfig); err != nil { - return pkgerrors.WithMessage(err, "starting kubernetes") + return errors.WithMessage(err, "starting kubernetes") } shArgs := cmds.StartupHookArgs{ @@ -83,7 +83,7 @@ func StartServer(ctx context.Context, wg *sync.WaitGroup, config *Config, cfg *c } for _, hook := range config.StartupHooks { if err := hook(ctx, config.ControlConfig.Runtime.StartupHooksWg, shArgs); err != nil { - return pkgerrors.WithMessage(err, "startup hook") + return errors.WithMessage(err, "startup hook") } } go startOnAPIServerReady(ctx, config) @@ -111,17 +111,17 @@ func runControllers(ctx context.Context, config *Config) error { sc, err := NewContext(ctx, config) if err != nil { - return pkgerrors.WithMessage(err, "failed to create new server context") + return errors.WithMessage(err, "failed to create new server context") } controlConfig.Runtime.StartupHooksWg.Wait() if err := stageFiles(ctx, sc, controlConfig); err != nil { - return pkgerrors.WithMessage(err, "failed to stage files") + return errors.WithMessage(err, "failed to stage files") } // start the nodepassword controller before we set controlConfig.Runtime.Core if err := nodepassword.Register(ctx, sc.K8s, sc.Core.Core().V1().Secret(), sc.Core.Core().V1().Node()); err != nil { - return pkgerrors.WithMessage(err, "failed to start node-password secret controller") + return errors.WithMessage(err, "failed to start node-password secret controller") } controlConfig.Runtime.K8s = sc.K8s @@ -142,12 +142,12 @@ func runControllers(ctx context.Context, config *Config) error { for _, controller := range config.Controllers { if err := controller(ctx, sc); err != nil { - return pkgerrors.WithMessagef(err, "failed to start %s controller", util.GetFunctionName(controller)) + return errors.WithMessagef(err, "failed to start %s controller", util.GetFunctionName(controller)) } } if err := sc.Start(ctx); err != nil { - return pkgerrors.WithMessage(err, "failed to start wranger controllers") + return errors.WithMessage(err, "failed to start wranger controllers") } if !controlConfig.DisableAPIServer { @@ -181,14 +181,14 @@ func apiserverControllers(ctx context.Context, sc *Context, config *Config) { } for _, controller := range config.LeaderControllers { if err := controller(ctx, sc); err != nil { - panic(pkgerrors.WithMessagef(err, "failed to start %s leader controller", util.GetFunctionName(controller))) + panic(errors.WithMessagef(err, "failed to start %s leader controller", util.GetFunctionName(controller))) } } // Re-run informer factory startup after core and leader-elected controllers have started. // Additional caches may need to start for the newly added OnChange/OnRemove callbacks. if err := sc.Start(ctx); err != nil { - panic(pkgerrors.WithMessage(err, "failed to start wranger controllers")) + panic(errors.WithMessage(err, "failed to start wranger controllers")) } } @@ -352,14 +352,14 @@ func HomeKubeConfig(write, rootless bool) (string, error) { if permissions.IsPrivileged() == nil && !rootless { return datadir.GlobalConfig, nil } - return resolvehome.Resolve(datadir.HomeConfig) + return home.Resolve(datadir.HomeConfig) } if _, err := os.Stat(datadir.GlobalConfig); err == nil { return datadir.GlobalConfig, nil } - return resolvehome.Resolve(datadir.HomeConfig) + return home.Resolve(datadir.HomeConfig) } func printTokens(config *config.Control) error { @@ -496,11 +496,11 @@ func setupDataDirAndChdir(config *config.Control) error { dataDir := config.DataDir if err := os.MkdirAll(dataDir, 0700); err != nil { - return pkgerrors.WithMessagef(err, "can not mkdir %s", dataDir) + return errors.WithMessagef(err, "can not mkdir %s", dataDir) } if err := os.Chdir(dataDir); err != nil { - return pkgerrors.WithMessagef(err, "can not chdir %s", dataDir) + return errors.WithMessagef(err, "can not chdir %s", dataDir) } return nil diff --git a/pkg/spegel/bootstrap.go b/pkg/spegel/bootstrap.go index d6d3bf381dc9..3e77f5ffce0c 100644 --- a/pkg/spegel/bootstrap.go +++ b/pkg/spegel/bootstrap.go @@ -3,7 +3,6 @@ package spegel import ( "context" "encoding/json" - "errors" "fmt" "os" "path/filepath" @@ -13,10 +12,9 @@ import ( "github.com/k3s-io/k3s/pkg/clientaccess" "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/version" "github.com/libp2p/go-libp2p/core/peer" - pkgerrors "github.com/pkg/errors" - "github.com/rancher/wrangler/v3/pkg/merr" "github.com/sirupsen/logrus" "github.com/spegel-org/spegel/pkg/routing" "golang.org/x/sync/errgroup" @@ -107,14 +105,14 @@ func (c *agentBootstrapper) Run(ctx context.Context, id peer.AddrInfo) error { withCert := clientaccess.WithClientCertificate(c.clientCert, c.clientKey) info, err := clientaccess.ParseAndValidateToken(c.server, c.token, withCert) if err != nil { - return pkgerrors.WithMessage(err, "failed to validate join token") + return errors.WithMessage(err, "failed to validate join token") } c.info = info } client, err := util.GetClientSet(c.kubeConfig) if err != nil { - return pkgerrors.WithMessage(err, "failed to create kubernetes client") + return errors.WithMessage(err, "failed to create kubernetes client") } go wait.PollUntilContextCancel(ctx, 1*time.Second, true, func(ctx context.Context) (bool, error) { @@ -264,7 +262,7 @@ func (c *chainingBootstrapper) Run(ctx context.Context, id peer.AddrInfo) error } func (c *chainingBootstrapper) Get(ctx context.Context) ([]peer.AddrInfo, error) { - errs := merr.Errors{} + errs := []error{} for i := range c.bootstrappers { b := c.bootstrappers[i] as, err := b.Get(ctx) @@ -274,7 +272,7 @@ func (c *chainingBootstrapper) Get(ctx context.Context) ([]peer.AddrInfo, error) return as, nil } } - return nil, merr.NewErrors(errs...) + return nil, errors.Join(errs...) } func waitForDone(ctx context.Context) error { diff --git a/pkg/spegel/spegel.go b/pkg/spegel/spegel.go index 3b524be7b2e2..f64b15e17047 100644 --- a/pkg/spegel/spegel.go +++ b/pkg/spegel/spegel.go @@ -5,7 +5,6 @@ import ( "crypto/tls" "crypto/x509" "encoding/json" - "errors" "fmt" "net" "net/http" @@ -18,28 +17,27 @@ import ( "time" "github.com/containerd/containerd/v2/core/remotes/docker" + "github.com/go-logr/logr" + leveldb "github.com/ipfs/go-ds-leveldb" + ipfslog "github.com/ipfs/go-log/v2" "github.com/k3s-io/k3s/pkg/agent/https" "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/server/auth" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/pkg/util/logger" + "github.com/k3s-io/k3s/pkg/util/mux" "github.com/k3s-io/k3s/pkg/version" - "github.com/rancher/dynamiclistener/cert" - "k8s.io/apimachinery/pkg/util/wait" - - "github.com/go-logr/logr" - "github.com/gorilla/mux" - leveldb "github.com/ipfs/go-ds-leveldb" - ipfslog "github.com/ipfs/go-log/v2" "github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoreds" - pkgerrors "github.com/pkg/errors" + "github.com/rancher/dynamiclistener/cert" "github.com/sirupsen/logrus" "github.com/spegel-org/spegel/pkg/metrics" "github.com/spegel-org/spegel/pkg/oci" "github.com/spegel-org/spegel/pkg/registry" "github.com/spegel-org/spegel/pkg/routing" "github.com/spegel-org/spegel/pkg/state" + "k8s.io/apimachinery/pkg/util/wait" "k8s.io/component-base/metrics/legacyregistry" ) @@ -166,7 +164,7 @@ func (c *Config) Start(ctx context.Context, nodeConfig *config.Node, criReadyCha // Get containerd client caCert, err := os.ReadFile(c.ServerCAFile) if err != nil { - return pkgerrors.WithMessage(err, "failed to read server CA") + return errors.WithMessage(err, "failed to read server CA") } certPool := x509.NewCertPool() @@ -190,33 +188,33 @@ func (c *Config) Start(ctx context.Context, nodeConfig *config.Node, criReadyCha } ociStore, err := NewDeferredContainerd(ctx, nodeConfig.Containerd.Address, registryNamespace, storeOpts...) if err != nil { - return pkgerrors.WithMessage(err, "failed to create OCI store") + return errors.WithMessage(err, "failed to create OCI store") } // create or load persistent private key keyFile := filepath.Join(nodeConfig.Containerd.Opt, "peer.key") keyBytes, _, err := cert.LoadOrGenerateKeyFile(keyFile, false) if err != nil { - return pkgerrors.WithMessage(err, "failed to load or generate p2p private key") + return errors.WithMessage(err, "failed to load or generate p2p private key") } privKey, err := cert.ParsePrivateKeyPEM(keyBytes) if err != nil { - return pkgerrors.WithMessage(err, "failed to parse p2p private key") + return errors.WithMessage(err, "failed to parse p2p private key") } p2pKey, _, err := crypto.KeyPairFromStdKey(privKey) if err != nil { - return pkgerrors.WithMessage(err, "failed to convert p2p private key") + return errors.WithMessage(err, "failed to convert p2p private key") } // create a peerstore to allow persisting nodes across restarts peerFile := filepath.Join(nodeConfig.Containerd.Opt, "peerstore.db") ds, err := leveldb.NewDatastore(peerFile, nil) if err != nil { - return pkgerrors.WithMessage(err, "failed to create peerstore datastore") + return errors.WithMessage(err, "failed to create peerstore datastore") } ps, err := pstoreds.NewPeerstore(ctx, ds, pstoreds.DefaultOpts()) if err != nil { - return pkgerrors.WithMessage(err, "failed to create peerstore") + return errors.WithMessage(err, "failed to create peerstore") } // get latest tag configuration override @@ -250,7 +248,7 @@ func (c *Config) Start(ctx context.Context, nodeConfig *config.Node, criReadyCha } c.router, err = routing.NewP2PRouter(ctx, routerAddr, NewNotSelfBootstrapper(c.Bootstrapper), c.RegistryPort, opts...) if err != nil { - return pkgerrors.WithMessage(err, "failed to create P2P router") + return errors.WithMessage(err, "failed to create P2P router") } go c.router.Run(ctx) @@ -263,7 +261,7 @@ func (c *Config) Start(ctx context.Context, nodeConfig *config.Node, criReadyCha } reg, err := registry.NewRegistry(ociStore, c.router, registryOpts...) if err != nil { - return pkgerrors.WithMessage(err, "failed to create embedded registry") + return errors.WithMessage(err, "failed to create embedded registry") } regSvr := &http.Server{ Addr: ":" + c.RegistryPort, @@ -296,10 +294,10 @@ func (c *Config) Start(ctx context.Context, nodeConfig *config.Node, criReadyCha if err != nil { return err } - mRouter.PathPrefix("/v2").Handler(regSvr.Handler) - sRouter := mRouter.PathPrefix("/v1-{program}/p2p").Subrouter() + mRouter.Handle("/v2/", regSvr.Handler) + sRouter := mRouter.SubRouter("/v1-" + version.Program + "/p2p") sRouter.Use(auth.MaxInFlight(maxNonMutatingPeerInfoRequests, maxMutatingPeerInfoRequests)) - sRouter.Handle("", c.peerInfo()) + sRouter.Handle("/", c.peerInfo()) // Wait up to 5 seconds for the p2p network to find peers. if err := wait.PollUntilContextTimeout(ctx, time.Second, resolveTimeout, true, func(ctx context.Context) (bool, error) { diff --git a/pkg/static/stage.go b/pkg/static/stage.go index 303c4f6c7e38..6915adc618d5 100644 --- a/pkg/static/stage.go +++ b/pkg/static/stage.go @@ -8,7 +8,7 @@ import ( "path/filepath" "github.com/k3s-io/k3s/pkg/util/bindata" - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/sirupsen/logrus" ) @@ -27,7 +27,7 @@ func Stage(dataDir string) error { logrus.Info("Writing static file: ", p) os.MkdirAll(filepath.Dir(p), 0700) if err := os.WriteFile(p, content, 0600); err != nil { - return pkgerrors.WithMessagef(err, "failed to write to %s", name) + return errors.WithMessagef(err, "failed to write to %s", name) } } diff --git a/pkg/util/api.go b/pkg/util/api.go index 80f857e5ca18..ed0e0f98c5fd 100644 --- a/pkg/util/api.go +++ b/pkg/util/api.go @@ -2,7 +2,6 @@ package util import ( "context" - "errors" "net" "net/http" "os" @@ -10,8 +9,7 @@ import ( "time" "github.com/k3s-io/k3s/pkg/signals" - pkgerrors "github.com/pkg/errors" - "github.com/rancher/wrangler/v3/pkg/merr" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/rancher/wrangler/v3/pkg/schemes" "github.com/sirupsen/logrus" authorizationv1 "k8s.io/api/authorization/v1" @@ -122,7 +120,7 @@ func WaitForAPIServerReady(ctx context.Context, kubeconfigPath string, timeout t }) if err != nil { - return merr.NewErrors(err, lastErr) + return errors.Join(err, lastErr) } return nil @@ -136,7 +134,7 @@ func APIServerReadyChan(ctx context.Context, kubeConfig string, timeout time.Dur go func() { if err := WaitForAPIServerReady(ctx, kubeConfig, timeout); err != nil { - signals.RequestShutdown(pkgerrors.WithMessage(err, "failed to wait for API server to become ready")) + signals.RequestShutdown(errors.WithMessage(err, "failed to wait for API server to become ready")) return } close(ready) @@ -183,7 +181,7 @@ func WaitForRBACReady(ctx context.Context, kubeconfigPath string, timeout time.D }) if err != nil { - return merr.NewErrors(err, lastErr) + return errors.Join(err, lastErr) } return nil diff --git a/pkg/util/errors.go b/pkg/util/errors.go deleted file mode 100644 index 237987c9ff06..000000000000 --- a/pkg/util/errors.go +++ /dev/null @@ -1,31 +0,0 @@ -package util - -import ( - "errors" - "fmt" - "path" - "runtime" - "slices" - "strings" -) - -var ErrCommandNoArgs = errors.New("this command does not take any arguments") -var ErrUnsupportedPlatform = errors.New("unsupported platform") - -func ErrWithStack(message string) error { - stack := []string{} - pcs := make([]uintptr, 32) - runtime.Callers(2, pcs) - frames := runtime.CallersFrames(pcs) - for { - frame, more := frames.Next() - if !strings.HasPrefix(frame.Function, "runtime.") { - stack = append(stack, fmt.Sprintf("%s(%s:%d)", frame.Function, path.Base(frame.File), frame.Line)) - } - if !more { - break - } - } - slices.Reverse(stack) - return errors.New(message + " at " + strings.Join(stack, "->")) -} diff --git a/pkg/util/errors/errors.go b/pkg/util/errors/errors.go new file mode 100644 index 000000000000..1e4186257883 --- /dev/null +++ b/pkg/util/errors/errors.go @@ -0,0 +1,51 @@ +package errors + +import ( + "errors" + "fmt" + "path" + "runtime" + "slices" + "strings" +) + +// wrap stdlib errors functions to make it easier to import this package as a replacement +var As = errors.As +var Is = errors.Is +var Join = errors.Join +var New = errors.New + +var ErrCommandNoArgs = New("this command does not take any arguments") +var ErrUnsupportedPlatform = New("unsupported platform") + +func WithStack(err error) error { + stack := []string{} + pcs := make([]uintptr, 32) + runtime.Callers(2, pcs) + frames := runtime.CallersFrames(pcs) + for { + frame, more := frames.Next() + if !strings.HasPrefix(frame.Function, "runtime.") { + stack = append(stack, fmt.Sprintf("%s(%s:%d)", frame.Function, path.Base(frame.File), frame.Line)) + } + if !more { + break + } + } + slices.Reverse(stack) + return fmt.Errorf("%w at %s", err, strings.Join(stack, "->")) +} + +func WithMessage(err error, msg string) error { + if err == nil { + return nil + } + return fmt.Errorf("%s: %w", msg, err) +} + +func WithMessagef(err error, format string, args ...any) error { + if err == nil { + return nil + } + return fmt.Errorf("%s: %w", fmt.Sprintf(format, args...), err) +} diff --git a/pkg/util/home/home.go b/pkg/util/home/home.go new file mode 100644 index 000000000000..b55d96027e6e --- /dev/null +++ b/pkg/util/home/home.go @@ -0,0 +1,26 @@ +package home + +import ( + "os" + "strings" + + "github.com/k3s-io/k3s/pkg/util/errors" +) + +var ( + homes = []string{"$HOME", "${HOME}", "~"} +) + +func Resolve(s string) (string, error) { + for _, home := range homes { + if strings.Contains(s, home) { + homeDir, err := os.UserHomeDir() + if err != nil { + return "", errors.WithMessage(err, "determining current user") + } + s = strings.Replace(s, home, homeDir, -1) + } + } + + return s, nil +} diff --git a/pkg/util/mux/mux.go b/pkg/util/mux/mux.go new file mode 100644 index 000000000000..f66d080d47cc --- /dev/null +++ b/pkg/util/mux/mux.go @@ -0,0 +1,122 @@ +package mux + +import ( + "net/http" +) + +// MiddlewareFunc is the function signature of middlewares. The middleware is expected +// to return a handler that does work and then either writes a response, or calls the +// provided handler for additional processing. +type MiddlewareFunc func(http.Handler) http.Handler + +// Handler wraps http.Handler and allows selectively running middleware on a matched route +type Handler interface { + http.Handler + Matched() bool +} + +// muxHandler is a wrapper around http.Handler, +// used to differentiate between http.ServeMux internal +// handlers and handlers from this package. +type muxHandler struct { + handler http.Handler +} + +// ServeHTTP calls the wrapped function of the same name. +func (mh *muxHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + mh.handler.ServeHTTP(rw, req) +} + +func (mh *muxHandler) Matched() bool { + return true +} + +// rootHandler runs the router's NotFoundHandler if one is set, +// or returns a fixed NotFound error. Middlewares are run +// if the NotFound handler was registered as a match for the root path. +type rootHandler struct { + r *Router + rootMatch bool +} + +func (rh *rootHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + if rh.r.NotFoundHandler != nil { + rh.r.NotFoundHandler.ServeHTTP(rw, req) + } else { + rw.WriteHeader(http.StatusNotFound) + } +} + +func (rh *rootHandler) Matched() bool { + return rh.rootMatch && rh.r.NotFoundHandler != nil +} + +// Router wraps http.ServeMux, adding functionality to call +// middlewares on matched requests. +type Router struct { + NotFoundHandler http.Handler + + sm *http.ServeMux + rootHandler *rootHandler + middlewares []MiddlewareFunc +} + +// NewRouter creates a new Router +func NewRouter() *Router { + r := &Router{sm: http.NewServeMux()} + r.rootHandler = &rootHandler{r: r} + r.sm.Handle("/", r.rootHandler) + return r +} + +// Use registers one or more middlewares. Middlewares are only run +// when a route is matched. +func (r *Router) Use(mwfs ...MiddlewareFunc) { + r.middlewares = append(r.middlewares, mwfs...) +} + +// SubRouter registers a route pattern, and returns a new router. Middlewares +// will only run if the subrouter pattern was matched. +// Note that the base pattern for the subrouter is NOT automatically +// prefixed to paths registered beneath it. +func (r *Router) SubRouter(pattern string) *Router { + sr := NewRouter() + r.Handle(pattern, sr) + return sr +} + +// Handle registers a route pattern to call a handler +func (r *Router) Handle(pattern string, handler http.Handler) { + handler = &muxHandler{handler: handler} + if pattern == "/" && r.NotFoundHandler == nil { + r.rootHandler.rootMatch = true + r.NotFoundHandler = handler + } else { + r.sm.Handle(pattern, handler) + } +} + +// HandleFunc registers a route pattern to call a handler function +func (r *Router) HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) { + r.Handle(pattern, http.HandlerFunc(handler)) +} + +// ServeHTTP handles the request, running middlewares if a registered pattern +// has been matched. +func (r *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + next := http.Handler(r.sm) + // fix up path for CONNECT requests so that they do not get redirected + if req.Method == http.MethodConnect && req.URL.Path == "" { + req.URL.Path = "/" + } + // only run middlewares if this is a mux handler; other handlers are + // http.ServeMux internal handlers that indicate no pattern was matched, and + // we should not run middleware. + handler, _ := r.sm.Handler(req) + if h, ok := handler.(Handler); ok && h.Matched() { + for i := len(r.middlewares) - 1; i >= 0; i-- { + next = r.middlewares[i](next) + } + } + next.ServeHTTP(rw, req) +} diff --git a/pkg/util/net.go b/pkg/util/net.go index 4123493537e5..1e65258f5603 100644 --- a/pkg/util/net.go +++ b/pkg/util/net.go @@ -9,7 +9,6 @@ import ( "strings" "time" - "github.com/rancher/wrangler/v3/pkg/merr" "github.com/sirupsen/logrus" apinet "k8s.io/apimachinery/pkg/util/net" netutils "k8s.io/utils/net" @@ -379,14 +378,14 @@ func (ml *multiListener) Addr() net.Addr { // Close closes all the listeners func (ml *multiListener) Close() error { close(ml.closing) - var errs merr.Errors + var errs []error for i := range ml.listeners { err := ml.listeners[i].Close() if err != nil { errs = append(errs, err) } } - return merr.NewErrors(errs) + return errors.Join(errs...) } // Accept returns a Conn/err pair from one of the waiting listeners diff --git a/pkg/util/permissions/permissions_windows.go b/pkg/util/permissions/permissions_windows.go index 0b4a9109198c..5b55a697d12a 100644 --- a/pkg/util/permissions/permissions_windows.go +++ b/pkg/util/permissions/permissions_windows.go @@ -3,9 +3,7 @@ package permissions import ( - "errors" - - pkgerrors "github.com/pkg/errors" + "github.com/k3s-io/k3s/pkg/util/errors" "golang.org/x/sys/windows" ) @@ -26,7 +24,7 @@ func IsPrivileged() error { 0, 0, 0, 0, 0, 0, &sid) if err != nil { - return pkgerrors.WithMessage(err, "failed to create Windows SID") + return errors.WithMessage(err, "failed to create Windows SID") } defer windows.FreeSid(sid) @@ -35,7 +33,7 @@ func IsPrivileged() error { member, err := token.IsMember(sid) if err != nil { - return pkgerrors.WithMessage(err, "failed to check group membership") + return errors.WithMessage(err, "failed to check group membership") } if !member { diff --git a/pkg/vpn/vpn.go b/pkg/vpn/vpn.go index 9580f8bc42c7..09c2649ec738 100644 --- a/pkg/vpn/vpn.go +++ b/pkg/vpn/vpn.go @@ -2,7 +2,6 @@ package vpn import ( "encoding/json" - "errors" "fmt" "net" "net/netip" @@ -10,8 +9,8 @@ import ( "strings" "github.com/k3s-io/k3s/pkg/util" + "github.com/k3s-io/k3s/pkg/util/errors" - pkgerrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -73,7 +72,7 @@ func StartVPN(vpnAuthConfigFile string) error { logrus.Debugf("Flags passed to tailscale up: %v", args) output, err := util.ExecCommand("tailscale", args) if err != nil { - return pkgerrors.WithMessage(err, "tailscale up failed: "+output) + return errors.WithMessage(err, "tailscale up failed: "+output) } logrus.Debugf("Output from tailscale up: %v", output) return nil diff --git a/scripts/airgap/image-list.txt b/scripts/airgap/image-list.txt index 311a485d7c8f..ef06f6e2c40f 100644 --- a/scripts/airgap/image-list.txt +++ b/scripts/airgap/image-list.txt @@ -1,8 +1,8 @@ -docker.io/rancher/klipper-helm:v0.9.14-build20260210 -docker.io/rancher/klipper-lb:v0.4.14 -docker.io/rancher/local-path-provisioner:v0.0.34 +docker.io/rancher/klipper-helm:v0.9.14-build20260309 +docker.io/rancher/klipper-lb:v0.4.15 +docker.io/rancher/local-path-provisioner:v0.0.35 docker.io/rancher/mirrored-coredns-coredns:1.14.2 docker.io/rancher/mirrored-library-busybox:1.37.0 -docker.io/rancher/mirrored-library-traefik:3.6.9 +docker.io/rancher/mirrored-library-traefik:3.6.10 docker.io/rancher/mirrored-metrics-server:v0.8.1 docker.io/rancher/mirrored-pause:3.6 diff --git a/scripts/version.sh b/scripts/version.sh index 75c4ecc92311..ce173fb9b3ab 100755 --- a/scripts/version.sh +++ b/scripts/version.sh @@ -64,7 +64,7 @@ fi VERSION_ROOT="v0.15.0" -VERSION_HELM_JOB="v0.9.14-build20260210" +VERSION_HELM_JOB="v0.9.14-build20260309" DEPENDENCIES_URL="https://raw.githubusercontent.com/kubernetes/kubernetes/${VERSION_K8S}/build/dependencies.yaml" VERSION_GOLANG="go"$(curl -sL "${DEPENDENCIES_URL}" | yq e '.dependencies[] | select(.name == "golang: upstream version").version' -) diff --git a/tests/docker/nixsnapshotter/nixsnapshotter_test.go b/tests/docker/nixsnapshotter/nixsnapshotter_test.go new file mode 100644 index 000000000000..f2f0cf197248 --- /dev/null +++ b/tests/docker/nixsnapshotter/nixsnapshotter_test.go @@ -0,0 +1,97 @@ +package main + +import ( + "flag" + "fmt" + "os" + "path/filepath" + "testing" + + "github.com/k3s-io/k3s/tests" + "github.com/k3s-io/k3s/tests/docker" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var k3sImage = flag.String("k3sImage", "", "The k3s image used to provision containers") +var ci = flag.Bool("ci", false, "running on CI, forced cleanup") +var config *docker.TestConfig + +func Test_DockerNixSnapshotter(t *testing.T) { + flag.Parse() + RegisterFailHandler(Fail) + RunSpecs(t, "Nix Snapshotter Docker Test Suite") +} + +var _ = Describe("Nix Snapshotter Tests", Ordered, func() { + + Context("Setup Cluster", func() { + It("should provision servers with nix snapshotter", func() { + var err error + config, err = docker.NewTestConfig(*k3sImage) + Expect(err).NotTo(HaveOccurred()) + + // Write a container entrypoint wrapper that symlinks nix-store + // into the PATH before starting k3s. This is needed because the + // NixSupported() check calls exec.LookPath("nix-store") during + // startup, before we have a chance to docker exec into the container. + entrypoint := filepath.Join(config.TestDir, "nix-entrypoint.sh") + Expect(os.WriteFile(entrypoint, []byte("#!/bin/sh\nln -sf /nix/var/nix/profiles/default/bin/nix-store /usr/local/bin/nix-store\nexec /bin/k3s \"$@\"\n"), 0755)).To(Succeed()) + + os.Setenv("SERVER_DOCKER_ARGS", fmt.Sprintf("--restart=always -v /nix:/nix -v %s:/usr/local/bin/nix-entrypoint.sh --entrypoint /usr/local/bin/nix-entrypoint.sh", entrypoint)) + + config.ServerYaml = "snapshotter: nix" + Expect(config.ProvisionServers(1)).To(Succeed()) + + Eventually(func() error { + return tests.CheckDefaultDeployments(config.KubeconfigFile) + }, "180s", "5s").Should(Succeed()) + Eventually(func() error { + return tests.NodesReady(config.KubeconfigFile, config.GetNodeNames()) + }, "40s", "5s").Should(Succeed()) + }) + }) + + Context("Verify Nix Snapshotter", func() { + It("should run a pod using a nix-built image", func() { + // Copy the nix test image OCI tar into the k3s container. + // Built by CI via: nix build github:pdtpartners/nix-snapshotter#image-hello + cmd := fmt.Sprintf("docker cp ../resources/nix-hello-image.tar %s:/tmp/nix-hello-image.tar", config.Servers[0].Name) + _, err := tests.RunCommand(cmd) + Expect(err).NotTo(HaveOccurred(), "failed to copy test image into container") + + // Run a pod using the nix:0 image reference prefix. This directs + // kubelet's PullImage through the nix-snapshotter image service, + // which loads the OCI tar and unpacks layers with nix-closure + // annotation processing. The snapshotter's Prepare() realizes + // the closure's nix store paths via nix-store and creates GC + // roots. The image's entrypoint (hello) prints and exits 0. + cmd = fmt.Sprintf("kubectl --kubeconfig=%s run nix-hello --image=nix:0/tmp/nix-hello-image.tar --image-pull-policy=Always --restart=Never", config.KubeconfigFile) + _, err = tests.RunCommand(cmd) + Expect(err).NotTo(HaveOccurred(), "failed to create nix-hello pod") + + // Wait for the pod to complete successfully. + Eventually(func() (string, error) { + cmd := fmt.Sprintf("kubectl --kubeconfig=%s get pod nix-hello -o jsonpath='{.status.phase}'", config.KubeconfigFile) + return tests.RunCommand(cmd) + }, "60s", "5s").Should(Equal("Succeeded")) + }) + }) +}) + +var failed bool +var _ = AfterEach(func() { + failed = failed || CurrentSpecReport().Failed() +}) + +var _ = AfterSuite(func() { + if failed { + AddReportEntry("describe", docker.DescribeNodesAndPods(config)) + AddReportEntry("docker-containers", docker.ListContainers()) + AddReportEntry("docker-logs", docker.TailDockerLogs(1000, append(config.Servers, config.Agents...))) + } + if config != nil && (*ci || !failed) { + Expect(config.Cleanup()).To(Succeed()) + } +}) + diff --git a/tests/integration/integration.go b/tests/integration/integration.go index c3be0d2d12e5..6f2b4db0c01a 100644 --- a/tests/integration/integration.go +++ b/tests/integration/integration.go @@ -16,8 +16,8 @@ import ( "time" "github.com/k3s-io/k3s/pkg/flock" + "github.com/k3s-io/k3s/pkg/util/errors" "github.com/k3s-io/k3s/tests" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/vishvananda/netlink" "golang.org/x/sys/unix" @@ -239,16 +239,16 @@ func K3sKillServer(server *K3sServer) error { logrus.Warnf("Unable to kill k3s server: %v", err) return nil } - return errors.Wrap(err, "failed to find k3s process group") + return errors.WithMessage(err, "failed to find k3s process group") } if err := syscall.Kill(-pgid, syscall.SIGKILL); err != nil { - return errors.Wrap(err, "failed to kill k3s process group") + return errors.WithMessage(err, "failed to kill k3s process group") } if err := server.cmd.Process.Kill(); err != nil { - return errors.Wrap(err, "failed to kill k3s process") + return errors.WithMessage(err, "failed to kill k3s process") } if _, err = server.cmd.Process.Wait(); err != nil { - return errors.Wrap(err, "failed to wait for k3s process exit") + return errors.WithMessage(err, "failed to wait for k3s process exit") } //Unmount all the associated filesystems unmountFolder("/run/k3s") diff --git a/tests/integration/kubeflags/kubeflags_test.go b/tests/integration/kubeflags/kubeflags_test.go index b6874dc7a2bf..4c29e57207c7 100644 --- a/tests/integration/kubeflags/kubeflags_test.go +++ b/tests/integration/kubeflags/kubeflags_test.go @@ -1,6 +1,7 @@ package kubeflags import ( + "errors" "strings" "testing" @@ -8,7 +9,6 @@ import ( testutil "github.com/k3s-io/k3s/tests/integration" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/pkg/errors" ) var server *testutil.K3sServer diff --git a/tests/mock/core.go b/tests/mock/core.go index 9cfb51dc5c01..abb59bf5a8e9 100644 --- a/tests/mock/core.go +++ b/tests/mock/core.go @@ -65,54 +65,62 @@ func (m *CoreMock) V1() corev1.Interface { var _ corev1.Interface = &V1Mock{} type V1Mock struct { - ConfigMapMock *fake.MockControllerInterface[*v1.ConfigMap, *v1.ConfigMapList] ConfigMapCache *fake.MockCacheInterface[*v1.ConfigMap] - EndpointsMock *fake.MockControllerInterface[*v1.Endpoints, *v1.EndpointsList] + ConfigMapMock *fake.MockControllerInterface[*v1.ConfigMap, *v1.ConfigMapList] EndpointsCache *fake.MockCacheInterface[*v1.Endpoints] - EventMock *fake.MockControllerInterface[*v1.Event, *v1.EventList] + EndpointsMock *fake.MockControllerInterface[*v1.Endpoints, *v1.EndpointsList] EventCache *fake.MockCacheInterface[*v1.Event] - NamespaceMock *fake.MockNonNamespacedControllerInterface[*v1.Namespace, *v1.NamespaceList] + EventMock *fake.MockControllerInterface[*v1.Event, *v1.EventList] + LimitRangeCache *fake.MockCacheInterface[*v1.LimitRange] + LimitRangeMock *fake.MockControllerInterface[*v1.LimitRange, *v1.LimitRangeList] NamespaceCache *fake.MockNonNamespacedCacheInterface[*v1.Namespace] - NodeMock *fake.MockNonNamespacedControllerInterface[*v1.Node, *v1.NodeList] + NamespaceMock *fake.MockNonNamespacedControllerInterface[*v1.Namespace, *v1.NamespaceList] NodeCache *fake.MockNonNamespacedCacheInterface[*v1.Node] - PersistentVolumeMock *fake.MockNonNamespacedControllerInterface[*v1.PersistentVolume, *v1.PersistentVolumeList] + NodeMock *fake.MockNonNamespacedControllerInterface[*v1.Node, *v1.NodeList] PersistentVolumeCache *fake.MockNonNamespacedCacheInterface[*v1.PersistentVolume] - PersistentVolumeClaimMock *fake.MockControllerInterface[*v1.PersistentVolumeClaim, *v1.PersistentVolumeClaimList] PersistentVolumeClaimCache *fake.MockCacheInterface[*v1.PersistentVolumeClaim] - PodMock *fake.MockControllerInterface[*v1.Pod, *v1.PodList] + PersistentVolumeClaimMock *fake.MockControllerInterface[*v1.PersistentVolumeClaim, *v1.PersistentVolumeClaimList] + PersistentVolumeMock *fake.MockNonNamespacedControllerInterface[*v1.PersistentVolume, *v1.PersistentVolumeList] PodCache *fake.MockCacheInterface[*v1.Pod] - SecretMock *fake.MockControllerInterface[*v1.Secret, *v1.SecretList] + PodMock *fake.MockControllerInterface[*v1.Pod, *v1.PodList] + ResourceQuotaCache *fake.MockCacheInterface[*v1.ResourceQuota] + ResourceQuotaMock *fake.MockControllerInterface[*v1.ResourceQuota, *v1.ResourceQuotaList] SecretCache *fake.MockCacheInterface[*v1.Secret] - ServiceMock *fake.MockControllerInterface[*v1.Service, *v1.ServiceList] - ServiceCache *fake.MockCacheInterface[*v1.Service] - ServiceAccountMock *fake.MockControllerInterface[*v1.ServiceAccount, *v1.ServiceAccountList] + SecretMock *fake.MockControllerInterface[*v1.Secret, *v1.SecretList] ServiceAccountCache *fake.MockCacheInterface[*v1.ServiceAccount] + ServiceAccountMock *fake.MockControllerInterface[*v1.ServiceAccount, *v1.ServiceAccountList] + ServiceCache *fake.MockCacheInterface[*v1.Service] + ServiceMock *fake.MockControllerInterface[*v1.Service, *v1.ServiceList] } func NewV1(c *gomock.Controller) *V1Mock { return &V1Mock{ - ConfigMapMock: fake.NewMockControllerInterface[*v1.ConfigMap, *v1.ConfigMapList](c), ConfigMapCache: fake.NewMockCacheInterface[*v1.ConfigMap](c), - EndpointsMock: fake.NewMockControllerInterface[*v1.Endpoints, *v1.EndpointsList](c), + ConfigMapMock: fake.NewMockControllerInterface[*v1.ConfigMap, *v1.ConfigMapList](c), EndpointsCache: fake.NewMockCacheInterface[*v1.Endpoints](c), - EventMock: fake.NewMockControllerInterface[*v1.Event, *v1.EventList](c), + EndpointsMock: fake.NewMockControllerInterface[*v1.Endpoints, *v1.EndpointsList](c), EventCache: fake.NewMockCacheInterface[*v1.Event](c), - NamespaceMock: fake.NewMockNonNamespacedControllerInterface[*v1.Namespace, *v1.NamespaceList](c), + EventMock: fake.NewMockControllerInterface[*v1.Event, *v1.EventList](c), + LimitRangeCache: fake.NewMockCacheInterface[*v1.LimitRange](c), + LimitRangeMock: fake.NewMockControllerInterface[*v1.LimitRange, *v1.LimitRangeList](c), NamespaceCache: fake.NewMockNonNamespacedCacheInterface[*v1.Namespace](c), - NodeMock: fake.NewMockNonNamespacedControllerInterface[*v1.Node, *v1.NodeList](c), + NamespaceMock: fake.NewMockNonNamespacedControllerInterface[*v1.Namespace, *v1.NamespaceList](c), NodeCache: fake.NewMockNonNamespacedCacheInterface[*v1.Node](c), - PersistentVolumeMock: fake.NewMockNonNamespacedControllerInterface[*v1.PersistentVolume, *v1.PersistentVolumeList](c), + NodeMock: fake.NewMockNonNamespacedControllerInterface[*v1.Node, *v1.NodeList](c), PersistentVolumeCache: fake.NewMockNonNamespacedCacheInterface[*v1.PersistentVolume](c), - PersistentVolumeClaimMock: fake.NewMockControllerInterface[*v1.PersistentVolumeClaim, *v1.PersistentVolumeClaimList](c), PersistentVolumeClaimCache: fake.NewMockCacheInterface[*v1.PersistentVolumeClaim](c), - PodMock: fake.NewMockControllerInterface[*v1.Pod, *v1.PodList](c), + PersistentVolumeClaimMock: fake.NewMockControllerInterface[*v1.PersistentVolumeClaim, *v1.PersistentVolumeClaimList](c), + PersistentVolumeMock: fake.NewMockNonNamespacedControllerInterface[*v1.PersistentVolume, *v1.PersistentVolumeList](c), PodCache: fake.NewMockCacheInterface[*v1.Pod](c), - SecretMock: fake.NewMockControllerInterface[*v1.Secret, *v1.SecretList](c), + PodMock: fake.NewMockControllerInterface[*v1.Pod, *v1.PodList](c), + ResourceQuotaCache: fake.NewMockCacheInterface[*v1.ResourceQuota](c), + ResourceQuotaMock: fake.NewMockControllerInterface[*v1.ResourceQuota, *v1.ResourceQuotaList](c), SecretCache: fake.NewMockCacheInterface[*v1.Secret](c), - ServiceMock: fake.NewMockControllerInterface[*v1.Service, *v1.ServiceList](c), - ServiceCache: fake.NewMockCacheInterface[*v1.Service](c), - ServiceAccountMock: fake.NewMockControllerInterface[*v1.ServiceAccount, *v1.ServiceAccountList](c), + SecretMock: fake.NewMockControllerInterface[*v1.Secret, *v1.SecretList](c), ServiceAccountCache: fake.NewMockCacheInterface[*v1.ServiceAccount](c), + ServiceAccountMock: fake.NewMockControllerInterface[*v1.ServiceAccount, *v1.ServiceAccountList](c), + ServiceCache: fake.NewMockCacheInterface[*v1.Service](c), + ServiceMock: fake.NewMockControllerInterface[*v1.Service, *v1.ServiceList](c), } } @@ -128,6 +136,10 @@ func (m *V1Mock) Event() corev1.EventController { return m.EventMock } +func (m *V1Mock) LimitRange() corev1.LimitRangeController { + return m.LimitRangeMock +} + func (m *V1Mock) Namespace() corev1.NamespaceController { return m.NamespaceMock } @@ -148,6 +160,10 @@ func (m *V1Mock) Pod() corev1.PodController { return m.PodMock } +func (m *V1Mock) ResourceQuota() corev1.ResourceQuotaController { + return m.ResourceQuotaMock +} + func (m *V1Mock) Secret() corev1.SecretController { return m.SecretMock }