Hello community,

here is the log from the commit of package python-cinderclient for 
openSUSE:Factory checked in at 2013-07-18 17:33:54
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-cinderclient (Old)
 and      /work/SRC/openSUSE:Factory/.python-cinderclient.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-cinderclient"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-cinderclient/python-cinderclient.changes  
2013-07-10 17:30:36.000000000 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-cinderclient.new/python-cinderclient.changes 
    2013-07-18 18:08:30.000000000 +0200
@@ -1,0 +2,14 @@
+Tue Jul 16 00:21:35 UTC 2013 - [email protected]
+
+- Update to version 1.0.4.62:
+  + Update to latest openstack/requirements.
+
+-------------------------------------------------------------------
+Sat Jul 13 23:35:16 UTC 2013 - [email protected]
+
+- Update to version 1.0.4.61:
+  + Fix wrong method call for extend subcommand
+  + Sync install_venv_common from oslo
+  + Implement ability to extend volume for v1.
+
+-------------------------------------------------------------------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-cinderclient.spec ++++++
--- /var/tmp/diff_new_pack.oqUh29/_old  2013-07-18 18:08:31.000000000 +0200
+++ /var/tmp/diff_new_pack.oqUh29/_new  2013-07-18 18:08:31.000000000 +0200
@@ -19,7 +19,7 @@
 %define component cinderclient
 
 Name:           python-%{component}
-Version:        1.0.4.56
+Version:        1.0.4.66
 Release:        0
 Summary:        Openstack Block Storage (Cinder) API Client
 License:        Apache-2.0
@@ -84,7 +84,7 @@
 This package contains testsuite files for %{name}.
 
 %prep
-%setup -q -n python-cinderclient-1.0.4.56.ga3985ee
+%setup -q -n python-cinderclient-1.0.4.66.g509a54b
 %openstack_cleanup_prep
 echo %{version} > cinderclient/versioninfo
 

++++++ python-cinderclient-master.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-cinderclient-1.0.4.56.ga3985ee/AUTHORS 
new/python-cinderclient-1.0.4.66.g509a54b/AUTHORS
--- old/python-cinderclient-1.0.4.56.ga3985ee/AUTHORS   2013-07-05 
18:45:44.000000000 +0200
+++ new/python-cinderclient-1.0.4.66.g509a54b/AUTHORS   2013-07-17 
07:14:04.000000000 +0200
@@ -29,12 +29,14 @@
 Josh Durgin <[email protected]>
 Liam Kelleher <[email protected]>
 Mark McLoughlin <[email protected]>
+Mathieu Gagné <[email protected]>
 Mike Perez <[email protected]>
 Monty Taylor <[email protected]>
 Nathan Reller <[email protected]>
 Nicolas Simonds <[email protected]>
 Nikolaj Starodubtsev <[email protected]>
 Ollie Leahy <[email protected]>
+Qiu Yu <[email protected]>
 Rongze Zhu <[email protected]>
 Stephen Mulcahy <[email protected]>
 Vasyl Khomenko <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-cinderclient-1.0.4.56.ga3985ee/ChangeLog 
new/python-cinderclient-1.0.4.66.g509a54b/ChangeLog
--- old/python-cinderclient-1.0.4.56.ga3985ee/ChangeLog 2013-07-05 
18:45:44.000000000 +0200
+++ new/python-cinderclient-1.0.4.66.g509a54b/ChangeLog 2013-07-17 
07:14:04.000000000 +0200
@@ -1,3 +1,103 @@
+commit 509a54bd37f5b637e925735c14873e254d02fb70
+Merge: 61f39d8 627b616
+Author: Jenkins <[email protected]>
+Date:   Wed Jul 17 05:02:07 2013 +0000
+
+    Merge "Add os-services extension support"
+
+commit 61f39d883670342a4f15cba4e0527695100c04fa
+Merge: d720884 2b0f086
+Author: Jenkins <[email protected]>
+Date:   Tue Jul 16 04:31:42 2013 +0000
+
+    Merge "Update index.rst"
+
+commit d7208847efb5bb0df1d1f3340681915d867847b9
+Author: John Griffith <[email protected]>
+Date:   Sun Jul 14 19:47:58 2013 -0600
+
+    Update to latest openstack/requirements.
+    
+    Fixes bug: 1200214
+    
+    Change-Id: I0ff8a76eb5d5a99892a270909c68207858e1bc8b
+
+commit 627b616227badd893ff2d8d7addf162d605b2299
+Author: Qiu Yu <[email protected]>
+Date:   Sun Jul 14 23:18:22 2013 +0800
+
+    Add os-services extension support
+    
+    Implement client bindings for Cinder os-services API extension, so
+    client would be able to list services, enable or disable particular
+    services.
+    
+    Usage:
+    cinder service-list [--host <hostname>] [--binary <binary>]
+    cinder service-enable <hostname> <binary>
+    cinder service-disable <hostname> <binary>
+    
+    This change is depended on following change at Cinder side
+    I7f3fa889294ca6caebdf46b8689345bcac1cdf54
+    
+    Implements blueprint os-services-extension
+    
+    Change-Id: I4a53fd545ed3b446441302d00a429168a996a34a
+
+commit 2b0f086e7b4db4daa6e096eeb2adc96b1d4884e3
+Author: John Griffith <[email protected]>
+Date:   Sat Jul 13 14:46:57 2013 -0600
+
+    Update index.rst
+    
+    Update the release info in index.rst to get ready
+    to push new version to PyPi.
+    
+    Change-Id: Id3b4b6bfd7374b74bf8566dc133ea66f5d2f74ed
+
+commit aef613f9949ae01a92474e82b5710edb23e15cb4
+Merge: 0990812 d702d54
+Author: Jenkins <[email protected]>
+Date:   Sat Jul 13 19:09:48 2013 +0000
+
+    Merge "Implement ability to extend volume for v1."
+
+commit 099081298ff5ce17b357b7e97728c3eb2094892b
+Merge: 1a15caf a26044f
+Author: Jenkins <[email protected]>
+Date:   Sat Jul 13 19:00:20 2013 +0000
+
+    Merge "Sync install_venv_common from oslo"
+
+commit 1a15caff9481e230ba7c47d9c1f33a99f423e15b
+Author: Mathieu Gagné <[email protected]>
+Date:   Mon Jul 8 19:19:10 2013 -0400
+
+    Fix wrong method call for extend subcommand
+    
+    Ensure extend is called instead of extend_volume
+    as the latter doesn't exist.
+    
+    Change-Id: I5a4ce5904dc73586a124f7bddebc8ffd30841980
+
+commit d702d5443f899d0011532cf13320a793e396983b
+Author: Mathieu Gagné <[email protected]>
+Date:   Mon Jul 8 17:59:59 2013 -0400
+
+    Implement ability to extend volume for v1.
+    
+    Backport implementation from v2 to v1.
+    
+    Change-Id: Ibb2334859e937a37481308580b072daef068f511
+
+commit a26044f6d700868b4715cf0e8e20ce380acab8db
+Author: Monty Taylor <[email protected]>
+Date:   Fri Jul 5 22:52:52 2013 -0400
+
+    Sync install_venv_common from oslo
+    
+    Change-Id: I1649a8e777baf288b3aa4c2c29e2fe532dfe93be
+
 commit a3985eeb63506b48e2d71143b4b9060442d0bc61
 Merge: a7a48b8 ee9f035
 Author: Jenkins <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-cinderclient-1.0.4.56.ga3985ee/PKG-INFO 
