Skip to content

Commit ac23a1e

Browse files
authored
cinder-csi-plugin: Add --with-topology option (#2743)
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]>
1 parent 324a883 commit ac23a1e

File tree

8 files changed

+61
-36
lines changed

8 files changed

+61
-36
lines changed

cmd/cinder-csi-plugin/main.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ var (
4343
provideControllerService bool
4444
provideNodeService bool
4545
noClient bool
46+
withTopology bool
4647
)
4748

4849
func main() {
@@ -87,6 +88,8 @@ func main() {
8788

8889
cmd.Flags().StringSliceVar(&cloudConfig, "cloud-config", nil, "CSI driver cloud config. This option can be given multiple times")
8990

91+
cmd.PersistentFlags().BoolVar(&withTopology, "with-topology", true, "cluster is topology-aware")
92+
9093
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.")
9194
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.")
9295

@@ -107,9 +110,10 @@ func main() {
107110
func handle() {
108111
// Initialize cloud
109112
d := cinder.NewDriver(&cinder.DriverOpts{
110-
Endpoint: endpoint,
111-
ClusterID: cluster,
112-
PVCLister: csi.GetPVCLister(),
113+
Endpoint: endpoint,
114+
ClusterID: cluster,
115+
PVCLister: csi.GetPVCLister(),
116+
WithTopology: withTopology,
113117
})
114118

115119
openstack.InitOpenStackProvider(cloudConfig, httpEndpoint)

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

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

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

102109
<dt>--provide-controller-service &lt;enabled&gt;</dt>
103110
<dd>
104-
If set to true then the CSI driver does provide the controller service.
111+
If set to true then the CSI driver provides the controller service.
105112

106-
The default is to provide the controller service.
113+
Defaults to `true` (enabled).
107114
</dd>
108115

109116
<dt>--provide-node-service &lt;enabled&gt;</dt>
110117
<dd>
111-
If set to true then the CSI driver does provide the node service.
118+
If set to true then the CSI driver provides the node service.
112119

113-
The default is to provide the node service.
120+
Defaults to `true` (enabled).
121+
</dd>
114122

115123
<dt>--pvc-annotations &lt;disabled&gt;</dt>
116124
<dd>
117125
If set to true then the CSI driver will use PVC annotations to provide volume
118126
scheduler hints. See [Supported PVC Annotations](#supported-pvc-annotations)
119127
for more information.
120128

121-
The default is not to provide the PVC annotations support.
129+
Defaults to `false` (disabled).
122130
</dd>
123131
</dl>
124132

pkg/csi/cinder/controllerserver.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,17 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
8484
// Volume Type
8585
volType := volParams["type"]
8686

87-
// First check if volAvailability is already specified, if not get preferred from Topology
88-
// Required, incase vol AZ is different from node AZ
89-
volAvailability := volParams["availability"]
90-
if volAvailability == "" {
91-
// Check from Topology
92-
if req.GetAccessibilityRequirements() != nil {
93-
volAvailability = sharedcsi.GetAZFromTopology(topologyKey, req.GetAccessibilityRequirements())
87+
var volAvailability string
88+
if cs.Driver.withTopology {
89+
// First check if volAvailability is already specified, if not get preferred from Topology
90+
// Required, incase vol AZ is different from node AZ
91+
volAvailability = volParams["availability"]
92+
if volAvailability == "" {
93+
accessibleTopologyReq := req.GetAccessibilityRequirements()
94+
// Check from Topology
95+
if accessibleTopologyReq != nil {
96+
volAvailability = sharedcsi.GetAZFromTopology(topologyKey, accessibleTopologyReq)
97+
}
9498
}
9599
}
96100

pkg/csi/cinder/controllerserver_test.go

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

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

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

pkg/csi/cinder/driver.go

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,11 @@ type CinderDriver = Driver
6363
//revive:enable:exported
6464

6565
type Driver struct {
66-
name string
67-
fqVersion string //Fully qualified version in format {Version}@{CPO version}
68-
endpoint string
69-
clusterID string
66+
name string
67+
fqVersion string //Fully qualified version in format {Version}@{CPO version}
68+
endpoint string
69+
clusterID string
70+
withTopology bool
7071

7172
ids *identityServer
7273
cs *controllerServer
@@ -80,23 +81,27 @@ type Driver struct {
8081
}
8182

8283
type DriverOpts struct {
83-
ClusterID string
84-
Endpoint string
84+
ClusterID string
85+
Endpoint string
86+
WithTopology bool
87+
8588
PVCLister v1.PersistentVolumeClaimLister
8689
}
8790

8891
func NewDriver(o *DriverOpts) *Driver {
8992
d := &Driver{
90-
name: driverName,
91-
fqVersion: fmt.Sprintf("%s@%s", Version, version.Version),
92-
endpoint: o.Endpoint,
93-
clusterID: o.ClusterID,
94-
pvcLister: o.PVCLister,
93+
name: driverName,
94+
fqVersion: fmt.Sprintf("%s@%s", Version, version.Version),
95+
endpoint: o.Endpoint,
96+
clusterID: o.ClusterID,
97+
withTopology: o.WithTopology,
98+
pvcLister: o.PVCLister,
9599
}
96100

97101
klog.Info("Driver: ", d.name)
98102
klog.Info("Driver version: ", d.fqVersion)
99103
klog.Info("CSI Spec version: ", specVersion)
104+
klog.Infof("Topology awareness: %T", d.withTopology)
100105

101106
d.AddControllerServiceCapabilities(
102107
[]csi.ControllerServiceCapability_RPC_Type{

pkg/csi/cinder/nodeserver.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -286,12 +286,20 @@ func (ns *nodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag
286286
}
287287

288288
func (ns *nodeServer) NodeGetInfo(ctx context.Context, req *csi.NodeGetInfoRequest) (*csi.NodeGetInfoResponse, error) {
289-
290289
nodeID, err := ns.Metadata.GetInstanceID()
291290
if err != nil {
292291
return nil, status.Errorf(codes.Internal, "[NodeGetInfo] unable to retrieve instance id of node %v", err)
293292
}
294293

294+
nodeInfo := &csi.NodeGetInfoResponse{
295+
NodeId: nodeID,
296+
MaxVolumesPerNode: ns.Opts.NodeVolumeAttachLimit,
297+
}
298+
299+
if !ns.Driver.withTopology {
300+
return nodeInfo, nil
301+
}
302+
295303
zone, err := ns.Metadata.GetAvailabilityZone()
296304
if err != nil {
297305
return nil, status.Errorf(codes.Internal, "[NodeGetInfo] Unable to retrieve availability zone of node %v", err)
@@ -301,13 +309,9 @@ func (ns *nodeServer) NodeGetInfo(ctx context.Context, req *csi.NodeGetInfoReque
301309
for k, v := range ns.Topologies {
302310
topologyMap[k] = v
303311
}
304-
topology := &csi.Topology{Segments: topologyMap}
312+
nodeInfo.AccessibleTopology = &csi.Topology{Segments: topologyMap}
305313

306-
return &csi.NodeGetInfoResponse{
307-
NodeId: nodeID,
308-
AccessibleTopology: topology,
309-
MaxVolumesPerNode: ns.Opts.NodeVolumeAttachLimit,
310-
}, nil
314+
return nodeInfo, nil
311315
}
312316

313317
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
@@ -41,7 +41,7 @@ var omock *openstack.OpenStackMock
4141
func init() {
4242
if fakeNs == nil {
4343

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

4646
// mock MountMock
4747
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)