Build from master
authorSergey Otpuschennikov <sotpuschennikov@mirantis.com>
Mon, 7 Jul 2014 07:33:14 +0000 (11:33 +0400)
committerSergey Otpuschennikov <sotpuschennikov@mirantis.com>
Tue, 12 Aug 2014 07:25:17 +0000 (11:25 +0400)
Change-Id: Ib3370c25d038003e75ca06f7f39bc8e518ab0422

24 files changed:
debian/changelog
debian/cinder-common.install
debian/cinder-common.postinst
debian/cinder-volume.install
debian/cinder_sudoers
debian/control
debian/patches/MIRA-Do-not-clone-non-raw-images-in-rbd-backend.patch [deleted file]
debian/patches/fix-babel-requirements.patch [deleted file]
debian/patches/fix-sqlalchemy-requirements.patch [deleted file]
debian/patches/series [deleted file]
debian/rules
rpm/SOURCES/0001-Ensure-we-don-t-access-the-net-when-building-docs.patch [deleted file]
rpm/SOURCES/0001-Remove-runtime-dep-on-python-pbr-python-d2to1.patch [moved from rpm/SOURCES/0003-Remove-runtime-dep-on-python-pbr-python-d2to1.patch with 90% similarity]
rpm/SOURCES/0002-Revert-Switch-over-to-oslosphinx.patch [new file with mode: 0644]
rpm/SOURCES/0002-Use-updated-parallel-install-versions-of-epel-packag.patch [deleted file]
rpm/SOURCES/0004-Revert-Use-oslo.sphinx-and-remove-local-copy-of-doc-.patch [deleted file]
rpm/SOURCES/MIRA-Do-not-clone-non-raw-images-in-rbd-backend.patch [deleted file]
rpm/SOURCES/cinder-dist.conf
rpm/SOURCES/cinder-tgt.conf
rpm/SOURCES/openstack-cinder-api.upstart [deleted file]
rpm/SOURCES/openstack-cinder-backup.upstart [deleted file]
rpm/SOURCES/openstack-cinder-scheduler.upstart [deleted file]
rpm/SOURCES/openstack-cinder-volume.upstart [deleted file]
rpm/SPECS/openstack-cinder.spec

index 14d1ad611d3f21ca14d003ef29258d7bd45c4cea..584a238fe9bce6a22d879047f5b00b5070c3aa8b 100644 (file)
@@ -1,8 +1,132 @@
-cinder (1:2013.2-0ubuntu1~cloud0) precise-havana; urgency=low
+cinder (1:2014.2~b2-0ubuntu1) utopic; urgency=medium
 
