Skip to content

Instantly share code, notes, and snippets.

@hemna
Created May 22, 2017 14:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hemna/be954564d9dd0cb9671ce3a10147a727 to your computer and use it in GitHub Desktop.
Save hemna/be954564d9dd0cb9671ce3a10147a727 to your computer and use it in GitHub Desktop.
diff --git a/brick_cinderclient_ext/__init__.py b/brick_cinderclient_ext/__init__.py
index 0d1253e..5e658a0 100644
--- a/brick_cinderclient_ext/__init__.py
+++ b/brick_cinderclient_ext/__init__.py
@@ -19,6 +19,7 @@ from __future__ import print_function
import json
import socket
+import cinderclient
import pbr.version
from brick_cinderclient_ext import brick_utils
diff --git a/brick_cinderclient_ext/client.py b/brick_cinderclient_ext/client.py
index 64b9f0a..9cfdddd 100644
--- a/brick_cinderclient_ext/client.py
+++ b/brick_cinderclient_ext/client.py
@@ -12,9 +12,14 @@
from __future__ import print_function
+import cinderclient
+from cinderclient import api_versions
from cinderclient import exceptions
+
+from oslo_utils import uuidutils
from os_brick.initiator import connector
from oslo_concurrency import processutils
+from pbr import version as pbr_version
from brick_cinderclient_ext import brick_utils
from brick_cinderclient_ext import volume_actions as actions
@@ -28,14 +33,30 @@ class Client(object):
1.0.0 - Initial version
1.1.0 - Query volume paths implementation
1.2.0 - Add --nic attribute to get-connector
+ 1.3.0 - Added new v3 attach/detach workflow support
"""
- version = '1.2.0'
+ version = '1.3.0'
+
+ # Can we use the new attach/detach workflow?
+ _use_v3_attach = False
def __init__(self, volumes_client=None):
self.volumes_client = volumes_client
+ # Test to see if we have a version of the cinderclient
+ # that can do the new volume attach/detach API
+ version_want = pbr_version.SemanticVersion(major=2)
+ current_version = cinderclient.version_info.semantic_version()
+ if (self.volumes_client.version == "3.0" and
+ current_version >= version_want):
+ # We have a recent enough client to test the microversion we need.
+ required_version = api_versions.APIVersion("3.27")
+ if self.volumes_client.api_version.matches(required_version):
+ # we can use the new attach/detach API
+ self._use_v3_attach = True
+
def _brick_get_connector(self, protocol, driver=None,
execute=processutils.execute,
use_multipath=False,
@@ -67,6 +88,27 @@ class Client(object):
def attach(self, volume_id, hostname, mountpoint=None, mode='rw',
multipath=False, enforce_multipath=False, nic=None):
+ """Main entry point for trying to attach a volume.
+
+ If the cinderclient has a recent version that can do the new attach
+ workflow, lets try that. Otherwise we revert to the older attach
+ workflow.
+ """
+ if self._use_v3_attach:
+ print("use _attach_v3")
+ return self._attach_v3(volume_id, hostname, mountpoint=mountpoint,
+ mode=mode, multipath=multipath,
+ enforce_multipath=enforce_multipath,
+ nic=nic)
+ else:
+ print("use _attach_v2")
+ return self._attach_v2(volume_id, hostname, mountpoint=mountpoint,
+ mode=mode, multipath=multipath,
+ enforce_multipath=enforce_multipath,
+ nic=nic)
+
+ def _attach_v2(self, volume_id, hostname, mountpoint=None, mode='rw',
+ multipath=False, enforce_multipath=False, nic=None):
# Reserve volume before attachment
with actions.Reserve(self.volumes_client, volume_id) as cmd:
cmd.reserve()
@@ -76,6 +118,9 @@ class Client(object):
connection = cmd.initialize(self, multipath, enforce_multipath,
nic)
+ import pprint
+ pprint.pprint(connection)
+
with actions.VerifyProtocol(self.volumes_client, volume_id) as cmd:
cmd.verify(connection['driver_volume_type'])
@@ -85,6 +130,49 @@ class Client(object):
device_info = cmd.connect(brick_connector,
connection['data'],
mountpoint, mode, hostname)
+ pprint.pprint(device_info)
+ return device_info
+
+ def _attach_v3(self, volume_id, hostname, mountpoint=None, mode='rw',
+ multipath=False, enforce_multipath=False, nic=None):
+ """Attempt to use the v3 API for attach workflow.
+
+ If the cinder API microversion is good enough, we will use the new
+ attach workflow, otherwise we resort back to the old workflow.
+ """
+ # We can use the new attach/detach workflow
+ print("We can use the new attach/detach workflow")
+ connector_properties = self.get_connector(
+ multipath=multipath,
+ enforce_multipath=enforce_multipath, nic=nic)
+
+ instance_id = uuidutils.generate_uuid()
+
+ print("call create")
+ print(volume_id)
+ print(connector_properties)
+ print(instance_id)
+ print("call create")
+ info = self.volumes_client.attachments.create(
+ volume_id, connector_properties, instance_id)
+ import pprint
+ pprint.pprint(info)
+
+ connection = info['connection_info']
+ print(connection['driver_volume_type'])
+
+ with actions.VerifyProtocol(self.volumes_client, volume_id) as cmd:
+ cmd.verify(connection['driver_volume_type'])
+
+ with actions.ConnectVolume(self.volumes_client, volume_id) as cmd:
+ brick_connector = self._brick_get_connector(
+ connection['driver_volume_type'], do_local_attach=True)
+ print("got brick connector object")
+ device_info = cmd.connect(brick_connector,
+ connection,
+ mountpoint, mode, hostname)
+ print("got device info")
+ pprint.pprint(device_info)
return device_info
def detach(self, volume_id, attachment_uuid=None, multipath=False,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment