Skip to content

CreateVolumeRequest: add requested AccessMode #61

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

Conversation

jsafrane
Copy link
Contributor

User should be able to specify (via CO) what kind of volume should be created.

Some applications running on CO may require a SINGLE_NODE_WRITER volume for a database, while others may want MULTI_NODE_MULTI_WRITER for say sharing of pictures. The Plugin should 1) see what the application needs and 2) be able to raise an error if it's not able to provision a volume with requested access mode.

User should be able to specify (via CO) what kind of volume should be
created.
Some applications may require a SINGLE_NODE_WRITER volume for a database,
while others may want MULTI_NODE_MULTI_WRITER for say sharing of pictures.
@jsafrane jsafrane force-pushed the create-accessmode branch 3 times, most recently from 974b462 to c381d18 Compare July 19, 2017 13:55
@cpuguy83
Copy link
Contributor

+1, this LGTM

@jdef
Copy link
Member

jdef commented Jul 19, 2017

This came up a few times while we wrote the spec, but I forget the reason why we pushed access mode to the *Publish calls. /cc @saad-ali @thockin @jieyu do you remember the reasoning here?

@jieyu
Copy link
Member

jieyu commented Jul 20, 2017

Thanks for the PR! This PR made me think: should we move AccessMode to VolumeCapability?
I was asking myself why AccessMode is any different than thing like Block/Mount? It looks like they are the same: all representing some capability of a volume. In CreateVolumeRequest, a CO can request a volume with certain capabilities, and the volume create MUST have those capabilities. AccessMode is just one of those capabilities.

For the sake of consistency, we should either add VolumeCapability to VolumeInfo, or remove AccessMode from VolumeInfo.

Something like the following:

message VolumeCapability {
  ...
  message AccessMode {
    ...
  }

  // One of the following fields MUST be specified.
  oneof value {
    BlockVolume block = 1; 
    MountVolume mount = 2; 
    AccessMode access_mode = 3;
  }
}

message VolumeInfo {
  uint64 capacity_bytes = 1;
  VolumeID id = 4;
  VolumeMetadata metadata = 5;
  repeated VolumeCapability volume_capabilities = 6;
}

Another nice thing about this proposal is that we now can get the AccessMode that a Plugin supports by calling ControllerGetCapabilities.

@jsafrane
Copy link
Contributor Author

I did not want to put it into VolumeCapabilities because it's not useful in NodePublishVolumeRequest - there already is readonly flag and eventual MULTI_NODE / SINGLE_NODE is IMO irrelevant here, it does not change the way how the plugin mounts the volume.

Also, what would be in NodeGetCapabilitiesResponse and ControllerGetCapabilitiesResponse? If a plugin supports SINGLE_NODE_WRITER, SINGLE_NODE_READER_ONLY and MULTI_NODE_READER_ONLY and ext2, ext3, ext4, xfs, btrfs and zfs, would it return 3 x 6 VolumeCapabilities? That does not seem to be useful.

@jieyu
Copy link
Member

jieyu commented Jul 26, 2017

@jsafrane good point on AccessMode is not necessary for NodePublishVolumeRequest. Currently, given that VolumeCapability is part of NodePublishVolumeRequest, according to your comment above, that means we should not have any volume capability that's not node related? That sounds a bit unfortunate.

RE: would it return 3 x 6 VolumeCapabilities? That does not seem to be useful.

Why 3*6, not 3+6?

// The requested minimal access mode. The Plugin MAY return a volume
// that allows a broader access mode, e.g. MULTI_NODE_MULTI_WRITER
// when CO asked just for SINGLE_NODE_WRITER. The Plugin MUST NOT
// return a volume with more restrictive access mode than the CO
Copy link
Member

Choose a reason for hiding this comment

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

We need to clearly define what "restrictive" means if we want to go with this route. If we define the order in AccessMode based on "restrictiveness", I don't think that forms a total order (it's a partial order meaning that there might not be an order between two enums).

