From baa8626eac9c975b719c03274d42b54ce3de74fe Mon Sep 17 00:00:00 2001 From: Gorka Eguileor Date: Thu, 28 Sep 2017 15:52:45 +0200 Subject: [PATCH] Kaminario K2: Support duplicated FQDN in network The Kaminario K2 driver uses the FQDN of the node that is doing the attach as an unique identifier to map the volume. The problem is that the FQDN is not always unique, there are environments where the same FQDN can be found in different systems, and in those cases if both try to attach volumes the second system will fail. One example of this happening would be on a QA environment where you are creating VMs and they all have names like controller-0.localdomain and compute-0.localdomain. This patch adds a configuration option to the K2 driver called `unique_fqdn_network` to support these kind of environments. Closes-Bug: #1720147 Change-Id: I2099b804a2043078e50a5a9e14c1497861576f61 --- .../unit/volume/drivers/test_kaminario.py | 21 ++++++++++++++++++ .../drivers/kaminario/kaminario_common.py | 22 ++++++++++++++++--- .../k2-non-unique-fqdns-b62a269a26fd53d5.yaml | 6 +++++ 3 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 releasenotes/notes/k2-non-unique-fqdns-b62a269a26fd53d5.yaml diff --git a/cinder/tests/unit/volume/drivers/test_kaminario.py b/cinder/tests/unit/volume/drivers/test_kaminario.py index c20c98f7311..3e68ccff0ce 100644 --- a/cinder/tests/unit/volume/drivers/test_kaminario.py +++ b/cinder/tests/unit/volume/drivers/test_kaminario.py @@ -13,6 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. """Unit tests for kaminario driver.""" +import re + import mock from oslo_utils import units import time @@ -137,6 +139,7 @@ class TestKaminarioISCSI(test.TestCase): self.conf = mock.Mock(spec=configuration.Configuration) self.conf.kaminario_dedup_type_name = "dedup" self.conf.volume_dd_blocksize = 2 + self.conf.unique_fqdn_network = True def _setup_driver(self): self.driver = (kaminario_iscsi. @@ -529,6 +532,16 @@ class TestKaminarioISCSI(test.TestCase): 'test') self.assertIsNone(result) + def test_get_initiator_host_name(self): + result = self.driver.get_initiator_host_name(CONNECTOR) + self.assertEqual(CONNECTOR['host'], result) + + def test_get_initiator_host_name_unique(self): + self.driver.configuration.unique_fqdn_network = False + result = self.driver.get_initiator_host_name(CONNECTOR) + expected = re.sub('[:.]', '_', CONNECTOR['initiator'][::-1][:32]) + self.assertEqual(expected, result) + class TestKaminarioFC(TestKaminarioISCSI): @@ -555,3 +568,11 @@ class TestKaminarioFC(TestKaminarioISCSI): """Test terminate_connection.""" result = self.driver.terminate_connection(self.vol, CONNECTOR) self.assertIn('data', result) + + def test_get_initiator_host_name_unique(self): + connector = CONNECTOR.copy() + del connector['initiator'] + self.driver.configuration.unique_fqdn_network = False + result = self.driver.get_initiator_host_name(connector) + expected = re.sub('[:.]', '_', connector['wwnns'][0][::-1][:32]) + self.assertEqual(expected, result) diff --git a/cinder/volume/drivers/kaminario/kaminario_common.py b/cinder/volume/drivers/kaminario/kaminario_common.py index ae6cc67c1e7..0dac5db42f2 100644 --- a/cinder/volume/drivers/kaminario/kaminario_common.py +++ b/cinder/volume/drivers/kaminario/kaminario_common.py @@ -50,7 +50,16 @@ kaminario_opts = [ cfg.BoolOpt('auto_calc_max_oversubscription_ratio', default=False, help="K2 driver will calculate max_oversubscription_ratio " - "on setting this option as True.")] + "on setting this option as True."), + cfg.BoolOpt('unique_fqdn_network', + default=True, + help="Whether or not our private network has unique FQDN on " + "each initiator or not. For example networks with QA " + "systems usually have multiple servers/VMs with the same " + "FQDN. When true this will create host entries on K2 " + "using the FQDN, when false it will use the reversed " + "IQN/WWNN."), +] CONF = cfg.CONF CONF.register_opts(kaminario_opts, group=configuration.SHARED_CONF_GROUP) @@ -826,13 +835,20 @@ class KaminarioCinderDriver(cinder.volume.driver.ISCSIDriver): 'kaminario:replication': True} def get_initiator_host_name(self, connector): - """Return the initiator host name. + """Return the initiator host name or unique ID. + + Unique ID when configuration's unique_fqdn_network is false will be + the reversed IQN/WWPNS. Valid characters: 0-9, a-z, A-Z, '-', '_' All other characters are replaced with '_'. Total characters in initiator host name: 32 """ - return re.sub('[^0-9a-zA-Z-_]', '_', connector.get('host', ''))[:32] + name = connector.get('initiator', + connector.get('wwnns', [''])[0])[::-1] + if self.configuration.unique_fqdn_network: + name = connector.get('host', name) + return re.sub('[^0-9a-zA-Z-_]', '_', name[:32]) def get_volume_group_name(self, vid): """Return the volume group name.""" diff --git a/releasenotes/notes/k2-non-unique-fqdns-b62a269a26fd53d5.yaml b/releasenotes/notes/k2-non-unique-fqdns-b62a269a26fd53d5.yaml new file mode 100644 index 00000000000..76c3db28ba1 --- /dev/null +++ b/releasenotes/notes/k2-non-unique-fqdns-b62a269a26fd53d5.yaml @@ -0,0 +1,6 @@ +--- +issues: + - | + Kaminario K2 now supports networks with duplicated FQDNs via configuration + option `unique_fqdn_network` so attaching in these networks will work + (bug #1720147).