new/python-cinderclient-1.0.4.66.g509a54b/PKG-INFO
--- old/python-cinderclient-1.0.4.56.ga3985ee/PKG-INFO  2013-07-05 
18:45:46.000000000 +0200
+++ new/python-cinderclient-1.0.4.66.g509a54b/PKG-INFO  2013-07-17 
07:14:06.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: python-cinderclient
-Version: 1.0.4.56.ga3985ee
+Version: 1.0.4.66.g509a54b
 Summary: OpenStack Block Storage API Client Library
 Home-page: http://www.openstack.org/
 Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/tests/v1/fakes.py 
new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/tests/v1/fakes.py
--- old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/tests/v1/fakes.py    
2013-07-05 18:45:13.000000000 +0200
+++ new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/tests/v1/fakes.py    
2013-07-17 07:13:30.000000000 +0200
@@ -13,6 +13,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from datetime import datetime
+
 try:
     import urlparse
 except ImportError:
@@ -152,6 +154,10 @@
     }
 
 
+def _stub_extend(id, new_size):
+    return {'volume_id': '712f4980-5ac1-41e5-9383-390aa7c9f58b'}
+
+
 class FakeClient(fakes.FakeClient, client.Client):
 
     def __init__(self, *args, **kwargs):
@@ -294,6 +300,8 @@
             assert body[action] is None
         elif action == 'os-reset_status':
             assert 'status' in body[action]
+        elif action == 'os-extend':
+            assert body[action].keys() == ['new_size']
         else:
             raise AssertionError("Unexpected action: %s" % action)
         return (resp, {}, _body)
@@ -504,3 +512,49 @@
         transfer1 = '5678'
         return (200, {},
                 {'transfer': _stub_transfer(transfer1, base_uri, tenant_id)})
+
+    #
+    # Services
+    #
+    def get_os_services(self, **kw):
+        host = kw.get('host', None)
+        binary = kw.get('binary', None)
+        services = [
+            {
+                'binary': 'cinder-volume',
+                'host': 'host1',
+                'zone': 'cinder',
+                'status': 'enabled',
+                'state': 'up',
+                'updated_at': datetime(2012, 10, 29, 13, 42, 2)
+            },
+            {
+                'binary': 'cinder-volume',
+                'host': 'host2',
+                'zone': 'cinder',
+                'status': 'disabled',
+                'state': 'down',
+                'updated_at': datetime(2012, 9, 18, 8, 3, 38)
+            },
+            {
+                'binary': 'cinder-scheduler',
+                'host': 'host2',
+                'zone': 'cinder',
+                'status': 'disabled',
+                'state': 'down',
+                'updated_at': datetime(2012, 9, 18, 8, 3, 38)
+            },
+        ]
+        if host:
+            services = filter(lambda i: i['host'] == host, services)
+        if binary:
+            services = filter(lambda i: i['binary'] == binary, services)
+        return (200, {}, {'services': services})
+
+    def put_os_services_enable(self, body, **kw):
+        return (200, {}, {'host': body['host'], 'binary': body['binary'],
+                'status': 'disabled'})
+
+    def put_os_services_disable(self, body, **kw):
+        return (200, {}, {'host': body['host'], 'binary': body['binary'],
+                'status': 'enabled'})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/tests/v1/test_services.py
 
new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/tests/v1/test_services.py
--- 
old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/tests/v1/test_services.py
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/tests/v1/test_services.py
    2013-07-17 07:13:30.000000000 +0200
@@ -0,0 +1,62 @@
+# Copyright 2013 OpenStack LLC.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from cinderclient.tests import utils
+from cinderclient.tests.v1 import fakes
+from cinderclient.v1 import services
+
+
+cs = fakes.FakeClient()
+
+
+class ServicesTest(utils.TestCase):
+
+    def test_list_services(self):
+        svs = cs.services.list()
+        cs.assert_called('GET', '/os-services')
+        self.assertEqual(len(svs), 3)
+        [self.assertTrue(isinstance(s, services.Service)) for s in svs]
+
+    def test_list_services_with_hostname(self):
+        svs = cs.services.list(host='host2')
+        cs.assert_called('GET', '/os-services?host=host2')
+        self.assertEqual(len(svs), 2)
+        [self.assertTrue(isinstance(s, services.Service)) for s in svs]
+        [self.assertEqual(s.host, 'host2') for s in svs]
+
+    def test_list_services_with_binary(self):
+        svs = cs.services.list(binary='cinder-volume')
+        cs.assert_called('GET', '/os-services?binary=cinder-volume')
+        self.assertEqual(len(svs), 2)
+        [self.assertTrue(isinstance(s, services.Service)) for s in svs]
+        [self.assertEqual(s.binary, 'cinder-volume') for s in svs]
+
+    def test_list_services_with_host_binary(self):
+        svs = cs.services.list('host2', 'cinder-volume')
+        cs.assert_called('GET', '/os-services?host=host2&binary=cinder-volume')
+        self.assertEqual(len(svs), 1)
+        [self.assertTrue(isinstance(s, services.Service)) for s in svs]
+        [self.assertEqual(s.host, 'host2') for s in svs]
+        [self.assertEqual(s.binary, 'cinder-volume') for s in svs]
+
+    def test_services_enable(self):
+        cs.services.enable('host1', 'cinder-volume')
+        values = {"host": "host1", 'binary': 'cinder-volume'}
+        cs.assert_called('PUT', '/os-services/enable', values)
+
+    def test_services_disable(self):
+        cs.services.disable('host1', 'cinder-volume')
+        values = {"host": "host1", 'binary': 'cinder-volume'}
+        cs.assert_called('PUT', '/os-services/disable', values)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/tests/v1/test_volumes.py 
new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/tests/v1/test_volumes.py
--- 
old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/tests/v1/test_volumes.py 
    2013-07-05 18:45:11.000000000 +0200
