diff --git a/.github/workflows/pull-request.yaml b/.github/workflows/pull-request.yaml index 045231e..e6db17d 100644 --- a/.github/workflows/pull-request.yaml +++ b/.github/workflows/pull-request.yaml @@ -7,7 +7,7 @@ jobs: unit-test: strategy: matrix: - go-version: [1.22.x] + go-version: [1.24.x] platform: [ubuntu-latest] runs-on: ${{ matrix.platform }} steps: @@ -24,7 +24,7 @@ jobs: build-test: strategy: matrix: - go-version: [1.22.x] + go-version: [1.24.x] platform: [ubuntu-latest] arch: [386, amd64, arm, arm64] runs-on: ${{ matrix.platform }} diff --git a/.golangci.yml b/.golangci.yml index a5a3a79..a6eb95e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,18 +1,35 @@ +version: "2" linters: enable: - dupl - errname - ginkgolinter - goconst - - godox - gosec - nilerr - prealloc - reassign - tparallel - wrapcheck - -linters-settings: - wrapcheck: - ignorePackageGlobs: - - google.golang.org/grpc/status + settings: + wrapcheck: + ignore-package-globs: + - google.golang.org/grpc/status + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + paths: + - third_party$ + - builtin$ + - examples$ +formatters: + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/Dockerfile b/Dockerfile index aa78889..35c366f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.22-alpine AS builder +FROM golang:1.24-alpine AS builder RUN apk update && apk add --no-cache git ca-certificates && update-ca-certificates @@ -14,9 +14,9 @@ COPY pkg/ pkg/ ARG TAG ARG COMMIT_SHA ARG BUILD_DATE -RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -a -ldflags "-w -s -X github.com/scaleway/scaleway-csi/driver.driverVersion=${TAG} -X github.com/scaleway/scaleway-csi/driver.buildDate=${BUILD_DATE} -X github.com/scaleway/scaleway-csi/driver.gitCommit=${COMMIT_SHA} " -o scaleway-csi ./cmd/scaleway-csi +RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -a -ldflags "-w -s -X github.com/scaleway/scaleway-csi/pkg/driver.driverVersion=${TAG} -X github.com/scaleway/scaleway-csi/pkg/driver.buildDate=${BUILD_DATE} -X github.com/scaleway/scaleway-csi/pkg/driver.gitCommit=${COMMIT_SHA} " -o scaleway-csi ./cmd/scaleway-csi -FROM alpine:3.15 +FROM alpine:3.19 RUN apk update && apk add --no-cache e2fsprogs e2fsprogs-extra xfsprogs xfsprogs-extra cryptsetup ca-certificates blkid && update-ca-certificates WORKDIR / COPY --from=builder /go/src/github.com/scaleway/scaleway-csi/scaleway-csi . diff --git a/go.mod b/go.mod index 0df16f4..b83e889 100644 --- a/go.mod +++ b/go.mod @@ -1,40 +1,40 @@ module github.com/scaleway/scaleway-csi -go 1.22.2 +go 1.24.5 require ( - github.com/container-storage-interface/spec v1.9.0 + github.com/container-storage-interface/spec v1.11.0 github.com/golang/protobuf v1.5.4 github.com/google/uuid v1.6.0 - github.com/kubernetes-csi/csi-test/v5 v5.2.0 - github.com/onsi/ginkgo/v2 v2.17.1 - github.com/onsi/gomega v1.32.0 - github.com/pkg/sftp v1.13.6 - github.com/scaleway/scaleway-sdk-go v1.0.0-beta.26 - golang.org/x/crypto v0.22.0 - golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f - golang.org/x/sys v0.19.0 - google.golang.org/grpc v1.63.2 - google.golang.org/protobuf v1.33.0 - k8s.io/klog/v2 v2.120.1 - k8s.io/mount-utils v0.30.0 - k8s.io/utils v0.0.0-20240310230437-4693a0247e57 + github.com/kubernetes-csi/csi-test/v5 v5.3.1 + github.com/onsi/ginkgo/v2 v2.23.4 + github.com/onsi/gomega v1.37.0 + github.com/pkg/sftp v1.13.9 + github.com/scaleway/scaleway-sdk-go v1.0.0-beta.34.0.20250722094606-7aefa3e74bff + golang.org/x/crypto v0.40.0 + golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 + golang.org/x/sys v0.34.0 + google.golang.org/grpc v1.73.0 + google.golang.org/protobuf v1.36.6 + k8s.io/klog/v2 v2.130.1 + k8s.io/mount-utils v0.33.3 + k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 oya.to/namedlocker v1.0.0 ) require ( - github.com/go-logr/logr v1.4.1 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect - github.com/google/go-cmp v0.6.0 // indirect - github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + github.com/golang/mock v1.6.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/kr/fs v0.1.0 // indirect - github.com/kr/text v0.2.0 // indirect - github.com/moby/sys/mountinfo v0.6.2 // indirect - github.com/stretchr/testify v1.9.0 // indirect - golang.org/x/net v0.24.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.20.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect + github.com/moby/sys/mountinfo v0.7.2 // indirect + go.uber.org/automaxprocs v1.6.0 // indirect + golang.org/x/net v0.42.0 // indirect + golang.org/x/text v0.27.0 // indirect + golang.org/x/tools v0.35.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 5b3a920..e468cc8 100644 --- a/go.sum +++ b/go.sum @@ -1,105 +1,166 @@ -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/container-storage-interface/spec v1.9.0 h1:zKtX4STsq31Knz3gciCYCi1SXtO2HJDecIjDVboYavY= -github.com/container-storage-interface/spec v1.9.0/go.mod h1:ZfDu+3ZRyeVqxZM0Ds19MVLkN2d1XJ5MAfi1L3VjlT0= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/container-storage-interface/spec v1.11.0 h1:H/YKTOeUZwHtyPOr9raR+HgFmGluGCklulxDYxSdVNM= +github.com/container-storage-interface/spec v1.11.0/go.mod h1:DtUvaQszPml1YJfIK7c00mlv6/g4wNMLanLgiUbKFRI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kubernetes-csi/csi-test/v5 v5.2.0 h1:Z+sdARWC6VrONrxB24clCLCmnqCnZF7dzXtzx8eM35o= -github.com/kubernetes-csi/csi-test/v5 v5.2.0/go.mod h1:o/c5w+NU3RUNE+DbVRhEUTmkQVBGk+tFOB2yPXT8teo= -github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= -github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= -github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= -github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= -github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= -github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= -github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= -github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= +github.com/kubernetes-csi/csi-test/v5 v5.3.1 h1:Wiukp1In+kif+BFo6q2ExjgB+MbrAz4jZWzGfijypuY= +github.com/kubernetes-csi/csi-test/v5 v5.3.1/go.mod h1:7hA2cSYJ6T8CraEZPA6zqkLZwemjBD54XAnPsPC3VpA= +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/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus= +github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8= +github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y= +github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= +github.com/pkg/sftp v1.13.9 h1:4NGkvGudBL7GteO3m6qnaQ4pC0Kvf0onSVc9gR3EWBw= +github.com/pkg/sftp v1.13.9/go.mod h1:OBN7bVXdstkFFN/gdnHPUb5TE8eb8G1Rp9wCItqjkkA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.26 h1:F+GIVtGqCFxPxO46ujf8cEOP574MBoRm3gNbPXECbxs= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.26/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= +github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.34.0.20250722094606-7aefa3e74bff h1:e4mzYR5VY0PBIJiSzxUKas4mvRxpHcjPMuSnlIpTlh4= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.34.0.20250722094606-7aefa3e74bff/go.mod h1:fw6BmcfYRs2BEHYW0c3/rR0JgZHvdx6uMYqpeUJx3Bc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= +go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= +go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= +go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= +go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 h1:R9PFI6EUdfVKgwKjZef7QIwGcBKu86OEFpJ9nUEP2l4= +golang.org/x/exp v0.0.0-20250718183923-645b1fa84792/go.mod h1:A+z0yzpGtvnG90cToK5n2tu8UJVP2XUATh+r+sfOOOc= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg= +golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= +golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= -google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 h1:e0AIkUUhxyBKh6ssZNrAMeqhA7RKUj42346d1y02i2g= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= +google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -108,11 +169,11 @@ 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= -k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= -k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/mount-utils v0.30.0 h1:EceYTNYVabfpdtIAHC4KgMzoZkm1B8ovZ1J666mYZQI= -k8s.io/mount-utils v0.30.0/go.mod h1:9sCVmwGLcV1MPvbZ+rToMDnl1QcGozy+jBPd0MsQLIo= -k8s.io/utils v0.0.0-20240310230437-4693a0247e57 h1:gbqbevonBh57eILzModw6mrkbwM0gQBEuevE/AaBsHY= -k8s.io/utils v0.0.0-20240310230437-4693a0247e57/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/mount-utils v0.33.3 h1:Q1jsnqdS4LdtJSYSXgiQv/XNrRHQncLk3gMYjKNSZrE= +k8s.io/mount-utils v0.33.3/go.mod h1:1JR4rKymg8B8bCPo618hpSAdrpO6XLh0Acqok/xVwPE= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= oya.to/namedlocker v1.0.0 h1:+HKiEvhKSzBtboeqiT8vK10aVUTASnneKpw+j79FQwA= oya.to/namedlocker v1.0.0/go.mod h1:+eBYtjcKHBxsdm/HAofHTTnSq6H96THcxHYG1A6WKX0= diff --git a/pkg/driver/controller.go b/pkg/driver/controller.go index 068b78f..ddc5315 100644 --- a/pkg/driver/controller.go +++ b/pkg/driver/controller.go @@ -6,7 +6,7 @@ import ( "github.com/container-storage-interface/spec/lib/go/csi" "github.com/scaleway/scaleway-csi/pkg/scaleway" - block "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1" + block "github.com/scaleway/scaleway-sdk-go/api/block/v1" "github.com/scaleway/scaleway-sdk-go/scw" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -53,11 +53,10 @@ var ( } ) -// controllerService implements csi.ControllerServer. -var _ csi.ControllerServer = &controllerService{} - // controllerService implements csi.ControllerServer. type controllerService struct { + csi.UnimplementedControllerServer + scaleway scaleway.Interface config *DriverConfig // Volume locks ensures we don't run parallel operations on volumes (e.g. @@ -80,7 +79,7 @@ func newControllerService(config *DriverConfig) (*controllerService, error) { // CreateVolume creates a new volume with the given CreateVolumeRequest. // This function is idempotent func (d *controllerService) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) { - klog.V(4).Infof("CreateVolume: called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("CreateVolume: called with %s", stripSecretFromReq(req)) volumeName := req.GetName() if volumeName == "" { @@ -143,7 +142,7 @@ func (d *controllerService) CreateVolume(ctx context.Context, req *csi.CreateVol // DeleteVolume deprovisions a volume. // This operation MUST be idempotent. func (d *controllerService) DeleteVolume(ctx context.Context, req *csi.DeleteVolumeRequest) (*csi.DeleteVolumeResponse, error) { - klog.V(4).Infof("DeleteVolume called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("DeleteVolume called with %s", stripSecretFromReq(req)) volumeID, volumeZone, err := ExtractIDAndZone(req.GetVolumeId()) if err != nil { return nil, status.Errorf(codes.InvalidArgument, "invalid parameter volumeID: %s", err) @@ -167,7 +166,7 @@ func (d *controllerService) DeleteVolume(ctx context.Context, req *csi.DeleteVol // ControllerPublishVolume perform the work that is necessary for making the volume available on the given node. // This operation MUST be idempotent. func (d *controllerService) ControllerPublishVolume(ctx context.Context, req *csi.ControllerPublishVolumeRequest) (*csi.ControllerPublishVolumeResponse, error) { - klog.V(4).Infof("ControllerPublishVolume called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("ControllerPublishVolume called with %s", stripSecretFromReq(req)) volumeID, volumeZone, err := ExtractIDAndZone(req.GetVolumeId()) if err != nil { @@ -229,7 +228,7 @@ func (d *controllerService) ControllerPublishVolume(ctx context.Context, req *cs // ControllerUnpublishVolume is the reverse operation of ControllerPublishVolume // This operation MUST be idempotent. func (d *controllerService) ControllerUnpublishVolume(ctx context.Context, req *csi.ControllerUnpublishVolumeRequest) (*csi.ControllerUnpublishVolumeResponse, error) { - klog.V(4).Infof("ControllerUnpublishVolume called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("ControllerUnpublishVolume called with %s", stripSecretFromReq(req)) volumeID, volumeZone, err := ExtractIDAndZone(req.GetVolumeId()) if err != nil { @@ -280,7 +279,7 @@ func (d *controllerService) ControllerUnpublishVolume(ctx context.Context, req * // volume capabilities specified in the request are supported. // This operation MUST be idempotent. func (d *controllerService) ValidateVolumeCapabilities(ctx context.Context, req *csi.ValidateVolumeCapabilitiesRequest) (*csi.ValidateVolumeCapabilitiesResponse, error) { - klog.V(4).Infof("ValidateVolumeCapabilities called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("ValidateVolumeCapabilities called with %s", stripSecretFromReq(req)) volumeID, volumeZone, err := ExtractIDAndZone(req.GetVolumeId()) if err != nil { return nil, status.Errorf(codes.InvalidArgument, "invalid parameter volumeID: %s", err) @@ -303,14 +302,18 @@ func (d *controllerService) ValidateVolumeCapabilities(ctx context.Context, req // ListVolumes returns the list of the requested volumes func (d *controllerService) ListVolumes(ctx context.Context, req *csi.ListVolumesRequest) (*csi.ListVolumesResponse, error) { - klog.V(4).Infof("ListVolumes called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("ListVolumes called with %s", stripSecretFromReq(req)) start, err := parseStartingToken(req.GetStartingToken()) if err != nil { return nil, status.Errorf(codes.Aborted, "invalid startingToken: %s", err) } - volumes, next, err := d.scaleway.ListVolumes(ctx, start, uint32(req.GetMaxEntries())) + if req.MaxEntries < 0 { + return nil, status.Error(codes.InvalidArgument, "maxEntries must be a positive number") + } + + volumes, next, err := d.scaleway.ListVolumes(ctx, start, uint32(req.MaxEntries)) if err != nil { return nil, status.Errorf(codes.Internal, "failed to list volumes: %s", err) } @@ -331,15 +334,9 @@ func (d *controllerService) ListVolumes(ctx context.Context, req *csi.ListVolume }, nil } -// GetCapacity returns the capacity of the storage pool from which the controller provisions volumes. -func (d *controllerService) GetCapacity(ctx context.Context, req *csi.GetCapacityRequest) (*csi.GetCapacityResponse, error) { - klog.V(4).Infof("GetCapacity is not yet implemented") - return nil, status.Error(codes.Unimplemented, "GetCapacity is not yet implemented") -} - // ControllerGetCapabilities returns the supported capabilities of controller service provided by the Plugin. func (d *controllerService) ControllerGetCapabilities(ctx context.Context, req *csi.ControllerGetCapabilitiesRequest) (*csi.ControllerGetCapabilitiesResponse, error) { - klog.V(4).Infof("ControllerGetCapabilities called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("ControllerGetCapabilities called with %s", stripSecretFromReq(req)) capabilities := make([]*csi.ControllerServiceCapability, 0, len(controllerCapabilities)) for _, capability := range controllerCapabilities { @@ -357,7 +354,7 @@ func (d *controllerService) ControllerGetCapabilities(ctx context.Context, req * // CreateSnapshot creates a snapshot of the given volume func (d *controllerService) CreateSnapshot(ctx context.Context, req *csi.CreateSnapshotRequest) (*csi.CreateSnapshotResponse, error) { - klog.V(4).Infof("CreateSnapshot called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("CreateSnapshot called with %s", stripSecretFromReq(req)) sourceVolumeID, sourceVolumeZone, err := ExtractIDAndZone(req.GetSourceVolumeId()) if err != nil { return nil, status.Errorf(codes.InvalidArgument, "invalid parameter sourceVolumeID: %s", err) @@ -388,7 +385,7 @@ func (d *controllerService) CreateSnapshot(ctx context.Context, req *csi.CreateS // DeleteSnapshot deletes the given snapshot func (d *controllerService) DeleteSnapshot(ctx context.Context, req *csi.DeleteSnapshotRequest) (*csi.DeleteSnapshotResponse, error) { - klog.V(4).Infof("DeleteSnapshot called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("DeleteSnapshot called with %s", stripSecretFromReq(req)) snapshotID, snapshotZone, err := ExtractIDAndZone(req.GetSnapshotId()) if err != nil { return nil, status.Errorf(codes.InvalidArgument, "invalid parameter snapshotID: %s", err) @@ -412,13 +409,17 @@ func (d *controllerService) DeleteSnapshot(ctx context.Context, req *csi.DeleteS // they were created. ListSnapshots SHALL NOT list a snapshot that // is being created but has not been cut successfully yet. func (d *controllerService) ListSnapshots(ctx context.Context, req *csi.ListSnapshotsRequest) (*csi.ListSnapshotsResponse, error) { - klog.V(4).Infof("ListSnapshots called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("ListSnapshots called with %s", stripSecretFromReq(req)) start, err := parseStartingToken(req.GetStartingToken()) if err != nil { return nil, status.Errorf(codes.Aborted, "invalid startingToken: %s", err) } + if req.MaxEntries < 0 { + return nil, status.Error(codes.InvalidArgument, "maxEntries must be a positive number") + } + var snapshots []*block.Snapshot var next string @@ -446,7 +447,7 @@ func (d *controllerService) ListSnapshots(ctx context.Context, req *csi.ListSnap return nil, status.Errorf(codes.InvalidArgument, "invalid parameter sourceVolumeID: %s", err) } - s, n, err := d.scaleway.ListSnapshotsBySourceVolume(ctx, start, uint32(req.GetMaxEntries()), sourceVolumeID, sourceVolumeZone) + s, n, err := d.scaleway.ListSnapshotsBySourceVolume(ctx, start, uint32(req.MaxEntries), sourceVolumeID, sourceVolumeZone) if err != nil { return nil, status.Errorf(codeFromScalewayError(err), "failed to get snapshots for volume %q: %s", req.GetSourceVolumeId(), err) } @@ -454,7 +455,7 @@ func (d *controllerService) ListSnapshots(ctx context.Context, req *csi.ListSnap snapshots = append(snapshots, s...) next = n default: - s, n, err := d.scaleway.ListSnapshots(ctx, start, uint32(req.GetMaxEntries())) + s, n, err := d.scaleway.ListSnapshots(ctx, start, uint32(req.MaxEntries)) if err != nil { return nil, status.Errorf(codeFromScalewayError(err), "failed to list snapshots: %s", err) } @@ -478,7 +479,7 @@ func (d *controllerService) ListSnapshots(ctx context.Context, req *csi.ListSnap // ControllerExpandVolume expands the given volume func (d *controllerService) ControllerExpandVolume(ctx context.Context, req *csi.ControllerExpandVolumeRequest) (*csi.ControllerExpandVolumeResponse, error) { - klog.V(4).Infof("ControllerExpandVolume called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("ControllerExpandVolume called with %s", stripSecretFromReq(req)) volumeID, volumeZone, err := ExtractIDAndZone(req.GetVolumeId()) if err != nil { return nil, status.Errorf(codes.InvalidArgument, "invalid parameter volumeID: %s", err) @@ -509,9 +510,9 @@ func (d *controllerService) ControllerExpandVolume(ctx context.Context, req *csi return nil, status.Errorf(codes.OutOfRange, "capacityRange invalid: %s", err) } - if int64(volumeResp.Size) >= newSize { + if volumeSize := scwSizetoInt64(volumeResp.Size); volumeSize >= newSize { // Volume is already larger than or equal to the target capacity. - return &csi.ControllerExpandVolumeResponse{CapacityBytes: int64(volumeResp.Size), NodeExpansionRequired: nodeExpansionRequired}, nil + return &csi.ControllerExpandVolumeResponse{CapacityBytes: volumeSize, NodeExpansionRequired: nodeExpansionRequired}, nil } if err = d.scaleway.ResizeVolume(ctx, volumeID, volumeZone, newSize); err != nil { @@ -523,7 +524,7 @@ func (d *controllerService) ControllerExpandVolume(ctx context.Context, req *csi // ControllerGetVolume gets a specific volume. func (d *controllerService) ControllerGetVolume(ctx context.Context, req *csi.ControllerGetVolumeRequest) (*csi.ControllerGetVolumeResponse, error) { - klog.V(4).Infof("ControllerGetVolume called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("ControllerGetVolume called with %s", stripSecretFromReq(req)) volumeID, volumeZone, err := ExtractIDAndZone(req.GetVolumeId()) if err != nil { return nil, status.Errorf(codes.InvalidArgument, "invalid parameter volumeID: %s", err) diff --git a/pkg/driver/driver.go b/pkg/driver/driver.go index 221df38..a0cae1a 100644 --- a/pkg/driver/driver.go +++ b/pkg/driver/driver.go @@ -53,6 +53,8 @@ type DriverConfig struct { // Driver implements the interfaces csi.IdentityServer, csi.ControllerServer and csi.NodeServer. type Driver struct { + csi.UnimplementedIdentityServer + // controllerService implements the ControllerServer. *controllerService diff --git a/pkg/driver/helpers.go b/pkg/driver/helpers.go index bb42dce..1d00ade 100644 --- a/pkg/driver/helpers.go +++ b/pkg/driver/helpers.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io/fs" + "math" "os" "path/filepath" "reflect" @@ -13,7 +14,7 @@ import ( "github.com/container-storage-interface/spec/lib/go/csi" "github.com/scaleway/scaleway-csi/pkg/scaleway" - block "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1" + block "github.com/scaleway/scaleway-sdk-go/api/block/v1" "github.com/scaleway/scaleway-sdk-go/scw" "golang.org/x/exp/slices" "google.golang.org/grpc/codes" @@ -247,13 +248,23 @@ const secretsField = "Secrets" func stripSecretFromReq(req any) string { ret := "{" + // Try to dereference pointer if needed. reqValue := reflect.ValueOf(req) + if reqValue.Kind() == reflect.Pointer { + reqValue = reqValue.Elem() + } + reqType := reqValue.Type() if reqType.Kind() == reflect.Struct { for i := 0; i < reqValue.NumField(); i++ { field := reqType.Field(i) value := reqValue.Field(i) + // Skip non-exported fields. + if !field.IsExported() { + continue + } + valueToPrint := fmt.Sprintf("%+v", value.Interface()) if field.Name == secretsField && value.Kind() == reflect.Map { @@ -285,8 +296,13 @@ func (d *controllerService) getOrCreateVolume(ctx context.Context, name, snapsho zones = append(zones, scw.Zone("")) } + scwSize, err := scaleway.NewSize(size) + if err != nil { + return nil, fmt.Errorf("size is invalid: %w", err) + } + for _, zone := range zones { - volume, err := d.scaleway.GetVolumeByName(ctx, name, scw.Size(size), zone) + volume, err := d.scaleway.GetVolumeByName(ctx, name, scwSize, zone) if err != nil && !errors.Is(err, scaleway.ErrVolumeNotFound) { return nil, fmt.Errorf("failed to try to get existing volume %q: %w", name, err) } @@ -361,7 +377,7 @@ func parseCreateVolumeParams(params map[string]string) (*uint32, bool, error) { encrypted = encryptedValue case volumeIOPSKey: - iops, err := strconv.Atoi(value) + iops, err := strconv.ParseUint(value, 10, 0) if err != nil { return nil, false, fmt.Errorf("invalid value (%s) for parameter %s: %s", value, key, err) } @@ -398,7 +414,7 @@ func csiVolume(volume *block.Volume) *csi.Volume { return &csi.Volume{ VolumeId: expandZonalID(volume.ID, volume.Zone), - CapacityBytes: int64(volume.Size), + CapacityBytes: scwSizetoInt64(volume.Size), AccessibleTopology: []*csi.Topology{ { Segments: map[string]string{ZoneTopologyKey: volume.Zone.String()}, @@ -427,7 +443,7 @@ func publishedNodeIDs(volume *block.Volume) []string { // csiSnapshot returns a CSI Snapshot from a Snapshot. func csiSnapshot(snapshot *block.Snapshot) *csi.Snapshot { snap := &csi.Snapshot{ - SizeBytes: int64(snapshot.Size), + SizeBytes: scwSizetoInt64(snapshot.Size), SnapshotId: expandZonalID(snapshot.ID, snapshot.Zone), ReadyToUse: snapshot.Status == block.SnapshotStatusAvailable, } @@ -449,15 +465,11 @@ func parseStartingToken(token string) (uint32, error) { return 0, nil } - start, err := strconv.Atoi(token) + start, err := strconv.ParseUint(token, 10, 0) if err != nil { return 0, fmt.Errorf("failed to parse token into a number: %w", err) } - if start < 0 { - return 0, nil - } - return uint32(start), nil } @@ -492,3 +504,19 @@ func codeFromScalewayError(err error) codes.Code { return codes.Internal } } + +// scwSizetoInt64 converts an scw.Size to int64. It panics if the size exceeds math.MaxInt64. +func scwSizetoInt64(s scw.Size) int64 { + return uint64ToInt64(uint64(s)) +} + +// uint64ToInt64 converts an uint64 value to an int64 value. It panics if the value +// exceeds math.MaxInt64. +func uint64ToInt64(v uint64) int64 { + // This should never happen in practice. + if v > math.MaxInt64 { + panic("value exceeds max int64") + } + + return int64(v) +} diff --git a/pkg/driver/helpers_test.go b/pkg/driver/helpers_test.go index e03ab21..a270871 100644 --- a/pkg/driver/helpers_test.go +++ b/pkg/driver/helpers_test.go @@ -7,7 +7,7 @@ import ( "github.com/container-storage-interface/spec/lib/go/csi" "github.com/scaleway/scaleway-csi/pkg/scaleway" - block "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1" + block "github.com/scaleway/scaleway-sdk-go/api/block/v1" "github.com/scaleway/scaleway-sdk-go/scw" ) @@ -1090,8 +1090,7 @@ func Test_parseStartingToken(t *testing.T) { args: args{ token: "-2", }, - want: 0, - wantErr: false, + wantErr: true, }, { name: "123", @@ -1175,3 +1174,33 @@ func Test_publishedNodeIDs(t *testing.T) { }) } } + +func Test_stripSecretFromReq(t *testing.T) { + type args struct { + req any + } + tests := []struct { + name string + args args + want string + }{ + { + name: "test", + args: args{ + req: &csi.CreateVolumeRequest{ + Name: "test", + Secrets: map[string]string{"test": "secret"}, + Parameters: map[string]string{"iops": "15000"}, + }, + }, + want: "{Name:test CapacityRange: VolumeCapabilities:[] Parameters:map[iops:15000] Secrets:[test:] VolumeContentSource: AccessibilityRequirements: MutableParameters:map[]}", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := stripSecretFromReq(tt.args.req); got != tt.want { + t.Errorf("stripSecretFromReq() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/driver/node.go b/pkg/driver/node.go index 389b0de..3256065 100644 --- a/pkg/driver/node.go +++ b/pkg/driver/node.go @@ -20,10 +20,9 @@ import ( // name of the secret for the encryption passphrase. const encryptionPassphraseKey = "encryptionPassphrase" -// nodeService implements csi.NodeServer. -var _ csi.NodeServer = &nodeService{} - type nodeService struct { + csi.UnimplementedNodeServer + diskUtils DiskUtils nodeID string @@ -57,7 +56,7 @@ func newNodeService() (*nodeService, error) { // for the first time or for the first time since a NodeUnstageVolume call // for the specified volume was called and returned success on that node. func (d *nodeService) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRequest) (*csi.NodeStageVolumeResponse, error) { - klog.V(4).Infof("NodeStageVolume called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("NodeStageVolume called with %s", stripSecretFromReq(req)) // check arguments volumeID, _, err := ExtractIDAndZone(req.GetVolumeId()) @@ -169,7 +168,7 @@ func (d *nodeService) NodeStageVolume(ctx context.Context, req *csi.NodeStageVol // NodeUnstageVolume is a reverse operation of NodeStageVolume. // It must undo the work by the corresponding NodeStageVolume. func (d *nodeService) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstageVolumeRequest) (*csi.NodeUnstageVolumeResponse, error) { - klog.V(4).Infof("NodeUnstageVolume called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("NodeUnstageVolume called with %s", stripSecretFromReq(req)) // check arguments volumeID, _, err := ExtractIDAndZone(req.GetVolumeId()) @@ -213,7 +212,7 @@ func (d *nodeService) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag // on a node. The Plugin SHALL assume that this RPC will be executed // on the node where the volume will be used. func (d *nodeService) NodePublishVolume(ctx context.Context, req *csi.NodePublishVolumeRequest) (*csi.NodePublishVolumeResponse, error) { - klog.V(4).Infof("NodePublishVolume called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("NodePublishVolume called with %s", stripSecretFromReq(req)) // check arguments volumeID, _, err := ExtractIDAndZone(req.GetVolumeId()) @@ -313,7 +312,7 @@ func (d *nodeService) NodePublishVolume(ctx context.Context, req *csi.NodePublis // NodeUnpublishVolume is a reverse operation of NodePublishVolume. // This RPC MUST undo the work by the corresponding NodePublishVolume. func (d *nodeService) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpublishVolumeRequest) (*csi.NodeUnpublishVolumeResponse, error) { - klog.V(4).Infof("NodeUnpublishVolume called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("NodeUnpublishVolume called with %s", stripSecretFromReq(req)) targetPath := req.GetTargetPath() if targetPath == "" { @@ -329,7 +328,7 @@ func (d *nodeService) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpu // NodeGetVolumeStats returns the volume capacity statistics available for the volume func (d *nodeService) NodeGetVolumeStats(ctx context.Context, req *csi.NodeGetVolumeStatsRequest) (*csi.NodeGetVolumeStatsResponse, error) { - klog.V(4).Infof("NodeGetVolumeStats called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("NodeGetVolumeStats called with %s", stripSecretFromReq(req)) volumeID, _, err := ExtractIDAndZone(req.GetVolumeId()) if err != nil { @@ -362,26 +361,26 @@ func (d *nodeService) NodeGetVolumeStats(ctx context.Context, req *csi.NodeGetVo return nil, status.Errorf(codes.Internal, "error doing stat on %s: %s", volumePath, err.Error()) } - totalBytes := fs.Blocks * uint64(fs.Bsize) - availableBytes := fs.Bfree * uint64(fs.Bsize) + totalBytes := uint64ToInt64(fs.Blocks) * int64(fs.Bsize) + availableBytes := uint64ToInt64(fs.Bfree) * int64(fs.Bsize) usedBytes := totalBytes - availableBytes - totalInodes := fs.Files - freeInodes := fs.Ffree + totalInodes := uint64ToInt64(fs.Files) + freeInodes := uint64ToInt64(fs.Ffree) usedInodes := totalInodes - freeInodes diskUsage := &csi.VolumeUsage{ Unit: csi.VolumeUsage_BYTES, - Total: int64(totalBytes), - Available: int64(availableBytes), - Used: int64(usedBytes), + Total: totalBytes, + Available: availableBytes, + Used: usedBytes, } inodesUsage := &csi.VolumeUsage{ Unit: csi.VolumeUsage_INODES, - Total: int64(totalInodes), - Available: int64(freeInodes), - Used: int64(usedInodes), + Total: totalInodes, + Available: freeInodes, + Used: usedInodes, } return &csi.NodeGetVolumeStatsResponse{ @@ -443,7 +442,7 @@ func (d *nodeService) NodeGetInfo(ctx context.Context, req *csi.NodeGetInfoReque // NodeExpandVolume expands the given volume func (d *nodeService) NodeExpandVolume(ctx context.Context, req *csi.NodeExpandVolumeRequest) (*csi.NodeExpandVolumeResponse, error) { - klog.V(4).Infof("NodeExpandVolume called with %s", stripSecretFromReq(*req)) + klog.V(4).Infof("NodeExpandVolume called with %s", stripSecretFromReq(req)) volumeID, _, err := ExtractIDAndZone(req.GetVolumeId()) if err != nil { diff --git a/pkg/scaleway/block.go b/pkg/scaleway/block.go index b38a22a..0a7e2ea 100644 --- a/pkg/scaleway/block.go +++ b/pkg/scaleway/block.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - block "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1" + block "github.com/scaleway/scaleway-sdk-go/api/block/v1" "github.com/scaleway/scaleway-sdk-go/scw" ) @@ -199,10 +199,15 @@ func (s *Scaleway) ResizeVolume(ctx context.Context, volumeID string, zone scw.Z return &scw.ResourceNotFoundError{Resource: snapshotResource, ResourceID: volumeID} } + scwSize, err := NewSize(size) + if err != nil { + return err + } + if _, err := s.block.UpdateVolume(&block.UpdateVolumeRequest{ VolumeID: volumeID, Zone: zone, - Size: scw.SizePtr(scw.Size(size)), + Size: scw.SizePtr(scwSize), }, scw.WithContext(ctx)); err != nil { return fmt.Errorf("failed to update volume with new size: %w", err) } @@ -232,6 +237,11 @@ func (s *Scaleway) CreateVolume(ctx context.Context, name, snapshotID string, si Zone: zone, } + scwSize, err := NewSize(size) + if err != nil { + return nil, err + } + if snapshotID != "" { if !isValidUUID(snapshotID) { return nil, &scw.ResourceNotFoundError{Resource: snapshotResource, ResourceID: snapshotID} @@ -239,11 +249,11 @@ func (s *Scaleway) CreateVolume(ctx context.Context, name, snapshotID string, si req.FromSnapshot = &block.CreateVolumeRequestFromSnapshot{ SnapshotID: snapshotID, - Size: scw.SizePtr(scw.Size(size)), + Size: scw.SizePtr(scwSize), } } else { req.FromEmpty = &block.CreateVolumeRequestFromEmpty{ - Size: scw.Size(size), + Size: scwSize, } } diff --git a/pkg/scaleway/fake.go b/pkg/scaleway/fake.go index 4a952b6..9a88cec 100644 --- a/pkg/scaleway/fake.go +++ b/pkg/scaleway/fake.go @@ -10,7 +10,7 @@ import ( "time" "github.com/google/uuid" - block "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1" + block "github.com/scaleway/scaleway-sdk-go/api/block/v1" "github.com/scaleway/scaleway-sdk-go/api/instance/v1" "github.com/scaleway/scaleway-sdk-go/scw" "golang.org/x/exp/maps" @@ -164,6 +164,11 @@ func (f *Fake) CreateVolume(ctx context.Context, name string, snapshotID string, zone = f.defaultZone } + scwSize, err := NewSize(size) + if err != nil { + return nil, err + } + volume := &block.Volume{ ID: uuid.NewString(), Name: name, @@ -190,7 +195,7 @@ func (f *Fake) CreateVolume(ctx context.Context, name string, snapshotID string, volume.ParentSnapshotID = scw.StringPtr(snapshotID) volume.Size = s.Size } else { - volume.Size = scw.Size(size) + volume.Size = scwSize } f.volumes[volume.ID] = volume @@ -387,12 +392,17 @@ func (f *Fake) ResizeVolume(ctx context.Context, volumeID string, zone scw.Zone, zone = f.defaultZone } + scwSize, err := NewSize(size) + if err != nil { + return err + } + if s, ok := f.volumes[volumeID]; ok && s.Zone == zone { - if size < int64(f.volumes[volumeID].Size) { + if scwSize < f.volumes[volumeID].Size { return errors.New("new volume size is less than current volume size") } - f.volumes[volumeID].Size = scw.Size(size) + f.volumes[volumeID].Size = scwSize return nil } diff --git a/pkg/scaleway/helpers.go b/pkg/scaleway/helpers.go index 274550f..7f33d83 100644 --- a/pkg/scaleway/helpers.go +++ b/pkg/scaleway/helpers.go @@ -1,6 +1,7 @@ package scaleway import ( + "errors" "fmt" "math" "strconv" @@ -15,21 +16,21 @@ const maxPageSize = 50 // paginatedList allows to list resources with a start and max pagination options. func paginatedList[T any](query func(page int32, pageSize uint32) ([]T, error), start, max uint32) (elements []T, next string, err error) { // Reduce page size if needed. - listPageSize := maxPageSize - if int(max) < listPageSize && max != 0 { - listPageSize = int(max) + listPageSize := uint32(maxPageSize) + if max < listPageSize && max != 0 { + listPageSize = max } var ( // first page to query (must start at 1). page = int32(math.Floor(float64(start)/float64(listPageSize))) + 1 // first element index. - first = int(start % uint32(listPageSize)) + first = int(start % listPageSize) ) for { var resp []T - resp, err = query(page, uint32(listPageSize)) + resp, err = query(page, listPageSize) if err != nil { return nil, "", err } @@ -47,7 +48,7 @@ func paginatedList[T any](query func(page int32, pageSize uint32) ([]T, error), // reached max elements. if len(elements) >= int(max) { - if respCount == listPageSize { + if respCount == int(listPageSize) { next = strconv.Itoa(int(start + max)) } @@ -56,7 +57,7 @@ func paginatedList[T any](query func(page int32, pageSize uint32) ([]T, error), } // less results than page size. - if respCount != listPageSize { + if respCount != int(listPageSize) { return } @@ -100,3 +101,11 @@ func isValidUUID(u string) bool { _, err := uuid.Parse(u) return err == nil } + +// NewSize creates a new scw.Size from an int64 value. +func NewSize(size int64) (scw.Size, error) { + if size < 0 { + return 0, errors.New("size cannot be a negative number") + } + return scw.Size(size), nil +} diff --git a/pkg/scaleway/instance.go b/pkg/scaleway/instance.go index bc60b5f..d91f87a 100644 --- a/pkg/scaleway/instance.go +++ b/pkg/scaleway/instance.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - block "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1" + block "github.com/scaleway/scaleway-sdk-go/api/block/v1" "github.com/scaleway/scaleway-sdk-go/api/instance/v1" "github.com/scaleway/scaleway-sdk-go/scw" ) diff --git a/pkg/scaleway/interface.go b/pkg/scaleway/interface.go index f3975a7..428d7c2 100644 --- a/pkg/scaleway/interface.go +++ b/pkg/scaleway/interface.go @@ -3,7 +3,7 @@ package scaleway import ( "context" - block "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1" + block "github.com/scaleway/scaleway-sdk-go/api/block/v1" "github.com/scaleway/scaleway-sdk-go/api/instance/v1" "github.com/scaleway/scaleway-sdk-go/scw" ) diff --git a/pkg/scaleway/scaleway.go b/pkg/scaleway/scaleway.go index ad14a0e..8d882d2 100644 --- a/pkg/scaleway/scaleway.go +++ b/pkg/scaleway/scaleway.go @@ -3,7 +3,7 @@ package scaleway import ( "fmt" - block "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1" + block "github.com/scaleway/scaleway-sdk-go/api/block/v1" "github.com/scaleway/scaleway-sdk-go/api/instance/v1" "github.com/scaleway/scaleway-sdk-go/scw" ) diff --git a/test/sanity/sanity_suite_test.go b/test/sanity/sanity_suite_test.go index 0b181ff..6ba16b7 100644 --- a/test/sanity/sanity_suite_test.go +++ b/test/sanity/sanity_suite_test.go @@ -12,6 +12,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/scaleway/scaleway-sdk-go/api/block/v1" "github.com/scaleway/scaleway-sdk-go/api/instance/v1" "github.com/scaleway/scaleway-sdk-go/api/marketplace/v2" "github.com/scaleway/scaleway-sdk-go/scw" @@ -31,6 +32,7 @@ var ( sshSigner ssh.Signer instanceAPI *instance.API + blockAPI *block.API marketplaceAPI *marketplace.API ) @@ -54,6 +56,7 @@ var _ = BeforeSuite(func() { // Create APIs. instanceAPI = instance.NewAPI(scwClient) + blockAPI = block.NewAPI(scwClient) marketplaceAPI = marketplace.NewAPI(scwClient) }) diff --git a/test/sanity/sanity_test.go b/test/sanity/sanity_test.go index f7ad007..b12dff8 100644 --- a/test/sanity/sanity_test.go +++ b/test/sanity/sanity_test.go @@ -13,10 +13,12 @@ import ( "os/exec" "path/filepath" "strings" + "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/pkg/sftp" + "github.com/scaleway/scaleway-sdk-go/api/block/v1" "github.com/scaleway/scaleway-sdk-go/api/instance/v1" "github.com/scaleway/scaleway-sdk-go/api/marketplace/v2" "github.com/scaleway/scaleway-sdk-go/scw" @@ -42,7 +44,7 @@ var _ = Describe("Sanity", func() { server, err := instanceAPI.CreateServer(&instance.CreateServerRequest{ Name: "csi-sanity", DynamicIPRequired: scw.BoolPtr(true), - Image: image.ID, + Image: &image.ID, CommercialType: instanceCommercialType, RoutedIPEnabled: scw.BoolPtr(true), Tags: []string{"AUTHORIZED_KEY=" + strings.ReplaceAll(sshPublicKey, " ", "_")}, @@ -52,9 +54,57 @@ var _ = Describe("Sanity", func() { DeferCleanup(func(ctx SpecContext) { _, err = instanceAPI.ServerAction(&instance.ServerActionRequest{ ServerID: server.Server.ID, - Action: instance.ServerActionTerminate, + Action: instance.ServerActionPoweroff, }, scw.WithContext(ctx)) Expect(err).NotTo(HaveOccurred()) + + _, err = instanceAPI.WaitForServer(&instance.WaitForServerRequest{ + ServerID: server.Server.ID, + Zone: server.Server.Zone, + }, scw.WithContext(ctx)) + Expect(err).ToNot(HaveOccurred()) + + // On success, we expect the server to only have one volume attached (the boot volume). + if !CurrentSpecReport().Failed() { + Expect(server.Server.Volumes).To(HaveLen(1)) + } + + for _, volume := range server.Server.Volumes { + Expect(volume.VolumeType).To(Equal(instance.VolumeServerVolumeTypeSbsVolume)) + + _, err := instanceAPI.DetachServerVolume(&instance.DetachServerVolumeRequest{ + Zone: server.Server.Zone, + ServerID: server.Server.ID, + VolumeID: volume.ID, + }, scw.WithContext(ctx)) + Expect(err).ToNot(HaveOccurred()) + + Eventually(func() error { + volume, err := blockAPI.GetVolume(&block.GetVolumeRequest{ + Zone: server.Server.Zone, + VolumeID: volume.ID, + }, scw.WithContext(ctx)) + if err != nil { + return fmt.Errorf("failed to get volume: %w", err) + } + + if volume.Status != block.VolumeStatusAvailable { + return fmt.Errorf("volume is not available: %s", volume.Status) + } + + return nil + }).WithContext(ctx).WithTimeout(time.Minute).ProbeEvery(time.Second).Should(Succeed()) + + Expect(blockAPI.DeleteVolume(&block.DeleteVolumeRequest{ + Zone: server.Server.Zone, + VolumeID: volume.ID, + }, scw.WithContext(ctx))).To(Succeed()) + } + + Expect(instanceAPI.DeleteServer(&instance.DeleteServerRequest{ + Zone: server.Server.Zone, + ServerID: server.Server.ID, + }, scw.WithContext(ctx))).To(Succeed()) }) // Poweron server and wait for it to start. @@ -70,11 +120,11 @@ var _ = Describe("Sanity", func() { // Make sure instance is running and has an IP. Expect(server.Server.State).To(Equal(instance.ServerStateRunning)) - Expect(server.Server.PublicIP).ToNot(BeNil()) + Expect(server.Server.PublicIPs).ToNot(BeEmpty()) By("Connecting to the instance") client := &sshClient{ - Address: server.Server.PublicIP.Address.String(), + Address: server.Server.PublicIPs[0].Address.String(), Signer: sshSigner, } Eventually(client.Open).WithContext(ctx).Should(Succeed()) @@ -130,7 +180,12 @@ var _ = Describe("Sanity", func() { Expect(err).NotTo(HaveOccurred()) By("Running csi-sanity on instance") - sanityResult, err := client.RunCmd(ctx, fmt.Sprintf("%s --csi.endpoint=unix:/tmp/csi.sock --ginkgo.no-color", remoteSanityPath), nil) + sanityResult, err := client.RunCmd(ctx, fmt.Sprintf( + "%s --csi.endpoint=unix:/tmp/csi.sock --ginkgo.no-color "+ + // Max name in test exceeds Scaleway Block Storage API max name length of 100 chars on volumes and snapshots. + // https://github.com/kubernetes-csi/csi-test/blob/35eb219ce5e9f6476ae4a451b6760597a9547563/pkg/sanity/controller.go#L42 + `--ginkgo.skip="maximum-length name"`, + remoteSanityPath), nil) Expect(err).NotTo(HaveOccurred()) By("Waiting for results") @@ -210,12 +265,13 @@ func (s *sshClient) RunCmd(ctx context.Context, cmd string, env map[string]strin result := make(chan sshResult) resultInternal := make(chan sshResult, 1) - var b bytes.Buffer - session.Stdout = &b - session.Stderr = &b + var stdout bytes.Buffer + var stderr bytes.Buffer + session.Stdout = &stdout + session.Stderr = &stderr go func() { err := session.Run(fmt.Sprintf("%s %s", envString.String(), cmd)) - resultInternal <- sshResult{Err: err, Output: b.String()} + resultInternal <- sshResult{Err: err, Output: fmt.Sprintf("Stdout: %s\nStderr: %s", stdout.String(), stderr.String())} close(resultInternal) }()