From 29030ae465a0c2b5c8c2c8181a5f50b7425edcf8 Mon Sep 17 00:00:00 2001 From: Timo Reimann Date: Tue, 30 Jul 2024 21:55:20 +0200 Subject: [PATCH 1/2] Make volumes-per-node limit configurable This is to support a future DO block storage volume limit increase. Adjusting the limit in the driver is to allow the Kubernetes scheduler to work correctly mostly. Specifically, it won't have an influence on what the DO storage backend permits. The two need to be synchronized. --- cmd/do-csi-plugin/main.go | 2 ++ driver/driver.go | 11 ++++++++--- driver/driver_test.go | 2 +- driver/node.go | 5 +---- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/cmd/do-csi-plugin/main.go b/cmd/do-csi-plugin/main.go index d93be9ae..ae973873 100644 --- a/cmd/do-csi-plugin/main.go +++ b/cmd/do-csi-plugin/main.go @@ -40,6 +40,7 @@ func main() { defaultVolumesPageSize = flag.Uint("default-volumes-page-size", 0, "The default page size used when paging through volumes results (default: do not specify and let the DO API choose)") doAPIRateLimitQPS = flag.Float64("do-api-rate-limit", 0, "Impose QPS rate limit on DigitalOcean API usage (default: do not rate limit)") validateAttachment = flag.Bool("validate-attachment", false, "Validate if the attachment has fully completed before formatting/mounting the device") + volumeLimit = flag.Uint("volume-limit", 7, "Volumes per node limit to report; needs to match limit imposed by DO storage backend (honored by Node service only)") version = flag.Bool("version", false, "Print the version and exit.") ) flag.Parse() @@ -64,6 +65,7 @@ func main() { DefaultVolumesPageSize: *defaultVolumesPageSize, DOAPIRateLimitQPS: *doAPIRateLimitQPS, ValidateAttachment: *validateAttachment, + VolumeLimit: *volumeLimit, }) if err != nil { log.Fatalln(err) diff --git a/driver/driver.go b/driver/driver.go index 709cad90..5bc1b342 100644 --- a/driver/driver.go +++ b/driver/driver.go @@ -42,6 +42,8 @@ const ( // DefaultDriverName defines the name that is used in Kubernetes and the CSI // system for the canonical, official name of this plugin DefaultDriverName = "dobs.csi.digitalocean.com" + + defaultMaxVolumesPerNode = 7 ) var ( @@ -86,8 +88,9 @@ type Driver struct { // ready defines whether the driver is ready to function. This value will // be used by the `Identity` service via the `Probe()` method. - readyMu sync.Mutex // protects ready - ready bool + readyMu sync.Mutex // protects ready + ready bool + volumeLimit uint } // NewDriverParams defines the parameters that can be passed to NewDriver. @@ -102,6 +105,7 @@ type NewDriverParams struct { DefaultVolumesPageSize uint DOAPIRateLimitQPS float64 ValidateAttachment bool + VolumeLimit uint } // NewDriver returns a CSI plugin that contains the necessary gRPC @@ -167,6 +171,7 @@ func NewDriver(p NewDriverParams) (*Driver, error) { endpoint: p.Endpoint, debugAddr: p.DebugAddr, defaultVolumesPageSize: p.DefaultVolumesPageSize, + volumeLimit: p.VolumeLimit, hostID: func() string { return hostID }, region: region, @@ -236,7 +241,7 @@ func (d *Driver) Run(ctx context.Context) error { d.log.WithFields(logrus.Fields{ "limit": details.limit, "num_volumes": details.numVolumes, - }).Warn("CSI plugin will not function correctly, please resolve volume limit") + }).Warn("CSI plugin may not function correctly, please resolve volume limit") } if d.debugAddr != "" { diff --git a/driver/driver_test.go b/driver/driver_test.go index a7666eac..06b791e9 100644 --- a/driver/driver_test.go +++ b/driver/driver_test.go @@ -311,7 +311,7 @@ func (f *fakeStorageActionsDriver) Attach(ctx context.Context, volumeID string, return nil, resp, errors.New("droplet was not found") } - if len(droplet.VolumeIDs) >= maxVolumesPerNode { + if len(droplet.VolumeIDs) >= defaultMaxVolumesPerNode { resp.Response = &http.Response{ StatusCode: http.StatusUnprocessableEntity, } diff --git a/driver/node.go b/driver/node.go index 6e03a744..872a64cc 100644 --- a/driver/node.go +++ b/driver/node.go @@ -45,9 +45,6 @@ const ( diskIDPath = "/dev/disk/by-id" diskDOPrefix = "scsi-0DO_Volume_" - // See: https://www.digitalocean.com/docs/volumes/overview/#limits - maxVolumesPerNode = 7 - volumeModeBlock = "block" volumeModeFilesystem = "filesystem" ) @@ -343,7 +340,7 @@ func (d *Driver) NodeGetInfo(ctx context.Context, req *csi.NodeGetInfoRequest) ( d.log.WithField("method", "node_get_info").Info("node get info called") return &csi.NodeGetInfoResponse{ NodeId: d.hostID(), - MaxVolumesPerNode: maxVolumesPerNode, + MaxVolumesPerNode: int64(d.volumeLimit), // make sure that the driver works on this particular region only AccessibleTopology: &csi.Topology{ From 9004a6afedc0571928aa3451637536d2f9c3562b Mon Sep 17 00:00:00 2001 From: Timo Reimann Date: Wed, 7 Aug 2024 15:47:04 +0200 Subject: [PATCH 2/2] Extend change log --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f0b97a3..faa19c9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## unreleased +* Make volumes-per-node limit configurable + [[GH-575]](https://github.com/digitalocean/csi-digitalocean/pull/575) + ## v4.10.0 - 2024.06.05 * Handle new max-volumes-per-node error message