CSI: fingerprint detailed node capabilities

In order to support new node RPCs, we need to fingerprint plugin capabilities
in more detail. This changeset mirrors recent work to fingerprint controller
capabilities, but is not yet in use by any Nomad RPC.
This commit is contained in:
Tim Gross
2021-04-01 15:39:38 -04:00
parent 7af5afb58d
commit c12c90262d
5 changed files with 71 additions and 16 deletions

View File

@@ -168,6 +168,9 @@ func (p *pluginFingerprinter) buildNodeFingerprint(ctx context.Context, base *st
return fp, err
}
fp.NodeInfo.RequiresNodeStageVolume = caps.HasStageUnstageVolume
fp.NodeInfo.SupportsStats = caps.HasGetVolumeStats
fp.NodeInfo.SupportsExpand = caps.HasExpandVolume
fp.NodeInfo.SupportsCondition = caps.HasVolumeCondition
return fp, nil
}

View File

@@ -952,6 +952,24 @@ const (
CSIControllerSupportsGet CSIControllerCapability = 11
)
type CSINodeCapability byte
const (
// CSINodeSupportsStageVolume indicates whether the client should
// Stage/Unstage volumes on this node.
CSINodeSupportsStageVolume CSINodeCapability = 0
// CSINodeSupportsStats indicates plugin support for GET_VOLUME_STATS
CSINodeSupportsStats CSINodeCapability = 1
// CSINodeSupportsExpand indicates plugin support for EXPAND_VOLUME
CSINodeSupportsExpand CSINodeCapability = 2
// CSINodeSupportsCondition indicates plugin support for VOLUME_CONDITION
CSINodeSupportsCondition CSINodeCapability = 3
)
func (p *CSIPlugin) HasControllerCapability(cap CSIControllerCapability) bool {
if len(p.Controllers) < 1 {
return false
@@ -991,6 +1009,29 @@ func (p *CSIPlugin) HasControllerCapability(cap CSIControllerCapability) bool {
return false
}
func (p *CSIPlugin) HasNodeCapability(cap CSINodeCapability) bool {
if len(p.Nodes) < 1 {
return false
}
// we're picking the first node because they should be uniform
// across the same version of the plugin
for _, c := range p.Nodes {
switch cap {
case CSINodeSupportsStageVolume:
return c.NodeInfo.RequiresNodeStageVolume
case CSINodeSupportsStats:
return c.NodeInfo.SupportsStats
case CSINodeSupportsExpand:
return c.NodeInfo.SupportsExpand
case CSINodeSupportsCondition:
return c.NodeInfo.SupportsCondition
default:
return false
}
}
return false
}
// AddPlugin adds a single plugin running on the node. Called from state.NodeUpdate in a
// transaction
func (p *CSIPlugin) AddPlugin(nodeID string, info *CSIInfo) error {

View File

@@ -95,6 +95,15 @@ type CSINodeInfo struct {
// RequiresNodeStageVolume indicates whether the client should Stage/Unstage
// volumes on this node.
RequiresNodeStageVolume bool
// SupportsStats indicates plugin support for GET_VOLUME_STATS
SupportsStats bool
// SupportsExpand indicates plugin support for EXPAND_VOLUME
SupportsExpand bool
// SupportsCondition indicates plugin support for VOLUME_CONDITION
SupportsCondition bool
}
func (n *CSINodeInfo) Copy() *CSINodeInfo {

View File

@@ -314,22 +314,7 @@ func TestClient_RPC_NodeGetCapabilities(t *testing.T) {
ExpectedErr: fmt.Errorf("some grpc error"),
},
{
Name: "ignores unknown capabilities",
Response: &csipbv1.NodeGetCapabilitiesResponse{
Capabilities: []*csipbv1.NodeServiceCapability{
{
Type: &csipbv1.NodeServiceCapability_Rpc{
Rpc: &csipbv1.NodeServiceCapability_RPC{
Type: csipbv1.NodeServiceCapability_RPC_EXPAND_VOLUME,
},
},
},
},
},
ExpectedResponse: &NodeCapabilitySet{},
},
{
Name: "detects stage volumes capability",
Name: "detects multiple capabilities",
Response: &csipbv1.NodeGetCapabilitiesResponse{
Capabilities: []*csipbv1.NodeServiceCapability{
{
@@ -339,10 +324,18 @@ func TestClient_RPC_NodeGetCapabilities(t *testing.T) {
},
},
},
{
Type: &csipbv1.NodeServiceCapability_Rpc{
Rpc: &csipbv1.NodeServiceCapability_RPC{
Type: csipbv1.NodeServiceCapability_RPC_EXPAND_VOLUME,
},
},
},
},
},
ExpectedResponse: &NodeCapabilitySet{
HasStageUnstageVolume: true,
HasExpandVolume: true,
},
},
}

View File

@@ -805,6 +805,9 @@ type ListSnapshotsResponse_Entry struct {
type NodeCapabilitySet struct {
HasStageUnstageVolume bool
HasGetVolumeStats bool
HasExpandVolume bool
HasVolumeCondition bool
}
func NewNodeCapabilitySet(resp *csipbv1.NodeGetCapabilitiesResponse) *NodeCapabilitySet {
@@ -815,6 +818,12 @@ func NewNodeCapabilitySet(resp *csipbv1.NodeGetCapabilitiesResponse) *NodeCapabi
switch c.Type {
case csipbv1.NodeServiceCapability_RPC_STAGE_UNSTAGE_VOLUME:
cs.HasStageUnstageVolume = true
case csipbv1.NodeServiceCapability_RPC_GET_VOLUME_STATS:
cs.HasGetVolumeStats = true
case csipbv1.NodeServiceCapability_RPC_EXPAND_VOLUME:
cs.HasExpandVolume = true
case csipbv1.NodeServiceCapability_RPC_VOLUME_CONDITION:
cs.HasVolumeCondition = true
default:
continue
}