]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Add cinder support to resource volume
authorJeff Peeler <jpeeler@redhat.com>
Mon, 28 Jan 2013 20:24:54 +0000 (15:24 -0500)
committerJeff Peeler <jpeeler@redhat.com>
Wed, 6 Feb 2013 05:02:10 +0000 (00:02 -0500)
Fixes bug #1073164

Change-Id: I190067e5ea9334e336e6f105222905b1d48408fd
Signed-off-by: Jeff Peeler <jpeeler@redhat.com>
heat/engine/clients.py
heat/engine/resource.py
heat/engine/resources/volume.py
heat/tests/test_volume.py

index 7a42b788a150a572a7b4b387d8b618f690aa8e6d..b32992b0de4e8e4e10d6a05af594b54d247294cd 100644 (file)
@@ -32,6 +32,11 @@ try:
 except ImportError:
     quantumclient = None
     logger.info('quantumclient not available')
+try:
+    from cinderclient.v1 import client as cinderclient
+except ImportError:
+    cinderclient = None
+    logger.info('cinderclient not available')
 
 
 cloud_opts = [
@@ -53,6 +58,7 @@ class OpenStackClients(object):
         self._keystone = None
         self._swift = None
         self._quantum = None
+        self._cinder = None
 
     def keystone(self):
         if self._keystone:
@@ -173,6 +179,38 @@ class OpenStackClients(object):
 
         return self._quantum
 
+    def cinder(self):
+        if cinderclient is None:
+            return self.nova('volume')
+        if self._cinder:
+            return self._cinder
+
+        con = self.context
+        args = {
+            'project_id': con.tenant,
+            'auth_url': con.auth_url,
+            'service_type': 'volume',
+        }
+
+        if con.password is not None:
+            args['username'] = con.username
+            args['api_key'] = con.password
+        elif con.auth_token is not None:
+            args['username'] = con.service_user
+            args['api_key'] = con.service_password
+            args['project_id'] = con.service_tenant
+            args['proxy_token'] = con.auth_token
+            args['proxy_token_id'] = con.tenant_id
+        else:
+            logger.error("Cinder connection failed, "
+                         "no password or auth_token!")
+            return None
+        logger.debug('cinder args %s', args)
+
+        self._cinder = cinderclient.Client(**args)
+
+        return self._cinder
+
 
 if cfg.CONF.cloud_backend:
     cloud_backend_module = importutils.import_module(cfg.CONF.cloud_backend)
index e6a5ee60305c16a0565daaab5f12e32e0987b7ed..98b6ea74461dae3f297e7e66085972cd885915ac 100644 (file)
@@ -268,6 +268,9 @@ class Resource(object):
     def quantum(self):
         return self.stack.clients.quantum()
 
+    def cinder(self):
+        return self.stack.clients.cinder()
+
     def create(self):
         '''
         Create the resource. Subclasses should provide a handle_create() method
index 9af2236f1d7617de458b15aabe9835bebf218a7a..4d5b2f923bf445c152a92893daae584f7e7a62e2 100644 (file)
@@ -34,7 +34,7 @@ class Volume(resource.Resource):
         super(Volume, self).__init__(name, json_snippet, stack)
 
     def handle_create(self):
-        vol = self.nova('volume').volumes.create(
+        vol = self.cinder().volumes.create(
             self.properties['Size'],
             display_name=self.physical_resource_name(),
             display_description=self.physical_resource_name())
@@ -52,12 +52,13 @@ class Volume(resource.Resource):
 
     def handle_delete(self):
         if self.resource_id is not None:
-            vol = self.nova('volume').volumes.get(self.resource_id)
+            vol = self.cinder().volumes.get(self.resource_id)
+
             if vol.status == 'in-use':
                 logger.warn('cant delete volume when in-use')
                 raise exception.Error("Volume in use")
 
-            self.nova('volume').volumes.delete(self.resource_id)
+            self.cinder().volumes.delete(self.resource_id)
 
 
 class VolumeAttachment(resource.Resource):
@@ -77,12 +78,13 @@ class VolumeAttachment(resource.Resource):
         volume_id = self.properties['VolumeId']
         logger.warn('Attaching InstanceId %s VolumeId %s Device %s' %
                     (server_id, volume_id, self.properties['Device']))
-        volapi = self.nova().volumes
-        va = volapi.create_server_volume(server_id=server_id,
-                                         volume_id=volume_id,
-                                         device=self.properties['Device'])
+        va = self.nova().volumes.create_server_volume(
+            server_id=server_id,
+            volume_id=volume_id,
+            device=self.properties['Device'])
+
+        vol = self.cinder().volumes.get(va.id)
 
-        vol = self.nova('volume').volumes.get(va.id)
         while vol.status == 'available' or vol.status == 'attaching':
             eventlet.sleep(1)
             vol.get()
@@ -100,12 +102,11 @@ class VolumeAttachment(resource.Resource):
         logger.info('VolumeAttachment un-attaching %s %s' %
                     (server_id, volume_id))
 
-        volapi = self.nova().volumes
         try:
-            volapi.delete_server_volume(server_id,
-                                        volume_id)
+            vol = self.cinder().volumes.get(volume_id)
 
-            vol = self.nova('volume').volumes.get(volume_id)
+            self.nova().volumes.delete_server_volume(server_id,
+                                                     volume_id)
 
             logger.info('un-attaching %s, status %s' % (volume_id, vol.status))
             while vol.status == 'in-use':
@@ -113,11 +114,13 @@ class VolumeAttachment(resource.Resource):
                             (volume_id, vol.status))
                 eventlet.sleep(1)
                 try:
-                    volapi.delete_server_volume(server_id,
-                                                volume_id)
+                    self.nova().volumes.delete_server_volume(
+                        server_id,
+                        volume_id)
                 except Exception:
                     pass
                 vol.get()
+            logger.info('volume status of %s now %s' % (volume_id, vol.status))
         except clients.novaclient.exceptions.NotFound as e:
             logger.warning('Deleting VolumeAttachment %s %s - not found' %
                           (server_id, volume_id))
index b831f6b32daf6ecdd4aab921335c2368f5f1fd23..6f967862f1125ad811dcfb017a80b3ec740f550a 100644 (file)
@@ -34,7 +34,8 @@ class VolumeTest(unittest.TestCase):
     def setUp(self):
         self.m = mox.Mox()
         self.fc = fakes.FakeClient()
-        self.m.StubOutWithMock(vol.Volume, 'nova')
+        self.m.StubOutWithMock(vol.Volume, 'cinder')
+        self.m.StubOutWithMock(vol.VolumeAttachment, 'cinder')
         self.m.StubOutWithMock(vol.VolumeAttachment, 'nova')
         self.m.StubOutWithMock(self.fc.volumes, 'create')
         self.m.StubOutWithMock(self.fc.volumes, 'get')
@@ -90,7 +91,7 @@ class VolumeTest(unittest.TestCase):
         stack_name = 'test_volume_stack'
 
         # create script
-        vol.Volume.nova('volume').MultipleTimes().AndReturn(self.fc)
+        vol.Volume.cinder().MultipleTimes().AndReturn(self.fc)
         self.fc.volumes.create(
             u'1', display_description='%s.DataVolume' % stack_name,
             display_name='%s.DataVolume' % stack_name).AndReturn(fv)
@@ -124,7 +125,7 @@ class VolumeTest(unittest.TestCase):
         stack_name = 'test_volume_create_error_stack'
 
         # create script
-        vol.Volume.nova('volume').AndReturn(self.fc)
+        vol.Volume.cinder().AndReturn(self.fc)
         self.fc.volumes.create(
             u'1', display_description='%s.DataVolume' % stack_name,
             display_name='%s.DataVolume' % stack_name).AndReturn(fv)
@@ -149,14 +150,15 @@ class VolumeTest(unittest.TestCase):
         stack_name = 'test_volume_attach_error_stack'
 
         # volume create
-        vol.Volume.nova('volume').MultipleTimes().AndReturn(self.fc)
+        vol.Volume.cinder().MultipleTimes().AndReturn(self.fc)
         self.fc.volumes.create(
             u'1', display_description='%s.DataVolume' % stack_name,
             display_name='%s.DataVolume' % stack_name).AndReturn(fv)
 
         # create script
         vol.VolumeAttachment.nova().MultipleTimes().AndReturn(self.fc)
-        vol.VolumeAttachment.nova('volume').MultipleTimes().AndReturn(self.fc)
+        vol.VolumeAttachment.cinder().MultipleTimes().AndReturn(self.fc)
+
         eventlet.sleep(1).MultipleTimes().AndReturn(None)
         self.fc.volumes.create_server_volume(
             device=u'/dev/vdc',
@@ -185,14 +187,14 @@ class VolumeTest(unittest.TestCase):
         stack_name = 'test_volume_attach_stack'
 
         # volume create
-        vol.Volume.nova('volume').MultipleTimes().AndReturn(self.fc)
+        vol.Volume.cinder().MultipleTimes().AndReturn(self.fc)
         self.fc.volumes.create(
             u'1', display_description='%s.DataVolume' % stack_name,
             display_name='%s.DataVolume' % stack_name).AndReturn(fv)
 
         # create script
         vol.VolumeAttachment.nova().MultipleTimes().AndReturn(self.fc)
-        vol.VolumeAttachment.nova('volume').MultipleTimes().AndReturn(self.fc)
+        vol.VolumeAttachment.cinder().MultipleTimes().AndReturn(self.fc)
         eventlet.sleep(1).MultipleTimes().AndReturn(None)
         self.fc.volumes.create_server_volume(
             device=u'/dev/vdc',