+++ 
new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/tests/v1/test_volumes.py 
    2013-07-17 07:13:30.000000000 +0200
@@ -69,3 +69,8 @@
         keys = ['key1']
         cs.volumes.delete_metadata(1234, keys)
         cs.assert_called('DELETE', '/volumes/1234/metadata/key1')
+
+    def test_extend(self):
+        v = cs.volumes.get('1234')
+        cs.volumes.extend(v, 2)
+        cs.assert_called('POST', '/volumes/1234/action')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/tests/v2/fakes.py 
new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/tests/v2/fakes.py
--- old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/tests/v2/fakes.py    
2013-07-05 18:45:13.000000000 +0200
+++ new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/tests/v2/fakes.py    
2013-07-17 07:13:30.000000000 +0200
@@ -12,6 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from datetime import datetime
+
 try:
     import urlparse
 except ImportError:
@@ -517,3 +519,49 @@
         transfer1 = '5678'
         return (200, {},
                 {'transfer': _stub_transfer(transfer1, base_uri, tenant_id)})
+
+    #
+    # Services
+    #
+    def get_os_services(self, **kw):
+        host = kw.get('host', None)
+        binary = kw.get('binary', None)
+        services = [
+            {
+                'binary': 'cinder-volume',
+                'host': 'host1',
+                'zone': 'cinder',
+                'status': 'enabled',
+                'state': 'up',
+                'updated_at': datetime(2012, 10, 29, 13, 42, 2)
+            },
+            {
+                'binary': 'cinder-volume',
+                'host': 'host2',
+                'zone': 'cinder',
+                'status': 'disabled',
+                'state': 'down',
+                'updated_at': datetime(2012, 9, 18, 8, 3, 38)
+            },
+            {
+                'binary': 'cinder-scheduler',
+                'host': 'host2',
+                'zone': 'cinder',
+                'status': 'disabled',
+                'state': 'down',
+                'updated_at': datetime(2012, 9, 18, 8, 3, 38)
+            },
+        ]
+        if host:
+            services = filter(lambda i: i['host'] == host, services)
+        if binary:
+            services = filter(lambda i: i['binary'] == binary, services)
+        return (200, {}, {'services': services})
+
+    def put_os_services_enable(self, body, **kw):
+        return (200, {}, {'host': body['host'], 'binary': body['binary'],
+                'status': 'disabled'})
+
+    def put_os_services_disable(self, body, **kw):
+        return (200, {}, {'host': body['host'], 'binary': body['binary'],
+                'status': 'enabled'})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/tests/v2/test_services.py
 
new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/tests/v2/test_services.py
--- 
old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/tests/v2/test_services.py
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/tests/v2/test_services.py
    2013-07-17 07:13:30.000000000 +0200
@@ -0,0 +1,62 @@
+# Copyright 2013 OpenStack LLC.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from cinderclient.tests import utils
+from cinderclient.tests.v2 import fakes
+from cinderclient.v2 import services
+
+
+cs = fakes.FakeClient()
+
+
+class ServicesTest(utils.TestCase):
+
+    def test_list_services(self):
+        svs = cs.services.list()
+        cs.assert_called('GET', '/os-services')
+        self.assertEqual(len(svs), 3)
+        [self.assertTrue(isinstance(s, services.Service)) for s in svs]
+
+    def test_list_services_with_hostname(self):
+        svs = cs.services.list(host='host2')
+        cs.assert_called('GET', '/os-services?host=host2')
+        self.assertEqual(len(svs), 2)
+        [self.assertTrue(isinstance(s, services.Service)) for s in svs]
+        [self.assertEqual(s.host, 'host2') for s in svs]
+
+    def test_list_services_with_binary(self):
+        svs = cs.services.list(binary='cinder-volume')
+        cs.assert_called('GET', '/os-services?binary=cinder-volume')
+        self.assertEqual(len(svs), 2)
+        [self.assertTrue(isinstance(s, services.Service)) for s in svs]
+        [self.assertEqual(s.binary, 'cinder-volume') for s in svs]
+
+    def test_list_services_with_host_binary(self):
+        svs = cs.services.list('host2', 'cinder-volume')
+        cs.assert_called('GET', '/os-services?host=host2&binary=cinder-volume')
+        self.assertEqual(len(svs), 1)
+        [self.assertTrue(isinstance(s, services.Service)) for s in svs]
+        [self.assertEqual(s.host, 'host2') for s in svs]
+        [self.assertEqual(s.binary, 'cinder-volume') for s in svs]
+
+    def test_services_enable(self):
+        cs.services.enable('host1', 'cinder-volume')
+        values = {"host": "host1", 'binary': 'cinder-volume'}
+        cs.assert_called('PUT', '/os-services/enable', values)
+
+    def test_services_disable(self):
+        cs.services.disable('host1', 'cinder-volume')
+        values = {"host": "host1", 'binary': 'cinder-volume'}
+        cs.assert_called('PUT', '/os-services/disable', values)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/v1/client.py 
new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/v1/client.py
--- old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/v1/client.py 
2013-07-05 18:45:13.000000000 +0200
+++ new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/v1/client.py 
2013-07-17 07:13:30.000000000 +0200
@@ -17,6 +17,7 @@
 from cinderclient.v1 import limits
 from cinderclient.v1 import quota_classes
 from cinderclient.v1 import quotas
+from cinderclient.v1 import services
 from cinderclient.v1 import volumes
 from cinderclient.v1 import volume_snapshots
 from cinderclient.v1 import volume_types
@@ -62,6 +63,7 @@
         self.backups = volume_backups.VolumeBackupManager(self)
         self.restores = volume_backups_restore.VolumeBackupRestoreManager(self)
         self.transfers = volume_transfers.VolumeTransferManager(self)