-  * New upstream release for the Ubuntu Cloud Archive.
+  * New upstream release.
+  * Clean up dependencies:
+    - debian/control: Dropped python-d2to1, python-hp3parclient,
+      python-hplefthandclient, python-lockfile, python-amqplib
+    - debian/control: Add python-oslosphinx, python-requests,
+      python-hacking, python-oslo.db.
+  * debian/patches/fix-requirements.patch: Refreshed.
+
+ -- Chuck Short <zulcss@ubuntu.com>  Thu, 24 Jul 2014 13:44:04 -0400
+
+cinder (1:2014.2~b1-0ubuntu2) utopic; urgency=medium
+
+  * SECURITY UPDATE: specify /etc/nova/rootwrap.conf for use with
+    nova-rootwrap
+    - CVE-2013-1068 (LP: #1185019) 
+
+ -- Chuck Short <zulcss@ubuntu.com>  Wed, 18 Jun 2014 11:37:45 -0400
+
+cinder (1:2014.2~b1-0ubuntu1) utopic; urgency=medium
+
+  * New upstream release.
+  * debian/control: Open up juno release
+  * debian/patches/fix-requirements.patch: Refreshed.
+
+ -- Chuck Short <zulcss@ubuntu.com>  Thu, 12 Jun 2014 10:35:06 -0400
+
+cinder (1:2014.1-0ubuntu1) trusty; urgency=medium
+
+  * New upstream release (LP: #1299055).
+
+ -- Corey Bryant <corey.bryant@canonical.com>  Wed, 16 Apr 2014 13:06:37 -0400
+
+cinder (1:2014.1~rc3-0ubuntu1) trusty; urgency=medium
+
+  * New release candidate (LP: #1299010).
+
+ -- Chuck Short <zulcss@ubuntu.com>  Tue, 15 Apr 2014 09:02:40 -0400
+
+cinder (1:2014.1~rc2-0ubuntu1) trusty; urgency=medium
+
+  * New upstream release (LP: #1299010).
+
+ -- Chuck Short <zulcss@ubuntu.com>  Mon, 07 Apr 2014 11:18:57 -0400
+
+cinder (1:2014.1~rc1-0ubuntu1) trusty; urgency=medium
+
+  * New upstream release (LP: #1299010).
+  * debian/patches/fixup-rbd-str-handling.patch: Dropped no longer needed. 
+  * debian/patches/fix-requirements.patch: Rediffed. 
+  * debian/control: Add python-oslo.messaging.
+
+ -- Chuck Short <zulcss@ubuntu.com>  Fri, 28 Mar 2014 09:48:21 -0400
+
+cinder (1:2014.1~b3-0ubuntu3) trusty; urgency=medium
+
+  * d/p/fixup-rbd-str-handling.patch: Cherry pick fix from upstream
+    Gerrit to resolve issue deleting Ceph volumes and snapshots
+    (LP: #1292433).
+  * d/control,rules: Use upstream run_tests.sh wrapper to execute unit tests,
+    add subunit to BD's to ensure output is correctly formatted.
+
+ -- James Page <james.page@ubuntu.com>  Fri, 14 Mar 2014 11:19:16 +0000
+
+cinder (1:2014.1~b3-0ubuntu2) trusty; urgency=medium
+
+  * d/cinder-common.postinst: Correct use of getent (LP: #1224275). 
+  * d/cinder-common.postinst: Tidy detection of local sqlite database use
+    for db sync operations (LP: #1290423).
+
+ -- James Page <james.page@ubuntu.com>  Thu, 13 Mar 2014 10:11:20 +0000
+
+cinder (1:2014.1~b3-0ubuntu1) trusty; urgency=medium
+
+  [ Chuck Short ]
+  * debian/patches/fix-requirements.patch: Refreshed. 
+  * debian/control: Bump python-keystoneclient to 0.4.2.
+  * debian/patches/skip-tests.patch: Temporarily skip
+    testlefthand tests since the needed python library hasnt been 
+    packaged yet.
+
+  [ James Page ]
+  * d/p/fix-requirements.patch: Refreshed.
+  * d/control,d/p/series/skip-tests.patch: Add BD on python-hplefthandclient,
+    bump version requirement on python-hp3parclient to >= 3.0.0 and drop
+    patch that skips hplefthandclient tests.
+
+  [ Corey Bryant ]
+  * New upstream release.
+
+ -- Corey Bryant <corey.bryant@canonical.com>  Thu, 06 Mar 2014 13:16:02 -0500
+
+cinder (1:2014.1~b2-0ubuntu1) trusty; urgency=low
+
+  [ James Page ]
+  * d/control: Add versioned dependency python-six >= 1.4.1 (LP: #1259203). 
+  * d/p/*: Refreshed.
+
+  [Chuck Short]
+  * New upstream release.
+  * debian/control: Add python-taskflow as a dependency.
+  * debian/control: Add python-oslo.rootwrap as a dependency.
+
+ -- Chuck Short <zulcss@ubuntu.com>  Thu, 23 Jan 2014 12:41:54 -0500
+
+cinder (1:2014.1~b1-0ubuntu1) trusty; urgency=low
+
+  [ Chuck Short ]
+  * New upstream release.
+  * debian/control:
+    - Open icehouse release.
+    - Add python-rtslib as a dependency.
+  * debian/patches/fix-sqlalchemy-requirements.patch: Dropped no longer needed.
+  * debian/patches/fix-babel-requirements.patch: Dropped no longer needed.
+  * debian/paches/fix-requirements.patch:  Fixed up requirements.txt for 
+    dependencies we have in Ubuntu.
+  * debian/cinder-common.install: Add "cinder-rtstool".
+
+  [ James Page ]
+  * debian/patches/*: Refresh.
+
+ -- Chuck Short <zulcss@ubuntu.com>  Thu, 05 Dec 2013 21:30:40 -0500
+
+cinder (1:2013.2-0ubuntu1) saucy; urgency=low
+
+  * New upstream release (LP: #1236462).
 
- -- James Page <james.page@ubuntu.com>  Wed, 16 Oct 2013 11:27:06 +0100
+ -- Chuck Short <zulcss@ubuntu.com>  Thu, 17 Oct 2013 10:00:43 -0400
 
 cinder (1:2013.2~rc3-0ubuntu1) saucy; urgency=low
 
index 3d068db3d5a2436a302d67a99a588c4482beb074..0269adf17c46264be2fc4fa2d6e227df541e5683 100644 (file)
@@ -6,4 +6,4 @@ etc/cinder/policy.json etc/cinder
 etc/cinder/rootwrap.conf etc/cinder
 usr/bin/cinder-manage
 usr/bin/cinder-rootwrap
-usr/bin/cinder-rpc-zmq-receiver
+usr/bin/cinder-rtstool
index 3443c56fa6c0aadeccfadde7b0088cb12e87d0c8..8045dbffb5afd52d18908d4bfcddf3470f23fd55 100644 (file)
@@ -1,11 +1,11 @@
 #!/bin/sh -e
 
 if [ "$1" = "configure" ]; then
-    if ! getenv group cinder > /dev/null 2>&1; then
+    if ! getent group cinder > /dev/null 2>&1; then
         addgroup --system cinder >/dev/null
     fi
 
-    if ! getenv passwd cinder > /dev/null 2>&1; then
+    if ! getent passwd cinder > /dev/null 2>&1; then
         adduser --system --home /var/lib/cinder --ingroup cinder --no-create-home \
             --shell /bin/false cinder
     fi
@@ -19,7 +19,8 @@ if [ "$1" = "configure" ]; then
     chmod 0755 /etc/cinder/rootwrap.d
     chown root:root /etc/cinder/rootwrap.conf
 
-    if ! grep -q sql_connection /etc/cinder/cinder.conf
+    if ! grep -qE "^(sql_)?connection.*" /etc/cinder/cinder.conf || \
+         grep -qE "^(sql_)?connection.*sqlite.*" /etc/cinder/cinder.conf
     then
         su -s /bin/sh -c 'cinder-manage db sync' cinder
     fi
index 6ae49b0cbb43a28d17b2412749f73761ca7fa8dd..bbaf426b33a3d21842f07d5119ccf71190d7e715 100644 (file)
@@ -1,5 +1,4 @@
 debian/cinder_tgt.conf etc/tgt/conf.d
 etc/cinder/rootwrap.d/volume.filters /etc/cinder/rootwrap.d
-usr/bin/cinder-clear-rabbit-queues
 usr/bin/cinder-volume
 usr/bin/cinder-volume-usage-audit
index 73142ab4e2f8fb718177ae9c1b619fc0ee9c5c4a..d38575d4db28c65dab57199ec2497cc2452df9e3 100644 (file)
@@ -1,3 +1,3 @@
 Defaults:cinder !requiretty
 
-cinder ALL = (root) NOPASSWD: /usr/bin/cinder-rootwrap 
+cinder ALL = (root) NOPASSWD: /usr/bin/cinder-rootwrap  /etc/cinder/rootwrap.conf
index 1f20f0fb89e77b638f0dab52762ac2e6cb110d0d..1be8693f3d34f30cc942d58ac1547e212e2bc46b 100644 (file)
@@ -4,47 +4,52 @@ Priority: extra
 Maintainer: Chuck Short <zulcss@ubuntu.com>
 Build-Depends: debhelper (>= 8.0.0), python-all (>= 2.6)
 Build-Depends-Indep:
- python-amqplib (>= 0.6.1),
  python-anyjson (>= 0.3.3),
- python-babel,
+ python-babel (>= 1.3),
  python-coverage,
- python-d2to1,
  python-eventlet (>= 0.13.0),
  python-fixtures (>= 0.3.14),
  python-glanceclient (>= 1:0.9.0),
  python-greenlet (>= 0.3.2),
- python-hp3parclient (>= 2.0.0),
+ python-hacking,
  python-iso8601,
- python-keystoneclient (>= 1:0.3.0),
+ python-keystoneclient (>= 1:0.4.2),
+ python-keystonemiddleware (>= 1.0.0),
  python-kombu (>= 2.5.12),
- python-lockfile,
  python-lxml (>= 2.3),
- python-migrate,
+ python-migrate (>= 0.9.1),
  python-mock,
  python-mox,
- python-mysqldb,
+ python-mysqldb        ,
  python-netaddr,
- python-novaclient (>= 1:2.15.0),
- python-oslo.config (>= 1:1.1.0),
- python-paramiko (>= 1.8),
+ python-novaclient (>= 2.17.0),
+ python-oslo.config (>= 1.2.1),
+ python-oslo.db,
+ python-oslo.rootwrap,
+ python-oslo.messaging,
+ python-oslosphinx,
+ python-paramiko (>= 1.13),
  python-paste,
- python-pastedeploy,
- python-pbr (>= 0.5.21),
+ python-pastedeploy (>= 1.5),
+ python-requests,
+ python-pbr (>= 0.6), python-pbr (<< 0.7) | python-pbr (>> 0.7), python-pbr (<< 1.0),
  python-routes,
  python-setuptools,
- python-six,
+ python-six (>= 1.7.0),
  python-sphinx,
- python-sqlalchemy (>= 0.8.2),
- python-stevedore (>= 0.10),
+ python-sqlalchemy (>= 0.8.4), python-sqlalchemy (<< 0.9.5) | python-sqlalchemy (>> 0.9.5), python-sqlalchemy (<= 0.9.99),
+ python-stevedore (>= 0.14),
  python-suds,
- python-swiftclient (>= 1:1.5),
+ python-swiftclient (>= 2.0.2),
+ python-taskflow,
  python-testtools (>= 0.9.32),
  python-webob (>= 1.2.3),
+ subunit,
  testrepository (>= 0.0.17)
 Standards-Version: 3.9.4
 Homepage: http://launchpad.net/cinder
-Vcs-Browser: http://bazaar.launchpad.net/~ubuntu-server-dev/cinder/havana/files
-Vcs-Bzr: https://code.launchpad.net/~ubuntu-server-dev/cinder/havana
+Vcs-Browser: http://bazaar.launchpad.net/~ubuntu-server-dev/cinder/juno/files
+Vcs-Bzr: https://code.launchpad.net/~ubuntu-server-dev/cinder/juno
 XS-Testsuite: autopkgtest
 
 Package: python-cinder
@@ -53,30 +58,32 @@ Architecture: all
 Depends:
  python-amqplib (>= 0.6.1),
  python-anyjson (>= 0.3.3),
- python-babel,
+ python-babel (>= 1.3),
  python-eventlet (>= 0.13.0),
  python-glanceclient (>= 1:0.9.0),
  python-greenlet (>= 0.3.2),
- python-importlib,
- python-iso8601,
+ python-iso8601 (>= 0.1.9) ,
  python-keystoneclient (>= 1:0.3.0),
+ python-keystonemiddleware (>= 1.0.0),
  python-kombu (>= 2.5.12),
  python-lockfile,
  python-lxml (>= 2.3),
- python-migrate,
- python-mysqldb,
- python-netaddr,
+ python-migrate (>= 0.9.1),
+ python-netaddr (>= 0.7.6),
  python-novaclient (>= 1:2.12.0),
- python-oslo.config (>= 1:1.1.0),
- python-paramiko (>= 1.8),
+ python-oslo.config (>= 1:1.2.1),
+ python-oslo.messaging,
+ python-paramiko (>= 1.13),
  python-paste,
- python-pastedeploy,
- python-routes,
- python-six,
- python-sqlalchemy (>= 0.8.2),
- python-stevedore (>= 0.10),
+ python-pastedeploy (>= 1.5),
+ python-routes (>= 1.12.3), python-routes (<< 2.0) | python-routes (> 2.0),
+ python-six (>= 1.7.0),
+ python-sqlalchemy (>= 0.8.4), python-sqlalchemy (<< 0.9.5) | python-sqlalchemy (>> 0.9.5), python-sqlalchemy (<= 0.9.99),
+ python-stevedore (>= 0.14),
  python-suds,
- python-swiftclient (>= 1:1.5),
+ python-swiftclient (>= 2.0.2),
+ python-taskflow,
+ python-rtslib-fb (>= 2.1.39),
  python-webob (>= 1.2.3),
  ${misc:Depends},
  ${python:Depends}
diff --git a/debian/patches/MIRA-Do-not-clone-non-raw-images-in-rbd-backend.patch b/debian/patches/MIRA-Do-not-clone-non-raw-images-in-rbd-backend.patch
deleted file mode 100755 (executable)
index 0b1f085..0000000
+++ /dev/null
@@ -1,496 +0,0 @@
-From fd7e9dd59ffa346bed5a11e5312f4bb1bf114ab4 Mon Sep 17 00:00:00 2001
-From: Dmitry Borodaenko <angdraug@gmail.com>
-Date: Wed, 27 Nov 2013 14:33:00 -0800
-Subject: [PATCH] Do not clone non-raw images in rbd backend
-
-RBD backend only supports booting from images in raw format. A volume
-that was cloned from an image in any other format is not bootable. The
-RBD driver will consider non-raw images to be uncloneable to trigger
-automatic conversion to raw format.
-
-Includes conversion of the corresponding unit test to use mock (instead
-of mox) and expanded comments and error messages from patchset #58893 by
-Edward Hope-Morley.
-
-Change-Id: I5725d2f7576bc1b3e9b874ba944ad17d33a6e2cb
-Closes-Bug: #1246219
-Closes-Bug: #1247998
----
- cinder/tests/test_gpfs.py                     |   6 +-
- cinder/tests/test_netapp_nfs.py               |  12 +-
- cinder/tests/test_rbd.py                      | 168 +++++++++++++++++---------
- cinder/tests/test_volume.py                   |   2 +-
- cinder/volume/driver.py                       |   7 +-
- cinder/volume/drivers/gpfs.py                 |   2 +-
- cinder/volume/drivers/lvm.py                  |   2 +-
- cinder/volume/drivers/netapp/nfs.py           |   2 +-
- cinder/volume/drivers/rbd.py                  |  14 ++-
- cinder/volume/drivers/scality.py              |   2 +-
- cinder/volume/flows/create_volume/__init__.py |   2 +-
- 11 files changed, 144 insertions(+), 75 deletions(-)
-
-diff --git a/cinder/tests/test_gpfs.py b/cinder/tests/test_gpfs.py
-index 4fdb788..1f47c6b 100644
---- a/cinder/tests/test_gpfs.py
-+++ b/cinder/tests/test_gpfs.py
-@@ -288,7 +288,8 @@ class GPFSDriverTestCase(test.TestCase):
-         CONF.gpfs_images_share_mode = 'copy_on_write'
-         self.driver.clone_image(volume,
-                                 None,
--                                self.image_id)
-+                                self.image_id,
-+                                {})
-         self.assertTrue(os.path.exists(volumepath))
-         self.volume.delete_volume(self.context, volume['id'])
-@@ -309,7 +310,8 @@ class GPFSDriverTestCase(test.TestCase):
-         CONF.gpfs_images_share_mode = 'copy'
-         self.driver.clone_image(volume,
-                                 None,
--                                self.image_id)
-+                                self.image_id,
-+                                {})
-         self.assertTrue(os.path.exists(volumepath))
-         self.volume.delete_volume(self.context, volume['id'])
-diff --git a/cinder/tests/test_netapp_nfs.py b/cinder/tests/test_netapp_nfs.py
-index 950efc8..042280e 100644
---- a/cinder/tests/test_netapp_nfs.py
-+++ b/cinder/tests/test_netapp_nfs.py
-@@ -469,7 +469,7 @@ class NetappDirectCmodeNfsDriverTestCase(test.TestCase):
-         drv._post_clone_image(volume)
-         mox.ReplayAll()
--        drv. clone_image(volume, ('image_location', None), 'image_id')
-+        drv.clone_image(volume, ('image_location', None), 'image_id', {})
-         mox.VerifyAll()
-     def get_img_info(self, format):
-@@ -493,7 +493,7 @@ class NetappDirectCmodeNfsDriverTestCase(test.TestCase):
-         mox.ReplayAll()
-         (prop, cloned) = drv. clone_image(
--            volume, ('nfs://127.0.0.1:/share/img-id', None), 'image_id')
-+            volume, ('nfs://127.0.0.1:/share/img-id', None), 'image_id', {})
-         mox.VerifyAll()
-         if not cloned and not prop['provider_location']:
-             pass
-@@ -529,7 +529,7 @@ class NetappDirectCmodeNfsDriverTestCase(test.TestCase):
-         mox.ReplayAll()
-         drv. clone_image(
--            volume, ('nfs://127.0.0.1:/share/img-id', None), 'image_id')
-+            volume, ('nfs://127.0.0.1:/share/img-id', None), 'image_id', {})
-         mox.VerifyAll()
-     def test_clone_image_cloneableshare_notraw(self):
-@@ -566,7 +566,7 @@ class NetappDirectCmodeNfsDriverTestCase(test.TestCase):
-         mox.ReplayAll()
-         drv. clone_image(
--            volume, ('nfs://127.0.0.1/share/img-id', None), 'image_id')
-+            volume, ('nfs://127.0.0.1/share/img-id', None), 'image_id', {})
-         mox.VerifyAll()
-     def test_clone_image_file_not_discovered(self):
-@@ -605,7 +605,7 @@ class NetappDirectCmodeNfsDriverTestCase(test.TestCase):
-         mox.ReplayAll()
-         vol_dict, result = drv. clone_image(
--            volume, ('nfs://127.0.0.1/share/img-id', None), 'image_id')
-+            volume, ('nfs://127.0.0.1/share/img-id', None), 'image_id', {})
-         mox.VerifyAll()
-         self.assertFalse(result)
-         self.assertFalse(vol_dict['bootable'])
-@@ -652,7 +652,7 @@ class NetappDirectCmodeNfsDriverTestCase(test.TestCase):
-         mox.ReplayAll()
-         vol_dict, result = drv. clone_image(
--            volume, ('nfs://127.0.0.1/share/img-id', None), 'image_id')
-+            volume, ('nfs://127.0.0.1/share/img-id', None), 'image_id', {})
-         mox.VerifyAll()
-         self.assertFalse(result)
-         self.assertFalse(vol_dict['bootable'])
-diff --git a/cinder/tests/test_rbd.py b/cinder/tests/test_rbd.py
-index 60de09b..054bbb5 100644
---- a/cinder/tests/test_rbd.py
-+++ b/cinder/tests/test_rbd.py
-@@ -34,6 +34,7 @@ from cinder.tests.test_volume import DriverTestCase
- from cinder import units
- from cinder.volume import configuration as conf
- import cinder.volume.drivers.rbd as driver
-+from cinder.volume.flows import create_volume
- LOG = logging.getLogger(__name__)
-@@ -247,7 +248,8 @@ class RBDTestCase(test.TestCase):
-             self.assertRaises(exception.ImageUnacceptable,
-                               self.driver._parse_location,
-                               loc)
--            self.assertFalse(self.driver._is_cloneable(loc))
-+            self.assertFalse(
-+                self.driver._is_cloneable(loc, {'disk_format': 'raw'}))
-     def test_cloneable(self):
-         self.stubs.Set(self.driver, '_get_fsid', lambda: 'abc')
-@@ -264,12 +266,14 @@ class RBDTestCase(test.TestCase):
-         self.mox.ReplayAll()
--        self.assertTrue(self.driver._is_cloneable(location))
-+        self.assertTrue(
-+            self.driver._is_cloneable(location, {'disk_format': 'raw'}))
-     def test_uncloneable_different_fsid(self):
-         self.stubs.Set(self.driver, '_get_fsid', lambda: 'abc')
-         location = 'rbd://def/pool/image/snap'
--        self.assertFalse(self.driver._is_cloneable(location))
-+        self.assertFalse(
-+            self.driver._is_cloneable(location, {'disk_format': 'raw'}))
-     def test_uncloneable_unreadable(self):
-         self.stubs.Set(self.driver, '_get_fsid', lambda: 'abc')
-@@ -284,7 +288,16 @@ class RBDTestCase(test.TestCase):
-         self.mox.ReplayAll()
--        self.assertFalse(self.driver._is_cloneable(location))
-+        self.assertFalse(
-+            self.driver._is_cloneable(location, {'disk_format': 'raw'}))
-+
-+    def test_uncloneable_bad_format(self):
-+        self.stubs.Set(self.driver, '_get_fsid', lambda: 'abc')
-+        location = 'rbd://abc/pool/image/snap'
-+        formats = ['qcow2', 'vmdk', 'vdi']
-+        for f in formats:
-+            self.assertFalse(
-+                self.driver._is_cloneable(location, {'disk_format': f}))
-     def _copy_image(self):
-         @contextlib.contextmanager
-@@ -504,26 +517,37 @@ class ManagedRBDTestCase(DriverTestCase):
-         super(ManagedRBDTestCase, self).setUp()
-         fake_image.stub_out_image_service(self.stubs)
-         self.volume.driver.set_initialized()
-+        self.called = []
--    def _clone_volume_from_image(self, expected_status,
--                                 clone_works=True):
-+    def _create_volume_from_image(self, expected_status, raw=False,
-+                                  clone_error=False):
-         """Try to clone a volume from an image, and check the status
-         afterwards.
-+
-+        NOTE: if clone_error is True we force the image type to raw otherwise
-+              clone_image is not called
-         """
--        def fake_clone_image(volume, image_location, image_id):
--            return {'provider_location': None}, True
-+        def mock_clone_image(volume, image_location, image_id, image_meta):
-+            self.called.append('clone_image')
-+            if clone_error:
-+                raise exception.CinderException()
-+            else:
-+                return {'provider_location': None}, True
--        def fake_clone_error(volume, image_location, image_id):
--            raise exception.CinderException()
-+        if clone_error:
-+            raw = True
--        self.stubs.Set(self.volume.driver, '_is_cloneable', lambda x: True)
--        if clone_works:
--            self.stubs.Set(self.volume.driver, 'clone_image', fake_clone_image)
-+        # See tests.image.fake for image types.
-+        if raw:
-+            expected_calls = ['clone_image']
-+            image_id = '155d900f-4e14-4e4c-a73d-069cbf4541e6'
-         else:
--            self.stubs.Set(self.volume.driver, 'clone_image', fake_clone_error)
-+            expected_calls = ['clone_image', 'create_volume',
-+                              'copy_image_to_volume']
-+            image_id = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
--        image_id = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
-         volume_id = 1
-+
-         # creating volume testdata
-         db.volume_create(self.context,
-                          {'id': volume_id,
-@@ -533,58 +557,88 @@ class ManagedRBDTestCase(DriverTestCase):
-                           'status': 'creating',
-                           'instance_uuid': None,
-                           'host': 'dummy'})
--        try:
--            if clone_works:
--                self.volume.create_volume(self.context,
--                                          volume_id,
--                                          image_id=image_id)
--            else:
--                self.assertRaises(exception.CinderException,
--                                  self.volume.create_volume,
--                                  self.context,
--                                  volume_id,
--                                  image_id=image_id)
--
--            volume = db.volume_get(self.context, volume_id)
--            self.assertEqual(volume['status'], expected_status)
--        finally:
--            # cleanup
--            db.volume_destroy(self.context, volume_id)
-+
-+        with mock.patch.object(self.volume.driver, 'create_volume') as \
-+                mock_create_volume:
-+            with mock.patch.object(self.volume.driver, 'clone_image',
-+                                   mock_clone_image):
-+                with mock.patch.object(create_volume.CreateVolumeFromSpecTask,
-+                                       '_copy_image_to_volume') as \
-+                        mock_copy_image_to_volume:
-+                    self.volume.driver._is_cloneable = mock.Mock()
-+                    self.volume.driver._is_cloneable.return_value = True
-+
-+                    try:
-+                        if not clone_error:
-+                            self.volume.create_volume(self.context,
-+                                                      volume_id,
-+                                                      image_id=image_id)
-+                        else:
-+                            self.assertRaises(exception.CinderException,
-+                                              self.volume.create_volume,
-+                                              self.context,
-+                                              volume_id,
-+                                              image_id=image_id)
-+
-+                        volume = db.volume_get(self.context, volume_id)
-+                        self.assertEqual(volume['status'], expected_status)
-+                    finally:
-+                        # cleanup
-+                        db.volume_destroy(self.context, volume_id)
-+
-+        if raw:
-+            self.assertEquals(self.called, ['clone_image'])
-+
-+        mock_create_volume.assert_called()
-+        mock_copy_image_to_volume.assert_called()
-     def test_create_vol_from_image_status_available(self):
--        """Verify that before cloning, an image is in the available state."""
--        self._clone_volume_from_image('available', True)
-+        """Clone raw image then verify volume is in available state."""
-+        self._create_volume_from_image('available', raw=True)
-+
-+    def test_create_vol_from_non_raw_image_status_available(self):
-+        """Clone non-raw image then verify volume is in available state."""
-+        self._create_volume_from_image('available', raw=False)
-     def test_create_vol_from_image_status_error(self):
--        """Verify that before cloning, an image is in the available state."""
--        self._clone_volume_from_image('error', False)
-+        """Clone raw image with failure then verify volume is in error
-+        state.
-+        """
-+        self._create_volume_from_image('error', raw=True, clone_error=True)
-     def test_clone_image(self):
--        # Test Failure Case(s)
--        expected = ({}, False)
-+        driver = self.volume.driver
--        self.stubs.Set(self.volume.driver, '_is_cloneable', lambda x: False)
--        image_loc = (object(), object())
--        actual = self.volume.driver.clone_image(object(), image_loc, object())
--        self.assertEqual(expected, actual)
-+        # Test uncloneable case(s)
-+        with mock.patch.object(driver, '_is_cloneable',
-+                               lambda *args: False) as mock_is_cloneable:
-+            image_loc = (mock.Mock(), mock.Mock())
-+            actual = driver.clone_image(mock.Mock(), image_loc,
-+                                        mock.Mock(), {})
-+            self.assertEqual(({}, False), actual)
--        self.stubs.Set(self.volume.driver, '_is_cloneable', lambda x: True)
--        self.assertEqual(expected,
--                         self.volume.driver.clone_image(object(), None, None))
-+        self.assertEqual(({}, False),
-+                         driver.clone_image(object(), None, None, {}))
--        # Test Success Case(s)
-+        # Test success case(s)
-         expected = ({'provider_location': None}, True)
--
--        self.stubs.Set(self.volume.driver, '_parse_location',
--                       lambda x: ('a', 'b', 'c', 'd'))
--
--        self.stubs.Set(self.volume.driver, '_clone', lambda *args: None)
--        self.stubs.Set(self.volume.driver, '_resize', lambda *args: None)
--        actual = self.volume.driver.clone_image(object(), image_loc, object())
--        self.assertEqual(expected, actual)
-+        mpo = mock.patch.object
-+        with mpo(driver, '_is_cloneable', lambda *args: True):
-+            with mpo(driver, '_parse_location',
-+                     lambda x: ('a', 'b', 'c', 'd')):
-+                with mpo(driver, '_clone') as mock_clone:
-+                    with mpo(driver, '_resize') as mock_resize:
-+                        actual = driver.clone_image(mock.Mock(), image_loc,
-+                                                    mock.Mock(),
-+                                                    {'disk_format': 'raw'})
-+                        self.assertEqual(expected, actual)
-+                        mock_clone.assert_called()
-+                        mock_resize.assert_called()
-     def test_clone_success(self):
--        self.stubs.Set(self.volume.driver, '_is_cloneable', lambda x: True)
--        self.stubs.Set(self.volume.driver, 'clone_image', lambda a, b, c: True)
-+        self.stubs.Set(self.volume.driver, '_is_cloneable', lambda *args: True)
-+        self.stubs.Set(self.volume.driver, 'clone_image',
-+                       lambda a, b, c, d: True)
-         image_id = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
--        self.assertTrue(self.volume.driver.clone_image({}, image_id, image_id))
-+        self.assertTrue(self.volume.driver.clone_image({},
-+                        image_id, image_id, {}))
-diff --git a/cinder/tests/test_volume.py b/cinder/tests/test_volume.py
-index 4a0d475..928799f 100644
---- a/cinder/tests/test_volume.py
-+++ b/cinder/tests/test_volume.py
-@@ -1216,7 +1216,7 @@ class VolumeTestCase(BaseVolumeTestCase):
-         def fake_fetch_to_raw(ctx, image_service, image_id, path, size=None):
-             pass
--        def fake_clone_image(volume_ref, image_location, image_id):
-+        def fake_clone_image(volume_ref, image_location, image_id, image_meta):
-             return {'provider_location': None}, True
-         dst_fd, dst_path = tempfile.mkstemp()
-diff --git a/cinder/volume/driver.py b/cinder/volume/driver.py
-index 21dd12b..dd2be3c 100644
---- a/cinder/volume/driver.py
-+++ b/cinder/volume/driver.py
-@@ -396,7 +396,7 @@ class VolumeDriver(object):
-         connector.disconnect_volume(attach_info['conn']['data'],
-                                     attach_info['device'])
--    def clone_image(self, volume, image_location, image_id):
-+    def clone_image(self, volume, image_location, image_id, image_meta):
-         """Create a volume efficiently from an existing image.
-         image_location is a string whose format depends on the
-@@ -407,6 +407,11 @@ class VolumeDriver(object):
-         It can be used by the driver to introspect internal
-         stores or registry to do an efficient image clone.
-+        image_meta is a dictionary that includes 'disk_format' (e.g.
-+        raw, qcow2) and other image attributes that allow drivers to
-+        decide whether they can clone the image without first requiring
-+        conversion.
-+
-         Returns a dict of volume properties eg. provider_location,
-         boolean indicating whether cloning occurred
-         """
-diff --git a/cinder/volume/drivers/gpfs.py b/cinder/volume/drivers/gpfs.py
-index 9a1a397..8792ad8 100644
---- a/cinder/volume/drivers/gpfs.py
-+++ b/cinder/volume/drivers/gpfs.py
-@@ -463,7 +463,7 @@ class GPFSDriver(driver.VolumeDriver):
-             return '100M'
-         return '%sG' % size_in_g
--    def clone_image(self, volume, image_location, image_id):
-+    def clone_image(self, volume, image_location, image_id, image_meta):
-         return self._clone_image(volume, image_location, image_id)
-     def _is_cloneable(self, image_id):
-diff --git a/cinder/volume/drivers/lvm.py b/cinder/volume/drivers/lvm.py
-index 094436f..c6023eb 100644
---- a/cinder/volume/drivers/lvm.py
-+++ b/cinder/volume/drivers/lvm.py
-@@ -322,7 +322,7 @@ class LVMVolumeDriver(driver.VolumeDriver):
-         finally:
-             self.delete_snapshot(temp_snapshot)
--    def clone_image(self, volume, image_location, image_id):
-+    def clone_image(self, volume, image_location, image_id, image_meta):
-         return None, False
-     def backup_volume(self, context, backup, backup_service):
-diff --git a/cinder/volume/drivers/netapp/nfs.py b/cinder/volume/drivers/netapp/nfs.py
-index 602a1dc..9463137 100644
---- a/cinder/volume/drivers/netapp/nfs.py
-+++ b/cinder/volume/drivers/netapp/nfs.py
-@@ -374,7 +374,7 @@ class NetAppNFSDriver(nfs.NfsDriver):
-             LOG.warning(_('Exception during deleting %s'), ex.__str__())
-             return False
--    def clone_image(self, volume, image_location, image_id):
-+    def clone_image(self, volume, image_location, image_id, image_meta):
-         """Create a volume efficiently from an existing image.
-         image_location is a string whose format depends on the
-diff --git a/cinder/volume/drivers/rbd.py b/cinder/volume/drivers/rbd.py
-index 775ab16..7ed59d0 100644
---- a/cinder/volume/drivers/rbd.py
-+++ b/cinder/volume/drivers/rbd.py
-@@ -706,7 +706,7 @@ class RBDDriver(driver.VolumeDriver):
-         with RADOSClient(self) as client:
-             return client.cluster.get_fsid()
--    def _is_cloneable(self, image_location):
-+    def _is_cloneable(self, image_location, image_meta):
-         try:
-             fsid, pool, image, snapshot = self._parse_location(image_location)
-         except exception.ImageUnacceptable as e:
-@@ -718,6 +718,13 @@ class RBDDriver(driver.VolumeDriver):
-             LOG.debug(reason)
-             return False
-+        if image_meta['disk_format'] != 'raw':
-+            reason = _("rbd image clone requires image format to be "
-+                       "'raw' but image {0} is '{1}'").format(
-+                           image_location, image_meta['disk_format'])
-+            LOG.debug(reason)
-+            return False
-+
-         # check that we can read the image
-         try:
-             with RBDVolumeProxy(self, image,
-@@ -730,9 +737,10 @@ class RBDDriver(driver.VolumeDriver):
-                       dict(loc=image_location, err=e))
-             return False
--    def clone_image(self, volume, image_location, image_id):
-+    def clone_image(self, volume, image_location, image_id, image_meta):
-         image_location = image_location[0] if image_location else None
--        if image_location is None or not self._is_cloneable(image_location):
-+        if image_location is None or not self._is_cloneable(
-+                image_location, image_meta):
-             return ({}, False)
-         prefix, pool, image, snapshot = self._parse_location(image_location)
-         self._clone(volume, pool, image, snapshot)
-diff --git a/cinder/volume/drivers/scality.py b/cinder/volume/drivers/scality.py
-index 4cf49c6..abd6c29 100644
---- a/cinder/volume/drivers/scality.py
-+++ b/cinder/volume/drivers/scality.py
-@@ -250,7 +250,7 @@ class ScalityDriver(driver.VolumeDriver):
-                                   image_meta,
-                                   self.local_path(volume))
--    def clone_image(self, volume, image_location, image_id):
-+    def clone_image(self, volume, image_location, image_id, image_meta):
-         """Create a volume efficiently from an existing image.
-         image_location is a string whose format depends on the
-diff --git a/cinder/volume/flows/create_volume/__init__.py b/cinder/volume/flows/create_volume/__init__.py
-index bb7acd3..e5aa371 100644
---- a/cinder/volume/flows/create_volume/__init__.py
-+++ b/cinder/volume/flows/create_volume/__init__.py
-@@ -1438,7 +1438,7 @@ class CreateVolumeFromSpecTask(base.CinderTask):
-         # dict containing provider_location for cloned volume
-         # and clone status.
-         model_update, cloned = self.driver.clone_image(
--            volume_ref, image_location, image_id)
-+            volume_ref, image_location, image_id, image_meta)
-         if not cloned:
-             # TODO(harlowja): what needs to be rolled back in the clone if this
-             # volume create fails?? Likely this should be a subflow or broken
--- 
-1.8.5.1
-
diff --git a/debian/patches/fix-babel-requirements.patch b/debian/patches/fix-babel-requirements.patch
deleted file mode 100644 (file)
index 675cc90..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-Author: Revert new babel requirements.
-Author: Chuck Short <zulcss@ubuntu.com>
-Forwarded: No, https://review.openstack.org/#/c/48739/
-diff --git a/requirements.txt b/requirements.txt
-index 219962d..01ec2e6 100644
---- a/requirements.txt
-+++ b/requirements.txt
-@@ -2,7 +2,7 @@ pbr>=0.5.21,<1.0
- amqplib>=0.6.1
- anyjson>=0.3.3
- argparse
--Babel>=1.3
-+Babel>=0.9.6
- eventlet>=0.13.0
- greenlet>=0.3.2
- iso8601>=0.1.8
-
diff --git a/debian/patches/fix-sqlalchemy-requirements.patch b/debian/patches/fix-sqlalchemy-requirements.patch
deleted file mode 100644 (file)
index c4217c6..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -Naurp cinder-2013.2.rc1.orig/requirements.txt cinder-2013.2.rc1/requirements.txt
---- cinder-2013.2.rc1.orig/requirements.txt    2013-10-04 05:11:50.000000000 -0400
-+++ cinder-2013.2.rc1/requirements.txt 2013-10-04 08:33:32.072164528 -0400
-@@ -20,7 +20,7 @@ python-novaclient>=2.15.0
- python-swiftclient>=1.5
- Routes>=1.12.3
- six>=1.4.1
--SQLAlchemy>=0.7.8,<=0.7.99
-+SQLAlchemy>=0.7.8,<=0.8.99
- sqlalchemy-migrate>=0.7.2
- stevedore>=0.10
- suds>=0.4
diff --git a/debian/patches/series b/debian/patches/series
deleted file mode 100644 (file)
index be203b8..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-fix-sqlalchemy-requirements.patch
-fix-babel-requirements.patch
-MIRA-Do-not-clone-non-raw-images-in-rbd-backend.patch
index d4ef58857951e1e532f446879a6b722d7fe70fb6..f38a7dc148abaeaeae0b954bd162b0d489bb6134 100755 (executable)
@@ -11,7 +11,7 @@ get-orig-source:
 
 ifeq (,$(findstring nocheck, $(DEB_BUILD_OPTIONS)))
 override_dh_auto_test:
-       testr init && testr run
+       ./run_tests.sh -N -P
 endif
 
 override_dh_install:
diff --git a/rpm/SOURCES/0001-Ensure-we-don-t-access-the-net-when-building-docs.patch b/rpm/SOURCES/0001-Ensure-we-don-t-access-the-net-when-building-docs.patch
deleted file mode 100644 (file)
index 865d8af..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-From 9904118c6d3d130624eaec31878649e41efd1bc2 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
-Date: Fri, 21 Sep 2012 13:33:26 +0100
-Subject: [PATCH] Ensure we don't access the net when building docs
-
-(Note, this has not been sent upstream)
----
- doc/source/conf.py | 1 -
- 1 file changed, 1 deletion(-)
-
-diff --git a/doc/source/conf.py b/doc/source/conf.py
-index e27d458..7a2bf1a 100644
---- a/doc/source/conf.py
-+++ b/doc/source/conf.py
-@@ -29,7 +29,6 @@ sys.path.insert(0, os.path.abspath('./'))
- # or your custom ones.
- extensions = ['sphinx.ext.autodoc',
--              'sphinx.ext.intersphinx',
-               'ext.cinder_todo',
-               'sphinx.ext.coverage',
-               'sphinx.ext.pngmath',
similarity index 90%
rename from rpm/SOURCES/0003-Remove-runtime-dep-on-python-pbr-python-d2to1.patch
rename to rpm/SOURCES/0001-Remove-runtime-dep-on-python-pbr-python-d2to1.patch
index 5fd94c95b8d0ced843ad7bb74d6a0169636f6837..a056afbd2588a9adb9e7092f2c4c453fafc0476b 100644 (file)
@@ -1,4 +1,4 @@
-From 6ed6db76f6e6b1a579d07c3db63283d444385c14 Mon Sep 17 00:00:00 2001
+From 302c285b0193bcae47aaaaec49f51340b4fbe6e7 Mon Sep 17 00:00:00 2001
 From: Eric Harney <eharney@redhat.com>
 Date: Thu, 13 Jun 2013 17:50:12 -0400
 Subject: [PATCH] Remove runtime dep on python-pbr, python-d2to1
@@ -9,10 +9,10 @@ Requires RPM spec to fill in REDHATCINDERVERSION.
  1 file changed, 13 insertions(+), 3 deletions(-)
 
 diff --git a/cinder/version.py b/cinder/version.py
-index ad1ebc0..b4f6fd8 100644
+index e3dbd70..ab8f888 100644
 --- a/cinder/version.py
 +++ b/cinder/version.py
-@@ -14,12 +14,22 @@
+@@ -12,12 +12,22 @@
  #    License for the specific language governing permissions and limitations
  #    under the License.
  
diff --git a/rpm/SOURCES/0002-Revert-Switch-over-to-oslosphinx.patch b/rpm/SOURCES/0002-Revert-Switch-over-to-oslosphinx.patch
new file mode 100644 (file)
index 0000000..f4437c1
--- /dev/null
@@ -0,0 +1,34 @@
+From 15cc208adf811d9a83e8f820fb4be775c5db9a00 Mon Sep 17 00:00:00 2001
+From: Eric Harney <eharney@redhat.com>
+Date: Thu, 27 Mar 2014 14:24:57 -0400
+Subject: [PATCH] Revert "Switch over to oslosphinx"
+
+This reverts commit ea7d4a599224b5d0c7674d03993bbe72c49f0d51.
+---
+ doc/source/conf.py    | 2 +-
+ test-requirements.txt | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/doc/source/conf.py b/doc/source/conf.py
+index ac2eadc..238a922 100644
+--- a/doc/source/conf.py
++++ b/doc/source/conf.py
+@@ -34,7 +34,7 @@ extensions = ['sphinx.ext.autodoc',
+               'sphinx.ext.pngmath',
+               'sphinx.ext.ifconfig',
+               'sphinx.ext.graphviz',
+-              'oslosphinx',
++              'oslo.sphinx',
+               ]
+ # autodoc generation is a bit aggressive and a nuisance
+diff --git a/test-requirements.txt b/test-requirements.txt
+index 56746da..15308b9 100644
+--- a/test-requirements.txt
++++ b/test-requirements.txt
+@@ -13,4 +13,4 @@ sphinx>=1.1.2,<1.2
+ python-subunit>=0.0.18
+ testtools>=0.9.34
+ testrepository>=0.0.18
+-oslosphinx
++oslo.sphinx
diff --git a/rpm/SOURCES/0002-Use-updated-parallel-install-versions-of-epel-packag.patch b/rpm/SOURCES/0002-Use-updated-parallel-install-versions-of-epel-packag.patch
deleted file mode 100644 (file)
index 6f2d741..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-From c8b9384ccf0e9c69f35978f3abbb5e5d5638d859 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
-Date: Wed, 24 Oct 2012 13:44:37 +0100
-Subject: [PATCH] Use updated parallel install versions of epel package
-
-Use sqlalchemy >= 0.6.3 WebOb >= 1.2 Routes >= 1.12.3 PasteDeploy >= 1.5.0
-and depend on the parallel installable
-versions of these packages to satisfy those requirements.
-
-Delve into pkg_resources a little to get it to modify sys.path,
-so that our parallel installed egg takes precedence over the
-system default module versions.
----
- bin/cinder-manage                 |  4 +++-
- cinder/__init__.py                | 30 ++++++++++++++++++++++++++++++
- cinder/db/sqlalchemy/migration.py |  7 ++++++-
- 3 files changed, 39 insertions(+), 2 deletions(-)
-
-diff --git a/bin/cinder-manage b/bin/cinder-manage
-index 3c05d77..9474e2e 100755
---- a/bin/cinder-manage
-+++ b/bin/cinder-manage
-@@ -62,7 +62,6 @@ import sys
- from oslo.config import cfg
--
- # If ../cinder/__init__.py exists, add ../ to Python search path, so that
- # it will override what happens to be installed in /usr/(local/)lib/python...
- POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
-@@ -84,6 +83,9 @@ from cinder.openstack.common import uuidutils
- from cinder import utils
- from cinder import version
-+from sqlalchemy import create_engine, MetaData, Table
-+from sqlalchemy.ext.declarative import declarative_base
-+from sqlalchemy.orm import sessionmaker
- CONF = cfg.CONF
-diff --git a/cinder/__init__.py b/cinder/__init__.py
-index d765b08..720320e 100644
---- a/cinder/__init__.py
-+++ b/cinder/__init__.py
-@@ -30,3 +30,33 @@
- .. moduleauthor:: Manish Singh <yosh@gimp.org>
- .. moduleauthor:: Andy Smith <andy@anarkystic.com>
- """
-+
-+import sys
-+import pkg_resources
-+
-+# If there is a conflicting non egg module,
-+# i.e. an older standard system module installed,
-+# then replace it with this requirement
-+def replace_dist(requirement):
-+    try:
-+        return pkg_resources.require(requirement)
-+    except pkg_resources.VersionConflict:
-+        e = sys.exc_info()[1]
-+        dist=e.args[0]
-+        req=e.args[1]
-+        if dist.key == req.key and not dist.location.endswith('.egg'):
-+            del pkg_resources.working_set.by_key[dist.key]
-+            # We assume there is no need to adjust sys.path
-+            # and the associated pkg_resources.working_set.entries
-+            return pkg_resources.require(requirement)
-+
-+replace_dist("WebOb >= 1.2")
-+replace_dist("SQLAlchemy >= 0.6.3")
-+replace_dist("Routes >= 1.12.3")
-+
-+replace_dist("PasteDeploy >= 1.5.0")
-+# This hack is needed because replace_dist() results in
-+# the standard paste module path being at the start of __path__.
-+# TODO: See can we get pkg_resources to do the right thing directly
-+import paste
-+paste.__path__.insert(0, paste.__path__.pop(-1))
-diff --git a/cinder/db/sqlalchemy/migration.py b/cinder/db/sqlalchemy/migration.py
-index e2463bc..9ba7b73 100644
---- a/cinder/db/sqlalchemy/migration.py
-+++ b/cinder/db/sqlalchemy/migration.py
-@@ -56,7 +56,12 @@ if (not hasattr(migrate, '__version__') or
- # NOTE(jkoelker) Delay importing migrate until we are patched
--from migrate import exceptions as versioning_exceptions
-+try:
-+    # Try the more specific path first (migrate <= 0.6)
-+    from migrate.versioning import exceptions as versioning_exceptions
-+except ImportError:
-+    # Use the newer path (migrate >= 0.7)
-+    from migrate import exceptions as versioning_exceptions
- from migrate.versioning import api as versioning_api
- from migrate.versioning.repository import Repository
diff --git a/rpm/SOURCES/0004-Revert-Use-oslo.sphinx-and-remove-local-copy-of-doc-.patch b/rpm/SOURCES/0004-Revert-Use-oslo.sphinx-and-remove-local-copy-of-doc-.patch
deleted file mode 100644 (file)
index f9609a7..0000000
+++ /dev/null
@@ -1,1237 +0,0 @@
-From bd1bfd86fbeacd893ff5d9abb969c7b0c994fbf4 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
-Date: Mon, 22 Jul 2013 03:14:27 +0100
-Subject: [PATCH] Revert "Use oslo.sphinx and remove local copy of doc theme"
-
-This reverts commit 8b1ae18ba95f04fedc04592b419401d75d448543.
-
-Conflicts:
-
-       test-requirements.txt
----
- doc/source/_static/.gitignore      |   0
- doc/source/_static/.placeholder    |   0
- doc/source/_static/basic.css       | 416 +++++++++++++++++++++++++++++++++++++
- doc/source/_static/default.css     | 230 ++++++++++++++++++++
- doc/source/_static/jquery.tweet.js | 154 ++++++++++++++
- doc/source/_static/tweaks.css      | 218 +++++++++++++++++++
- doc/source/_templates/.gitignore   |   0
- doc/source/_templates/.placeholder |   0
- doc/source/_theme/layout.html      |  95 +++++++++
- doc/source/_theme/theme.conf       |   5 +
- doc/source/conf.py                 |   8 +-
- test-requirements.txt              |   1 -
- 12 files changed, 1121 insertions(+), 6 deletions(-)
- create mode 100644 doc/source/_static/.gitignore
- create mode 100644 doc/source/_static/.placeholder
- create mode 100644 doc/source/_static/basic.css
- create mode 100644 doc/source/_static/default.css
- create mode 100644 doc/source/_static/jquery.tweet.js
- create mode 100644 doc/source/_static/tweaks.css
- create mode 100644 doc/source/_templates/.gitignore
- create mode 100644 doc/source/_templates/.placeholder
- create mode 100644 doc/source/_theme/layout.html
- create mode 100644 doc/source/_theme/theme.conf
-
-diff --git a/doc/source/_static/.gitignore b/doc/source/_static/.gitignore
-new file mode 100644
-index 0000000..e69de29
-diff --git a/doc/source/_static/.placeholder b/doc/source/_static/.placeholder
-new file mode 100644
-index 0000000..e69de29
-diff --git a/doc/source/_static/basic.css b/doc/source/_static/basic.css
-new file mode 100644
-index 0000000..d909ce3
---- /dev/null
-+++ b/doc/source/_static/basic.css
-@@ -0,0 +1,416 @@
-+/**
-+ * Sphinx stylesheet -- basic theme
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ */
-+
-+/* -- main layout ----------------------------------------------------------- */
-+
-+div.clearer {
-+    clear: both;
-+}
-+
-+/* -- relbar ---------------------------------------------------------------- */
-+
-+div.related {
-+    width: 100%;
-+    font-size: 90%;
-+}
-+
-+div.related h3 {
-+    display: none;
-+}
-+
-+div.related ul {
-+    margin: 0;
-+    padding: 0 0 0 10px;
-+    list-style: none;
-+}
-+
-+div.related li {
-+    display: inline;
-+}
-+
-+div.related li.right {
-+    float: right;
-+    margin-right: 5px;
-+}
-+
-+/* -- sidebar --------------------------------------------------------------- */
-+
-+div.sphinxsidebarwrapper {
-+    padding: 10px 5px 0 10px;
-+}
-+
-+div.sphinxsidebar {
-+    float: left;
-+    width: 230px;
-+    margin-left: -100%;
-+    font-size: 90%;
-+}
-+
-+div.sphinxsidebar ul {
-+    list-style: none;
-+}
-+
-+div.sphinxsidebar ul ul,
-+div.sphinxsidebar ul.want-points {
-+    margin-left: 20px;
-+    list-style: square;
-+}
-+
-+div.sphinxsidebar ul ul {
-+    margin-top: 0;
-+    margin-bottom: 0;
-+}
-+
-+div.sphinxsidebar form {
-+    margin-top: 10px;
-+}
-+
-+div.sphinxsidebar input {
-+    border: 1px solid #98dbcc;
-+    font-family: sans-serif;
-+    font-size: 1em;
-+}
-+
-+img {
-+    border: 0;
-+}
-+
-+/* -- search page ----------------------------------------------------------- */
-+
-+ul.search {
-+    margin: 10px 0 0 20px;
-+    padding: 0;
-+}
-+
-+ul.search li {
-+    padding: 5px 0 5px 20px;
-+    background-image: url(file.png);
-+    background-repeat: no-repeat;
-+    background-position: 0 7px;
-+}
-+
-+ul.search li a {
-+    font-weight: bold;
-+}
-+
-+ul.search li div.context {
-+    color: #888;
-+    margin: 2px 0 0 30px;
-+    text-align: left;
-+}
-+
-+ul.keywordmatches li.goodmatch a {
-+    font-weight: bold;
-+}
-+
-+/* -- index page ------------------------------------------------------------ */
-+
-+table.contentstable {
-+    width: 90%;
-+}
-+
-+table.contentstable p.biglink {
-+    line-height: 150%;
-+}
-+
-+a.biglink {
-+    font-size: 1.3em;
-+}
-+
-+span.linkdescr {
-+    font-style: italic;
-+    padding-top: 5px;
-+    font-size: 90%;
-+}
-+
-+/* -- general index --------------------------------------------------------- */
-+
-+table.indextable td {
-+    text-align: left;
-+    vertical-align: top;
-+}
-+
-+table.indextable dl, table.indextable dd {
-+    margin-top: 0;
-+    margin-bottom: 0;
-+}
-+
-+table.indextable tr.pcap {
-+    height: 10px;
-+}
-+
-+table.indextable tr.cap {
-+    margin-top: 10px;
-+    background-color: #f2f2f2;
-+}
-+
-+img.toggler {
-+    margin-right: 3px;
-+    margin-top: 3px;
-+    cursor: pointer;
-+}
-+
-+/* -- general body styles --------------------------------------------------- */
-+
-+a.headerlink {
-+    visibility: hidden;
-+}
-+
-+h1:hover > a.headerlink,
-+h2:hover > a.headerlink,
-+h3:hover > a.headerlink,
-+h4:hover > a.headerlink,
-+h5:hover > a.headerlink,
-+h6:hover > a.headerlink,
-+dt:hover > a.headerlink {
-+    visibility: visible;
-+}
-+
-+div.body p.caption {
-+    text-align: inherit;
-+}
-+
-+div.body td {
-+    text-align: left;
-+}
-+
-+.field-list ul {
-+    padding-left: 1em;
-+}
-+
-+.first {
-+}
-+
-+p.rubric {
-+    margin-top: 30px;
-+    font-weight: bold;
-+}
-+
-+/* -- sidebars -------------------------------------------------------------- */
-+
-+div.sidebar {
-+    margin: 0 0 0.5em 1em;
-+    border: 1px solid #ddb;
-+    padding: 7px 7px 0 7px;
-+    background-color: #ffe;
-+    width: 40%;
-+    float: right;
-+}
-+
-+p.sidebar-title {
-+    font-weight: bold;
-+}
-+
-+/* -- topics ---------------------------------------------------------------- */
-+
-+div.topic {
-+    border: 1px solid #ccc;
-+    padding: 7px 7px 0 7px;
-+    margin: 10px 0 10px 0;
-+}
-+
-+p.topic-title {
-+    font-size: 1.1em;
-+    font-weight: bold;
-+    margin-top: 10px;
-+}
-+
-+/* -- admonitions ----------------------------------------------------------- */
-+
-+div.admonition {
-+    margin-top: 10px;
-+    margin-bottom: 10px;
-+    padding: 7px;
-+}
-+
-+div.admonition dt {
-+    font-weight: bold;
-+}
-+
-+div.admonition dl {
-+    margin-bottom: 0;
-+}
-+
-+p.admonition-title {
-+    margin: 0px 10px 5px 0px;
-+    font-weight: bold;
-+}
-+
-+div.body p.centered {
-+    text-align: center;
-+    margin-top: 25px;
-+}
-+
-+/* -- tables ---------------------------------------------------------------- */
-+
-+table.docutils {
-+    border: 0;
-+    border-collapse: collapse;
-+}
-+
-+table.docutils td, table.docutils th {
-+    padding: 1px 8px 1px 0;
-+    border-top: 0;
-+    border-left: 0;
-+    border-right: 0;
-+    border-bottom: 1px solid #aaa;
-+}
-+
-+table.field-list td, table.field-list th {
-+    border: 0 !important;
-+}
-+
-+table.footnote td, table.footnote th {
-+    border: 0 !important;
-+}
-+
-+th {
-+    text-align: left;
-+    padding-right: 5px;
-+}
-+
-+/* -- other body styles ----------------------------------------------------- */
-+
-+dl {
-+    margin-bottom: 15px;
-+}
-+
-+dd p {
-+    margin-top: 0px;
-+}
-+
-+dd ul, dd table {
-+    margin-bottom: 10px;
-+}
-+
-+dd {
-+    margin-top: 3px;
-+    margin-bottom: 10px;
-+    margin-left: 30px;
-+}
-+
-+dt:target, .highlight {
-+    background-color: #fbe54e;
-+}
-+
-+dl.glossary dt {
-+    font-weight: bold;
-+    font-size: 1.1em;
-+}
-+
-+.field-list ul {
-+    margin: 0;
-+    padding-left: 1em;
-+}
-+
-+.field-list p {
-+    margin: 0;
-+}
-+
-+.refcount {
-+    color: #060;
-+}
-+
-+.optional {
-+    font-size: 1.3em;
-+}
-+
-+.versionmodified {
-+    font-style: italic;
-+}
-+
-+.system-message {
-+    background-color: #fda;
-+    padding: 5px;
-+    border: 3px solid red;
-+}
-+
-+.footnote:target  {
-+    background-color: #ffa
-+}
-+
-+.line-block {
-+    display: block;
-+    margin-top: 1em;
-+    margin-bottom: 1em;
-+}
-+
-+.line-block .line-block {
-+    margin-top: 0;
-+    margin-bottom: 0;
-+    margin-left: 1.5em;
-+}
-+
-+/* -- code displays --------------------------------------------------------- */
-+
-+pre {
-+    overflow: auto;
-+}
-+
-+td.linenos pre {
-+    padding: 5px 0px;
-+    border: 0;
-+    background-color: transparent;
-+    color: #aaa;
-+}
-+
-+table.highlighttable {
-+    margin-left: 0.5em;
-+}
-+
-+table.highlighttable td {
-+    padding: 0 0.5em 0 0.5em;
-+}
-+
-+tt.descname {
-+    background-color: transparent;
-+    font-weight: bold;
-+    font-size: 1.2em;
-+}
-+
-+tt.descclassname {
-+    background-color: transparent;
-+}
-+
-+tt.xref, a tt {
-+    background-color: transparent;
-+    font-weight: bold;
-+}
-+
-+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
-+    background-color: transparent;
-+}
-+
-+/* -- math display ---------------------------------------------------------- */
-+
-+img.math {
-+    vertical-align: middle;
-+}
-+
-+div.body div.math p {
-+    text-align: center;
-+}
-+
-+span.eqno {
-+    float: right;
-+}
-+
-+/* -- printout stylesheet --------------------------------------------------- */
-+
-+@media print {
-+    div.document,
-+    div.documentwrapper,
-+    div.bodywrapper {
-+        margin: 0 !important;
-+        width: 100%;
-+    }
-+
-+    div.sphinxsidebar,
-+    div.related,
-+    div.footer,
-+    #top-link {
-+        display: none;
-+    }
-+}
-diff --git a/doc/source/_static/default.css b/doc/source/_static/default.css
-new file mode 100644
-index 0000000..c8091ec
---- /dev/null
-+++ b/doc/source/_static/default.css
-@@ -0,0 +1,230 @@
-+/**
-+ * Sphinx stylesheet -- default theme
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ */
-+
-+@import url("basic.css");
-+
-+/* -- page layout ----------------------------------------------------------- */
-+
-+body {
-+    font-family: sans-serif;
-+    font-size: 100%;
-+    background-color: #11303d;
-+    color: #000;
-+    margin: 0;
-+    padding: 0;
-+}
-+
-+div.document {
-+    background-color: #1c4e63;
-+}
-+
-+div.documentwrapper {
-+    float: left;
-+    width: 100%;
-+}
-+
-+div.bodywrapper {
-+    margin: 0 0 0 230px;
-+}
-+
-+div.body {
-+    background-color: #ffffff;
-+    color: #000000;
-+    padding: 0 20px 30px 20px;
-+}
-+
-+div.footer {
-+    color: #ffffff;
-+    width: 100%;
-+    padding: 9px 0 9px 0;
-+    text-align: center;
-+    font-size: 75%;
-+}
-+
-+div.footer a {
-+    color: #ffffff;
-+    text-decoration: underline;
-+}
-+
-+div.related {
-+    background-color: #133f52;
-+    line-height: 30px;
-+    color: #ffffff;
-+}
-+
-+div.related a {
-+    color: #ffffff;
-+}
-+
-+div.sphinxsidebar {
-+}
-+
-+div.sphinxsidebar h3 {
-+    font-family: 'Trebuchet MS', sans-serif;
-+    color: #ffffff;
-+    font-size: 1.4em;
-+    font-weight: normal;
-+    margin: 0;
-+    padding: 0;
-+}
-+
-+div.sphinxsidebar h3 a {
-+    color: #ffffff;
-+}
-+
-+div.sphinxsidebar h4 {
-+    font-family: 'Trebuchet MS', sans-serif;
-+    color: #ffffff;
-+    font-size: 1.3em;
-+    font-weight: normal;
-+    margin: 5px 0 0 0;
-+    padding: 0;
-+}
-+
-+div.sphinxsidebar p {
-+    color: #ffffff;
-+}
-+
-+div.sphinxsidebar p.topless {
-+    margin: 5px 10px 10px 10px;
-+}
-+
-+div.sphinxsidebar ul {
-+    margin: 10px;
-+    padding: 0;
-+    color: #ffffff;
-+}
-+
-+div.sphinxsidebar a {
-+    color: #98dbcc;
-+}
-+
-+div.sphinxsidebar input {
-+    border: 1px solid #98dbcc;
-+    font-family: sans-serif;
-+    font-size: 1em;
-+}
-+
-+/* -- body styles ----------------------------------------------------------- */
-+
-+a {
-+    color: #355f7c;
-+    text-decoration: none;
-+}
-+
-+a:hover {
-+    text-decoration: underline;
-+}
-+
-+div.body p, div.body dd, div.body li {
-+    text-align: left;
-+    line-height: 130%;
-+}
-+
-+div.body h1,
-+div.body h2,
-+div.body h3,
-+div.body h4,
-+div.body h5,
-+div.body h6 {
-+    font-family: 'Trebuchet MS', sans-serif;
-+    background-color: #f2f2f2;
-+    font-weight: normal;
-+    color: #20435c;
-+    border-bottom: 1px solid #ccc;
-+    margin: 20px -20px 10px -20px;
-+    padding: 3px 0 3px 10px;
-+}
-+
-+div.body h1 { margin-top: 0; font-size: 200%; }
-+div.body h2 { font-size: 160%; }
-+div.body h3 { font-size: 140%; }
-+div.body h4 { font-size: 120%; }
-+div.body h5 { font-size: 110%; }
-+div.body h6 { font-size: 100%; }
-+
-+a.headerlink {
-+    color: #c60f0f;
-+    font-size: 0.8em;
-+    padding: 0 4px 0 4px;
-+    text-decoration: none;
-+}
-+
-+a.headerlink:hover {
-+    background-color: #c60f0f;
-+    color: white;
-+}
-+
-+div.body p, div.body dd, div.body li {
-+    text-align: left;
-+    line-height: 130%;
-+}
-+
-+div.admonition p.admonition-title + p {
-+    display: inline;
-+}
-+
-+div.admonition p {
-+    margin-bottom: 5px;
-+}
-+
-+div.admonition pre {
-+    margin-bottom: 5px;
-+}
-+
-+div.admonition ul, div.admonition ol {
-+    margin-bottom: 5px;
-+}
-+
-+div.note {
-+    background-color: #eee;
-+    border: 1px solid #ccc;
-+}
-+
-+div.seealso {
-+    background-color: #ffc;
-+    border: 1px solid #ff6;
-+}
-+
-+div.topic {
-+    background-color: #eee;
-+}
-+
-+div.warning {
-+    background-color: #ffe4e4;
-+    border: 1px solid #f66;
-+}
-+
-+p.admonition-title {
-+    display: inline;
-+}
-+
-+p.admonition-title:after {
-+    content: ":";
-+}
-+
-+pre {
-+    padding: 5px;
-+    background-color: #eeffcc;
-+    color: #333333;
-+    line-height: 120%;
-+    border: 1px solid #ac9;
-+    border-left: none;
-+    border-right: none;
-+}
-+
-+tt {
-+    background-color: #ecf0f3;
-+    padding: 0 1px 0 1px;
-+    font-size: 0.95em;
-+}
-+
-+.warning tt {
-+    background: #efc2c2;
-+}
-+
-+.note tt {
-+    background: #d6d6d6;
-+}
-diff --git a/doc/source/_static/jquery.tweet.js b/doc/source/_static/jquery.tweet.js
-new file mode 100644
-index 0000000..79bf0bd
---- /dev/null
-+++ b/doc/source/_static/jquery.tweet.js
-@@ -0,0 +1,154 @@
-+(function($) {
-+
-+  $.fn.tweet = function(o){
-+    var s = {
-+      username: ["seaofclouds"],              // [string]   required, unless you want to display our tweets. :) it can be an array, just do ["username1","username2","etc"]
-+      list: null,                              //[string]   optional name of list belonging to username
-+      avatar_size: null,                      // [integer]  height and width of avatar if displayed (48px max)
-+      count: 3,                               // [integer]  how many tweets to display?
-+      intro_text: null,                       // [string]   do you want text BEFORE your your tweets?
-+      outro_text: null,                       // [string]   do you want text AFTER your tweets?
-+      join_text:  null,                       // [string]   optional text in between date and tweet, try setting to "auto"
-+      auto_join_text_default: "i said,",      // [string]   auto text for non verb: "i said" bullocks
-+      auto_join_text_ed: "i",                 // [string]   auto text for past tense: "i" surfed
-+      auto_join_text_ing: "i am",             // [string]   auto tense for present tense: "i was" surfing
-+      auto_join_text_reply: "i replied to",   // [string]   auto tense for replies: "i replied to" @someone "with"
-+      auto_join_text_url: "i was looking at", // [string]   auto tense for urls: "i was looking at" http:...
-+      loading_text: null,                     // [string]   optional loading text, displayed while tweets load
-+      query: null                             // [string]   optional search query
-+    };
-+
-+    if(o) $.extend(s, o);
-+
-+    $.fn.extend({
-+      linkUrl: function() {
-+        var returning = [];
-+        var regexp = /((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi;
-+        this.each(function() {
-+          returning.push(this.replace(regexp,"<a href=\"$1\">$1</a>"));
-+        });
-+        return $(returning);
-+      },
-+      linkUser: function() {
-+        var returning = [];
-+        var regexp = /[\@]+([A-Za-z0-9-_]+)/gi;
-+        this.each(function() {
-+          returning.push(this.replace(regexp,"<a href=\"http://twitter.com/$1\">@$1</a>"));
-+        });
-+        return $(returning);
-+      },
-+      linkHash: function() {
-+        var returning = [];
-+        var regexp = / [\#]+([A-Za-z0-9-_]+)/gi;
-+        this.each(function() {
-+          returning.push(this.replace(regexp, ' <a href="http://search.twitter.com/search?q=&tag=$1&lang=all&from='+s.username.join("%2BOR%2B")+'">#$1</a>'));
-+        });
-+        return $(returning);
-+      },
-+      capAwesome: function() {
-+        var returning = [];
-+        this.each(function() {
-+          returning.push(this.replace(/\b(awesome)\b/gi, '<span class="awesome">$1</span>'));
-+        });
-+        return $(returning);
-+      },
-+      capEpic: function() {
-+        var returning = [];
-+        this.each(function() {
-+          returning.push(this.replace(/\b(epic)\b/gi, '<span class="epic">$1</span>'));
-+        });
-+        return $(returning);
-+      },
-+      makeHeart: function() {
-+        var returning = [];
-+        this.each(function() {
-+          returning.push(this.replace(/(&lt;)+[3]/gi, "<tt class='heart'>&#x2665;</tt>"));
-+        });
-+        return $(returning);
-+      }
-+    });
-+
-+    function relative_time(time_value) {
-+      var parsed_date = Date.parse(time_value);
-+      var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
-+      var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
-+      var pluralize = function (singular, n) {
-+        return '' + n + ' ' + singular + (n == 1 ? '' : 's');
-+      };
-+      if(delta < 60) {
-+      return 'less than a minute ago';
-+      } else if(delta < (45*60)) {
-+      return 'about ' + pluralize("minute", parseInt(delta / 60)) + ' ago';
-+      } else if(delta < (24*60*60)) {
-+      return 'about ' + pluralize("hour", parseInt(delta / 3600)) + ' ago';
-+      } else {
-+      return 'about ' + pluralize("day", parseInt(delta / 86400)) + ' ago';
-+      }
-+    }
-+
-+    function build_url() {
-+      var proto = ('https:' == document.location.protocol ? 'https:' : 'http:');
-+      if (s.list) {
-+        return proto+"//api.twitter.com/1/"+s.username[0]+"/lists/"+s.list+"/statuses.json?per_page="+s.count+"&callback=?";
-+      } else if (s.query == null && s.username.length == 1) {
-+        return proto+'//twitter.com/status/user_timeline/'+s.username[0]+'.json?count='+s.count+'&callback=?';
-+      } else {
-+        var query = (s.query || 'from:'+s.username.join('%20OR%20from:'));
-+        return proto+'//search.twitter.com/search.json?&q='+query+'&rpp='+s.count+'&callback=?';
-+      }
-+    }
-+
-+    return this.each(function(){
-+      var list = $('<ul class="tweet_list">').appendTo(this);
-+      var intro = '<p class="tweet_intro">'+s.intro_text+'</p>';
-+      var outro = '<p class="tweet_outro">'+s.outro_text+'</p>';
-+      var loading = $('<p class="loading">'+s.loading_text+'</p>');
-+
-+      if(typeof(s.username) == "string"){
-+        s.username = [s.username];
-+      }
-+
-+      if (s.loading_text) $(this).append(loading);
-+      $.getJSON(build_url(), function(data){
-+        if (s.loading_text) loading.remove();
-+        if (s.intro_text) list.before(intro);
-+        $.each((data.results || data), function(i,item){
-+          // auto join text based on verb tense and content
-+          if (s.join_text == "auto") {
-+            if (item.text.match(/^(@([A-Za-z0-9-_]+)) .*/i)) {
-+              var join_text = s.auto_join_text_reply;
-+            } else if (item.text.match(/(^\w+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+) .*/i)) {
-+              var join_text = s.auto_join_text_url;
-+            } else if (item.text.match(/^((\w+ed)|just) .*/im)) {
-+              var join_text = s.auto_join_text_ed;
-+            } else if (item.text.match(/^(\w*ing) .*/i)) {
-+              var join_text = s.auto_join_text_ing;
-+            } else {
-+              var join_text = s.auto_join_text_default;
-+            }
-+          } else {
-+            var join_text = s.join_text;
-+          };
-+
-+          var from_user = item.from_user || item.user.screen_name;
-+          var profile_image_url = item.profile_image_url || item.user.profile_image_url;
-+          var join_template = '<span class="tweet_join"> '+join_text+' </span>';
-+          var join = ((s.join_text) ? join_template : ' ');
-+          var avatar_template = '<a class="tweet_avatar" href="http://twitter.com/'+from_user+'"><img src="'+profile_image_url+'" height="'+s.avatar_size+'" width="'+s.avatar_size+'" alt="'+from_user+'\'s avatar" title="'+from_user+'\'s avatar" border="0"/></a>';
-+          var avatar = (s.avatar_size ? avatar_template : '');
-+          var date = '<a href="http://twitter.com/'+from_user+'/statuses/'+item.id+'" title="view tweet on twitter">'+relative_time(item.created_at)+'</a>';
-+          var text = '<span class="tweet_text">' +$([item.text]).linkUrl().linkUser().linkHash().makeHeart().capAwesome().capEpic()[0]+ '</span>';
-+
-+          // until we create a template option, arrange the items below to alter a tweet's display.
-+          list.append('<li>' + avatar + date + join + text + '</li>');
-+
-+          list.children('li:first').addClass('tweet_first');
-+          list.children('li:odd').addClass('tweet_even');
-+          list.children('li:even').addClass('tweet_odd');
-+        });
-+        if (s.outro_text) list.after(outro);
-+      });
-+
-+    });
-+  };
-+})(jQuery);
-\ No newline at end of file
-diff --git a/doc/source/_static/tweaks.css b/doc/source/_static/tweaks.css
-new file mode 100644
-index 0000000..046ead8
---- /dev/null
-+++ b/doc/source/_static/tweaks.css
-@@ -0,0 +1,218 @@
-+ul.todo_list {
-+    list-style-type: none;
-+    margin: 0;
-+    padding: 0;
-+}
-+
-+ul.todo_list li {
-+    display: block;
-+    margin: 0;
-+    padding: 7px 0;
-+    border-top: 1px solid #eee;
-+}
-+
-+ul.todo_list li p {
-+    display: inline;
-+}
-+
-+ul.todo_list li p.link {
-+    font-weight: bold;
-+}
-+
-+ul.todo_list li p.details {
-+    font-style: italic;
-+}
-+
-+ul.todo_list li {
-+}
-+
-+div.admonition {
-+    border: 1px solid #8F1000;
-+}
-+
-+div.admonition p.admonition-title {
-+    background-color: #8F1000;
-+    border-bottom: 1px solid #8E8E8E;
-+}
-+
-+a {
-+      color: #CF2F19;
-+}
-+
-+div.related ul li a {
-+      color: #CF2F19;
-+}
-+
-+div.sphinxsidebar h4 {
-+      background-color:#8E8E8E;
-+      border:1px solid #255E6E;
-+      color:white;
-+      font-size:1em;
-+      margin:1em 0 0.5em;
-+      padding:0.1em 0 0.1em 0.5em;
-+}
-+
-+em {
-+    font-style: normal;
-+}
-+
-+table.docutils {
-+      font-size: 11px;
-+}
-+
-+.tweet_list li {
-+    font-size: 0.9em;
-+    border-bottom: 1px solid #eee;
-+    padding: 5px 0;
-+}
-+
-+.tweet_list li .tweet_avatar {
-+    float: left;
-+}
-+
-+/* ------------------------------------------
-+PURE CSS SPEECH BUBBLES
-+by Nicolas Gallagher
-+- http://nicolasgallagher.com/pure-css-speech-bubbles/
-+
-+http://nicolasgallagher.com
-+http://twitter.com/necolas
-+
-+Created: 02 March 2010
-+Version: 1.1 (21 October 2010)
-+
-+Dual licensed under MIT and GNU GPLv2 © Nicolas Gallagher
-+------------------------------------------ */
-+/* THE SPEECH BUBBLE
-+------------------------------------------------------------------------------------------------------------------------------- */
-+
-+/* THE SPEECH BUBBLE
-+------------------------------------------------------------------------------------------------------------------------------- */
-+
-+.triangle-border {
-+      position:relative;
-+      padding:15px;
-+      margin:1em 0 3em;
-+      border:5px solid #BC1518;
-+      color:#333;
-+      background:#fff;
-+
-+      /* css3 */
-+      -moz-border-radius:10px;
-+      -webkit-border-radius:10px;
-+      border-radius:10px;
-+}
-+
-+/* Variant : for left positioned triangle
-+------------------------------------------ */
-+
-+.triangle-border.left {
-+      margin-left:30px;
-+}
-+
-+/* Variant : for right positioned triangle
-+------------------------------------------ */
-+
-+.triangle-border.right {
-+      margin-right:30px;
-+}
-+
-+/* THE TRIANGLE
-+------------------------------------------------------------------------------------------------------------------------------- */
-+
-+.triangle-border:before {
-+      content:"";
-+      display:block; /* reduce the damage in FF3.0 */
-+      position:absolute;
-+      bottom:-40px; /* value = - border-top-width - border-bottom-width */
-+      left:40px; /* controls horizontal position */
-+      width:0;
-+      height:0;
-+      border:20px solid transparent;
-+      border-top-color:#BC1518;
-+}
-+
-+/* creates the smaller  triangle */
-+.triangle-border:after {
-+      content:"";
-+      display:block; /* reduce the damage in FF3.0 */
-+      position:absolute;
-+      bottom:-26px; /* value = - border-top-width - border-bottom-width */
-+      left:47px; /* value = (:before left) + (:before border-left) - (:after border-left) */
-+      width:0;
-+      height:0;
-+      border:13px solid transparent;
-+      border-top-color:#fff;
-+}
-+
-+/* Variant : top
-+------------------------------------------ */
-+
-+/* creates the larger triangle */
-+.triangle-border.top:before {
-+      top:-40px; /* value = - border-top-width - border-bottom-width */
-+      right:40px; /* controls horizontal position */
-+      bottom:auto;
-+      left:auto;
-+      border:20px solid transparent;
-+      border-bottom-color:#BC1518;
-+}
-+
-+/* creates the smaller  triangle */
-+.triangle-border.top:after {
-+      top:-26px; /* value = - border-top-width - border-bottom-width */
-+      right:47px; /* value = (:before right) + (:before border-right) - (:after border-right) */
-+      bottom:auto;
-+      left:auto;
-+      border:13px solid transparent;
-+      border-bottom-color:#fff;
-+}
-+
-+/* Variant : left
-+------------------------------------------ */
-+
-+/* creates the larger triangle */
-+.triangle-border.left:before {
-+      top:10px; /* controls vertical position */
-+      left:-30px; /* value = - border-left-width - border-right-width */
-+      bottom:auto;
-+      border-width:15px 30px 15px 0;
-+      border-style:solid;
-+      border-color:transparent #BC1518;
-+}
-+
-+/* creates the smaller  triangle */
-+.triangle-border.left:after {
-+      top:16px; /* value = (:before top) + (:before border-top) - (:after border-top) */
-+      left:-21px; /* value = - border-left-width - border-right-width */
-+      bottom:auto;
-+      border-width:9px 21px 9px 0;
-+      border-style:solid;
-+      border-color:transparent #fff;
-+}
-+
-+/* Variant : right
-+------------------------------------------ */
-+
-+/* creates the larger triangle */
-+.triangle-border.right:before {
-+      top:10px; /* controls vertical position */
-+      right:-30px; /* value = - border-left-width - border-right-width */
-+      bottom:auto;
-+    left:auto;
-+      border-width:15px 0 15px 30px;
-+      border-style:solid;
-+      border-color:transparent #BC1518;
-+}
-+
-+/* creates the smaller  triangle */
-+.triangle-border.right:after {
-+      top:16px; /* value = (:before top) + (:before border-top) - (:after border-top) */
-+      right:-21px; /* value = - border-left-width - border-right-width */
-+      bottom:auto;
-+    left:auto;
-+      border-width:9px 0 9px 21px;
-+      border-style:solid;
-+      border-color:transparent #fff;
-+}
-+
-diff --git a/doc/source/_templates/.gitignore b/doc/source/_templates/.gitignore
-new file mode 100644
-index 0000000..e69de29
-diff --git a/doc/source/_templates/.placeholder b/doc/source/_templates/.placeholder
-new file mode 100644
-index 0000000..e69de29
-diff --git a/doc/source/_theme/layout.html b/doc/source/_theme/layout.html
-new file mode 100644
-index 0000000..f5b388c
---- /dev/null
-+++ b/doc/source/_theme/layout.html
-@@ -0,0 +1,95 @@
-+{% extends "sphinxdoc/layout.html" %}
-+{% set css_files = css_files + ['_static/tweaks.css'] %}
-+{% set script_files = script_files + ['_static/jquery.tweet.js'] %}
-+{% block extrahead %}
-+    <script type='text/javascript'>
-+        $(document).ready(function(){
-+            $("#twitter_feed").tweet({
-+                username: "openstack",
-+                query: "from:openstack",
-+                avatar_size: 32,
-+                count: 10,
-+                loading_text: "loading tweets..."
-+            });
-+        });
-+    </script>
-+{% endblock %}
-+
-+{%- macro sidebar() %}
-+      {%- if not embedded %}{% if not theme_nosidebar|tobool %}
-+      <div class="sphinxsidebar">
-+        <div class="sphinxsidebarwrapper">
-+          {%- block sidebarlogo %}
-+          {%- if logo %}
-+            <p class="logo"><a href="{{ pathto(master_doc) }}">
-+              <img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/>
-+            </a></p>
-+          {%- endif %}
-+          {%- endblock %}
-+          {%- block sidebartoc %}
-+          {%- if display_toc %}
-+            <h3><a href="{{ pathto(master_doc) }}">{{ _('Table Of Contents') }}</a></h3>
-+            {{ toc }}
-+          {%- endif %}
-+          {%- endblock %}
-+          {%- block sidebarrel %}
-+          {%- if prev %}
-+            <h4>{{ _('Previous topic') }}</h4>
-+            <p class="topless"><a href="{{ prev.link|e }}"
-+                                  title="{{ _('previous chapter') }}">{{ prev.title }}</a></p>
-+          {%- endif %}
-+          {%- if next %}
-+            <h4>{{ _('Next topic') }}</h4>
-+            <p class="topless"><a href="{{ next.link|e }}"
-+                                  title="{{ _('next chapter') }}">{{ next.title }}</a></p>
-+          {%- endif %}
-+          {%- endblock %}
-+          {%- block sidebarsourcelink %}
-+          {%- if show_source and has_source and sourcename %}
-+            <h3>{{ _('This Page') }}</h3>
-+            <ul class="this-page-menu">
-+              <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}"
-+                     rel="nofollow">{{ _('Show Source') }}</a></li>
-+            </ul>
-+          {%- endif %}
-+          {%- endblock %}
-+          {%- if customsidebar %}
-+          {% include customsidebar %}
-+          {%- endif %}
-+          {%- block sidebarsearch %}
-+          {%- if pagename != "search" %}
-+          <div id="searchbox" style="display: none">
-+            <h3>{{ _('Quick search') }}</h3>
-+              <form class="search" action="{{ pathto('search') }}" method="get">
-+                <input type="text" name="q" size="18" />
-+                <input type="submit" value="{{ _('Go') }}" />
-+                <input type="hidden" name="check_keywords" value="yes" />
-+                <input type="hidden" name="area" value="default" />
-+              </form>
-+              <p class="searchtip" style="font-size: 90%">
-+              {{ _('Enter search terms or a module, class or function name.') }}
-+              </p>
-+          </div>
-+          <script type="text/javascript">$('#searchbox').show(0);</script>
-+          
-+          <p class="triangle-border right">
-+                              Psst... hey. You're reading the latest content, but it's for the Block Storage project only. You can read <a href="http://docs.openstack.org">all OpenStack docs</a> too.
-+                      </p>
-+          
-+          {%- endif %}
-+
-+          {%- if pagename == "index" %}
-+          
-+          
-+          <h3>{{ _('Twitter Feed') }}</h3>
-+                <div id="twitter_feed" class='twitter_feed'></div>
-+          {%- endif %}
-+          
-+          
-+
-+
-+          {%- endblock %}
-+        </div>
-+      </div>
-+      {%- endif %}{% endif %}
-+{%- endmacro %}
-diff --git a/doc/source/_theme/theme.conf b/doc/source/_theme/theme.conf
-new file mode 100644
-index 0000000..e039fe0
---- /dev/null
-+++ b/doc/source/_theme/theme.conf
-@@ -0,0 +1,5 @@
-+[theme]
-+inherit = sphinxdoc
-+stylesheet = sphinxdoc.css
-+pygments_style = friendly
-+
-diff --git a/doc/source/conf.py b/doc/source/conf.py
-index 7a2bf1a..01bd3b4 100644
---- a/doc/source/conf.py
-+++ b/doc/source/conf.py
-@@ -33,9 +33,7 @@ extensions = ['sphinx.ext.autodoc',
-               'sphinx.ext.coverage',
-               'sphinx.ext.pngmath',
-               'sphinx.ext.ifconfig',
--              'sphinx.ext.graphviz',
--              'oslo.sphinx',
--              ]
-+              'sphinx.ext.graphviz']
- # autodoc generation is a bit aggressive and a nuisance
- # when doing heavy text edit cycles. Execute "export SPHINX_DEBUG=1"
-@@ -133,8 +131,8 @@ man_pages = [
- # The theme to use for HTML and HTML Help pages.  Major themes that come with
- # Sphinx are currently 'default' and 'sphinxdoc'.
--# html_theme_path = ["."]
--# html_theme = '_theme'
-+html_theme_path = ["."]
-+html_theme = '_theme'
- # Theme options are theme-specific and customize the look and feel of a theme
- # further.  For a list of options available for each theme, see the
-diff --git a/test-requirements.txt b/test-requirements.txt
-index 3d8e9bf..f83b20b 100644
---- a/test-requirements.txt
-+++ b/test-requirements.txt
-@@ -12,4 +12,3 @@ sphinx>=1.1.2
- python-subunit
- testtools>=0.9.32
- testrepository>=0.0.17
--oslo.sphinx
diff --git a/rpm/SOURCES/MIRA-Do-not-clone-non-raw-images-in-rbd-backend.patch b/rpm/SOURCES/MIRA-Do-not-clone-non-raw-images-in-rbd-backend.patch
deleted file mode 100755 (executable)
index 0b1f085..0000000
+++ /dev/null
@@ -1,496 +0,0 @@
-From fd7e9dd59ffa346bed5a11e5312f4bb1bf114ab4 Mon Sep 17 00:00:00 2001
-From: Dmitry Borodaenko <angdraug@gmail.com>
-Date: Wed, 27 Nov 2013 14:33:00 -0800
-Subject: [PATCH] Do not clone non-raw images in rbd backend
-
-RBD backend only supports booting from images in raw format. A volume
-that was cloned from an image in any other format is not bootable. The
-RBD driver will consider non-raw images to be uncloneable to trigger
-automatic conversion to raw format.
-
-Includes conversion of the corresponding unit test to use mock (instead
-of mox) and expanded comments and error messages from patchset #58893 by
-Edward Hope-Morley.
-
-Change-Id: I5725d2f7576bc1b3e9b874ba944ad17d33a6e2cb
-Closes-Bug: #1246219
-Closes-Bug: #1247998
----
- cinder/tests/test_gpfs.py                     |   6 +-
- cinder/tests/test_netapp_nfs.py               |  12 +-
- cinder/tests/test_rbd.py                      | 168 +++++++++++++++++---------
- cinder/tests/test_volume.py                   |   2 +-
- cinder/volume/driver.py                       |   7 +-
- cinder/volume/drivers/gpfs.py                 |   2 +-
- cinder/volume/drivers/lvm.py                  |   2 +-
- cinder/volume/drivers/netapp/nfs.py           |   2 +-
- cinder/volume/drivers/rbd.py                  |  14 ++-
- cinder/volume/drivers/scality.py              |   2 +-
- cinder/volume/flows/create_volume/__init__.py |   2 +-
- 11 files changed, 144 insertions(+), 75 deletions(-)
-
-diff --git a/cinder/tests/test_gpfs.py b/cinder/tests/test_gpfs.py
-index 4fdb788..1f47c6b 100644
---- a/cinder/tests/test_gpfs.py
-+++ b/cinder/tests/test_gpfs.py
-@@ -288,7 +288,8 @@ class GPFSDriverTestCase(test.TestCase):
-         CONF.gpfs_images_share_mode = 'copy_on_write'
-         self.driver.clone_image(volume,
-                                 None,
--                                self.image_id)
-+                                self.image_id,
-+                                {})
-         self.assertTrue(os.path.exists(volumepath))
-         self.volume.delete_volume(self.context, volume['id'])
-@@ -309,7 +310,8 @@ class GPFSDriverTestCase(test.TestCase):
-         CONF.gpfs_images_share_mode = 'copy'
-         self.driver.clone_image(volume,
-                                 None,
--                                self.image_id)
-+                                self.image_id,
-+                                {})
-         self.assertTrue(os.path.exists(volumepath))
-         self.volume.delete_volume(self.context, volume['id'])
-diff --git a/cinder/tests/test_netapp_nfs.py b/cinder/tests/test_netapp_nfs.py
-index 950efc8..042280e 100644
---- a/cinder/tests/test_netapp_nfs.py
-+++ b/cinder/tests/test_netapp_nfs.py
-@@ -469,7 +469,7 @@ class NetappDirectCmodeNfsDriverTestCase(test.TestCase):
-         drv._post_clone_image(volume)
-         mox.ReplayAll()
--        drv. clone_image(volume, ('image_location', None), 'image_id')
-+        drv.clone_image(volume, ('image_location', None), 'image_id', {})
-         mox.VerifyAll()
-     def get_img_info(self, format):
-@@ -493,7 +493,7 @@ class NetappDirectCmodeNfsDriverTestCase(test.TestCase):
-         mox.ReplayAll()
-         (prop, cloned) = drv. clone_image(
--            volume, ('nfs://127.0.0.1:/share/img-id', None), 'image_id')
-+            volume, ('nfs://127.0.0.1:/share/img-id', None), 'image_id', {})
-         mox.VerifyAll()
-         if not cloned and not prop['provider_location']:
-             pass
-@@ -529,7 +529,7 @@ class NetappDirectCmodeNfsDriverTestCase(test.TestCase):
-         mox.ReplayAll()
-         drv. clone_image(
--            volume, ('nfs://127.0.0.1:/share/img-id', None), 'image_id')
-+            volume, ('nfs://127.0.0.1:/share/img-id', None), 'image_id', {})
-         mox.VerifyAll()
-     def test_clone_image_cloneableshare_notraw(self):
-@@ -566,7 +566,7 @@ class NetappDirectCmodeNfsDriverTestCase(test.TestCase):
-         mox.ReplayAll()
-         drv. clone_image(
--            volume, ('nfs://127.0.0.1/share/img-id', None), 'image_id')
-+            volume, ('nfs://127.0.0.1/share/img-id', None), 'image_id', {})
-         mox.VerifyAll()
-     def test_clone_image_file_not_discovered(self):
-@@ -605,7 +605,7 @@ class NetappDirectCmodeNfsDriverTestCase(test.TestCase):
-         mox.ReplayAll()
-         vol_dict, result = drv. clone_image(
--            volume, ('nfs://127.0.0.1/share/img-id', None), 'image_id')
-+            volume, ('nfs://127.0.0.1/share/img-id', None), 'image_id', {})
-         mox.VerifyAll()
-         self.assertFalse(result)
-         self.assertFalse(vol_dict['bootable'])
-@@ -652,7 +652,7 @@ class NetappDirectCmodeNfsDriverTestCase(test.TestCase):
-         mox.ReplayAll()
-         vol_dict, result = drv. clone_image(
--            volume, ('nfs://127.0.0.1/share/img-id', None), 'image_id')
-+            volume, ('nfs://127.0.0.1/share/img-id', None), 'image_id', {})
-         mox.VerifyAll()
-         self.assertFalse(result)
-         self.assertFalse(vol_dict['bootable'])
-diff --git a/cinder/tests/test_rbd.py b/cinder/tests/test_rbd.py
-index 60de09b..054bbb5 100644
---- a/cinder/tests/test_rbd.py
-+++ b/cinder/tests/test_rbd.py
-@@ -34,6 +34,7 @@ from cinder.tests.test_volume import DriverTestCase
- from cinder import units
- from cinder.volume import configuration as conf
- import cinder.volume.drivers.rbd as driver
-+from cinder.volume.flows import create_volume
- LOG = logging.getLogger(__name__)
-@@ -247,7 +248,8 @@ class RBDTestCase(test.TestCase):
-             self.assertRaises(exception.ImageUnacceptable,
-                               self.driver._parse_location,
-                               loc)
--            self.assertFalse(self.driver._is_cloneable(loc))
-+            self.assertFalse(
-+                self.driver._is_cloneable(loc, {'disk_format': 'raw'}))
-     def test_cloneable(self):
-         self.stubs.Set(self.driver, '_get_fsid', lambda: 'abc')
-@@ -264,12 +266,14 @@ class RBDTestCase(test.TestCase):
-         self.mox.ReplayAll()
--        self.assertTrue(self.driver._is_cloneable(location))
-+        self.assertTrue(
-+            self.driver._is_cloneable(location, {'disk_format': 'raw'}))
-     def test_uncloneable_different_fsid(self):
-         self.stubs.Set(self.driver, '_get_fsid', lambda: 'abc')
-         location = 'rbd://def/pool/image/snap'
--        self.assertFalse(self.driver._is_cloneable(location))
-+        self.assertFalse(
-+            self.driver._is_cloneable(location, {'disk_format': 'raw'}))
-     def test_uncloneable_unreadable(self):
-         self.stubs.Set(self.driver, '_get_fsid', lambda: 'abc')
-@@ -284,7 +288,16 @@ class RBDTestCase(test.TestCase):
-         self.mox.ReplayAll()
--        self.assertFalse(self.driver._is_cloneable(location))
-+        self.assertFalse(
-+            self.driver._is_cloneable(location, {'disk_format': 'raw'}))
-+
-+    def test_uncloneable_bad_format(self):
-+        self.stubs.Set(self.driver, '_get_fsid', lambda: 'abc')
-+        location = 'rbd://abc/pool/image/snap'
-+        formats = ['qcow2', 'vmdk', 'vdi']
-+        for f in formats:
-+            self.assertFalse(
-+                self.driver._is_cloneable(location, {'disk_format': f}))
-     def _copy_image(self):
-         @contextlib.contextmanager
-@@ -504,26 +517,37 @@ class ManagedRBDTestCase(DriverTestCase):
-         super(ManagedRBDTestCase, self).setUp()
-         fake_image.stub_out_image_service(self.stubs)
-         self.volume.driver.set_initialized()
-+        self.called = []
--    def _clone_volume_from_image(self, expected_status,
--                                 clone_works=True):
-+    def _create_volume_from_image(self, expected_status, raw=False,
-+                                  clone_error=False):
-         """Try to clone a volume from an image, and check the status
-         afterwards.
-+
-+        NOTE: if clone_error is True we force the image type to raw otherwise
-+              clone_image is not called
-         """
--        def fake_clone_image(volume, image_location, image_id):
--            return {'provider_location': None}, True
-+        def mock_clone_image(volume, image_location, image_id, image_meta):
-+            self.called.append('clone_image')
-+            if clone_error:
-+                raise exception.CinderException()
-+            else:
-+                return {'provider_location': None}, True
--        def fake_clone_error(volume, image_location, image_id):
--            raise exception.CinderException()
-+        if clone_error:
-+            raw = True
--        self.stubs.Set(self.volume.driver, '_is_cloneable', lambda x: True)
--        if clone_works:
--            self.stubs.Set(self.volume.driver, 'clone_image', fake_clone_image)
-+        # See tests.image.fake for image types.
-+        if raw:
-+            expected_calls = ['clone_image']
-+            image_id = '155d900f-4e14-4e4c-a73d-069cbf4541e6'
-         else:
--            self.stubs.Set(self.volume.driver, 'clone_image', fake_clone_error)
-+            expected_calls = ['clone_image', 'create_volume',
-+                              'copy_image_to_volume']
-+            image_id = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
--        image_id = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
-         volume_id = 1
-+
-         # creating volume testdata
-         db.volume_create(self.context,
-                          {'id': volume_id,
-@@ -533,58 +557,88 @@ class ManagedRBDTestCase(DriverTestCase):
-                           'status': 'creating',
-                           'instance_uuid': None,
-                           'host': 'dummy'})
--        try:
--            if clone_works:
--                self.volume.create_volume(self.context,
--                                          volume_id,
--                                          image_id=image_id)
--            else:
--                self.assertRaises(exception.CinderException,
--                                  self.volume.create_volume,
--                                  self.context,
--                                  volume_id,
--                                  image_id=image_id)
--
--            volume = db.volume_get(self.context, volume_id)
--            self.assertEqual(volume['status'], expected_status)
--        finally:
--            # cleanup
--            db.volume_destroy(self.context, volume_id)
-+
-+        with mock.patch.object(self.volume.driver, 'create_volume') as \
-+                mock_create_volume:
-+            with mock.patch.object(self.volume.driver, 'clone_image',
-+                                   mock_clone_image):
-+                with mock.patch.object(create_volume.CreateVolumeFromSpecTask,
-+                                       '_copy_image_to_volume') as \
-+                        mock_copy_image_to_volume:
-+                    self.volume.driver._is_cloneable = mock.Mock()
-+                    self.volume.driver._is_cloneable.return_value = True
-+
-+                    try:
-+                        if not clone_error:
-+                            self.volume.create_volume(self.context,
-+                                                      volume_id,
-+                                                      image_id=image_id)
-+                        else:
-+                            self.assertRaises(exception.CinderException,
-+                                              self.volume.create_volume,
-+                                              self.context,
-+                                              volume_id,
-+                                              image_id=image_id)
-+
-+                        volume = db.volume_get(self.context, volume_id)
-+                        self.assertEqual(volume['status'], expected_status)
-+                    finally:
-+                        # cleanup
-+                        db.volume_destroy(self.context, volume_id)
-+
-+        if raw:
-+            self.assertEquals(self.called, ['clone_image'])
-+
-+        mock_create_volume.assert_called()
-+        mock_copy_image_to_volume.assert_called()
-     def test_create_vol_from_image_status_available(self):
--        """Verify that before cloning, an image is in the available state."""
--        self._clone_volume_from_image('available', True)
-+        """Clone raw image then verify volume is in available state."""
-+        self._create_volume_from_image('available', raw=True)
-+
-+    def test_create_vol_from_non_raw_image_status_available(self):
-+        """Clone non-raw image then verify volume is in available state."""
-+        self._create_volume_from_image('available', raw=False)
-     def test_create_vol_from_image_status_error(self):
--        """Verify that before cloning, an image is in the available state."""
--        self._clone_volume_from_image('error', False)
-+        """Clone raw image with failure then verify volume is in error
-+        state.
-+        """
-+        self._create_volume_from_image('error', raw=True, clone_error=True)
-     def test_clone_image(self):
--        # Test Failure Case(s)
--        expected = ({}, False)
-+        driver = self.volume.driver
--        self.stubs.Set(self.volume.driver, '_is_cloneable', lambda x: False)
--        image_loc = (object(), object())
--        actual = self.volume.driver.clone_image(object(), image_loc, object())
--        self.assertEqual(expected, actual)
-+        # Test uncloneable case(s)
-+        with mock.patch.object(driver, '_is_cloneable',
-+                               lambda *args: False) as mock_is_cloneable:
-+            image_loc = (mock.Mock(), mock.Mock())
-+            actual = driver.clone_image(mock.Mock(), image_loc,
-+                                        mock.Mock(), {})
-+            self.assertEqual(({}, False), actual)
--        self.stubs.Set(self.volume.driver, '_is_cloneable', lambda x: True)
--        self.assertEqual(expected,
--                         self.volume.driver.clone_image(object(), None, None))
-+        self.assertEqual(({}, False),
-+                         driver.clone_image(object(), None, None, {}))
--        # Test Success Case(s)
-+        # Test success case(s)
-         expected = ({'provider_location': None}, True)
--
--        self.stubs.Set(self.volume.driver, '_parse_location',
--                       lambda x: ('a', 'b', 'c', 'd'))
--
--        self.stubs.Set(self.volume.driver, '_clone', lambda *args: None)
--        self.stubs.Set(self.volume.driver, '_resize', lambda *args: None)
--        actual = self.volume.driver.clone_image(object(), image_loc, object())
--        self.assertEqual(expected, actual)
-+        mpo = mock.patch.object
-+        with mpo(driver, '_is_cloneable', lambda *args: True):
-+            with mpo(driver, '_parse_location',
-+                     lambda x: ('a', 'b', 'c', 'd')):
-+                with mpo(driver, '_clone') as mock_clone:
-+                    with mpo(driver, '_resize') as mock_resize:
-+                        actual = driver.clone_image(mock.Mock(), image_loc,
-+                                                    mock.Mock(),
-+                                                    {'disk_format': 'raw'})
-+                        self.assertEqual(expected, actual)
-+                        mock_clone.assert_called()
-+                        mock_resize.assert_called()
-     def test_clone_success(self):
--        self.stubs.Set(self.volume.driver, '_is_cloneable', lambda x: True)
--        self.stubs.Set(self.volume.driver, 'clone_image', lambda a, b, c: True)
-+        self.stubs.Set(self.volume.driver, '_is_cloneable', lambda *args: True)
-+        self.stubs.Set(self.volume.driver, 'clone_image',
-+                       lambda a, b, c, d: True)
-         image_id = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
--        self.assertTrue(self.volume.driver.clone_image({}, image_id, image_id))
-+        self.assertTrue(self.volume.driver.clone_image({},
-+                        image_id, image_id, {}))
-diff --git a/cinder/tests/test_volume.py b/cinder/tests/test_volume.py
-index 4a0d475..928799f 100644
---- a/cinder/tests/test_volume.py
-+++ b/cinder/tests/test_volume.py
-@@ -1216,7 +1216,7 @@ class VolumeTestCase(BaseVolumeTestCase):
-         def fake_fetch_to_raw(ctx, image_service, image_id, path, size=None):
-             pass
--        def fake_clone_image(volume_ref, image_location, image_id):
-+        def fake_clone_image(volume_ref, image_location, image_id, image_meta):
-             return {'provider_location': None}, True
-         dst_fd, dst_path = tempfile.mkstemp()
-diff --git a/cinder/volume/driver.py b/cinder/volume/driver.py
-index 21dd12b..dd2be3c 100644
---- a/cinder/volume/driver.py
-+++ b/cinder/volume/driver.py
-@@ -396,7 +396,7 @@ class VolumeDriver(object):
-         connector.disconnect_volume(attach_info['conn']['data'],
-                                     attach_info['device'])
--    def clone_image(self, volume, image_location, image_id):
-+    def clone_image(self, volume, image_location, image_id, image_meta):
-         """Create a volume efficiently from an existing image.
-         image_location is a string whose format depends on the
-@@ -407,6 +407,11 @@ class VolumeDriver(object):
-         It can be used by the driver to introspect internal
-         stores or registry to do an efficient image clone.
-+        image_meta is a dictionary that includes 'disk_format' (e.g.
-+        raw, qcow2) and other image attributes that allow drivers to
-+        decide whether they can clone the image without first requiring
-+        conversion.
-+
-         Returns a dict of volume properties eg. provider_location,
-         boolean indicating whether cloning occurred
-         """
-diff --git a/cinder/volume/drivers/gpfs.py b/cinder/volume/drivers/gpfs.py
-index 9a1a397..8792ad8 100644
---- a/cinder/volume/drivers/gpfs.py
-+++ b/cinder/volume/drivers/gpfs.py
-@@ -463,7 +463,7 @@ class GPFSDriver(driver.VolumeDriver):
-             return '100M'
-         return '%sG' % size_in_g
--    def clone_image(self, volume, image_location, image_id):
-+    def clone_image(self, volume, image_location, image_id, image_meta):
-         return self._clone_image(volume, image_location, image_id)
-     def _is_cloneable(self, image_id):
-diff --git a/cinder/volume/drivers/lvm.py b/cinder/volume/drivers/lvm.py
-index 094436f..c6023eb 100644
---- a/cinder/volume/drivers/lvm.py
-+++ b/cinder/volume/drivers/lvm.py
-@@ -322,7 +322,7 @@ class LVMVolumeDriver(driver.VolumeDriver):
-         finally:
-             self.delete_snapshot(temp_snapshot)
--    def clone_image(self, volume, image_location, image_id):
-+    def clone_image(self, volume, image_location, image_id, image_meta):
-         return None, False
-     def backup_volume(self, context, backup, backup_service):
-diff --git a/cinder/volume/drivers/netapp/nfs.py b/cinder/volume/drivers/netapp/nfs.py
-index 602a1dc..9463137 100644
---- a/cinder/volume/drivers/netapp/nfs.py
-+++ b/cinder/volume/drivers/netapp/nfs.py
-@@ -374,7 +374,7 @@ class NetAppNFSDriver(nfs.NfsDriver):
-             LOG.warning(_('Exception during deleting %s'), ex.__str__())
-             return False
--    def clone_image(self, volume, image_location, image_id):
-+    def clone_image(self, volume, image_location, image_id, image_meta):
-         """Create a volume efficiently from an existing image.
-         image_location is a string whose format depends on the
-diff --git a/cinder/volume/drivers/rbd.py b/cinder/volume/drivers/rbd.py
-index 775ab16..7ed59d0 100644
---- a/cinder/volume/drivers/rbd.py
-+++ b/cinder/volume/drivers/rbd.py
-@@ -706,7 +706,7 @@ class RBDDriver(driver.VolumeDriver):
-         with RADOSClient(self) as client:
-             return client.cluster.get_fsid()
--    def _is_cloneable(self, image_location):
-+    def _is_cloneable(self, image_location, image_meta):
-         try:
-             fsid, pool, image, snapshot = self._parse_location(image_location)
-         except exception.ImageUnacceptable as e:
-@@ -718,6 +718,13 @@ class RBDDriver(driver.VolumeDriver):
-             LOG.debug(reason)
-             return False
-+        if image_meta['disk_format'] != 'raw':
-+            reason = _("rbd image clone requires image format to be "
-+                       "'raw' but image {0} is '{1}'").format(
-+                           image_location, image_meta['disk_format'])
-+            LOG.debug(reason)
-+            return False
-+
-         # check that we can read the image
-         try:
-             with RBDVolumeProxy(self, image,
-@@ -730,9 +737,10 @@ class RBDDriver(driver.VolumeDriver):
-                       dict(loc=image_location, err=e))
-             return False
--    def clone_image(self, volume, image_location, image_id):
-+    def clone_image(self, volume, image_location, image_id, image_meta):
-         image_location = image_location[0] if image_location else None
--        if image_location is None or not self._is_cloneable(image_location):
-+        if image_location is None or not self._is_cloneable(
-+                image_location, image_meta):
-             return ({}, False)
-         prefix, pool, image, snapshot = self._parse_location(image_location)
-         self._clone(volume, pool, image, snapshot)
-diff --git a/cinder/volume/drivers/scality.py b/cinder/volume/drivers/scality.py
-index 4cf49c6..abd6c29 100644
---- a/cinder/volume/drivers/scality.py
-+++ b/cinder/volume/drivers/scality.py
-@@ -250,7 +250,7 @@ class ScalityDriver(driver.VolumeDriver):
-                                   image_meta,
-                                   self.local_path(volume))
--    def clone_image(self, volume, image_location, image_id):
-+    def clone_image(self, volume, image_location, image_id, image_meta):
-         """Create a volume efficiently from an existing image.
-         image_location is a string whose format depends on the
-diff --git a/cinder/volume/flows/create_volume/__init__.py b/cinder/volume/flows/create_volume/__init__.py
-index bb7acd3..e5aa371 100644
---- a/cinder/volume/flows/create_volume/__init__.py
-+++ b/cinder/volume/flows/create_volume/__init__.py
-@@ -1438,7 +1438,7 @@ class CreateVolumeFromSpecTask(base.CinderTask):
-         # dict containing provider_location for cloned volume
-         # and clone status.
-         model_update, cloned = self.driver.clone_image(
--            volume_ref, image_location, image_id)
-+            volume_ref, image_location, image_id, image_meta)
-         if not cloned:
-             # TODO(harlowja): what needs to be rolled back in the clone if this
-             # volume create fails?? Likely this should be a subflow or broken
--- 
-1.8.5.1
-
index ccc7c3f6c13f1cf3c93aa703b80a6e7d6bf233d6..933c4a87086523496a94353548b4144e59f0df43 100644 (file)
@@ -3,9 +3,8 @@ logdir = /var/log/cinder
 state_path = /var/lib/cinder
 lock_path = /var/lib/cinder/tmp
 volumes_dir = /etc/cinder/volumes
-iscsi_helper = tgtadm
+iscsi_helper = lioadm
 sql_connection = mysql://cinder:cinder@localhost/cinder
-rpc_backend = cinder.openstack.common.rpc.impl_qpid
 rootwrap_config = /etc/cinder/rootwrap.conf
 auth_strategy = keystone
 
index 1581c7953f784250f8ca5fad30ccecd904a651bd..b07cc478848310f2e0b391e94001f7cbc8deb9bc 100644 (file)
@@ -1,5 +1 @@
-# Note this config mode is not supported by scsi-target-utils in RHEL <= 6.4
-# include /etc/cinder/volumes/
-# So instead please add the following line (without the leading comment char)
-# to the top of /etc/tgt/targets.conf
-# include /etc/cinder/volumes/*
+include /etc/cinder/volumes/
diff --git a/rpm/SOURCES/openstack-cinder-api.upstart b/rpm/SOURCES/openstack-cinder-api.upstart
deleted file mode 100644 (file)
index 51acbc5..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-description "OpenStack Cinder API Server"
-
-start on stopped rc RUNLEVEL=[2345]
-stop on runlevel [S016]
-
-respawn
-
-exec su -s /bin/sh -c "exec /usr/bin/cinder-api --config-file /usr/share/cinder/cinder-dist.conf --config-file /etc/cinder/cinder.conf --logfile /var/log/cinder/api.log" cinder
diff --git a/rpm/SOURCES/openstack-cinder-backup.upstart b/rpm/SOURCES/openstack-cinder-backup.upstart
deleted file mode 100644 (file)
index 1c23c21..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-description "OpenStack Cinder Backup Server"
-
-start on stopped rc RUNLEVEL=[2345]
-stop on runlevel [S016]
-
-respawn
-
-exec su -s /bin/sh -c "exec /usr/bin/cinder-backup --config-file /usr/share/cinder/cinder-dist.conf --config-file /etc/cinder/cinder.conf --logfile /var/log/cinder/backup.log" cinder
diff --git a/rpm/SOURCES/openstack-cinder-scheduler.upstart b/rpm/SOURCES/openstack-cinder-scheduler.upstart
deleted file mode 100644 (file)
index b152c18..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-description "OpenStack Cinder Scheduler Server"
-
-start on stopped rc RUNLEVEL=[2345]
-stop on runlevel [S016]
-
-respawn
-
-exec su -s /bin/sh -c "exec /usr/bin/cinder-scheduler --config-file /usr/share/cinder/cinder-dist.conf --config-file /etc/cinder/cinder.conf --logfile /var/log/cinder/scheduler.log" cinder
diff --git a/rpm/SOURCES/openstack-cinder-volume.upstart b/rpm/SOURCES/openstack-cinder-volume.upstart
deleted file mode 100644 (file)
index 46020f4..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-description "OpenStack Cinder Volume Server"
-
-start on stopped rc RUNLEVEL=[2345]
-stop on runlevel [S016]
-
-respawn
-
-exec su -s /bin/sh -c "exec /usr/bin/cinder-volume --config-file /usr/share/cinder/cinder-dist.conf --config-file /etc/cinder/cinder.conf --logfile /var/log/cinder/volume.log" cinder
index e39dd511f66fd67f60a5ebb8b48f97e8f78eb194..2c30b2deb9a730ea2d496bade78999e1394cf447 100644 (file)
@@ -1,50 +1,39 @@
 %global with_doc %{!?_without_doc:1}%{?_without_doc:0}
 
 Name:             openstack-cinder
-Version:          2013.2
-Release:          0.9.b3%{?dist}
+Version:          2014.2
+Release:          2%{?dist}
 Summary:          OpenStack Volume service
 
 Group:            Applications/System
 License:          ASL 2.0
 URL:              http://www.openstack.org/software/openstack-storage/
-Source0:          https://launchpad.net/cinder/havana/havana-3/+download/cinder-%{version}.b3.tar.gz
+Source0:          https://launchpad.net/cinder/icehouse/2014.1/+download/cinder-%{version}.tar.gz
 Source1:          cinder-dist.conf
 Source2:          cinder.logrotate
 Source3:          cinder-tgt.conf
 
 Source10:         openstack-cinder-api.init
-Source100:        openstack-cinder-api.upstart
 Source11:         openstack-cinder-scheduler.init
-Source110:        openstack-cinder-scheduler.upstart
 Source12:         openstack-cinder-volume.init
-Source120:        openstack-cinder-volume.upstart
 Source13:         openstack-cinder-backup.init
-Source130:        openstack-cinder-backup.upstart
 
 Source20:         cinder-sudoers
 
 #
-# patches_base=2013.2.b3
+# patches_base=2014.1.1
 #
-Patch0001: 0001-Ensure-we-don-t-access-the-net-when-building-docs.patch
-Patch0002: 0002-Use-updated-parallel-install-versions-of-epel-packag.patch
-Patch0003: 0003-Remove-runtime-dep-on-python-pbr-python-d2to1.patch
-Patch0004: 0004-Revert-Use-oslo.sphinx-and-remove-local-copy-of-doc-.patch
-Patch0005: MIRA-Do-not-clone-non-raw-images-in-rbd-backend.patch
+Patch0001: 0001-Remove-runtime-dep-on-python-pbr-python-d2to1.patch
+Patch0002: 0002-Revert-Switch-over-to-oslosphinx.patch
 
 BuildArch:        noarch
 BuildRequires:    intltool
 BuildRequires:    python-d2to1
+BuildRequires:    python-oslo-sphinx
 BuildRequires:    python-pbr
-BuildRequires:    python-sphinx10
+BuildRequires:    python-sphinx
 BuildRequires:    python-setuptools
 BuildRequires:    python-netaddr
-BuildRequires:    openstack-utils
-BuildRequires:    python-paste-deploy1.5
-BuildRequires:    python-routes1.12
-BuildRequires:    python-sqlalchemy0.7
-BuildRequires:    python-webob1.2
 
 Requires:         openstack-utils
 Requires:         python-cinder = %{version}-%{release}
@@ -76,41 +65,49 @@ Requires:         MySQL-python
 Requires:         qemu-img
 Requires:         sysfsutils
 
-Requires:         python-paramiko
+Requires:         python-paramiko >= 1.13.0
 
 Requires:         python-qpid
 Requires:         python-kombu
 Requires:         python-amqplib
-Requires:         python-importlib
-
-Requires:         python-eventlet
-Requires:         python-greenlet
-Requires:         python-iso8601
-Requires:         python-netaddr
-Requires:         python-lxml
-Requires:         python-anyjson
-Requires:         python-cheetah
-Requires:         python-stevedore
+
+Requires:         python-eventlet >= 0.13.0
+Requires:         python-greenlet >= 0.3.2
+Requires:         python-iso8601 >= 0.1.9
+Requires:         python-netaddr >= 0.7.6
+Requires:         python-lxml >= 2.3
+Requires:         python-anyjson >= 0.3.3
+#Requires:         python-cheetah
+Requires:         python-stevedore >= 0.14
 Requires:         python-suds
 
-Requires:         python-sqlalchemy0.7
-Requires:         python-migrate
+Requires:         python-sqlalchemy  >= 0.8.4, python-sqlalchemy < 0.95, python-sqlalchemy > 0.9.5, python-sqlalchemy <= 0.9.99
+Requires:         python-migrate >= 0.9.1
 
-Requires:         python-paste-deploy1.5
-Requires:         python-routes1.12
-Requires:         python-webob1.2
+Requires:         python-paste-deploy >= 1.5.0
+Requires:         python-routes >= 1.12.3, python-routes < 2.0, python-routes > 2.0
+Requires:         python-webob >= 1.2.3
 
 Requires:         python-glanceclient >= 1:0
-Requires:         python-swiftclient >= 1.2
-Requires:         python-keystoneclient
-Requires:         python-novaclient >= 2.14
+Requires:         python-swiftclient >= 2.0.2
+Requires:         python-keystoneclient 
+Requires:         python-keystonemiddleware >= 1.0.0
+Requires:         python-novaclient >= 1:2.17
 
 Requires:         python-oslo-config >= 1:1.2.0
-Requires:         python-six
+Requires:         python-six >= 1.7.0
 
-Requires:         python-babel
+Requires:         python-babel >= 1.3
 Requires:         python-lockfile
 
+Requires:         python-oslo-rootwrap
+Requires:         python-rtslib-fb
+Requires:         python-taskflow
+Requires:         python-oslo-messaging >= 1.3.0-0.1.a9
+
+Requires:         python-ceph
+#Requires:         iscsi-initiator-utils
+
 %description -n   python-cinder
 OpenStack Volume (codename Cinder) provides services to manage and
 access block storage volumes for use by Virtual Machine instances.
@@ -128,9 +125,9 @@ BuildRequires:    graphviz
 
 # Required to build module documents
 BuildRequires:    python-eventlet
-BuildRequires:    python-routes1.12
-BuildRequires:    python-sqlalchemy0.7
-BuildRequires:    python-webob1.2
+BuildRequires:    python-routes
+BuildRequires:    python-sqlalchemy
+BuildRequires:    python-webob
 # while not strictly required, quiets the build down when building docs.
 BuildRequires:    python-migrate, python-iso8601
 
@@ -146,9 +143,6 @@ This package contains documentation files for cinder.
 
 %patch0001 -p1
 %patch0002 -p1
-%patch0003 -p1
-%patch0004 -p1
-%patch0005 -p1
 
 find . \( -name .gitignore -o -name .placeholder \) -delete
 
@@ -166,15 +160,6 @@ sed -i s/REDHATCINDERVERSION/%{version}/ cinder/version.py
 sed -i s/REDHATCINDERRELEASE/%{release}/ cinder/version.py
 
 %build
-
-# Move authtoken configuration out of paste.ini
-openstack-config --del etc/cinder/api-paste.ini filter:authtoken admin_tenant_name
-openstack-config --del etc/cinder/api-paste.ini filter:authtoken admin_user
-openstack-config --del etc/cinder/api-paste.ini filter:authtoken admin_password
-openstack-config --del etc/cinder/api-paste.ini filter:authtoken auth_host
-openstack-config --del etc/cinder/api-paste.ini filter:authtoken auth_port
-openstack-config --del etc/cinder/api-paste.ini filter:authtoken auth_protocol
-
 %{__python} setup.py build
 
 %install
@@ -186,7 +171,7 @@ export PYTHONPATH="$( pwd ):$PYTHONPATH"
 pushd doc
 
 %if 0%{?with_doc}
-SPHINX_DEBUG=1 sphinx-1.0-build -b html source build/html
+SPHINX_DEBUG=1 sphinx-build -b html source build/html
 # Fix hidden-file-or-dir warnings
 rm -fr build/html/.doctrees build/html/.buildinfo
 %endif
@@ -194,7 +179,7 @@ rm -fr build/html/.doctrees build/html/.buildinfo
 # Create dir link to avoid a sphinx-build exception
 mkdir -p build/man/.doctrees/
 ln -s .  build/man/.doctrees/man
-SPHINX_DEBUG=1 sphinx-1.0-build -b man -c source source/man build/man
+SPHINX_DEBUG=1 sphinx-build -b man -c source source/man build/man
 mkdir -p %{buildroot}%{_mandir}/man1
 install -p -D -m 644 build/man/*.1 %{buildroot}%{_mandir}/man1/
 
@@ -230,13 +215,6 @@ install -p -D -m 644 %{SOURCE2} %{buildroot}%{_sysconfdir}/logrotate.d/openstack
 # Install pid directory
 install -d -m 755 %{buildroot}%{_localstatedir}/run/cinder
 
-# Install upstart jobs examples
-install -d -m 755 %{buildroot}%{_datadir}/cinder
-install -p -m 644 %{SOURCE100} %{buildroot}%{_datadir}/cinder/
-install -p -m 644 %{SOURCE110} %{buildroot}%{_datadir}/cinder/
-install -p -m 644 %{SOURCE120} %{buildroot}%{_datadir}/cinder/
-install -p -m 644 %{SOURCE130} %{buildroot}%{_datadir}/cinder/
-
 # Install rootwrap files in /usr/share/cinder/rootwrap
 mkdir -p %{buildroot}%{_datarootdir}/cinder/rootwrap/
 install -p -D -m 644 etc/cinder/rootwrap.d/* %{buildroot}%{_datarootdir}/cinder/rootwrap/
@@ -255,16 +233,13 @@ fi
 exit 0
 
 %post
-if [ $1 -eq 1 ] ; then
-    # Initial installation
-    for svc in volume api scheduler; do
-        /sbin/chkconfig --add openstack-cinder-$svc
-    done
-fi
+for svc in volume api scheduler backup; do
+    /sbin/chkconfig --add openstack-cinder-$svc
+done
 
 %preun
 if [ $1 -eq 0 ] ; then
-    for svc in volume api scheduler; do
+    for svc in volume api scheduler backup; do
         /sbin/service openstack-cinder-${svc} stop > /dev/null 2>&1
         /sbin/chkconfig --del openstack-cinder-${svc}
     done
@@ -273,7 +248,7 @@ fi
 %postun
 if [ $1 -ge 1 ] ; then
     # Package upgrade, not uninstall
-    for svc in volume api scheduler; do
+    for svc in volume api scheduler backup; do
         /sbin/service openstack-cinder-${svc} condrestart > /dev/null 2>&1 || :
     done
 fi
@@ -315,6 +290,78 @@ fi
 %endif
 
 %changelog
+* Wed Jun 11 2014 Eric Harney <eharney@redhat.com> - 2014.1.1-2
+- Add dependency on iscsi-initiator-utils
+
+* Mon Jun 09 2014 Eric Harney <eharney@redhat.com> - 2014.1.1-1
+- Update to Icehouse stable release 1
+
+* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2014.1-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Tue Apr 29 2014 Alan Pevec <apevec@redhat.com> - 2014.1-3
+- drop crudini build dependency
+
+* Mon Apr 21 2014 Eric Harney <eharney@redhat.com> - 2014.1-2
+- Remove qpid settings from cinder-dist.conf
+
+* Thu Apr 17 2014 Eric Harney <eharney@redhat.com> - 2014.1-1
+- Update to 2014.1 (Icehouse)
+
+* Tue Apr 15 2014 Eric Harney <eharney@redhat.com> - 2014.1-0.10.rc3
+- Add python-oslo-messaging requirement
+- Add GlusterFS delete patch
+- Add systemd patches (not used yet)
+
+* Tue Apr 15 2014 Eric Harney <eharney@redhat.com> - 2014.1-0.9.rc3
+- Update to Icehouse RC3
+
+* Mon Apr 07 2014 Eric Harney <eharney@redhat.com> - 2014.1-0.8.rc2
+- Update to Icehouse RC2
+- Icehouse requires newer version of python-six
+
+* Thu Mar 27 2014 Eric Harney <eharney@redhat.com> - 2014.1-0.7.rc1
+- Update to Icehouse RC1
+
+* Tue Mar 25 2014 Pádraig Brady <pbrady@redhat.com> - 2014.1-0.6.b3
+- Depend on python-rtslib and targetcli rather than scsi-target-utils
+
+* Fri Mar 21 2014 Pádraig Brady <pbrady@redhat.com> - 2014.1-0.5.b3
+- Use lioadm iSCSI helper rather than tgtadm
+
+* Sun Mar 16 2014 Eric Harney <eharney@redhat.com> - 2014.1-0.4.b3
+- Update to Icehouse milestone 3
+- Add deps on python-oslo-rootwrap, python-taskflow
+
+* Mon Jan 27 2014 Eric Harney <eharney@redhat.com> - 2014.1-0.3.b2
+- Update to Icehouse milestone 2
+
+* Mon Jan 06 2014 Pádraig Brady <pbrady@redhat.com> - 2014.1-0.2.b1
+- Set python-six min version to ensure updated
+
+* Thu Dec 19 2013 Eric Harney <eharney@redhat.com> - 2014.1-0.1.b1
+- Update to Icehouse milestone 1
+
+* Mon Oct 28 2013 Eric Harney <eharney@redhat.com> - 2013.2-2
+- Fix GlusterFS volume driver clone operations
+
+* Thu Oct 17 2013 Eric Harney <eharney@redhat.com> - 2013.2-1
+- Update to 2013.2 (Havana)
+- Restart/remove cinder-backup service during upgrade/uninstallation
+
+* Wed Oct 16 2013 Eric Harney <eharney@redhat.com> - 2013.2-0.13.rc3
+- Update to Havana RC3
+
+* Fri Oct 11 2013 Eric Harney <eharney@redhat.com> - 2013.2-0.12.rc2
+- Update to Havana RC2
+
+* Tue Oct 08 2013 Eric Harney <eharney@redhat.com> - 2013.2-0.11.rc1
+- Update to Havana RC1
+- Fix python-novaclient req epoch
+
+* Mon Sep 23 2013 Eric Harney <eharney@redhat.com> - 2013.2-0.10.b3
+- Depend on python-novaclient 2.15
+
 * Wed Sep 18 2013 Eric Harney <eharney@redhat.com> - 2013.2-0.9.b3
 - Add cinder-dist.conf
 - Tighten permissions on /var/log/cinder
@@ -323,33 +370,38 @@ fi
 - Update to Havana milestone 3
 - Add dependency on python-novaclient
 
-* Thu Aug 29 2013 Pádraig Brady <pbrady@redhat.com> - 2013.2-0.7.b2
+* Thu Aug 29 2013 PÃ\83¡draig Brady <pbrady@redhat.com> - 2013.2-0.7.b2
 - Add dependency on sysfsutils to support the fiber channel driver
 
-* Mon Aug 26 2013 Eric Harney <eharney@redhat.com> - 2013.2-0.5.b2
+* Mon Aug 26 2013 Eric Harney <eharney@redhat.com> - 2013.2-0.6.b2
 - Add cinder-backup service init script
 
-* Mon Jul 22 2013 Pádraig Brady <pbrady@redhat.com> - 2013.2-0.4.b2
+* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2013.2-0.5.b2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
+
+* Mon Jul 22 2013 Pádraig Brady <pbrady@redhat.com> - 2013.2-0.4.b2
 - Add dependency on python-suds to support the netapp driver
 - Add dependency on python-keystoneclient for auth token middleware
 - Add dependency on qemu-img for volume creation from Glance images
 
-* Sun Jul 21 2013 Pádraig Brady <pbrady@redhat.com> - 2013.2-0.3.b2
+* Sun Jul 21 2013 PÃ\83¡draig Brady <pbrady@redhat.com> - 2013.2-0.3.b2
 - Update to Havana milestone 2
 
 * Thu Jun 13 2013 Eric Harney <eharney@redhat.com> - 2013.2-0.2.b1
 - Update to Havana milestone 1
 
-* Fri May 10 2013 Eric Harney <eharney@redhat.com> - 2013.1.1-1
-- Update to Grizzly stable release 1
+* Mon May 13 2013 Eric Harney <eharney@redhat.com> - 2013.1.1-1
+- Update to Grizzly stable release 1, 2013.1.1
 
 * Mon Apr 08 2013 Eric Harney <eharney@redhat.com> - 2013.1-2
 - Backport fix for GlusterFS driver get_volume_stats
-- Adjust to support sqlalchemy-0.8.0
 
 * Thu Apr 04 2013 Eric Harney <eharney@redhat.com> - 2013.1-1
 - Update to Grizzly final release
 
+* Tue Apr  2 2013 Pádraig Brady <pbrady@redhat.com> - 2013.1-0.6.rc3
+- Adjust to support sqlalchemy-0.8.0
+
 * Wed Mar 27 2013 Eric Harney <eharney@redhat.com> - 2013.1-0.5.rc3
 - Update to Grizzly RC3 release
 
@@ -359,26 +411,40 @@ fi
 * Mon Mar 18 2013 Eric Harney <eharney@redhat.com> - 2013.1-0.5.rc1
 - Update to Grizzly RC1 release
 
-* Tue Mar 05 2013 Pádraig Brady <P@draigBrady.com> - 2013.1-0.4.g3
+* Tue Mar 05 2013 PÃ\83¡draig Brady <P@draigBrady.com> - 2013.1-0.4.g3
 - Add dependency on python-stevedore
 
-* Wed Feb 27 2013 Eric Harney <eharney@redhat.com> - 2013.1-0.2.g3
+* Mon Feb 25 2013 Eric Harney <eharney@redhat.com> - 2013.1-0.3.g3
+- Fix build issues with G-3 update
+
+* Mon Feb 25 2013 Eric Harney <eharney@redhat.com> - 2013.1-0.2.g3
 - Update to Grizzly milestone 3
 
+* Thu Feb 14 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2013.1-0.2.g2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
 * Thu Jan 10 2013 Eric Harney <eharney@redhat.com> - 2013.1-0.1.g2
 - Update to Grizzly milestone 2
 
-* Thu Dec 20 2012 Eric Harney <eharney@redhat.com> - 2013.1-0.1.g1
+* Thu Nov 29 2012 Eric Harney <eharney@redhat.com> - 2013.1-0.1.g1
 - Update to Grizzly milestone 1
 
-* Mon Dec 03 2012 Eric Harney <eharney@redhat.com> - 2012.2.1-1
-- Update to Folsom stable release 1
-
-* Wed Nov 14 2012 Eric Harney <eharney@redhat.com> - 2012.2-4
+* Wed Nov 14 2012 Eric Harney <eharney@redhat.com> - 2012.2-2
 - Remove unused dependency on python-daemon
 
-* Wed Oct 31 2012 Pádraig Brady <P@draigBrady.com> - 2012.2-3
-- Adjust to be compatible with python-migrate-0.6
+* Thu Sep 27 2012 Pádraig Brady <P@draigBrady.com> - 2012.2-1
+- Update to Folsom final
+
+* Fri Sep 21 2012 Pádraig Brady <P@draigBrady.com> - 2012.2-0.5.rc1
+- Update to Folsom RC1
+
+* Fri Sep 21 2012 Pádraig Brady <P@draigBrady.com> - 2012.2-0.4.f3
+- Fix to ensure that tgt configuration is honored
+
+* Mon Sep 17 2012 Pádraig Brady <P@draigBrady.com> - 2012.2-0.3.f3
+- Move user config out of /etc/cinder/api-paste.ini
+- Require python-cinderclient
+
+* Mon Sep  3 2012 Pádraig Brady <P@draigBrady.com> - 2012.2-0.2.f3
+- Initial release
 
-* Wed Oct 24 2012 Pádraig Brady <P@draigBrady.com> - 2012.2-2
-- Initial Folsom release