@jsafrane
Copy link
Contributor Author

RE: would it return 3 x 6 VolumeCapabilities? That does not seem to be useful.

Why 3*6, not 3+6?

My interpretation of repeated NodeServiceCapability capabilities is that all possible combinations of fs_type and access_mode should be returned. Most filesystems like ext4 support single mount read/write mount or multiple read only mounts with no writer (i.e. SINGLE_NODE_WRITER, SINGLE_NODE_READER_ONLY and MULTI_NODE_READER_ONLY), but there are some filesystems that allow multiple writers, e.g. gfs2. So it's not enough to return one VolumeCapability for each fs_type + one VolumeCapability for each:

[
  {fs_type: "ext4"},
  {fs_type: "xfs"},
  {fs_type: "gfs2"},
  {access_mode: "SINGLE_NODE_WRITER"},
  {access_mode: "SINGLE_NODE_READER_ONLY"},
  {access_mode: "MULTI_NODE_READER_ONLY"},
  {access_mode: "MULTI_NODE_SINGLE_WRITER"},
  {access_mode: "MULTI_NODE_MULTI_WRITER"}
]

How CO knows what fs supports which access mode? You must return the allowed combinations:

[
  {fs_type: "ext4", access_mode: "SINGLE_NODE_WRITER"},
  {fs_type: "ext4", access_mode: "SINGLE_NODE_READER_ONLY"},
  {fs_type: "ext4", access_mode: "MULTI_NODE_READER_ONLY"},
  {fs_type: "xfs", access_mode: "SINGLE_NODE_WRITER"},
  {fs_type: "xfs", access_mode: "SINGLE_NODE_READER_ONLY"},
  {fs_type: "xfs", access_mode: "MULTI_NODE_READER_ONLY"},
  {fs_type: "gfs2", access_mode: "SINGLE_NODE_WRITER"},
  {fs_type: "gfs2", access_mode: "SINGLE_NODE_READER_ONLY"},
  {fs_type: "gfs2", access_mode: "MULTI_NODE_READER_ONLY"},
  {fs_type: "gfs2", access_mode: "MULTI_NODE_SINGLE_WRITER"},
  {fs_type: "gfs2", access_mode: "MULTI_NODE_MULTI_WRITER"}
]

And that's too ugly I think.

@jieyu
Copy link
Member

jieyu commented Aug 9, 2017

@jsafrane I thought about it a bit more. I agree with you that asking the plugin to return a complete combination of VolumeCapability that it supports in ControllerGetCapabilities probably does not make sense and not scalable. There probably will be a lot of filesystems that a plugin supports. Not to mention the fact that one might consider building a meta plugin that supports multiple backends.