+        self.services = services.ServiceManager(self)
 
         # Add in any extensions...
         if extensions:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/v1/services.py 
new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/v1/services.py
--- old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/v1/services.py       
1970-01-01 01:00:00.000000000 +0100
+++ new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/v1/services.py       
2013-07-17 07:13:30.000000000 +0200
@@ -0,0 +1,56 @@
+# Copyright 2013 OpenStack LLC.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+"""
+service interface
+"""
+from cinderclient import base
+
+
+class Service(base.Resource):
+
+    def __repr__(self):
+        return "<Service: %s>" % self.service
+
+
+class ServiceManager(base.ManagerWithFind):
+    resource_class = Service
+
+    def list(self, host=None, binary=None):
+        """
+        Describes service list for host.
+
+        :param host: destination host name.
+        :param binary: service binary.
+        """
+        url = "/os-services"
+        filters = []
+        if host:
+            filters.append("host=%s" % host)
+        if binary:
+            filters.append("binary=%s" % binary)
+        if filters:
+            url = "%s?%s" % (url, "&".join(filters))
+        return self._list(url, "services")
+
+    def enable(self, host, binary):
+        """Enable the service specified by hostname and binary."""
+        body = {"host": host, "binary": binary}
+        self._update("/os-services/enable", body)
+
+    def disable(self, host, binary):
+        """Enable the service specified by hostname and binary."""
+        body = {"host": host, "binary": binary}
+        self._update("/os-services/disable", body)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/v1/shell.py 
new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/v1/shell.py
--- old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/v1/shell.py  
2013-07-05 18:45:13.000000000 +0200
+++ new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/v1/shell.py  
2013-07-17 07:13:30.000000000 +0200
@@ -819,3 +819,43 @@
         info.pop('links')
 
     utils.print_dict(info)
+
+
[email protected]('volume', metavar='<volume>', help='ID of the volume to extend.')
[email protected]('new_size',
+           metavar='<new-size>',
+           type=int,
+           help='New size of volume in GB')
[email protected]_type('volume')
+def do_extend(cs, args):
+    """Attempt to extend the size of an existing volume."""
+    volume = _find_volume(cs, args.volume)
+    cs.volumes.extend(volume, args.new_size)
+
+
[email protected]('--host', metavar='<hostname>', default=None,
+           help='Name of host.')
[email protected]('--binary', metavar='<binary>', default=None,
+           help='Service binary.')
[email protected]_type('volume')
+def do_service_list(cs, args):
+    """List all the services. Filter by host & service binary."""
+    result = cs.services.list(host=args.host, binary=args.binary)
+    columns = ["Binary", "Host", "Zone", "Status", "State", "Updated_at"]
+    utils.print_list(result, columns)
+
+
[email protected]('host', metavar='<hostname>', help='Name of host.')
[email protected]('binary', metavar='<binary>', help='Service binary.')
[email protected]_type('volume')
+def do_service_enable(cs, args):
+    """Enable the service."""
+    cs.services.enable(args.host, args.binary)
+
+
[email protected]('host', metavar='<hostname>', help='Name of host.')
[email protected]('binary', metavar='<binary>', help='Service binary.')
[email protected]_type('volume')
+def do_service_disable(cs, args):
+    """Disable the service."""
+    cs.services.disable(args.host, args.binary)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/v1/volumes.py 
new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/v1/volumes.py
--- old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/v1/volumes.py        
2013-07-05 18:45:13.000000000 +0200
+++ new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/v1/volumes.py        
2013-07-17 07:13:30.000000000 +0200
@@ -105,6 +105,15 @@
         """Update the volume with the provided state."""
         self.manager.reset_state(self, state)
 
+    def extend(self, volume, new_size):
+        """Extend the size of the specified volume.
+
+        :param volume: The UUID of the volume to extend
+        :param new_size: The desired size to extend volume to.
+        """
+
+        self.manager.extend(self, volume, new_size)
+
 
 class VolumeManager(base.ManagerWithFind):
     """
@@ -338,3 +347,8 @@
     def reset_state(self, volume, state):
         """Update the provided volume with the provided state."""
         return self._action('os-reset_status', volume, {'status': state})
+
+    def extend(self, volume, new_size):
+        return self._action('os-extend',
+                            base.getid(volume),
+                            {'new_size': new_size})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/v2/client.py 
new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/v2/client.py
--- old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/v2/client.py 
2013-07-05 18:45:13.000000000 +0200
+++ new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/v2/client.py 
2013-07-17 07:13:30.000000000 +0200
@@ -17,6 +17,7 @@
 from cinderclient.v2 import limits
 from cinderclient.v2 import quota_classes
 from cinderclient.v2 import quotas
+from cinderclient.v2 import services
 from cinderclient.v2 import volumes
 from cinderclient.v2 import volume_snapshots
 from cinderclient.v2 import volume_types
@@ -60,6 +61,7 @@
         self.backups = volume_backups.VolumeBackupManager(self)
         self.restores = volume_backups_restore.VolumeBackupRestoreManager(self)
         self.transfers = volume_transfers.VolumeTransferManager(self)
+        self.services = services.ServiceManager(self)
 
         # Add in any extensions...
         if extensions:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/v2/services.py 
