Skip to content

Commit 6a61a80

Browse files
authored
Merge pull request #1136 from rackerlabs/chop-down-cinder
fix(cinder-understack): remove unnecessary code and follow upstream options setting
2 parents 015c911 + 0ca3a02 commit 6a61a80

File tree

2 files changed

+22
-143
lines changed

2 files changed

+22
-143
lines changed

python/cinder-understack/cinder_understack/dynamic_netapp_driver.py

Lines changed: 16 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from cinder import interface
66
from cinder.objects import volume_type as vol_type_obj
77
from cinder.volume import driver as volume_driver
8-
from cinder.volume.drivers.netapp import options
8+
from cinder.volume.drivers.netapp import options as na_opts
99
from cinder.volume.drivers.netapp.dataontap.client.client_cmode_rest import (
1010
RestClient as RestNaServer,
1111
)
@@ -21,14 +21,13 @@
2121
# Configuration options for dynamic NetApp driver
2222
# Using cinder.volume.configuration approach for better abstraction
2323
NETAPP_DYNAMIC_OPTS = [
24-
options.netapp_proxy_opts,
25-
options.netapp_connection_opts,
26-
options.netapp_transport_opts,
27-
options.netapp_basicauth_opts,
28-
options.netapp_provisioning_opts,
29-
options.netapp_cluster_opts,
30-
options.netapp_san_opts,
31-
volume_driver.volume_opts,
24+
na_opts.netapp_connection_opts,
25+
na_opts.netapp_basicauth_opts,
26+
na_opts.netapp_transport_opts,
27+
na_opts.netapp_provisioning_opts,
28+
na_opts.netapp_support_opts,
29+
na_opts.netapp_san_opts,
30+
na_opts.netapp_cluster_opts,
3231
]
3332

3433

@@ -40,84 +39,18 @@ class NetappDynamicLibrary(NetAppNVMeStorageLibrary):
4039
- Ours: Multiple SVMs per backend, SVM name from volume type
4140
"""
4241

42+
REQUIRED_CMODE_FLAGS = []
43+
4344
def __init__(self, *args, **kwargs):
4445
"""Initialize driver without creating SVM connections.
4546
4647
Parent driver creates static connections during init. We defer
4748
SVM connections until volume creation when we know which SVM to use.
4849
"""
49-
self.initialized = False
50+
super().__init__(*args, **kwargs)
5051
self.client = None
51-
driver_name = kwargs.pop("driver_name", "NetAppDynamicNVMe")
52-
driver_protocol = kwargs.pop("driver_protocol", "nvme")
53-
self.app_version = kwargs.get("app_version", "1.0.0")
54-
55-
self._setup_configuration(**kwargs)
56-
57-
super().__init__(driver_name, driver_protocol, **kwargs)
5852
self.ssc_library = None
5953
self.perf_library = None
60-
self.init_capabilities()
61-
62-
def _setup_configuration(self, **kwargs):
63-
"""Setup configuration using cinder.volume.configuration module."""
64-
from cinder.volume import configuration
65-
66-
config_obj = kwargs.get("configuration", None)
67-
68-
if config_obj:
69-
# here we can access any cinder-provided config .
70-
self.configuration = config_obj
71-
config_group = getattr(config_obj, "config_group", "netapp_nvme")
72-
73-
# Register NetApp-specific options using configuration.append()
74-
# Following the exact pattern from upstream NetApp drivers
75-
76-
try:
77-
for opt_group in NETAPP_DYNAMIC_OPTS:
78-
self.configuration.append_config_values(opt_group)
79-
80-
LOG.info(
81-
"Registered NetApp configuration options for group: %s",
82-
config_group,
83-
)
84-
85-
except Exception as e:
86-
LOG.warning("Failed to register configuration options: %s", e)
87-
# Continue default configuration handling for backward compatibility
88-
else:
89-
# Testing/Fallback: Create configuration object with all options
90-
config_group = "netapp_nvme"
91-
self.configuration = configuration.Configuration(
92-
volume_driver.volume_opts, config_group=config_group
93-
)
94-
95-
# Register additional NetApp options for testing
96-
try:
97-
for opt_group in NETAPP_DYNAMIC_OPTS:
98-
if (
99-
opt_group != volume_driver.volume_opts
100-
): # Avoid duplicate registration
101-
self.configuration.append_config_values(opt_group)
102-
103-
LOG.info(
104-
"Registered NetApp configuration options for testing group: %s",
105-
config_group,
106-
)
107-
108-
except Exception as e:
109-
LOG.warning(
110-
"Failed to register configuration options for testing: %s", e
111-
)
112-
113-
@property
114-
def supported(self):
115-
# Used by Cinder to determine whether this driver is active/enabled
116-
return True
117-
118-
def get_version(self):
119-
# Called at Cinder service startup to report backend driver version
120-
return "NetappCinderDynamicDriver 1.0"
12154

12255
def do_setup(self, context):
12356
"""Skip static NetApp connections, defer to volume creation time."""
@@ -132,22 +65,6 @@ def check_for_setup_error(self):
13265
"""Skip static validation since we connect to SVMs dynamically."""
13366
pass
13467

135-
def init_capabilities(self):
136-
"""Set driver capabilities for Cinder scheduler."""
137-
max_over_subscription_ratio = self.configuration.max_over_subscription_ratio
138-
self._capabilities = {
139-
"thin_provisioning_support": True,
140-
"thick_provisioning_support": True,
141-
"multiattach": True,
142-
"snapshot_support": True,
143-
"max_over_subscription_ratio": max_over_subscription_ratio,
144-
}
145-
self.capabilities = self._capabilities
146-
147-
def set_initialized(self):
148-
"""Mark driver as ready for volume operations."""
149-
self.initialized = True
150-
15168
def _get_all_svm_clients_from_volume_types(self):
15269
"""Connect to all SVMs found in volume type metadata."""
15370
svm_clients = {}
@@ -539,37 +456,6 @@ def get_goodness_function(self):
539456
"""Return the goodness function for Cinder's scheduler scoring."""
540457
return self.configuration.safe_get("goodness_function") or None
541458

