Skip to content

Commit 6cb478d

Browse files
EmilienMstephenfin
andauthored
cinder-csi-plugin: Add --with-topology option (#2743) (#2746)
Many clouds do not have a 1:1 mapping of compute and storage AZs. As we generate topology information from the metadata service on the node (i.e. a compute AZ), this can prevent us from being able to schedule VMs. Add a new boolean, '--with-topology', to allow users to disable the topology feature where it does not make sense. An identical option already exists for the Manila CSI driver. However, unlike that option, this one defaults to 'true' to retain current behavior. Signed-off-by: Stephen Finucane <[email protected]> (cherry picked from commit ac23a1e) Co-authored-by: Stephen Finucane <[email protected]>
1 parent 6f1d78d commit 6cb478d

File tree

8 files changed

+57
-31
lines changed

8 files changed

+57
-31
lines changed

cmd/cinder-csi-plugin/main.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ var (
4141
provideControllerService bool
4242
provideNodeService bool
4343
noClient bool
44+
withTopology bool
4445
)
4546

4647
func main() {
@@ -68,6 +69,8 @@ func main() {
6869
klog.Fatalf("Unable to mark flag cloud-config to be required: %v", err)
6970
}
7071

72+
cmd.PersistentFlags().BoolVar(&withTopology, "with-topology", true, "cluster is topology-aware")
73+
7174
cmd.PersistentFlags().StringSliceVar(&cloudNames, "cloud-name", []string{""}, "Cloud name to instruct CSI driver to read additional OpenStack cloud credentials from the configuration subsections. This option can be specified multiple times to manage multiple OpenStack clouds.")
7275
cmd.PersistentFlags().StringToStringVar(&additionalTopologies, "additional-topology", map[string]string{}, "Additional CSI driver topology keys, for example topology.kubernetes.io/region=REGION1. This option can be specified multiple times to add multiple additional topology keys.")
7376

@@ -86,7 +89,11 @@ func main() {
8689

8790
func handle() {
8891
// Initialize cloud
89-
d := cinder.NewDriver(&cinder.DriverOpts{Endpoint: endpoint, ClusterID: cluster})
92+
d := cinder.NewDriver(&cinder.DriverOpts{
93+
Endpoint: endpoint,
94+
ClusterID: cluster,
95+
WithTopology: withTopology,
96+
})
9097

9198
openstack.InitOpenStackProvider(cloudConfig, httpEndpoint)
9299

docs/cinder-csi-plugin/using-cinder-csi-plugin.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ In addition to the standard set of klog flags, `cinder-csi-plugin` accepts the f
6969
The manifests default this to `unix://csi/csi.sock`, which is supplied via the `CSI_ENDPOINT` environment variable.
7070
</dd>
7171

72+
<dt>--with-topology &lt;enabled&gt;</dt>
73+
<dd>
74+
If set to true then the CSI driver reports topology information and the controller respects it.
75+
76+
Defaults to `true` (enabled).
77+
</dd>
78+
7279
<dt>--cloud-config &lt;config file&gt; [--cloud-config &lt;config file&gt; ...]</dt>
7380
<dd>
7481
This argument must be given at least once.
@@ -100,23 +107,23 @@ In addition to the standard set of klog flags, `cinder-csi-plugin` accepts the f
100107

101108
<dt>--provide-controller-service &lt;enabled&gt;</dt>
102109
<dd>
103-
If set to true then the CSI driver does provide the controller service.
110+
If set to true then the CSI driver provides the controller service.
104111

105-
The default is to provide the controller service.
112+
Defaults to `true` (enabled).
106113
</dd>
107114

108115
<dt>--provide-node-service &lt;enabled&gt;</dt>
109116
<dd>
110-
If set to true then the CSI driver does provide the node service.
117+
If set to true then the CSI driver provides the node service.
111118

112-
The default is to provide the node service.
119+
Defaults to `true` (enabled).
113120
</dd>
114121

115122
<dt>--node-service-no-os-client &lt;disabled&gt;</dt>
116123
<dd>
117124
If set to true then the CSI driver does not provide the OpenStack client in the node service.
118125

119-
The default is to provide the OpenStack client in the node service.
126+
Defaults to `false` (disabled).
120127
</dd>
121128
</dl>
122129

pkg/csi/cinder/controllerserver.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
6161
// Volume Name
6262
volName := req.GetName()
6363
volCapabilities := req.GetVolumeCapabilities()
64+
volParams := req.GetParameters()
6465

6566
if len(volName) == 0 {
6667
return nil, status.Error(codes.InvalidArgument, "[CreateVolume] missing Volume Name")
@@ -80,13 +81,17 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
8081
// Volume Type
8182
volType := req.GetParameters()["type"]
8283

83-
// First check if volAvailability is already specified, if not get preferred from Topology
84-
// Required, incase vol AZ is different from node AZ
85-
volAvailability := req.GetParameters()["availability"]
86-
if volAvailability == "" {
87-
// Check from Topology
88-
if req.GetAccessibilityRequirements() != nil {
89-
volAvailability = util.GetAZFromTopology(topologyKey, req.GetAccessibilityRequirements())
84+
var volAvailability string
85+
if cs.Driver.withTopology {
86+
// First check if volAvailability is already specified, if not get preferred from Topology
87+
// Required, incase vol AZ is different from node AZ
88+
volAvailability = volParams["availability"]
89+
if volAvailability == "" {
90+
accessibleTopologyReq := req.GetAccessibilityRequirements()
91+
// Check from Topology
92+
if accessibleTopologyReq != nil {
93+
volAvailability = util.GetAZFromTopology(topologyKey, accessibleTopologyReq)
94+
}
9095
}
9196
}
9297

pkg/csi/cinder/controllerserver_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func init() {
3838
osmock = new(openstack.OpenStackMock)
3939
osmockRegionX = new(openstack.OpenStackMock)
4040

41-
d := NewDriver(&DriverOpts{Endpoint: FakeEndpoint, ClusterID: FakeCluster})
41+
d := NewDriver(&DriverOpts{Endpoint: FakeEndpoint, ClusterID: FakeCluster, WithTopology: true})
4242

4343
fakeCs = NewControllerServer(d, map[string]openstack.IOpenStack{
4444
"": osmock,

pkg/csi/cinder/driver.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,11 @@ type CinderDriver = Driver
5656
//revive:enable:exported
5757

5858
type Driver struct {
59-
name string
60-
fqVersion string //Fully qualified version in format {Version}@{CPO version}
61-
endpoint string
62-
cluster string
59+
name string
60+
fqVersion string //Fully qualified version in format {Version}@{CPO version}
61+
endpoint string
62+
cluster string
63+
withTopology bool
6364

6465
ids *identityServer
6566
cs *controllerServer
@@ -71,8 +72,9 @@ type Driver struct {
7172
}
7273

7374
type DriverOpts struct {
74-
ClusterID string
75-
Endpoint string
75+
ClusterID string
76+
Endpoint string
77+
WithTopology bool
7678
}
7779

7880
func NewDriver(o *DriverOpts) *Driver {
@@ -81,10 +83,12 @@ func NewDriver(o *DriverOpts) *Driver {
8183
d.fqVersion = fmt.Sprintf("%s@%s", Version, version.Version)
8284
d.endpoint = o.Endpoint
8385
d.cluster = o.ClusterID
86+
d.withTopology = o.WithTopology
8487

8588
klog.Info("Driver: ", d.name)
8689
klog.Info("Driver version: ", d.fqVersion)
8790
klog.Info("CSI Spec version: ", specVersion)
91+
klog.Infof("Topology awareness: %T", d.withTopology)
8892

8993
d.AddControllerServiceCapabilities(
9094
[]csi.ControllerServiceCapability_RPC_Type{

pkg/csi/cinder/nodeserver.go

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -359,12 +359,21 @@ func (ns *nodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag
359359
}
360360

361361
func (ns *nodeServer) NodeGetInfo(ctx context.Context, req *csi.NodeGetInfoRequest) (*csi.NodeGetInfoResponse, error) {
362-
363362
nodeID, err := ns.Metadata.GetInstanceID()
364363
if err != nil {
365364
return nil, status.Errorf(codes.Internal, "[NodeGetInfo] unable to retrieve instance id of node %v", err)
366365
}
367366

367+
maxVolume := ns.Cloud.GetMaxVolLimit()
368+
nodeInfo := &csi.NodeGetInfoResponse{
369+
NodeId: nodeID,
370+
MaxVolumesPerNode: maxVolume,
371+
}
372+
373+
if !ns.Driver.withTopology {
374+
return nodeInfo, nil
375+
}
376+
368377
zone, err := ns.Metadata.GetAvailabilityZone()
369378
if err != nil {
370379
return nil, status.Errorf(codes.Internal, "[NodeGetInfo] Unable to retrieve availability zone of node %v", err)
@@ -374,15 +383,9 @@ func (ns *nodeServer) NodeGetInfo(ctx context.Context, req *csi.NodeGetInfoReque
374383
for k, v := range ns.Topologies {
375384
topologyMap[k] = v
376385
}
377-
topology := &csi.Topology{Segments: topologyMap}
378-
379-
maxVolume := ns.Cloud.GetMaxVolLimit()
386+
nodeInfo.AccessibleTopology = &csi.Topology{Segments: topologyMap}
380387

381-
return &csi.NodeGetInfoResponse{
382-
NodeId: nodeID,
383-
AccessibleTopology: topology,
384-
MaxVolumesPerNode: maxVolume,
385-
}, nil
388+
return nodeInfo, nil
386389
}
387390

388391
func (ns *nodeServer) NodeGetCapabilities(ctx context.Context, req *csi.NodeGetCapabilitiesRequest) (*csi.NodeGetCapabilitiesResponse, error) {

pkg/csi/cinder/nodeserver_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ var omock *openstack.OpenStackMock
4040
func init() {
4141
if fakeNs == nil {
4242

43-
d := NewDriver(&DriverOpts{Endpoint: FakeEndpoint, ClusterID: FakeCluster})
43+
d := NewDriver(&DriverOpts{Endpoint: FakeEndpoint, ClusterID: FakeCluster, WithTopology: true})
4444

4545
// mock MountMock
4646
mmock = new(mount.MountMock)

tests/sanity/cinder/sanity_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func TestDriver(t *testing.T) {
1919
endpoint := "unix://" + socket
2020
cluster := "kubernetes"
2121

22-
d := cinder.NewDriver(&cinder.DriverOpts{Endpoint: endpoint, ClusterID: cluster})
22+
d := cinder.NewDriver(&cinder.DriverOpts{Endpoint: endpoint, ClusterID: cluster, WithTopology: true})
2323

2424
fakecloudprovider := getfakecloud()
2525
openstack.OsInstances = map[string]openstack.IOpenStack{

0 commit comments

Comments
 (0)