new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/v2/services.py
--- old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/v2/services.py       
1970-01-01 01:00:00.000000000 +0100
+++ new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/v2/services.py       
2013-07-17 07:13:30.000000000 +0200
@@ -0,0 +1,56 @@
+# Copyright 2013 OpenStack LLC.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+"""
+service interface
+"""
+from cinderclient import base
+
+
+class Service(base.Resource):
+
+    def __repr__(self):
+        return "<Service: %s>" % self.service
+
+
+class ServiceManager(base.ManagerWithFind):
+    resource_class = Service
+
+    def list(self, host=None, binary=None):
+        """
+        Describes service list for host.
+
+        :param host: destination host name.
+        :param binary: service binary.
+        """
+        url = "/os-services"
+        filters = []
+        if host:
+            filters.append("host=%s" % host)
+        if binary:
+            filters.append("binary=%s" % binary)
+        if filters:
+            url = "%s?%s" % (url, "&".join(filters))
+        return self._list(url, "services")
+
+    def enable(self, host, binary):
+        """Enable the service specified by hostname and binary."""
+        body = {"host": host, "binary": binary}
+        self._update("/os-services/enable", body)
+
+    def disable(self, host, binary):
+        """Enable the service specified by hostname and binary."""
+        body = {"host": host, "binary": binary}
+        self._update("/os-services/disable", body)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/v2/shell.py 
new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/v2/shell.py
--- old/python-cinderclient-1.0.4.56.ga3985ee/cinderclient/v2/shell.py  
2013-07-05 18:45:13.000000000 +0200
+++ new/python-cinderclient-1.0.4.66.g509a54b/cinderclient/v2/shell.py  
2013-07-17 07:13:30.000000000 +0200
@@ -915,4 +915,32 @@
 def do_extend(cs, args):
     """Attempt to extend the size of an existing volume."""
     volume = _find_volume(cs, args.volume)
-    cs.volumes.extend_volume(volume, args.new_size)
+    cs.volumes.extend(volume, args.new_size)
+
+
[email protected]('--host', metavar='<hostname>', default=None,
+           help='Name of host.')
[email protected]('--binary', metavar='<binary>', default=None,
+           help='Service binary.')
[email protected]_type('volume')
+def do_service_list(cs, args):
+    """List all the services. Filter by host & service binary."""
+    result = cs.services.list(host=args.host, binary=args.binary)
+    columns = ["Binary", "Host", "Zone", "Status", "State", "Updated_at"]
+    utils.print_list(result, columns)
+
+
[email protected]('host', metavar='<hostname>', help='Name of host.')
[email protected]('binary', metavar='<binary>', help='Service binary.')
[email protected]_type('volume')
+def do_service_enable(cs, args):
+    """Enable the service."""
+    cs.services.enable(args.host, args.binary)
+
+
[email protected]('host', metavar='<hostname>', help='Name of host.')
[email protected]('binary', metavar='<binary>', help='Service binary.')
[email protected]_type('volume')
+def do_service_disable(cs, args):
+    """Disable the service."""
+    cs.services.disable(args.host, args.binary)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/doc/source/index.rst 
new/python-cinderclient-1.0.4.66.g509a54b/doc/source/index.rst
--- old/python-cinderclient-1.0.4.56.ga3985ee/doc/source/index.rst      
2013-07-05 18:45:11.000000000 +0200
+++ new/python-cinderclient-1.0.4.66.g509a54b/doc/source/index.rst      
2013-07-17 07:13:30.000000000 +0200
@@ -27,6 +27,23 @@
 
 Release Notes
 =============
+1.0.5
+-----
+* Add support for scheduler-hints
+* Add support to extend volumes
+* Add support to reset state on volumes and snapshots
+* Add snapshot support for quota class
+
+.. _1190853: http://bugs.launchpad.net/python-cinderclient/+bug/1190853
+.. _1190731: http://bugs.launchpad.net/python-cinderclient/+bug/1190731
+.. _1169455: http://bugs.launchpad.net/python-cinderclient/+bug/1169455
+.. _1188452: http://bugs.launchpad.net/python-cinderclient/+bug/1188452
+.. _1180393: http://bugs.launchpad.net/python-cinderclient/+bug/1180393
+.. _1182678: http://bugs.launchpad.net/python-cinderclient/+bug/1182678
+.. _1179008: http://bugs.launchpad.net/python-cinderclient/+bug/1179008
+.. _1180059: http://bugs.launchpad.net/python-cinderclient/+bug/1180059
+.. _1170565: http://bugs.launchpad.net/python-cinderclient/+bug/1170565
+
 1.0.4
 -----
 * Added suport for backup-service commands
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/openstack-common.conf 
new/python-cinderclient-1.0.4.66.g509a54b/openstack-common.conf
--- old/python-cinderclient-1.0.4.56.ga3985ee/openstack-common.conf     
2013-07-05 18:45:13.000000000 +0200
+++ new/python-cinderclient-1.0.4.66.g509a54b/openstack-common.conf     
2013-07-17 07:13:30.000000000 +0200
@@ -1,7 +1,9 @@
 [DEFAULT]
 
 # The list of modules to copy from openstack-common
-modules=apiclient,strutils
+module=apiclient
+module=strutils
+module=install_venv_common
 
 # The base module to hold the copy of openstack.common
 base=cinderclient
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/python_cinderclient.egg-info/PKG-INFO 
new/python-cinderclient-1.0.4.66.g509a54b/python_cinderclient.egg-info/PKG-INFO
--- 
old/python-cinderclient-1.0.4.56.ga3985ee/python_cinderclient.egg-info/PKG-INFO 
    2013-07-05 18:45:44.000000000 +0200
+++ 
new/python-cinderclient-1.0.4.66.g509a54b/python_cinderclient.egg-info/PKG-INFO 
    2013-07-17 07:14:04.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: python-cinderclient
-Version: 1.0.4.56.ga3985ee
+Version: 1.0.4.66.g509a54b
 Summary: OpenStack Block Storage API Client Library
 Home-page: http://www.openstack.org/
 Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/python_cinderclient.egg-info/SOURCES.txt
 
new/python-cinderclient-1.0.4.66.g509a54b/python_cinderclient.egg-info/SOURCES.txt
--- 
old/python-cinderclient-1.0.4.56.ga3985ee/python_cinderclient.egg-info/SOURCES.txt
  2013-07-05 18:45:46.000000000 +0200
+++ 
new/python-cinderclient-1.0.4.66.g509a54b/python_cinderclient.egg-info/SOURCES.txt
  2013-07-17 07:14:06.000000000 +0200
@@ -41,6 +41,7 @@
 cinderclient/tests/v1/test_auth.py
 cinderclient/tests/v1/test_quota_classes.py
 cinderclient/tests/v1/test_quotas.py
+cinderclient/tests/v1/test_services.py
 cinderclient/tests/v1/test_shell.py
 cinderclient/tests/v1/test_types.py
 cinderclient/tests/v1/test_volume_backups.py
@@ -54,6 +55,7 @@
 cinderclient/tests/v2/test_auth.py
 cinderclient/tests/v2/test_quota_classes.py
 cinderclient/tests/v2/test_quotas.py
+cinderclient/tests/v2/test_services.py
 cinderclient/tests/v2/test_shell.py
 cinderclient/tests/v2/test_types.py
 cinderclient/tests/v2/test_volume_backups.py
@@ -66,6 +68,7 @@
 cinderclient/v1/limits.py
 cinderclient/v1/quota_classes.py
 cinderclient/v1/quotas.py
+cinderclient/v1/services.py
 cinderclient/v1/shell.py
 cinderclient/v1/volume_backups.py
 cinderclient/v1/volume_backups_restore.py
@@ -80,6 +83,7 @@
 cinderclient/v2/limits.py
 cinderclient/v2/quota_classes.py
 cinderclient/v2/quotas.py
+cinderclient/v2/services.py
 cinderclient/v2/shell.py
 cinderclient/v2/volume_backups.py
 cinderclient/v2/volume_backups_restore.py
@@ -104,4 +108,5 @@
 tools/colorizer.py
 tools/generate_authors.sh
 tools/install_venv.py
+tools/install_venv_common.py
 tools/with_venv.sh
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/python_cinderclient.egg-info/requires.txt
 
new/python-cinderclient-1.0.4.66.g509a54b/python_cinderclient.egg-info/requires.txt
--- 
old/python-cinderclient-1.0.4.56.ga3985ee/python_cinderclient.egg-info/requires.txt
 2013-07-05 18:45:44.000000000 +0200
+++ 
new/python-cinderclient-1.0.4.66.g509a54b/python_cinderclient.egg-info/requires.txt
 2013-07-17 07:14:04.000000000 +0200
@@ -1,6 +1,6 @@
 d2to1>=0.2.10,<0.3
-pbr>=0.5,<0.6
+pbr>=0.5.16,<0.6
 prettytable>=0.6,<0.8
-requests>=0.8
+requests>=1.1,<1.2.3
 simplejson>=2.0.9
 six
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/requirements.txt 
new/python-cinderclient-1.0.4.66.g509a54b/requirements.txt
--- old/python-cinderclient-1.0.4.56.ga3985ee/requirements.txt  2013-07-05 
18:45:11.000000000 +0200
+++ new/python-cinderclient-1.0.4.66.g509a54b/requirements.txt  2013-07-17 
07:13:30.000000000 +0200
@@ -1,7 +1,7 @@
 d2to1>=0.2.10,<0.3
-pbr>=0.5,<0.6
+pbr>=0.5.16,<0.6
 argparse
 prettytable>=0.6,<0.8
-requests>=0.8
+requests>=1.1,<1.2.3
 simplejson>=2.0.9
 six
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/test-requirements.txt 
new/python-cinderclient-1.0.4.66.g509a54b/test-requirements.txt
--- old/python-cinderclient-1.0.4.56.ga3985ee/test-requirements.txt     
2013-07-05 18:45:11.000000000 +0200
+++ new/python-cinderclient-1.0.4.66.g509a54b/test-requirements.txt     
2013-07-17 07:13:30.000000000 +0200
@@ -2,13 +2,12 @@
 pep8==1.4.5
 pyflakes==0.7.2
 flake8==2.0
-hacking>=0.5.3,<0.6
-
+hacking>=0.5.6,<0.6
 coverage>=3.6
 discover
 fixtures>=0.3.12
 mock>=0.8.0
 python-subunit
 sphinx>=1.1.2
-testtools>=0.9.29
-testrepository>=0.0.13
+testtools>=0.9.32
+testrepository>=0.0.15
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/tools/install_venv.py 
new/python-cinderclient-1.0.4.66.g509a54b/tools/install_venv.py
--- old/python-cinderclient-1.0.4.56.ga3985ee/tools/install_venv.py     
2013-07-05 18:45:11.000000000 +0200
+++ new/python-cinderclient-1.0.4.66.g509a54b/tools/install_venv.py     
2013-07-17 07:13:30.000000000 +0200
@@ -4,244 +4,74 @@
 # Administrator of the National Aeronautics and Space Administration.
 # All Rights Reserved.
 #
-# Copyright 2010 OpenStack, LLC
+# Copyright 2010 OpenStack Foundation
+# Copyright 2013 IBM Corp.
+# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
 #
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
 #
-#         http://www.apache.org/licenses/LICENSE-2.0
+#      http://www.apache.org/licenses/LICENSE-2.0
 #
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-"""
-Installation script for Nova's development virtualenv
-"""
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
 
-from __future__ import print_function
-
-import optparse
+import ConfigParser
 import os
-import subprocess
 import sys
-import platform
-
-
-ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
-VENV = os.path.join(ROOT, '.venv')
-PIP_REQUIRES = os.path.join(ROOT, 'requirements.txt')
-TEST_REQUIRES = os.path.join(ROOT, 'test-requirements.txt')
-PY_VERSION = "python%s.%s" % (sys.version_info[0], sys.version_info[1])
-
-
-def die(message, *args):
-    print(message % args, file=sys.stderr)
-    sys.exit(1)
-
-
-def check_python_version():
-    if sys.version_info < (2, 6):
-        die("Need Python Version >= 2.6")
-
-
-def run_command_with_code(cmd, redirect_output=True, check_exit_code=True):
-    """
-    Runs a command in an out-of-process shell, returning the
-    output of that command.  Working directory is ROOT.
-    """
-    if redirect_output:
-        stdout = subprocess.PIPE
-    else:
-        stdout = None
-
-    proc = subprocess.Popen(cmd, cwd=ROOT, stdout=stdout)
-    output = proc.communicate()[0]
-    if check_exit_code and proc.returncode != 0:
-        die('Command "%s" failed.\n%s', ' '.join(cmd), output)
-    return (output, proc.returncode)
-
-
-def run_command(cmd, redirect_output=True, check_exit_code=True):
-    return run_command_with_code(cmd, redirect_output, check_exit_code)[0]
-
-
-class Distro(object):
-
-    def check_cmd(self, cmd):
-        return bool(run_command(['which', cmd], check_exit_code=False).strip())
-
-    def install_virtualenv(self):
-        if self.check_cmd('virtualenv'):
-            return
-
-        if self.check_cmd('easy_install'):
-            print('Installing virtualenv via easy_install...', end=' ')
-            if run_command(['easy_install', 'virtualenv']):
-                print('Succeeded')
-                return
-            else:
-                print('Failed')
-
-        die('ERROR: virtualenv not found.\n\nDevelopment'
-            ' requires virtualenv, please install it using your'
-            ' favorite package management tool')
-
-    def post_process(self):
-        """Any distribution-specific post-processing gets done here.
-
-        In particular, this is useful for applying patches to code inside
-        the venv."""
-        pass
-
-
-class Debian(Distro):
-    """This covers all Debian-based distributions."""
-
-    def check_pkg(self, pkg):
-        return run_command_with_code(['dpkg', '-l', pkg],
-                                     check_exit_code=False)[1] == 0
-
-    def apt_install(self, pkg, **kwargs):
-        run_command(['sudo', 'apt-get', 'install', '-y', pkg], **kwargs)
 
-    def apply_patch(self, originalfile, patchfile):
-        run_command(['patch', originalfile, patchfile])
+import install_venv_common as install_venv  # flake8: noqa
 
-    def install_virtualenv(self):
-        if self.check_cmd('virtualenv'):
-            return
 
-        if not self.check_pkg('python-virtualenv'):
-            self.apt_install('python-virtualenv', check_exit_code=False)
-
-        super(Debian, self).install_virtualenv()
-
-
-class Fedora(Distro):
-    """This covers all Fedora-based distributions.
-
-    Includes: Fedora, RHEL, CentOS, Scientific Linux"""
-
-    def check_pkg(self, pkg):
-        return run_command_with_code(['rpm', '-q', pkg],
-                                     check_exit_code=False)[1] == 0
-
-    def yum_install(self, pkg, **kwargs):
-        run_command(['sudo', 'yum', 'install', '-y', pkg], **kwargs)
-
-    def apply_patch(self, originalfile, patchfile):
-        run_command(['patch', originalfile, patchfile])
-
-    def install_virtualenv(self):
-        if self.check_cmd('virtualenv'):
-            return
-
-        if not self.check_pkg('python-virtualenv'):
-            self.yum_install('python-virtualenv', check_exit_code=False)
-
-        super(Fedora, self).install_virtualenv()
-
-
-def get_distro():
-    if os.path.exists('/etc/fedora-release') or \
-       os.path.exists('/etc/redhat-release'):
-        return Fedora()
-    elif os.path.exists('/etc/debian_version'):
-        return Debian()
-    else:
-        return Distro()
-
-
-def check_dependencies():
-    get_distro().install_virtualenv()
-
-
-def create_virtualenv(venv=VENV, no_site_packages=True):
-    """Creates the virtual environment and installs PIP only into the
-    virtual environment
-    """
-    print('Creating venv...', end=' ')
-    if no_site_packages:
-        run_command(['virtualenv', '-q', '--no-site-packages', VENV])
-    else:
-        run_command(['virtualenv', '-q', VENV])
-    print('done.')
-    print('Installing pip in virtualenv...', end=' ')
-    if not run_command(['tools/with_venv.sh', 'easy_install',
-                        'pip>1.0']).strip():
-        die("Failed to install pip.")
-    print('done.')
-
-
-def pip_install(*args):
-    run_command(['tools/with_venv.sh',
-                 'pip', 'install', '--upgrade'] + list(args),
-                redirect_output=False)
-
-
-def install_dependencies(venv=VENV):
-    print('Installing dependencies with pip (this can take a while)...')
-
-    # First things first, make sure our venv has the latest pip and distribute.
-    pip_install('pip')
-    pip_install('distribute')
-
-    pip_install('-r', PIP_REQUIRES)
-    pip_install('-r', TEST_REQUIRES)
-    # Tell the virtual env how to "import cinder"
-    pthfile = os.path.join(venv, "lib", PY_VERSION, "site-packages",
-                        "cinderclient.pth")
-    f = open(pthfile, 'w')
-    f.write("%s\n" % ROOT)
-
-
-def post_process():
-    get_distro().post_process()
-
-
-def print_help():
+def print_help(project, venv, root):
     help = """
