diff options
| author | Aaron Madsen <amadsen@codifiant.com> | 2025-01-31 18:15:54 -0700 |
|---|---|---|
| committer | Chris Lu <chrislusf@users.noreply.github.com> | 2025-05-04 05:23:16 -0700 |
| commit | d22a187d747f443c6671d8f9ab076c4985dd82a2 (patch) | |
| tree | 0a3427918b973150da80b6da1884dd573bca7f29 | |
| parent | d83de3149ad80ccfe70376b949baa00541bb9838 (diff) | |
| download | seaweedfs-csi-driver-d22a187d747f443c6671d8f9ab076c4985dd82a2.tar.xz seaweedfs-csi-driver-d22a187d747f443c6671d8f9ab076c4985dd82a2.zip | |
Make sure the volume ID is a valid bucket name
| -rw-r--r-- | cmd/seaweedfs-csi-driver/Dockerfile.dev | 6 | ||||
| -rw-r--r-- | deploy/nomad/example-seaweedfs-volume.hcl | 6 | ||||
| -rw-r--r-- | pkg/driver/controllerserver.go | 35 |
3 files changed, 41 insertions, 6 deletions
diff --git a/cmd/seaweedfs-csi-driver/Dockerfile.dev b/cmd/seaweedfs-csi-driver/Dockerfile.dev index 6daecb1..8e758a6 100644 --- a/cmd/seaweedfs-csi-driver/Dockerfile.dev +++ b/cmd/seaweedfs-csi-driver/Dockerfile.dev @@ -6,11 +6,15 @@ RUN mkdir -p /go/src/github.com/seaweedfs/ RUN git clone https://github.com/seaweedfs/seaweedfs /go/src/github.com/seaweedfs/seaweedfs RUN cd /go/src/github.com/seaweedfs/seaweedfs/weed && go install +WORKDIR /go/src/github.com/seaweedfs/seaweedfs-csi-driver +COPY . . +RUN cd /go/src/github.com/seaweedfs/seaweedfs-csi-driver && go build -ldflags="-s -w" -o /seaweedfs-csi-driver ./cmd/seaweedfs-csi-driver/main.go + FROM alpine AS final RUN apk add fuse LABEL author="Chris Lu" COPY --from=builder /go/bin/weed /usr/bin/ -COPY ./_output/seaweedfs-csi-driver /seaweedfs-csi-driver +COPY --from=builder /seaweedfs-csi-driver / RUN chmod +x /seaweedfs-csi-driver ENTRYPOINT ["/seaweedfs-csi-driver"] diff --git a/deploy/nomad/example-seaweedfs-volume.hcl b/deploy/nomad/example-seaweedfs-volume.hcl index 3a5fb66..145dd8b 100644 --- a/deploy/nomad/example-seaweedfs-volume.hcl +++ b/deploy/nomad/example-seaweedfs-volume.hcl @@ -1,4 +1,10 @@ +# id - Nomad internal ID. It is not sent to the CSI plugin but is used by Nomad for `per_alloc` +# volume configurations, etc. id = "example-seaweedfs-volume" +# name - the name sent to the CSI plugin as an idempotency key and suggested volume ID. The CSI +# spec requires the calling Container Orchestrator to respect the actual volumeId returned by the +# CSI plugin. Nomad does this, storing it as the volume's ExternalID and using it in subsequent +# calls to the controller and node. name = "example-seaweedfs-volume" type = "csi" plugin_id = "seaweedfs" diff --git a/pkg/driver/controllerserver.go b/pkg/driver/controllerserver.go index 1bd2169..03d5920 100644 --- a/pkg/driver/controllerserver.go +++ b/pkg/driver/controllerserver.go @@ -6,15 +6,19 @@ import ( "encoding/hex" "fmt" "io" + "regexp" "strings" "github.com/container-storage-interface/spec/lib/go/csi" "github.com/seaweedfs/seaweedfs/weed/glog" "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb" + "github.com/seaweedfs/seaweedfs/weed/s3api/s3bucket" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) +var unsafeVolumeIdChars = regexp.MustCompile(`[^-.a-zA-Z0-9]`) + type ControllerServer struct { csi.UnimplementedControllerServer @@ -26,17 +30,18 @@ var _ = csi.ControllerServer(&ControllerServer{}) func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) { glog.Infof("create volume req: %v", req.GetName()) - volumeId := sanitizeVolumeId(req.GetName()) + // Check arguments + suggestedVolumeId := req.GetName() + if suggestedVolumeId == "" { + return nil, status.Error(codes.InvalidArgument, "Name missing in request") + } + volumeId := sanitizeVolumeId(suggestedVolumeId) if err := cs.Driver.ValidateControllerServiceRequest(csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME); err != nil { glog.V(3).Infof("invalid create volume req: %v", req) return nil, err } - // Check arguments - if volumeId == "" { - return nil, status.Error(codes.InvalidArgument, "Name missing in request") - } if req.GetVolumeCapabilities() == nil { return nil, status.Error(codes.InvalidArgument, "Volume Capabilities missing in request") } @@ -189,11 +194,31 @@ func (cs *ControllerServer) ControllerExpandVolume(ctx context.Context, req *csi func sanitizeVolumeId(volumeId string) string { volumeId = strings.ToLower(volumeId) + // NOTE: leave original length-only logic to ensure backward compatibility with volumes + // that happened to work because their suggested volumeId was too long if len(volumeId) > 63 { h := sha1.New() io.WriteString(h, volumeId) volumeId = hex.EncodeToString(h.Sum(nil)) } + + // check for a valid s3 bucket name according to the rules the filer uses + if s3bucket.VerifyS3BucketName(volumeId) != nil { + // The suggested volumeId can't be used directly. Use it to generate a new one + // that is compatible with our filer's name restrictions. + // generate a 40 hexidecimal character SHA1 hash to avoid name collisions + h := sha1.New() + io.WriteString(h, volumeId) + // hexidecimal encoding of sha1 is 40 characters long + hexhash := hex.EncodeToString(h.Sum(nil)) + sanitized := unsafeVolumeIdChars.ReplaceAllString(volumeId, "-") + // 21 here is 62 - 40 characters for the hash - 1 more for the "-" we use join + // the sanitized ID to the hash + if len(sanitized) > 21 { + sanitized = sanitized[0:21] + } + volumeId = fmt.Sprintf("%s.%s", sanitized, hexhash) + } return volumeId } |
