Hello community, here is the log from the commit of package openstack-cinder for openSUSE:Factory checked in at 2013-10-18 19:22:10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/openstack-cinder (Old) and /work/SRC/openSUSE:Factory/.openstack-cinder.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "openstack-cinder" Changes: -------- --- /work/SRC/openSUSE:Factory/openstack-cinder/openstack-cinder.changes 2013-10-09 23:41:44.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.openstack-cinder.new/openstack-cinder.changes 2013-10-18 19:23:11.000000000 +0200 @@ -1,0 +2,12 @@ +Thu Oct 17 15:26:40 UTC 2013 - [email protected] + +- update to 2013.2: + + No changes + +------------------------------------------------------------------- +Sat Oct 12 11:47:39 UTC 2013 - [email protected] + +- Update to version 2013.2.rc2: + + No changes + +------------------------------------------------------------------- Old: ---- cinder-2013.2.rc1.tar.gz New: ---- cinder-2013.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ openstack-cinder-doc.spec ++++++ --- /var/tmp/diff_new_pack.74yd2l/_old 2013-10-18 19:23:13.000000000 +0200 +++ /var/tmp/diff_new_pack.74yd2l/_new 2013-10-18 19:23:13.000000000 +0200 @@ -19,13 +19,13 @@ %define component cinder Name: openstack-%{component}-doc -Version: 2013.2.rc1 +Version: 2013.2 Release: 0 Summary: OpenStack Block Storage (Cinder) - Documentation License: Apache-2.0 Group: Documentation/HTML Url: https://launchpad.net/cinder -Source: cinder-2013.2.rc1.tar.gz +Source: cinder-2013.2.tar.gz BuildRequires: graphviz BuildRequires: openstack-suse-macros BuildRequires: python-Babel @@ -62,7 +62,7 @@ This package contains documentation files for %{name}. %prep -%setup -q -n cinder-2013.2.rc1 +%setup -q -n cinder-2013.2 %openstack_cleanup_prep %build ++++++ openstack-cinder.spec ++++++ --- /var/tmp/diff_new_pack.74yd2l/_old 2013-10-18 19:23:13.000000000 +0200 +++ /var/tmp/diff_new_pack.74yd2l/_new 2013-10-18 19:23:13.000000000 +0200 @@ -21,13 +21,13 @@ %define username openstack-%{component} Name: openstack-%{component} -Version: 2013.2.rc1 +Version: 2013.2 Release: 0 Summary: OpenStack Block Storage (Cinder) License: Apache-2.0 Group: System/Management Url: https://launchpad.net/cinder -Source: cinder-2013.2.rc1.tar.gz +Source: cinder-2013.2.tar.gz Source1: %{name}.init Source2: %{name}.logrotate Source3: cinder-sudoers @@ -82,7 +82,7 @@ Summary: OpenStack Block Storage (Cinder) - Python module Group: Development/Languages/Python Requires: python >= 2.6.8 -Requires: python-Babel >= 0.9.6 +Requires: python-Babel >= 1.3 Requires: python-Paste Requires: python-PasteDeploy >= 1.5.0 Requires: python-Routes >= 1.12.3 @@ -99,7 +99,7 @@ Requires: python-lockfile >= 0.8 Requires: python-lxml >= 2.3 Requires: python-netaddr -Requires: python-novaclient >= 2.12.0 +Requires: python-novaclient >= 2.15.0 Requires: python-paramiko >= 1.8.0 Requires: python-six Requires: python-sqlalchemy-migrate >= 0.7.2 @@ -180,7 +180,7 @@ functionality of OpenStack Cinder. %prep -%setup -q -n cinder-2013.2.rc1 +%setup -q -n cinder-2013.2 %patch0 -p1 %openstack_cleanup_prep ++++++ _service ++++++ --- /var/tmp/diff_new_pack.74yd2l/_old 2013-10-18 19:23:13.000000000 +0200 +++ /var/tmp/diff_new_pack.74yd2l/_new 2013-10-18 19:23:13.000000000 +0200 @@ -1,7 +1,7 @@ <services> <service name="git_tarballs" mode="disabled"> - <param name="url">http://tarballs.openstack.org/cinder/cinder-master.tar.gz</param> - <param name="url">http://tarballs.openstack.org/cinder/cinder-2013.2.rc1.tar.gz</param> + <!--<param name="url">http://tarballs.openstack.org/cinder/cinder-master.tar.gz</param>--> + <param name="url">http://tarballs.openstack.org/cinder/cinder-2013.2.tar.gz</param> <param name="email">[email protected]</param> <param name="plain-version">True</param> </service> ++++++ cinder-2013.2.rc1.tar.gz -> cinder-2013.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/AUTHORS new/cinder-2013.2/AUTHORS --- old/cinder-2013.2.rc1/AUTHORS 2013-10-04 11:14:34.000000000 +0200 +++ new/cinder-2013.2/AUTHORS 2013-10-17 15:48:37.000000000 +0200 @@ -57,6 +57,7 @@ Flaper Fesp <[email protected]> Frederic Lepied <[email protected]> Ghe Rivero <[email protected]> +Giulio Fidente <[email protected]> Haomai Wang <[email protected]> Hui Cheng <[email protected]> James E. Blair <[email protected]> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/ChangeLog new/cinder-2013.2/ChangeLog --- old/cinder-2013.2.rc1/ChangeLog 2013-10-04 11:14:34.000000000 +0200 +++ new/cinder-2013.2/ChangeLog 2013-10-17 15:48:36.000000000 +0200 @@ -1,3 +1,170 @@ +commit bdb5d982d069ac6464c8ef857a0f95dde02005de +Author: John Griffith <[email protected]> +Date: Tue Oct 15 19:13:45 2013 -0600 + + Fix lvm.extend_volume to pass Gig suffix + + The extend function in the lvm driver was not converting + the cinder size value to Gigabytes before passing the call + to the vg module. The result was that we would attempt to + extend a volume to "new size in Megabytes" which of course + is less than the current size since we do a Gigabyte string + conversion on create and everywhere else. + + This change makes sure we pass the integer change through + the sizestr method to get the G suffix needed to work properly. + + Change-Id: I070962a3aa7038f612e19a93ccaa60cbc13008f6 + Closes-Bug: #1240287 + (cherry picked from commit ec442e41d2d243003a42ed60ae862e96142a5cde) + +commit 5e489f475f4fe0529280f419b4708aa22c13ad39 +Author: John Griffith <[email protected]> +Date: Tue Oct 15 13:57:48 2013 -0600 + + FK lookup failures during migration + + There are a couple of cases where migrations have failed + upgrading from Grizzly to Havana, this seems to be isolated + to a couple of migrations so far and the error message is a + failure to lookup/associate the volume-id FK dependency. + + It appears that this is caused by not setting the charset + in the migration, so the result is that the initial db setup + uses utf8 and the migrations are using the default latin1. + + This patch goes through all of the migrations in Havana that + specify InnoDB and explicitly sets the charset to utf8 to match + the volumes table (and the other original tables). + + Change-Id: I43b219ff5e4eea10a7391ad65ef68a80b7460370 + Closes-Bug: #1233861 + (cherry picked from commit 645a84f990c90e28548cf35b4b5f242eb0e0c286) + +commit 2d8ad0d30d390624e0c24e1ce3db87219967390f +Merge: 36c831f 3c7bfcd +Author: Jenkins <[email protected]> +Date: Thu Oct 10 22:57:52 2013 +0000 + + Merge "VMware: Disallow snapshot of attached volume" into milestone-proposed + +commit 36c831f109802706528140daf3626096189443cb +Merge: 9fb4c73 de03181 +Author: Jenkins <[email protected]> +Date: Thu Oct 10 22:05:05 2013 +0000 + + Merge "improves lvm version parsing for customised builds" into milestone-proposed + +commit 9fb4c7378eb7e7a7c47c2c0149ebea36a86f4a19 +Merge: 9c0b9e0 af092c5 +Author: Jenkins <[email protected]> +Date: Thu Oct 10 22:02:53 2013 +0000 + + Merge "Support Huawei driver upgrade from grizzly to havana" into milestone-proposed + +commit 9c0b9e0b3892a2cf034a1bd7c5499473a74917d6 +Merge: 8a2a3d6 46afd20 +Author: Jenkins <[email protected]> +Date: Thu Oct 10 21:21:51 2013 +0000 + + Merge "VMware: Re-create session for RetrievePropertiesEx" into milestone-proposed + +commit de031813b90d4a29fc6011a53fefa6c19001022e +Author: Giulio Fidente <[email protected]> +Date: Thu Oct 10 14:59:44 2013 +0200 + + improves lvm version parsing for customised builds + + supports_thin_provisioning now uses a regexp to ensure parsing of + lvm version succeeds when the build is customised; also adds a test + for a customised string parsing + + Closes-Bug: #1237994 + Change-Id: I49049a58bbdb5315b9d2d7c259a9324ca15d78cb + (cherry picked from commit 51fd5edb106e26d65696ce37a70eef6a4f75b1e2) + +commit 8a2a3d691fa54c07d14b3e32558641f43b69c040 +Author: Alan Jiang <[email protected]> +Date: Thu Oct 3 17:03:09 2013 -0500 + + long flashcopy operation may block volume service + + Storwize family uses flashcopy for snapshot or volume clone. The + volume delete has to wait until flashcopy finishes or errors out. + The _delete_vdisk() will poll volume FlashCopy status in a loop. + This may block volume serivce heartheat since it is in the same + . The solution is to use openstack FixedIntervalLoopingCall + to run the FlashCopy status poll in a timer thread. + + The cinder volume mananger will resume delete operation for those + volumes that are in the deleting state during volume service startup. + Since Storwize volume delete may wait for a long time, this can cause + volume service to have long delay before it becomes available. + A greenpool is used to offload those volume delete operations. + + Change-Id: Ie01a441a327e1e318fa8da0040ae130731b7a686 + Closes-Bug: #1203152 + (cherry picked from commit 7aa4f65a8c17aa037deff0f5b534ed694c17e62a) + +commit af092c5401e6721df4ddfa5a93a0fe155fc8782d +Author: zhangchao010 <[email protected]> +Date: Wed Oct 9 15:37:49 2013 +0800 + + Support Huawei driver upgrade from grizzly to havana + + To make the driver upgrade from grizzly to higher versions, the patch + checks the old host name firstly when creating and deleting host in + Huawei storage system. + If the old host name exists: + *get and use it directly when adding host. + *delete it directly when deleting host. + + Closes-bug 1237189 + + Change-Id: I82a9dbc1ef0bb0b91771afea4aadec5afe65eecf + (cherry picked from commit 0c9dc5d0e01576969f09edc0c9c72a2aa91b248a) + +commit 3c7bfcdb378ca7f59186822f4c905e1176e4722a +Author: Kartik Bommepally <[email protected]> +Date: Tue Oct 8 06:33:33 2013 -0700 + + VMware: Disallow snapshot of attached volume + + The current implementation perform snapshot of attached volume. + This is invalid because when we take snapshot of the backing, the instance + continues pointing to the readonly delta and tries writing to it. + This patch will disallow snapshot creation of attached volume. + + We have similar issue with delete of snapshot, when deleted the instance will + point to an invalid disk file, since that will get merged with its parent. + Hence any writes by the instance will fail with disk not found error. + This patch will ignore delete snapshot of attached volume. + + Since we disallow snapshot of attached volume, we disallow linked clone of + attached source volume and also upload of attached volume. + + Fixes bug: 1236891 + + Change-Id: I6a91eac8529836d1fe1de73bf6b28ec098aa7c54 + (cherry picked from commit 2451a027bee50c834890f9e049fbaf4bfa911546) + +commit 46afd20ac76d5c947c33395eeff80b53e6493a98 +Author: Kartik Bommepally <[email protected]> +Date: Fri Oct 4 04:05:09 2013 -0700 + + VMware: Re-create session for RetrievePropertiesEx + + When RetrievePropertiesEx API is called after session timeout, the driver + does not re-create session automatically. + + This is a regression caused when moving from RetrieveProperties to + RetrievePropertiesEx API. + + Fixes bug: 1235187 + + Change-Id: I8a1e2452dfb3029365d59eae7850d1a9363b25f0 + (cherry picked from commit 2d4ea101252141486fa6fd61b100772fafd40102) + commit f021629df31328324ca429c29a827efab832eee0 Author: John Griffith <[email protected]> Date: Thu Oct 3 15:54:20 2013 -0600 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/PKG-INFO new/cinder-2013.2/PKG-INFO --- old/cinder-2013.2.rc1/PKG-INFO 2013-10-04 11:14:35.000000000 +0200 +++ new/cinder-2013.2/PKG-INFO 2013-10-17 15:48:37.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: cinder -Version: 2013.2.rc1 +Version: 2013.2 Summary: OpenStack Block Storage Home-page: http://www.openstack.org/ Author: OpenStack diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder/brick/local_dev/lvm.py new/cinder-2013.2/cinder/brick/local_dev/lvm.py --- old/cinder-2013.2.rc1/cinder/brick/local_dev/lvm.py 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/cinder/brick/local_dev/lvm.py 2013-10-17 15:46:46.000000000 +0200 @@ -136,10 +136,12 @@ for line in lines: if 'LVM version' in line: version_list = line.split() + # NOTE(gfidente): version is formatted as follows: + # major.minor.patchlevel(library API version)[-customisation] version = version_list[2] - if '(2)' in version: - version = version.replace('(2)', '') - version_tuple = tuple(map(int, version.split('.'))) + version_filter = "(\d+)\.(\d+)\.(\d+).*" + r = re.search(version_filter, version) + version_tuple = tuple(map(int, r.group(1, 2, 3))) if version_tuple >= (2, 2, 95): return True return False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder/db/sqlalchemy/migrate_repo/versions/010_add_transfers_table.py new/cinder-2013.2/cinder/db/sqlalchemy/migrate_repo/versions/010_add_transfers_table.py --- old/cinder-2013.2.rc1/cinder/db/sqlalchemy/migrate_repo/versions/010_add_transfers_table.py 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/cinder/db/sqlalchemy/migrate_repo/versions/010_add_transfers_table.py 2013-10-17 15:46:46.000000000 +0200 @@ -40,7 +40,8 @@ Column('salt', String(length=255)), Column('crypt_hash', String(length=255)), Column('expires_at', DateTime(timezone=False)), - mysql_engine='InnoDB' + mysql_engine='InnoDB', + mysql_charset='utf8' ) try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder/db/sqlalchemy/migrate_repo/versions/015_drop_migrations_table.py new/cinder-2013.2/cinder/db/sqlalchemy/migrate_repo/versions/015_drop_migrations_table.py --- old/cinder-2013.2.rc1/cinder/db/sqlalchemy/migrate_repo/versions/015_drop_migrations_table.py 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/cinder/db/sqlalchemy/migrate_repo/versions/015_drop_migrations_table.py 2013-10-17 15:46:46.000000000 +0200 @@ -53,7 +53,8 @@ Column('new_instance_type_id', Integer), Column('instance_uuid', String(length=255), nullable=True), Column('status', String(length=255)), - mysql_engine='InnoDB' + mysql_engine='InnoDB', + mysql_charset='utf8' ) try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder/db/sqlalchemy/migrate_repo/versions/016_drop_sm_tables.py new/cinder-2013.2/cinder/db/sqlalchemy/migrate_repo/versions/016_drop_sm_tables.py --- old/cinder-2013.2.rc1/cinder/db/sqlalchemy/migrate_repo/versions/016_drop_sm_tables.py 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/cinder/db/sqlalchemy/migrate_repo/versions/016_drop_sm_tables.py 2013-10-17 15:46:46.000000000 +0200 @@ -59,7 +59,8 @@ Column('sr_uuid', String(length=255)), Column('sr_type', String(length=255)), Column('config_params', String(length=2047)), - mysql_engine='InnoDB' + mysql_engine='InnoDB', + mysql_charset='utf8' ) sm_flavors = Table( @@ -71,7 +72,8 @@ Column('id', Integer, primary_key=True, nullable=False), Column('label', String(length=255)), Column('description', String(length=255)), - mysql_engine='InnoDB' + mysql_engine='InnoDB', + mysql_charset='utf8' ) sm_volume = Table( @@ -87,7 +89,8 @@ Column('backend_id', Integer, ForeignKey('sm_backend_config.id'), nullable=False), Column('vdi_uuid', String(length=255)), - mysql_engine='InnoDB' + mysql_engine='InnoDB', + mysql_charset='utf8' ) tables = [sm_flavors, sm_backend_config, sm_volume] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder/db/sqlalchemy/migrate_repo/versions/017_add_encryption_information.py new/cinder-2013.2/cinder/db/sqlalchemy/migrate_repo/versions/017_add_encryption_information.py --- old/cinder-2013.2.rc1/cinder/db/sqlalchemy/migrate_repo/versions/017_add_encryption_information.py 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/cinder/db/sqlalchemy/migrate_repo/versions/017_add_encryption_information.py 2013-10-17 15:46:46.000000000 +0200 @@ -74,7 +74,8 @@ Column('volume_type_id', String(length=36), ForeignKey(volume_types.c.id), primary_key=True, nullable=False), - mysql_engine='InnoDB' + mysql_engine='InnoDB', + mysql_charset='utf8' ) try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder/db/sqlalchemy/migrate_repo/versions/018_add_qos_specs.py new/cinder-2013.2/cinder/db/sqlalchemy/migrate_repo/versions/018_add_qos_specs.py --- old/cinder-2013.2.rc1/cinder/db/sqlalchemy/migrate_repo/versions/018_add_qos_specs.py 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/cinder/db/sqlalchemy/migrate_repo/versions/018_add_qos_specs.py 2013-10-17 15:46:46.000000000 +0200 @@ -40,7 +40,8 @@ ForeignKey('quality_of_service_specs.id')), Column('key', String(255)), Column('value', String(255)), - mysql_engine='InnoDB' + mysql_engine='InnoDB', + mysql_charset='utf8' ) try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder/db/sqlalchemy/migrate_repo/versions/020_add_volume_admin_metadata_table.py new/cinder-2013.2/cinder/db/sqlalchemy/migrate_repo/versions/020_add_volume_admin_metadata_table.py --- old/cinder-2013.2.rc1/cinder/db/sqlalchemy/migrate_repo/versions/020_add_volume_admin_metadata_table.py 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/cinder/db/sqlalchemy/migrate_repo/versions/020_add_volume_admin_metadata_table.py 2013-10-17 15:46:46.000000000 +0200 @@ -38,7 +38,8 @@ nullable=False), Column('key', String(length=255)), Column('value', String(length=255)), - mysql_engine='InnoDB' + mysql_engine='InnoDB', + mysql_charset='utf8' ) try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder/tests/brick/test_brick_lvm.py new/cinder-2013.2/cinder/tests/brick/test_brick_lvm.py --- old/cinder-2013.2.rc1/cinder/tests/brick/test_brick_lvm.py 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/cinder/tests/brick/test_brick_lvm.py 2013-10-17 15:46:47.000000000 +0200 @@ -58,6 +58,9 @@ def fake_old_lvm_version(obj, *cmd, **kwargs): return (" LVM version: 2.02.65(2) (2012-03-06)\n", "") + def fake_customised_lvm_version(obj, *cmd, **kwargs): + return (" LVM version: 2.02.100(2)-RHEL6 (2013-09-12)\n", "") + def fake_execute(obj, *cmd, **kwargs): cmd_string = ', '.join(cmd) data = "\n" @@ -133,7 +136,7 @@ def test_thin_support(self): # lvm.supports_thin() is a static method and doesn't # use the self._executor fake we pass in on init - # so we need to stub proessutils.execute appropriately + # so we need to stub processutils.execute appropriately self.stubs.Set(processutils, 'execute', self.fake_execute) self.assertTrue(self.vg.supports_thin_provisioning('sudo')) @@ -144,6 +147,11 @@ self.stubs.Set(processutils, 'execute', self.fake_old_lvm_version) self.assertFalse(self.vg.supports_thin_provisioning('sudo')) + self.stubs.Set(processutils, + 'execute', + self.fake_customised_lvm_version) + self.assertTrue(self.vg.supports_thin_provisioning('sudo')) + def test_volume_create_after_thin_creation(self): """Test self.vg.vg_thin_pool is set to pool_name diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder/tests/test_storwize_svc.py new/cinder-2013.2/cinder/tests/test_storwize_svc.py --- old/cinder-2013.2.rc1/cinder/tests/test_storwize_svc.py 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/cinder/tests/test_storwize_svc.py 2013-10-17 15:46:47.000000000 +0200 @@ -39,6 +39,7 @@ from cinder.volume.drivers import storwize_svc from cinder.volume import volume_types +from eventlet import greenthread LOG = logging.getLogger(__name__) @@ -1165,7 +1166,7 @@ 'no']) for d in to_delete: - del self._fcmappings_list[k] + del self._fcmappings_list[d] return self._print_info_cmd(rows=rows, **kwargs) @@ -1485,6 +1486,8 @@ self.driver.do_setup(None) self.driver.check_for_setup_error() self.stubs.Set(storwize_svc.time, 'sleep', lambda s: None) + self.stubs.Set(greenthread, 'sleep', lambda *x, **y: None) + self.stubs.Set(storwize_svc, 'CHECK_FCMAPPING_INTERVAL', 0) def _set_flag(self, flag, value): group = self.driver.configuration.config_group diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder/tests/test_vmware_vmdk.py new/cinder-2013.2/cinder/tests/test_vmware_vmdk.py --- old/cinder-2013.2.rc1/cinder/tests/test_vmware_vmdk.py 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/cinder/tests/test_vmware_vmdk.py 2013-10-17 15:46:47.000000000 +0200 @@ -28,6 +28,7 @@ from cinder.volume import configuration from cinder.volume.drivers.vmware import api from cinder.volume.drivers.vmware import error_util +from cinder.volume.drivers.vmware import vim from cinder.volume.drivers.vmware import vim_util from cinder.volume.drivers.vmware import vmdk from cinder.volume.drivers.vmware import vmware_images @@ -66,13 +67,14 @@ class FakeObject(object): - fields = {} + def __init__(self): + self._fields = {} def __setitem__(self, key, value): - self.fields[key] = value + self._fields[key] = value def __getitem__(self, item): - return self.fields[item] + return self._fields[item] class FakeManagedObjectReference(object): @@ -588,6 +590,7 @@ self._volumeops.get_hosts().AndReturn(retrieve_result) m.StubOutWithMock(self._driver, '_create_backing') volume = FakeObject() + volume['name'] = 'vol_name' backing = FakeMor('VirtualMachine', 'my_back') mux = self._driver._create_backing(volume, host1.obj) mux.AndRaise(error_util.VimException('Maintenance mode')) @@ -836,6 +839,9 @@ m.StubOutWithMock(self._volumeops, 'get_backing') snapshot = FakeObject() snapshot['volume_name'] = 'volume_name' + snapshot['name'] = 'snap_name' + snapshot['volume'] = FakeObject() + snapshot['volume']['status'] = 'available' self._volumeops.get_backing(snapshot['volume_name']) m.ReplayAll() @@ -853,6 +859,8 @@ snapshot['volume_name'] = 'volume_name' snapshot['name'] = 'snapshot_name' snapshot['display_description'] = 'snapshot_desc' + snapshot['volume'] = FakeObject() + snapshot['volume']['status'] = 'available' backing = FakeMor('VirtualMachine', 'my_back') self._volumeops.get_backing(snapshot['volume_name']).AndReturn(backing) m.StubOutWithMock(self._volumeops, 'create_snapshot') @@ -864,6 +872,15 @@ m.UnsetStubs() m.VerifyAll() + def test_create_snapshot_when_attached(self): + """Test vmdk.create_snapshot when volume is attached.""" + snapshot = FakeObject() + snapshot['volume'] = FakeObject() + snapshot['volume']['status'] = 'in-use' + + self.assertRaises(exception.InvalidVolume, + self._driver.create_snapshot, snapshot) + def test_get_snapshot_from_tree(self): """Test _get_snapshot_from_tree.""" volops = volumeops.VMwareVolumeOps @@ -946,6 +963,9 @@ m.StubOutWithMock(self._volumeops, 'get_backing') snapshot = FakeObject() snapshot['volume_name'] = 'volume_name' + snapshot['name'] = 'snap_name' + snapshot['volume'] = FakeObject() + snapshot['volume']['status'] = 'available' self._volumeops.get_backing(snapshot['volume_name']) m.ReplayAll() @@ -962,6 +982,9 @@ snapshot = FakeObject() snapshot['name'] = 'snapshot_name' snapshot['volume_name'] = 'volume_name' + snapshot['name'] = 'snap_name' + snapshot['volume'] = FakeObject() + snapshot['volume']['status'] = 'available' backing = FakeMor('VirtualMachine', 'my_back') self._volumeops.get_backing(snapshot['volume_name']).AndReturn(backing) m.StubOutWithMock(self._volumeops, 'delete_snapshot') @@ -973,6 +996,15 @@ m.UnsetStubs() m.VerifyAll() + def test_delete_snapshot_when_attached(self): + """Test delete_snapshot when volume is attached.""" + snapshot = FakeObject() + snapshot['volume'] = FakeObject() + snapshot['volume']['status'] = 'in-use' + + self.assertRaises(exception.InvalidVolume, + self._driver.delete_snapshot, snapshot) + def test_create_cloned_volume_without_backing(self): """Test create_cloned_volume without a backing.""" m = self.mox @@ -981,6 +1013,7 @@ m.StubOutWithMock(self._volumeops, 'get_backing') volume = FakeObject() volume['name'] = 'volume_name' + volume['status'] = 'available' src_vref = FakeObject() src_vref['name'] = 'src_volume_name' self._volumeops.get_backing(src_vref['name']) @@ -1090,6 +1123,7 @@ volume['name'] = 'volume_name' snapshot = FakeObject() snapshot['volume_name'] = 'volume_name' + snapshot['name'] = 'snap_name' self._volumeops.get_backing(snapshot['volume_name']) m.ReplayAll() @@ -1342,6 +1376,7 @@ image_meta['disk_format'] = 'novmdk' volume = FakeObject() volume['name'] = 'vol-name' + volume['status'] = 'available' m.ReplayAll() self.assertRaises(exception.ImageUnacceptable, @@ -1351,6 +1386,20 @@ m.UnsetStubs() m.VerifyAll() + def test_copy_volume_to_image_when_attached(self): + """Test copy_volume_to_image when volume is attached.""" + m = self.mox + volume = FakeObject() + volume['status'] = 'in-use' + + m.ReplayAll() + self.assertRaises(exception.InvalidVolume, + self._driver.copy_volume_to_image, + mox.IgnoreArg(), volume, + mox.IgnoreArg(), mox.IgnoreArg()) + m.UnsetStubs() + m.VerifyAll() + def test_copy_volume_to_image_vmdk(self): """Test copy_volume_to_image for a valid vmdk disk format.""" m = self.mox @@ -1372,6 +1421,7 @@ volume = FakeObject() volume['name'] = vol_name volume['project_id'] = project_id + volume['status'] = 'available' # volumeops.get_backing backing = FakeMor("VirtualMachine", "my_vm") m.StubOutWithMock(self._volumeops, 'get_backing') @@ -1382,10 +1432,6 @@ vmdk_file_path = '[%s] %s' % (datastore_name, file_path) m.StubOutWithMock(self._volumeops, 'get_vmdk_path') self._volumeops.get_vmdk_path(backing).AndReturn(vmdk_file_path) - # volumeops.create_snapshot - snapshot_name = 'snapshot-%s' % image_id - m.StubOutWithMock(self._volumeops, 'create_snapshot') - self._volumeops.create_snapshot(backing, snapshot_name, None, True) tmp_vmdk = '[datastore1] %s.vmdk' % image_id # volumeops.get_host host = FakeMor('Host', 'my_host') @@ -1435,6 +1481,38 @@ m.UnsetStubs() m.VerifyAll() + def test_retrieve_properties_ex_fault_checker(self): + """Test retrieve_properties_ex_fault_checker is called.""" + m = self.mox + + class FakeVim(vim.Vim): + def __init__(self): + pass + + @property + def client(self): + + class FakeRetrv(object): + def RetrievePropertiesEx(self, collector): + pass + + def __getattr__(self, name): + if name == 'service': + return FakeRetrv() + + return FakeRetrv() + + def RetrieveServiceContent(self, type='ServiceInstance'): + return mox.MockAnything() + + _vim = FakeVim() + m.ReplayAll() + # retrieve_properties_ex_fault_checker throws authentication error + self.assertRaises(error_util.VimFaultException, + _vim.RetrievePropertiesEx, mox.IgnoreArg()) + m.UnsetStubs() + m.VerifyAll() + class VMwareVcVmdkDriverTestCase(VMwareEsxVmdkDriverTestCase): """Test class for VMwareVcVmdkDriver.""" @@ -1752,6 +1830,7 @@ backing = FakeMor('VirtualMachine', 'my_back') src_vref = FakeObject() src_vref['name'] = 'src_vol_name' + src_vref['status'] = 'available' self._volumeops.get_backing(src_vref['name']).AndReturn(backing) volume = FakeObject() volume['volume_type_id'] = None @@ -1763,7 +1842,7 @@ self._driver.create_cloned_volume(volume, src_vref) m.UnsetStubs() - def test_create_lined_cloned_volume_with_backing(self): + def test_create_linked_cloned_volume_with_backing(self): """Test create_cloned_volume with clone type - linked.""" m = self.mox m.StubOutWithMock(self._driver.__class__, 'volumeops') @@ -1772,6 +1851,7 @@ backing = FakeMor('VirtualMachine', 'my_back') src_vref = FakeObject() src_vref['name'] = 'src_vol_name' + src_vref['status'] = 'available' self._volumeops.get_backing(src_vref['name']).AndReturn(backing) volume = FakeObject() volume['id'] = 'volume_id' @@ -1790,4 +1870,25 @@ m.ReplayAll() self._driver.create_cloned_volume(volume, src_vref) m.UnsetStubs() + + def test_create_linked_cloned_volume_when_attached(self): + """Test create_cloned_volume linked clone when volume is attached.""" + m = self.mox + m.StubOutWithMock(self._driver.__class__, 'volumeops') + self._driver.volumeops = self._volumeops + m.StubOutWithMock(self._volumeops, 'get_backing') + backing = FakeMor('VirtualMachine', 'my_back') + src_vref = FakeObject() + src_vref['name'] = 'src_vol_name' + src_vref['status'] = 'in-use' + volume = FakeObject() + self._volumeops.get_backing(src_vref['name']).AndReturn(backing) + m.StubOutWithMock(vmdk.VMwareVcVmdkDriver, '_get_clone_type') + moxed = vmdk.VMwareVcVmdkDriver._get_clone_type(volume) + moxed.AndReturn(volumeops.LINKED_CLONE_TYPE) + + m.ReplayAll() + self.assertRaises(exception.InvalidVolume, + self._driver.create_cloned_volume, volume, src_vref) + m.UnsetStubs() m.VerifyAll() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder/volume/drivers/huawei/huawei_t.py new/cinder-2013.2/cinder/volume/drivers/huawei/huawei_t.py --- old/cinder-2013.2.rc1/cinder/volume/drivers/huawei/huawei_t.py 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/cinder/volume/drivers/huawei/huawei_t.py 2013-10-17 15:46:47.000000000 +0200 @@ -106,7 +106,8 @@ self._get_iscsi_params(connector['initiator']) # First, add a host if not added before. - host_id = self.common.add_host(connector['host']) + host_id = self.common.add_host(connector['host'], + connector['initiator']) # Then, add the iSCSI port to the host. self._add_iscsi_port_to_host(host_id, connector) @@ -324,7 +325,8 @@ self.common._update_login_info() host_id = self.common.remove_map(volume['provider_location'], - connector['host']) + connector['host'], + connector['initiator']) if not self.common._get_host_map_info(host_id): self._remove_iscsi_port(host_id, connector) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder/volume/drivers/huawei/ssh_common.py new/cinder-2013.2/cinder/volume/drivers/huawei/ssh_common.py --- old/cinder-2013.2.rc1/cinder/volume/drivers/huawei/ssh_common.py 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/cinder/volume/drivers/huawei/ssh_common.py 2013-10-17 15:46:47.000000000 +0200 @@ -892,7 +892,7 @@ return hostlun_id - def add_host(self, host_name): + def add_host(self, host_name, initiator=None): """Create a host and add it to hostgroup.""" # Create an OpenStack hostgroup if not created before. hostgroup_name = HOST_GROUP_NAME @@ -902,6 +902,14 @@ self.hostgroup_id = self._get_hostgroup_id(hostgroup_name) # Create a host and add it to the hostgroup. + # Check the old host name to support the upgrade from grizzly to + # higher versions. + if initiator: + old_host_name = HOST_NAME_PREFIX + str(hash(initiator)) + old_host_id = self._get_host_id(old_host_name, self.hostgroup_id) + if old_host_id is not None: + return old_host_id + host_name = HOST_NAME_PREFIX + host_name host_id = self._get_host_id(host_name, self.hostgroup_id) if host_id is None: @@ -1003,13 +1011,20 @@ 'LUN %s' % lun_id, cli_cmd, out) - def remove_map(self, volume_id, host_name): + def remove_map(self, volume_id, host_name, initiator=None): """Remove host map.""" - host_name = HOST_NAME_PREFIX + host_name - host_id = self._get_host_id(host_name, self.hostgroup_id) + # Check the old host name to support the upgrade from grizzly to + # higher versions. + host_id = None + if initiator: + old_host_name = HOST_NAME_PREFIX + str(hash(initiator)) + host_id = self._get_host_id(old_host_name, self.hostgroup_id) if host_id is None: - LOG.error(_('remove_map: Host %s does not exist.') % host_name) - raise exception.HostNotFound(host=host_name) + host_name = HOST_NAME_PREFIX + host_name + host_id = self._get_host_id(host_name, self.hostgroup_id) + if host_id is None: + LOG.error(_('remove_map: Host %s does not exist.') % host_name) + raise exception.HostNotFound(host=host_name) if not self._check_volume_created(volume_id): LOG.error(_('remove_map: Volume %s does not exist.') % volume_id) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder/volume/drivers/lvm.py new/cinder-2013.2/cinder/volume/drivers/lvm.py --- old/cinder-2013.2.rc1/cinder/volume/drivers/lvm.py 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/cinder/volume/drivers/lvm.py 2013-10-17 15:46:47.000000000 +0200 @@ -380,7 +380,8 @@ def extend_volume(self, volume, new_size): """Extend an existing voumes size.""" - self.vg.extend_volume(volume['name'], new_size) + self.vg.extend_volume(volume['name'], + self._sizestr(new_size)) class LVMISCSIDriver(LVMVolumeDriver, driver.ISCSIDriver): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder/volume/drivers/storwize_svc.py new/cinder-2013.2/cinder/volume/drivers/storwize_svc.py --- old/cinder-2013.2.rc1/cinder/volume/drivers/storwize_svc.py 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/cinder/volume/drivers/storwize_svc.py 2013-10-17 15:46:47.000000000 +0200 @@ -51,6 +51,7 @@ from cinder import exception from cinder.openstack.common import excutils from cinder.openstack.common import log as logging +from cinder.openstack.common import loopingcall from cinder.openstack.common import processutils from cinder.openstack.common import strutils from cinder import utils @@ -112,6 +113,8 @@ CONF = cfg.CONF CONF.register_opts(storwize_svc_opts) +CHECK_FCMAPPING_INTERVAL = 300 + class StorwizeSVCDriver(san.SanDriver): """IBM Storwize V7000 and SVC iSCSI/FC volume driver. @@ -1243,55 +1246,73 @@ return True def _ensure_vdisk_no_fc_mappings(self, name, allow_snaps=True): - # Ensure vdisk has no FlashCopy mappings + """Ensure vdisk has no flashcopy mappings.""" + timer = loopingcall.FixedIntervalLoopingCall( + self._check_vdisk_fc_mappings, name, allow_snaps) + # Create a timer greenthread. The default volume service heart + # beat is every 10 seconds. The flashcopy usually takes hours + # before it finishes. Don't set the sleep interval shorter + # than the heartbeat. Otherwise volume service heartbeat + # will not be serviced. + LOG.debug(_('Calling _ensure_vdisk_no_fc_mappings: vdisk %s') + % name) + ret = timer.start(interval=CHECK_FCMAPPING_INTERVAL).wait() + timer.stop() + return ret + + def _check_vdisk_fc_mappings(self, name, allow_snaps=True): + """FlashCopy mapping check helper.""" + + LOG.debug(_('Loopcall: _check_vdisk_fc_mappings(), vdisk %s') % name) mapping_ids = self._get_vdisk_fc_mappings(name) - while len(mapping_ids): - wait_for_copy = False - for map_id in mapping_ids: - attrs = self._get_flashcopy_mapping_attributes(map_id) - if not attrs: - continue - source = attrs['source_vdisk_name'] - target = attrs['target_vdisk_name'] - copy_rate = attrs['copy_rate'] - status = attrs['status'] - - if copy_rate == '0': - # Case #2: A vdisk that has snapshots - if source == name: - if not allow_snaps: - return False - ssh_cmd = ['svctask', 'chfcmap', '-copyrate', '50', - '-autodelete', 'on', map_id] - out, err = self._run_ssh(ssh_cmd) - wait_for_copy = True - # Case #3: A snapshot - else: - msg = (_('Vdisk %(name)s not involved in ' - 'mapping %(src)s -> %(tgt)s') % - {'name': name, 'src': source, 'tgt': target}) - self._driver_assert(target == name, msg) - if status in ['copying', 'prepared']: - self._run_ssh(['svctask', 'stopfcmap', map_id]) - elif status in ['stopping', 'preparing']: - wait_for_copy = True - else: - self._run_ssh(['svctask', 'rmfcmap', '-force', - map_id]) - # Case 4: Copy in progress - wait and will autodelete + wait_for_copy = False + for map_id in mapping_ids: + attrs = self._get_flashcopy_mapping_attributes(map_id) + if not attrs: + continue + source = attrs['source_vdisk_name'] + target = attrs['target_vdisk_name'] + copy_rate = attrs['copy_rate'] + status = attrs['status'] + + if copy_rate == '0': + # Case #2: A vdisk that has snapshots. Return + # False if snapshot is not allowed. + if source == name: + if not allow_snaps: + raise loopingcall.LoopingCallDone(retvalue=False) + ssh_cmd = ['svctask', 'chfcmap', '-copyrate', '50', + '-autodelete', 'on', map_id] + out, err = self._run_ssh(ssh_cmd) + wait_for_copy = True + # Case #3: A snapshot else: - if status == 'prepared': + msg = (_('Vdisk %(name)s not involved in ' + 'mapping %(src)s -> %(tgt)s') % + {'name': name, 'src': source, 'tgt': target}) + self._driver_assert(target == name, msg) + if status in ['copying', 'prepared']: self._run_ssh(['svctask', 'stopfcmap', map_id]) - self._run_ssh(['svctask', 'rmfcmap', '-force', map_id]) - elif status == 'idle_or_copied': - # Prepare failed - self._run_ssh(['svctask', 'rmfcmap', '-force', map_id]) - else: + # Need to wait for the fcmap to change to + # stopped state before remove fcmap + wait_for_copy = True + elif status in ['stopping', 'preparing']: wait_for_copy = True - if wait_for_copy: - time.sleep(5) - mapping_ids = self._get_vdisk_fc_mappings(name) - return True + else: + self._run_ssh(['svctask', 'rmfcmap', '-force', + map_id]) + # Case 4: Copy in progress - wait and will autodelete + else: + if status == 'prepared': + self._run_ssh(['svctask', 'stopfcmap', map_id]) + self._run_ssh(['svctask', 'rmfcmap', '-force', map_id]) + elif status == 'idle_or_copied': + # Prepare failed + self._run_ssh(['svctask', 'rmfcmap', '-force', map_id]) + else: + wait_for_copy = True + if not wait_for_copy or not len(mapping_ids): + raise loopingcall.LoopingCallDone(retvalue=True) def _delete_vdisk(self, name, force): """Deletes existing vdisks. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder/volume/drivers/vmware/vim.py new/cinder-2013.2/cinder/volume/drivers/vmware/vim.py --- old/cinder-2013.2.rc1/cinder/volume/drivers/vmware/vim.py 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/cinder/volume/drivers/vmware/vim.py 2013-10-17 15:46:47.000000000 +0200 @@ -118,19 +118,20 @@ def __getattr__(self, attr_name): """Makes the API call and gets the result.""" - def retrieve_properties_fault_checker(response): - """Checks the RetrieveProperties response for errors. + def retrieve_properties_ex_fault_checker(response): + """Checks the RetrievePropertiesEx response for errors. Certain faults are sent as part of the SOAP body as property of missingSet. For example NotAuthenticated fault. The method raises appropriate VimFaultException when an error is found. - :param response: Response from RetrieveProperties API call + :param response: Response from RetrievePropertiesEx API call """ + fault_list = [] if not response: # This is the case when the session has timed out. ESX SOAP - # server sends an empty RetrievePropertiesResponse. Normally + # server sends an empty RetrievePropertiesExResponse. Normally # missingSet in the returnval field has the specifics about # the error, but that's not the case with a timed out idle # session. It is as bad as a terminated session for we cannot @@ -150,7 +151,7 @@ raise error_util.VimFaultException(fault_list, _("Error(s): %s occurred " "in the call to " - "RetrieveProperties.") % + "RetrievePropertiesEx.") % exc_msg_list) def vim_request_handler(managed_object, **kwargs): @@ -163,15 +164,16 @@ :param kwargs: Keyword arguments of the call :return: Response of the API call """ + try: if isinstance(managed_object, str): # For strings use string value for value and type # of the managed object. managed_object = get_moref(managed_object, managed_object) - request = getattr(self._client.service, attr_name) + request = getattr(self.client.service, attr_name) response = request(managed_object, **kwargs) - if (attr_name.lower() == 'retrieveproperties'): - retrieve_properties_fault_checker(response) + if (attr_name.lower() == 'retrievepropertiesex'): + retrieve_properties_ex_fault_checker(response) return response except error_util.VimFaultException as excep: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder/volume/drivers/vmware/vmdk.py new/cinder-2013.2/cinder/volume/drivers/vmware/vmdk.py --- old/cinder-2013.2.rc1/cinder/volume/drivers/vmware/vmdk.py 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/cinder/volume/drivers/vmware/vmdk.py 2013-10-17 15:46:47.000000000 +0200 @@ -437,9 +437,16 @@ If the volume does not have a backing then simply pass, else create a snapshot. + Snapshot of only available volume is supported. :param snapshot: Snapshot object """ + + volume = snapshot['volume'] + if volume['status'] != 'available': + msg = _("Snapshot of volume not supported in state: %s.") + LOG.error(msg % volume['status']) + raise exception.InvalidVolume(msg % volume['status']) backing = self.volumeops.get_backing(snapshot['volume_name']) if not backing: LOG.info(_("There is no backing, so will not create " @@ -461,9 +468,16 @@ If the volume does not have a backing or the snapshot does not exist then simply pass, else delete the snapshot. + Snapshot deletion of only available volume is supported. :param snapshot: Snapshot object """ + + volume = snapshot['volume'] + if volume['status'] != 'available': + msg = _("Delete snapshot of volume not supported in state: %s.") + LOG.error(msg % volume['status']) + raise exception.InvalidVolume(msg % volume['status']) backing = self.volumeops.get_backing(snapshot['volume_name']) if not backing: LOG.info(_("There is no backing, and so there is no " @@ -655,19 +669,24 @@ def copy_volume_to_image(self, context, volume, image_service, image_meta): """Creates glance image from volume. + Upload of only available volume is supported. Steps followed are: 1. Get the name of the vmdk file which the volume points to right now. Can be a chain of snapshots, so we need to know the last in the chain. - 2. Create the snapshot. A new vmdk is created which the volume points - to now. The earlier vmdk becomes read-only. - 3. Call CopyVirtualDisk which coalesces the disk chain to form a + 2. Call CopyVirtualDisk which coalesces the disk chain to form a single vmdk, rather a .vmdk metadata file and a -flat.vmdk disk data file. - 4. Now upload the -flat.vmdk file to the image store. - 5. Delete the coalesced .vmdk and -flat.vmdk created. + 3. Now upload the -flat.vmdk file to the image store. + 4. Delete the coalesced .vmdk and -flat.vmdk created. """ + + if volume['status'] != 'available': + msg = _("Upload to glance of volume not supported in state: %s.") + LOG.error(msg % volume['status']) + raise exception.InvalidVolume(msg % volume['status']) + LOG.debug(_("Copy Volume: %s to new image.") % volume['name']) VMwareEsxVmdkDriver._validate_disk_format(image_meta['disk_format']) @@ -680,12 +699,8 @@ vmdk_file_path = self.volumeops.get_vmdk_path(backing) datastore_name = volumeops.split_datastore_path(vmdk_file_path)[0] - # Create a snapshot + # Create a copy of the vmdk into a tmp file image_id = image_meta['id'] - snapshot_name = "snapshot-%s" % image_id - self.volumeops.create_snapshot(backing, snapshot_name, None, True) - - # Create a copy of the snapshotted vmdk into a tmp file tmp_vmdk_file_path = '[%s] %s.vmdk' % (datastore_name, image_id) host = self.volumeops.get_host(backing) datacenter = self.volumeops.get_dc(host) @@ -841,10 +856,12 @@ """Creates volume clone. If source volume's backing does not exist, then pass. + Linked clone of attached volume is not supported. :param volume: New Volume object :param src_vref: Source Volume object """ + backing = self.volumeops.get_backing(src_vref['name']) if not backing: LOG.info(_("There is no backing for the source volume: %(src)s. " @@ -854,6 +871,11 @@ clone_type = VMwareVcVmdkDriver._get_clone_type(volume) snapshot = None if clone_type == volumeops.LINKED_CLONE_TYPE: + if src_vref['status'] != 'available': + msg = _("Linked clone of source volume not supported " + "in state: %s.") + LOG.error(msg % src_vref['status']) + raise exception.InvalidVolume(msg % src_vref['status']) # For performing a linked clone, we snapshot the volume and # then create the linked clone out of this snapshot point. name = 'snapshot-%s' % volume['id'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder/volume/manager.py new/cinder-2013.2/cinder/volume/manager.py --- old/cinder-2013.2.rc1/cinder/volume/manager.py 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/cinder/volume/manager.py 2013-10-17 15:46:47.000000000 +0200 @@ -64,6 +64,8 @@ from cinder.taskflow import states +from eventlet.greenpool import GreenPool + LOG = logging.getLogger(__name__) QUOTAS = quota.QUOTAS @@ -76,6 +78,10 @@ default=300, help='Timeout for creating the volume to migrate to ' 'when performing volume migration (seconds)'), + cfg.BoolOpt('volume_service_inithost_offload', + default=False, + help='Offload pending volume delete during ' + 'volume service startup'), ] CONF = cfg.CONF @@ -144,6 +150,8 @@ *args, **kwargs) self.configuration = Configuration(volume_manager_opts, config_group=service_name) + self._tp = GreenPool() + if not volume_driver: # Get from configuration, which will get the default # if its not using the multi backend @@ -165,6 +173,9 @@ configuration=self.configuration, db=self.db) + def _add_to_threadpool(self, func, *args, **kwargs): + self._tp.spawn_n(func, *args, **kwargs) + def init_host(self): """Do any initialization that needs to be run if this is a standalone service. @@ -208,7 +219,15 @@ for volume in volumes: if volume['status'] == 'deleting': LOG.info(_('Resuming delete on volume: %s') % volume['id']) - self.delete_volume(ctxt, volume['id']) + if CONF.volume_service_inithost_offload: + # Offload all the pending volume delete operations to the + # threadpool to prevent the main volume service thread + # from being blocked. + self._add_to_threadpool(self.delete_volume(ctxt, + volume['id'])) + else: + # By default, delete volumes sequentially + self.delete_volume(ctxt, volume['id']) # collect and publish service capabilities self.publish_service_capabilities(ctxt) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/cinder.egg-info/PKG-INFO new/cinder-2013.2/cinder.egg-info/PKG-INFO --- old/cinder-2013.2.rc1/cinder.egg-info/PKG-INFO 2013-10-04 11:14:34.000000000 +0200 +++ new/cinder-2013.2/cinder.egg-info/PKG-INFO 2013-10-17 15:48:37.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: cinder -Version: 2013.2.rc1 +Version: 2013.2 Summary: OpenStack Block Storage Home-page: http://www.openstack.org/ Author: OpenStack diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.rc1/etc/cinder/cinder.conf.sample new/cinder-2013.2/etc/cinder/cinder.conf.sample --- old/cinder-2013.2.rc1/etc/cinder/cinder.conf.sample 2013-10-04 11:11:50.000000000 +0200 +++ new/cinder-2013.2/etc/cinder/cinder.conf.sample 2013-10-17 15:46:47.000000000 +0200 @@ -1760,6 +1760,10 @@ # performing volume migration (seconds) (integer value) #migration_create_volume_timeout_secs=300 +# Offload pending volume delete during volume service startup +# (boolean value) +#volume_service_inithost_offload=false + # # Options defined in cinder.volume.utils @@ -1770,4 +1774,4 @@ #volume_dd_blocksize=1M -# Total option count: 381 +# Total option count: 382 -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