-    python-cinderclient development environment setup is complete.
+    %(project)s development environment setup is complete.
 
-    python-cinderclient development uses virtualenv to track and manage Python
+    %(project)s development uses virtualenv to track and manage Python
     dependencies while in development and testing.
 
-    To activate the python-cinderclient virtualenv for the extent of your
-    current shell session you can run:
-
-    $ source .venv/bin/activate
+    To activate the %(project)s virtualenv for the extent of your current
+    shell session you can run:
 
-    Or, if you prefer, you can run commands in the virtualenv on a case by case
-    basis by running:
+    $ source %(venv)s/bin/activate
 
-    $ tools/with_venv.sh <your command>
+    Or, if you prefer, you can run commands in the virtualenv on a case by
+    case basis by running:
 
-    Also, make test will automatically use the virtualenv.
+    $ %(root)s/tools/with_venv.sh <your command>
     """
-    print(help)
-
-
-def parse_args():
-    """Parse command-line arguments"""
-    parser = optparse.OptionParser()
-    parser.add_option("-n", "--no-site-packages", dest="no_site_packages",
-        default=False, action="store_true",
-        help="Do not inherit packages from global Python install")
-    return parser.parse_args()
+    print help % dict(project=project, venv=venv, root=root)
 
 
 def main(argv):
-    (options, args) = parse_args()
-    check_python_version()
-    check_dependencies()
-    create_virtualenv(no_site_packages=options.no_site_packages)
-    install_dependencies()
-    post_process()
-    print_help()
+    root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
+
+    if os.environ.get('tools_path'):
+        root = os.environ['tools_path']
+    venv = os.path.join(root, '.venv')
+    if os.environ.get('venv'):
+        venv = os.environ['venv']
+
+    pip_requires = os.path.join(root, 'requirements.txt')
+    test_requires = os.path.join(root, 'test-requirements.txt')
+    py_version = "python%s.%s" % (sys.version_info[0], sys.version_info[1])
+    setup_cfg = ConfigParser.ConfigParser()
+    setup_cfg.read('setup.cfg')
+    project = setup_cfg.get('metadata', 'name')
+
+    install = install_venv.InstallVenv(
+        root, venv, pip_requires, test_requires, py_version, project)
+    options = install.parse_args(argv)
+    install.check_python_version()
+    install.check_dependencies()
+    install.create_virtualenv(no_site_packages=options.no_site_packages)
+    install.install_dependencies()
+    install.post_process()
+    print_help(project, venv, root)
 
 if __name__ == '__main__':
     main(sys.argv)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-cinderclient-1.0.4.56.ga3985ee/tools/install_venv_common.py 
new/python-cinderclient-1.0.4.66.g509a54b/tools/install_venv_common.py
--- old/python-cinderclient-1.0.4.56.ga3985ee/tools/install_venv_common.py      
1970-01-01 01:00:00.000000000 +0100
+++ new/python-cinderclient-1.0.4.66.g509a54b/tools/install_venv_common.py      
2013-07-17 07:13:30.000000000 +0200
@@ -0,0 +1,212 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 OpenStack Foundation
+# Copyright 2013 IBM Corp.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+"""Provides methods needed by installation script for OpenStack development
+virtual environments.
+
+Since this script is used to bootstrap a virtualenv from the system's Python
+environment, it should be kept strictly compatible with Python 2.6.
+
+Synced in from openstack-common
+"""
+
+from __future__ import print_function
+
+import optparse
+import os
+import subprocess
+import sys
+
+
+class InstallVenv(object):
+
+    def __init__(self, root, venv, requirements,
+                 test_requirements, py_version,
+                 project):
+        self.root = root
+        self.venv = venv
+        self.requirements = requirements
+        self.test_requirements = test_requirements
+        self.py_version = py_version
+        self.project = project
+
+    def die(self, message, *args):
+        print(message % args, file=sys.stderr)
+        sys.exit(1)
+
+    def check_python_version(self):
+        if sys.version_info < (2, 6):
+            self.die("Need Python Version >= 2.6")
+
+    def run_command_with_code(self, cmd, redirect_output=True,
+                              check_exit_code=True):
+        """Runs a command in an out-of-process shell.
+
+        Returns the output of that command. Working directory is self.root.
+        """
+        if redirect_output:
+            stdout = subprocess.PIPE
+        else:
+            stdout = None
+
+        proc = subprocess.Popen(cmd, cwd=self.root, stdout=stdout)
+        output = proc.communicate()[0]
+        if check_exit_code and proc.returncode != 0:
+            self.die('Command "%s" failed.\n%s', ' '.join(cmd), output)
+        return (output, proc.returncode)
+
+    def run_command(self, cmd, redirect_output=True, check_exit_code=True):
+        return self.run_command_with_code(cmd, redirect_output,
+                                          check_exit_code)[0]
+
+    def get_distro(self):
+        if (os.path.exists('/etc/fedora-release') or
+                os.path.exists('/etc/redhat-release')):
+            return Fedora(
+                self.root, self.venv, self.requirements,
+                self.test_requirements, self.py_version, self.project)
+        else:
+            return Distro(
+                self.root, self.venv, self.requirements,
+                self.test_requirements, self.py_version, self.project)
+
+    def check_dependencies(self):
+        self.get_distro().install_virtualenv()
+
+    def create_virtualenv(self, no_site_packages=True):
+        """Creates the virtual environment and installs PIP.
+
+        Creates the virtual environment and installs PIP only into the
+        virtual environment.
+        """
+        if not os.path.isdir(self.venv):
+            print('Creating venv...', end=' ')
+            if no_site_packages:
+                self.run_command(['virtualenv', '-q', '--no-site-packages',
+                                 self.venv])
+            else:
+                self.run_command(['virtualenv', '-q', self.venv])
+            print('done.')
+        else:
+            print("venv already exists...")
+            pass
+
+    def pip_install(self, *args):
+        self.run_command(['tools/with_venv.sh',
+                         'pip', 'install', '--upgrade'] + list(args),
+                         redirect_output=False)
+
+    def install_dependencies(self):
+        print('Installing dependencies with pip (this can take a while)...')
+
+        # First things first, make sure our venv has the latest pip and
+        # setuptools.
+        self.pip_install('pip>=1.3')
+        self.pip_install('setuptools')
+
+        self.pip_install('-r', self.requirements)
+        self.pip_install('-r', self.test_requirements)
+
+    def post_process(self):
+        self.get_distro().post_process()
+
+    def parse_args(self, argv):
+        """Parses command-line arguments."""
+        parser = optparse.OptionParser()
+        parser.add_option('-n', '--no-site-packages',
+                          action='store_true',
+                          help="Do not inherit packages from global Python "
+                               "install")
+        return parser.parse_args(argv[1:])[0]
+
+
+class Distro(InstallVenv):
+
+    def check_cmd(self, cmd):
+        return bool(self.run_command(['which', cmd],
+                    check_exit_code=False).strip())
+
+    def install_virtualenv(self):
+        if self.check_cmd('virtualenv'):
+            return
+
+        if self.check_cmd('easy_install'):
+            print('Installing virtualenv via easy_install...', end=' ')
+            if self.run_command(['easy_install', 'virtualenv']):
+                print('Succeeded')
+                return
+            else:
+                print('Failed')
+
+        self.die('ERROR: virtualenv not found.\n\n%s development'
+                 ' requires virtualenv, please install it using your'
+                 ' favorite package management tool' % self.project)
+
+    def post_process(self):
+        """Any distribution-specific post-processing gets done here.
+
+        In particular, this is useful for applying patches to code inside
+        the venv.
+        """
+        pass
+
+
+class Fedora(Distro):
+    """This covers all Fedora-based distributions.
+
+    Includes: Fedora, RHEL, CentOS, Scientific Linux
+    """
+
+    def check_pkg(self, pkg):
+        return self.run_command_with_code(['rpm', '-q', pkg],
+                                          check_exit_code=False)[1] == 0
+
+    def apply_patch(self, originalfile, patchfile):
+        self.run_command(['patch', '-N', originalfile, patchfile],
+                         check_exit_code=False)
+
+    def install_virtualenv(self):
+        if self.check_cmd('virtualenv'):
+            return
+
+        if not self.check_pkg('python-virtualenv'):
+            self.die("Please install 'python-virtualenv'.")
+
+        super(Fedora, self).install_virtualenv()
+
+    def post_process(self):
+        """Workaround for a bug in eventlet.
+
+        This currently affects RHEL6.1, but the fix can safely be
+        applied to all RHEL and Fedora distributions.
+
+        This can be removed when the fix is applied upstream.
+
+        Nova: https://bugs.launchpad.net/nova/+bug/884915
+        Upstream: https://bitbucket.org/eventlet/eventlet/issue/89
+        RHEL: https://bugzilla.redhat.com/958868
+        """
+
+        # Install "patch" program if it's not there
+        if not self.check_pkg('patch'):
+            self.die("Please install 'patch'.")
+
+        # Apply the eventlet patch
+        self.apply_patch(os.path.join(self.venv, 'lib', self.py_version,
+                                      'site-packages',
+                                      'eventlet/green/subprocess.py'),
+                         'contrib/redhat-eventlet.patch')

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to