I think a more practical way is to let the CO drive the volume capability check. So here is my proposal:

  1. Remove volume_capability in ControllerServiceCapability. For a plugin that manages multiple pools of storage space that have different volume capabilities, probably make more sense to integrate with GetCapacity (related to Proposal: GetCapacity MAY report capacity w/ respect to capabilities + parameters #59)
  2. Make AccessMode be one of the VolumeCapability. Remove oneof for the fields in VolumeCapability. That means a VolumeCapability can represent a combination (e.g., (MountVolume(xfs, noquota), "SINGLE_NODE_WRITER")). Certain combination will be disallowed. For instance, either 'block' or 'mount' can be set, but not both.
message VolumeCapability {
  ...
  message AccessMode {
    ...
  }

  BlockVolume block = 1; 
  MountVolume mount = 2; 
  AccessMode access_mode = 3;
}
  1. Remove access_mode in VolumeInfo. For pre-existing volumes, the CO can use ValidateVolumeCapabilities to check if a pre-existing volume has certain volume capabilities it intends to use.
message VolumeInfo {
  uint64 capacity_bytes = 1;
  VolumeID id = 4;
  VolumeMetadata metadata = 5;
}
  1. Add VolumeCapability to ControllerPublishVolumeRequest. Similar to NodePublishVolumeRequest. This tells the Plugin about how the CO is about to use the volume and what volume capability that the CO expect. This should be one of the volume capabilities that the CO specifies in CreateVolumeRequest (or in ValidateVolumeCapabilities for pre-existing volumes).
message ControllerPublishVolumeRequest {
  ...
  VolumeCapability volume_capability = 6;
}

@jsafrane let me know if that makes sense to you or not. If you agree, let me know if you're interested in updating the spec. If not, I'm happy to prepare a PR for this.

cc @saad-ali @jdef @cpuguy83 @julian-hj

@jsafrane
Copy link
Contributor Author

Just thinking out loud...

For pre-existing volumes, the CO can use ValidateVolumeCapabilities to check if a pre-existing volume has certain volume capabilities it intends to use.

I could imagine a GUI where CO asks user what kind of FS should be created on a volume. There should be a way how CO asks the plugin "give me list of everything you support" so the GUI provides a list of filesystems. This is not possible with ValidateVolumeCapabilities, where CO needs to know all filesystems in the world in advance and then check if the plugin supports each of them.

Is it a valid use case for CSI?

The rest of the proposal looks solid to me. Feel free to prepare a PR on my behalf, thanks in advance :-).

@jdef
Copy link
Member

jdef commented Aug 10, 2017

Is the intent to also modify NodeServiceCapability by removing its volume_capability field?

Perhaps we amend Jie's point (1) such that supported filesystems (not filesystem/mount-option combos) can still be queried?

message ControllerServiceCapability {
  message RPC {
    enum Type {
      UNKNOWN = 0;
      ... // RPC types here
    }

    Type type = 1;
  }
  
  oneof type {
    // RPC that the controller supports.
    RPC rpc = 1;
    
    // File system type that the Plugin supports. Empty strings not allowed.
    string fs_type = 2;
  }
}

jieyu added a commit to jieyu/csi-spec that referenced this pull request Aug 14, 2017
This patch moved `AccessMode` to `VolumeCapability`, because access mode
is strongly related to the filesystem type. For instance, a plugin might
support `SINGLE_NODE_WRITER` for `xfs`, and `MULTI_NODE_READER_ONLY` for
`gfs2`.

This patch also removed `VolumeCapability` fields from
`ControllerGetCapabilities` and `NodeGetCapabilities` RPCs. It becomes
very tedious to ask the plugins to enumerate all volume capabilities
that a plugin supports, and probably provides less value. To check the
capablities of a volume, the CO should use `ValidateVolumeCapabilities`.
This applies to both newly provisioned volumes and pre-existing volumes.

See discussion in container-storage-interface#61.
@cpuguy83
Copy link
Contributor

Does it make sense to move the mount/block fields into access mode at this point?
It still seems like it would need to be a OneOf for block vs mount.

@jieyu
Copy link
Member

jieyu commented Aug 15, 2017

@cpuguy83 this is pretty much what I did in the PR (except the naming). Take a look at #82

jieyu added a commit that referenced this pull request Aug 23, 2017
This patch moved `AccessMode` to `VolumeCapability`, because access mode
is strongly related to the filesystem type. For instance, a plugin might
support `SINGLE_NODE_WRITER` for `xfs`, and `MULTI_NODE_READER_ONLY` for
`gfs2`.

This patch also removed `VolumeCapability` fields from
`ControllerGetCapabilities` and `NodeGetCapabilities` RPCs. It becomes
very tedious to ask the plugins to enumerate all volume capabilities
that a plugin supports, and probably provides less value. To check the
capablities of a volume, the CO should use `ValidateVolumeCapabilities`.
This applies to both newly provisioned volumes and pre-existing volumes.

See discussion in #61.
@jieyu
Copy link
Member

jieyu commented Aug 23, 2017

Close this one as #82 is merged.

@jieyu jieyu closed this Aug 23, 2017
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.

4 participants