542-
def update_provider_info(self, *args, **kwargs):
543-
"""Update provider info for existing volumes.
544-
545-
This is called during service startup to sync our view of volumes
546-
with what's actually on the storage. The parent class has some
547-
weird argument handling, so we have to be defensive here.
548-
"""
549-
# Called during _sync_provider_info() in VolumeManager.
550-
# If not implemented, Cinder raises a TypeError during service startup.
551-
# Wrote this logic because it was registered with 3 and was called using 2 args
552-
# There is issue with in-built drivers calling logic
553-
if len(args) == 2:
554-
volumes, snapshots = args
555-
elif len(args) >= 3:
556-
_, volumes, snapshots = args[:3]
557-
else:
558-
raise TypeError(
559-
"update_provider_info() expects at least volumes and snapshots."
560-
)
561-
return {}, {}
562-
563-
def set_throttle(self):
564-
"""No-op throttle implementation to prevent AttributeError.
565-
566-
Some parts of Cinder expect this method to exist for rate limiting,
567-
but our driver doesn't implement throttling. This empty method
568-
prevents crashes when Cinder tries to call it.
569-
"""
570-
# Got AttributeError
571-
pass
572-
573459
def _get_flexvol_capacity_with_fallback(self, client, vol_name):
574460
"""Get FlexVol capacity with custom volume name to junction path mapping."""
575461
# TODO : find a API endpoint to fetch the junction path with svm and pool
@@ -981,6 +867,11 @@ def __init__(self, *args, **kwargs):
981867
super().__init__(*args, **kwargs)
982868
self.library = NetappDynamicLibrary(self.DRIVER_NAME, "NVMe", **kwargs)
983869

870+
@staticmethod
871+
def get_driver_options():
872+
"""All options this driver supports."""
873+
return [item for sublist in NETAPP_DYNAMIC_OPTS for item in sublist]
874+
984875
def do_setup(self, context):
985876
"""Setup the driver."""
986877
self.library.do_setup(context)
@@ -1029,10 +920,6 @@ def get_volume_stats(self, refresh=False):
1029920
"""Get volume stats."""
1030921
return self.library.get_volume_stats(refresh)
1031922

1032-
def update_provider_info(self, volumes, snapshots):
1033-
"""Update provider info."""
1034-
return self.library.update_provider_info(volumes, snapshots)
1035-
1036923
def create_export(self, context, volume, connector):
1037924
"""Create export for volume."""
1038925
return self.library.create_export(context, volume, connector)
@@ -1044,12 +931,3 @@ def ensure_export(self, context, volume):
1044931
def remove_export(self, context, volume):
1045932
"""Remove export for volume."""
1046933
return self.library.remove_export(context, volume)
1047-
1048-
1049-
# NOTES
1050-
# Namespace: Manually created because we skip standard do_setup()
1051-
# Pool: Custom svm#flexvol format to support multi-SVM
1052-
# Client: Runtime creation based on volume type metadata vs static config
1053-
# Metadata: volume type extra_specs vs cinder.conf
1054-
# Library Initialization: Lazy initialization during volume creation
1055-
# Pool Discovery: Multi-SVM aggregation vs single SVM

python/cinder-understack/cinder_understack/tests/test_dynamic_netapp_driver.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from cinder.tests.unit import test
66
from cinder.tests.unit.volume.drivers.netapp import fakes as na_fakes
7+
from cinder.volume.drivers.netapp.dataontap.nvme_library import NetAppNVMeStorageLibrary
78

89
from cinder_understack import dynamic_netapp_driver
910

@@ -24,7 +25,11 @@ def setUp(self):
2425

2526
def get_config_base(self):
2627
"""Get base configuration for testing."""
27-
return na_fakes.create_configuration()
28+
cfg = na_fakes.create_configuration()
29+
cfg.netapp_login = "fake_user"
30+
cfg.netapp_password = "fake_pass" # noqa: S105
31+
cfg.netapp_server_hostname = "127.0.0.1"
32+
return cfg
2833

2934
def test_driver_has_correct_attributes(self):
3035
"""Test that driver has expected attributes."""
@@ -37,10 +42,6 @@ def test_driver_has_library_instance(self):
3742

3843
def test_library_inherits_from_netapp_library(self):
3944
"""Test that library inherits from NetApp NVMe library."""
40-
from cinder.volume.drivers.netapp.dataontap.nvme_library import (
41-
NetAppNVMeStorageLibrary,
42-
)
43-
4445
self.assertIsInstance(self.library, NetAppNVMeStorageLibrary)
4546

4647
@mock.patch.object(dynamic_netapp_driver.NetappDynamicLibrary, "do_setup")

0 commit comments

Comments
 (0)