Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CreateVolume RPC refinements #101

Merged
merged 6 commits into from
Nov 19, 2018
Merged

CreateVolume RPC refinements #101

merged 6 commits into from
Nov 19, 2018

Conversation

joonas
Copy link
Contributor

@joonas joonas commented Nov 10, 2018

After looking through the CreateVolume code, I thought that there was a few improvements I could make to it, so here they are.. Let me know if you'd prefer me to break this up or drop some of these.

Joonas Bergius added 5 commits November 10, 2018 13:51
…abilities

From reading through the Error Scheme section[1] of the spec and
comparing that to the list of CreateVolume Errors[2], I came to the
conclusion that AlreadyExists does not quite apply as outlined in the
RPC-specific error code section, and instead we should be referring to
the general Error Scheme.

This changes the error codes around to be more appropriate for signaling
what the actual error was, and thus better aligning with the error
description we pass back.

[1]: https:/container-storage-interface/spec/blob/master/spec.md#error-scheme
[2]: https:/container-storage-interface/spec/blob/master/spec.md#createvolume-errors
There is no point continuing any further in the volume creation process if the
passed in volume capabilities (access mode) can not be supported by the driver
Added handling for:
* Ensuring that the requested volume is at least the minimum supported volume size (1 GB)
* Ensuring that the requested volume is not larger than maximum supported volume size (16 TB)

Changed the returned error code to InvalidArgument
requiredBytes := capRange.GetRequiredBytes()
requiredSet := 0 < requiredBytes
limitBytes := capRange.GetLimitBytes()
limitSet := 0 < limitBytes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't need requiredSet and limitSet variables as it makes this function complicated. One because it's not a valid value:

// The capacity of the storage space in bytes. To specify an exact size,
// `required_bytes` and `limit_bytes` SHALL be set to the same value. At
// least one of the these fields MUST be specified.
type CapacityRange struct {
	// Volume MUST be at least this big. This field is OPTIONAL.
	// A value of 0 is equal to an unspecified field value.
	// The value of this field MUST NOT be negative.
	RequiredBytes int64 `protobuf:"varint,1,opt,name=required_bytes,json=requiredBytes" json:"required_bytes,omitempty"`
	// Volume MUST not be bigger than this. This field is OPTIONAL.
	// A value of 0 is equal to an unspecified field value.
	// The value of this field MUST NOT be negative.
	LimitBytes           int64    `protobuf:"varint,2,opt,name=limit_bytes,json=limitBytes" json:"limit_bytes,omitempty"`

It can't be negative, if it's negative, we should return an error immediately. Once we return an error if any of them are negative:

	if 0 < requiredBytes || 0 < limitBytes {
		return 0, fmt.Errorf("limit %v or required %v bytes can't be negative", limitBytes, requiredBytes)
	}

we can then remove all limitSet and requiredSet variables and it would be simpler.

Copy link
Contributor Author

@joonas joonas Nov 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately that's not what these variables are for, they are meant to be used as a way to check whether RequiredBytes or LimitBytes was provided.

Since both of these values are optional, per the CSI spec, we can't be sure that one, both or either of them have been set, which is why I thought storing them in a variable that you can simply use to check whether one or the other was set would be convenient.

As it stands today, Kubernetes (via external-provisioner) only ever sets RequiredBytes, but this was intended as a way to future proof things should this change.

I'm happy to drop these values if you feel that's better, but as it stands the code wasn't accounting for a few specific cases, which is why I felt that it would be useful to add these and use them to check different cases.

WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's ok, thanks for the explanation Joonas. PR looks fine 👍

@joonas
Copy link
Contributor Author

joonas commented Nov 18, 2018

I made some additional error message formatting improvements, the errors you'll now see from trying to provision either a too small or too large volume will be as follows:

Events:
  Type       Reason                Age              From                                                                                Message
  ----       ------                ----             ----                                                                                -------
  Normal     ExternalProvisioning  8s (x3 over 8s)  persistentvolume-controller                                                         waiting for a volume to be created, either by external provisioner "dobs.csi.digitalocean.com" or manually created by system administrator
  Normal     Provisioning          8s (x2 over 8s)  dobs.csi.digitalocean.com_csi-do-controller-0_285c902f-ead0-11e8-91b9-02420af43e03  External provisioner is provisioning volume for claim "default/csi-pod-pvc"
  Warning    ProvisioningFailed    8s (x2 over 8s)  dobs.csi.digitalocean.com_csi-do-controller-0_285c902f-ead0-11e8-91b9-02420af43e03  failed to provision volume with StorageClass "do-block-storage": rpc error: code = OutOfRange desc = invalid capacity range: required (953.7Mi) can not be less than minimum supported volume size (1Gi)
Events:
  Type       Reason                Age                From                                                                                Message
  ----       ------                ----               ----                                                                                -------
  Normal     Provisioning          13s (x2 over 13s)  dobs.csi.digitalocean.com_csi-do-controller-0_285c902f-ead0-11e8-91b9-02420af43e03  External provisioner is provisioning volume for claim "default/csi-pod-pvc"
  Warning    ProvisioningFailed    13s (x2 over 13s)  dobs.csi.digitalocean.com_csi-do-controller-0_285c902f-ead0-11e8-91b9-02420af43e03  failed to provision volume with StorageClass "do-block-storage": rpc error: code = OutOfRange desc = invalid capacity range: required (17Ti) can not exceed maximum supported volume size (16Ti)
  Normal     ExternalProvisioning  11s (x4 over 13s)  persistentvolume-controller                                                         waiting for a volume to be created, either by external provisioner "dobs.csi.digitalocean.com" or manually created by system administrator

@fatih fatih merged commit c114839 into digitalocean:master Nov 19, 2018
@joonas joonas deleted the joonas/refine-createvolume-rpc branch December 17, 2018 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants