Hello community,
here is the log from the commit of package openstack-cinder for openSUSE:Factory checked in at 2014-02-11 10:40:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/openstack-cinder (Old)
and /work/SRC/openSUSE:Factory/.openstack-cinder.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "openstack-cinder"
Changes:
--------
--- /work/SRC/openSUSE:Factory/openstack-cinder/openstack-cinder.changes 2014-01-30 17:42:14.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.openstack-cinder.new/openstack-cinder.changes 2014-02-11 10:40:17.000000000 +0100
@@ -1,0 +2,17 @@
+Thu Feb 6 14:48:37 UTC 2014 - dmueller@suse.com
+
+- fix typo in logrotate
+
+-------------------------------------------------------------------
+Mon Feb 3 00:43:03 UTC 2014 - opensuse-cloud@opensuse.org
+
+- Update to version 2013.2.2.dev21.g240c81d:
+ + hanges I8686a1be,I4a9ea40d into stable/havan
+ + GlusterFS: Use correct base argument when deleting attached snaps
+
+-------------------------------------------------------------------
+Thu Jan 30 15:09:12 UTC 2014 - dmueller@suse.com
+
+- move lock_path to /var/run
+
+-------------------------------------------------------------------
New:
----
openstack-cinder.conf
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ openstack-cinder-doc.spec ++++++
--- /var/tmp/diff_new_pack.NtS2Rk/_old 2014-02-11 10:40:18.000000000 +0100
+++ /var/tmp/diff_new_pack.NtS2Rk/_new 2014-02-11 10:40:18.000000000 +0100
@@ -19,7 +19,7 @@
%define component cinder
Name: openstack-%{component}-doc
-Version: 2013.2.2.dev16.g77fade5
+Version: 2013.2.2.dev21.g240c81d
Release: 0
Summary: OpenStack Block Storage (Cinder) - Documentation
License: Apache-2.0
@@ -62,7 +62,7 @@
This package contains documentation files for %{name}.
%prep
-%setup -q -n cinder-2013.2.2.dev16.g77fade5
+%setup -q -n cinder-2013.2.2.dev21.g240c81d
%openstack_cleanup_prep
%build
++++++ openstack-cinder.spec ++++++
--- /var/tmp/diff_new_pack.NtS2Rk/_old 2014-02-11 10:40:18.000000000 +0100
+++ /var/tmp/diff_new_pack.NtS2Rk/_new 2014-02-11 10:40:18.000000000 +0100
@@ -21,7 +21,7 @@
%define username openstack-%{component}
Name: openstack-%{component}
-Version: 2013.2.2.dev16.g77fade5
+Version: 2013.2.2.dev21.g240c81d
Release: 0
Summary: OpenStack Block Storage (Cinder)
License: Apache-2.0
@@ -31,6 +31,10 @@
Source1: %{name}.init
Source2: %{name}.logrotate
Source3: cinder-sudoers
+%if 0%{?suse_version} > 1230
+Source10: %name.conf
+BuildRequires: systemd
+%endif
Patch0: 0001-Avoid-using-GREENDNS-due-to-dnspython.patch
Patch1: 0001-Set-useful-vendor-product-id-in-Cinder-ISCSI-exports.patch
Patch2: 0001-Robustify-skipactivation-detection.patch
@@ -188,7 +192,7 @@
functionality of OpenStack Cinder.
%prep
-%setup -q -n cinder-2013.2.2.dev16.g77fade5
+%setup -q -n cinder-2013.2.2.dev21.g240c81d
%patch0 -p1
%patch1 -p1
%patch2 -p1
@@ -205,7 +209,11 @@
### directories
install -d -m 755 %{buildroot}%{_localstatedir}/{lib,log}/%{component}
-install -d -m 750 %{buildroot}%{_localstatedir}/{lock,cache,run}/%{component}
+install -d -m 750 %{buildroot}%{_localstatedir}/cache/%{component}
+install -d -m 700 %{buildroot}%{_localstatedir}/run/%{component}
+%if 0%{?suse_version} > 1230
+install -D -m 644 %{SOURCE10} %{buildroot}/%_tmpfilesdir/%name.conf
+%endif
install -d -m 755 %{buildroot}%{_sysconfdir}/%{component}
### configuration files
@@ -258,7 +266,7 @@
#NOTE(saschpe): Can't hurt to set the default volume_group, only the LVM driver has a it otherwise:
crudini --set %{cinder_conf} DEFAULT volume_group cinder-volumes
crudini --set %{cinder_conf} keystone_authtoken signing_dir /var/cache/%component/keystone-signing
-crudini --set %{cinder_conf} DEFAULT lock_path /var/lock/%component
+crudini --set %{cinder_conf} DEFAULT lock_path /var/run/%component
%pre
getent group %{groupname} >/dev/null || groupadd -r %{groupname}
@@ -309,9 +317,13 @@
%doc LICENSE README.rst
%dir %attr(0755, %{username}, %{groupname}) %{_localstatedir}/lib/%{component}
%dir %attr(0750, %{username}, %{groupname}) %{_localstatedir}/cache/%{component}
-%dir %attr(0750, %{username}, %{groupname}) %{_localstatedir}/lock/%{component}
%dir %attr(0750, %{username}, %{groupname}) %{_localstatedir}/log/%{component}
-%ghost %dir %attr(0750, %{username}, %{groupname}) %{_localstatedir}/run/%{component}
+%if 0%{?suse_version} > 1230
+%ghost %dir %attr(700,%{username},%{groupname}) %{_localstatedir}/run/%{component}
+%_tmpfilesdir/%name.conf
+%else
+%dir %attr(0700, %{username}, %{groupname}) %{_localstatedir}/run/%{component}
+%endif
%dir %{_sysconfdir}/%{component}
%dir %{_sysconfdir}/%{component}/rootwrap.d
%config(noreplace) %{_sysconfdir}/logrotate.d/%{name}
++++++ cinder-stable-havana.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.2.dev16.g77fade5/ChangeLog new/cinder-2013.2.2.dev21.g240c81d/ChangeLog
--- old/cinder-2013.2.2.dev16.g77fade5/ChangeLog 2014-01-29 21:08:23.000000000 +0100
+++ new/cinder-2013.2.2.dev21.g240c81d/ChangeLog 2014-02-02 07:49:45.000000000 +0100
@@ -1,3 +1,21 @@
+commit 240c81d00a49f924e1b9257fee76a7d924246c57
+Merge: f02d4fe 5ef9c9b
+Author: Jenkins
+Date: Sun Feb 2 06:47:03 2014 +0000
+
+ Merge "GlusterFS: Use correct base argument when deleting attached snaps" into stable/havana
+
+commit f02d4fed0c5b3019449dbf8cf81fff1e64337aa1
+Merge: 77fade5 5122593
+Author: Jenkins
+Date: Sun Feb 2 05:58:45 2014 +0000
+
+ Merge changes I8686a1be,I4a9ea40d into stable/havana
+
+ * changes:
+ GlusterFS: Complete snapshot_delete when info doesn't exist
+ GlusterFS: Ensure Cinder can write to shares
+
commit 77fade503a4bc2ff45f43855d03125a361a43ffb
Merge: 3d967e0 c07d60f
Author: Jenkins
@@ -42,6 +60,53 @@
Change-Id: Ic40cd0cdc862b44b0a7d3e5b1d7c4fee8ea1b28d
(cherry picked from commit 21ebf2898e2f5fc8127b7a3bdc9743c49933f952)
+commit 5ef9c9b92812b5a66218fecd5ace8515b149ea1a
+Author: Eric Harney
+Date: Wed Dec 18 19:11:44 2013 -0500
+
+ GlusterFS: Use correct base argument when deleting attached snaps
+
+ When deleting the most recent snapshot, the 'file_to_merge' field
+ which translates into the base= field for libvirt's blockRebase
+ call in Nova must be set depending on whether other snapshots exist.
+
+ If there are no other snapshots, base = None, which results in
+ libvirt clearing the qcow2 backing file pointer for the active
+ disk image.
+
+ If there are other snapshots, pass the parent of the file being
+ deleted as the new base file. The snapshot info pointer for the
+ prior base file must also be updated in this case.
+
+ Closes-Bug: #1262880
+
+ (cherry picked from commit 186221779a92002ff9fa13c254710c0abb3803be)
+ Conflicts:
+ cinder/tests/test_glusterfs.py
+
+ Change-Id: If7bc8259b031d0406346caafb8f688e65a38dba6
+
+commit 5122593add816c0d20affe2f3d703a1657ceb0fc
+Author: Eric Harney
+Date: Tue Nov 19 16:25:47 2013 -0500
+
+ GlusterFS: Complete snapshot_delete when info doesn't exist
+
+ The snapshot_delete operation will fail if the snapshot info file
+ doesn't contain a record for the snapshot, or does not exist.
+ This happens in cases such as when snapshot_create fails to commit
+ anything to disk.
+
+ The driver should allow the manager to delete the snapshot
+ in this case, as there is no action required for the driver
+ to delete anything.
+
+ Closes-Bug: #1252864
+
+ (cherry picked from commit d8a11168c908fe6c6a07fbb30a5bc88a6df6e939)
+
+ Change-Id: I8686a1be09dbb7984072538bff6c026bb84eeb52
+
commit ec8ce6cdf236154b4ba0b392202fa7bd7c7c9b61
Merge: 5228001 1b437d9
Author: Jenkins
@@ -258,6 +323,23 @@
Merge "GlusterFS: Synchronize operations that manipulate qcow2 data" into stable/havana
+commit d39b2d2d808a79280201f6dc00aa93f576d70acd
+Author: Eric Harney
+Date: Tue Nov 19 18:01:55 2013 -0500
+
+ GlusterFS: Ensure Cinder can write to shares
+
+ Ensure the Cinder user can write to the GlusterFS share. This
+ is required for snapshot functionality, and means the admin
+ does not have to set this permission manually.
+
+ Conflicts:
+ cinder/tests/test_glusterfs.py
+
+ Closes-Bug: #1236966
+ Change-Id: I4a9ea40df9681ca6931ad6b390aa21b09d6cfec9
+ (cherry picked from commit 371fa540600b20b97eae389e1f976145866cadae)
+
commit 9e2ba7b5274c07cba5275d9d65ed8c73810f21f8
Author: Eric Harney
Date: Mon Nov 18 13:42:37 2013 -0500
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.2.dev16.g77fade5/PKG-INFO new/cinder-2013.2.2.dev21.g240c81d/PKG-INFO
--- old/cinder-2013.2.2.dev16.g77fade5/PKG-INFO 2014-01-29 21:08:24.000000000 +0100
+++ new/cinder-2013.2.2.dev21.g240c81d/PKG-INFO 2014-02-02 07:49:46.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: cinder
-Version: 2013.2.2.dev16.g77fade5
+Version: 2013.2.2.dev21.g240c81d
Summary: OpenStack Block Storage
Home-page: http://www.openstack.org/
Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.2.dev16.g77fade5/cinder/tests/test_glusterfs.py new/cinder-2013.2.2.dev21.g240c81d/cinder/tests/test_glusterfs.py
--- old/cinder-2013.2.2.dev16.g77fade5/cinder/tests/test_glusterfs.py 2014-01-29 21:06:39.000000000 +0100
+++ new/cinder-2013.2.2.dev21.g240c81d/cinder/tests/test_glusterfs.py 2014-02-02 07:47:48.000000000 +0100
@@ -19,6 +19,7 @@
import errno
import json
import os
+import tempfile
import mox as mox_lib
from mox import IgnoreArg
@@ -34,6 +35,7 @@
from cinder import test
from cinder.tests.compute import test_nova
from cinder import units
+from cinder import utils
from cinder.volume import configuration as conf
from cinder.volume.drivers import glusterfs
@@ -311,6 +313,11 @@
mox = self._mox
drv = self._driver
+ mox.StubOutWithMock(utils, 'get_file_mode')
+ mox.StubOutWithMock(utils, 'get_file_gid')
+ mox.StubOutWithMock(drv, '_execute')
+ mox.StubOutWithMock(drv, '_ensure_share_writable')
+
mox.StubOutWithMock(drv, '_get_mount_point_for_share')
drv._get_mount_point_for_share(self.TEST_EXPORT1).\
AndReturn(self.TEST_MNT_POINT)
@@ -319,6 +326,15 @@
drv._mount_glusterfs(self.TEST_EXPORT1, self.TEST_MNT_POINT,
ensure=True)
+ utils.get_file_gid(self.TEST_MNT_POINT).AndReturn(333333)
+
+ utils.get_file_mode(self.TEST_MNT_POINT).AndReturn(0o777)
+
+ drv._ensure_share_writable(self.TEST_MNT_POINT)
+
+ drv._execute('chgrp', IgnoreArg(), self.TEST_MNT_POINT,
+ run_as_root=True)
+
mox.ReplayAll()
drv._ensure_share_mounted(self.TEST_EXPORT1)
@@ -399,6 +415,52 @@
mox.VerifyAll()
+ def _fake_load_shares_config(self, conf):
+ self._driver.shares = {'127.7.7.7:/gluster1': None}
+
+ def _fake_NamedTemporaryFile(self, prefix=None, dir=None):
+ raise OSError('Permission denied!')
+
+ def test_setup_set_share_permissions(self):
+ mox = self._mox
+ drv = self._driver
+
+ glusterfs.CONF.glusterfs_shares_config = self.TEST_SHARES_CONFIG_FILE
+
+ self.stubs.Set(drv, '_load_shares_config',
+ self._fake_load_shares_config)
+ self.stubs.Set(tempfile, 'NamedTemporaryFile',
+ self._fake_NamedTemporaryFile)
+ mox.StubOutWithMock(os.path, 'exists')
+ mox.StubOutWithMock(drv, '_execute')
+ mox.StubOutWithMock(utils, 'get_file_gid')
+ mox.StubOutWithMock(utils, 'get_file_mode')
+ mox.StubOutWithMock(os, 'getegid')
+
+ drv._execute('mount.glusterfs', check_exit_code=False)
+
+ drv._execute('mkdir', '-p', mox_lib.IgnoreArg())
+
+ os.path.exists(self.TEST_SHARES_CONFIG_FILE).AndReturn(True)
+
+ drv._execute('mount', '-t', 'glusterfs', '127.7.7.7:/gluster1',
+ mox_lib.IgnoreArg(), run_as_root=True)
+
+ utils.get_file_gid(mox_lib.IgnoreArg()).AndReturn(33333)
+ # perms not writable
+ utils.get_file_mode(mox_lib.IgnoreArg()).AndReturn(0o000)
+
+ os.getegid().AndReturn(888)
+
+ drv._execute('chgrp', 888, mox_lib.IgnoreArg(), run_as_root=True)
+ drv._execute('chmod', 'g+w', mox_lib.IgnoreArg(), run_as_root=True)
+
+ mox.ReplayAll()
+
+ drv.do_setup(IsA(context.RequestContext))
+
+ mox.VerifyAll()
+
def test_find_share_should_throw_error_if_there_is_no_mounted_shares(self):
"""_find_share should throw error if there is no mounted shares."""
drv = self._driver
@@ -765,6 +827,7 @@
(mox, drv) = self._mox, self._driver
hashed = drv._get_hash_str(self.TEST_EXPORT1)
+ volume_dir = os.path.join(self.TEST_MNT_POINT_BASE, hashed)
volume_path = '%s/%s/volume-%s' % (self.TEST_MNT_POINT_BASE,
hashed,
self.VOLUME_UUID)
@@ -789,8 +852,11 @@
mox.StubOutWithMock(drv, '_get_backing_chain_for_path')
mox.StubOutWithMock(drv, '_get_matching_backing_file')
mox.StubOutWithMock(drv, '_write_info_file')
+ mox.StubOutWithMock(drv, '_ensure_share_writable')
mox.StubOutWithMock(image_utils, 'qemu_img_info')
+ drv._ensure_share_writable(volume_dir)
+
img_info = image_utils.QemuImgInfo(qemu_img_info_output)
image_utils.qemu_img_info(snap_path_2).AndReturn(img_info)
@@ -810,7 +876,8 @@
snap_path_chain = [{self.SNAP_UUID: snap_file},
{'active': snap_file}]
- drv._read_info_file(info_path).AndReturn(info_file_dict)
+ drv._read_info_file(info_path, empty_if_missing=True).\
+ AndReturn(info_file_dict)
drv._execute('qemu-img', 'commit', snap_path_2, run_as_root=True)
@@ -850,6 +917,7 @@
hashed = drv._get_hash_str(self.TEST_EXPORT1)
volume_file = 'volume-%s' % self.VOLUME_UUID
+ volume_dir = os.path.join(self.TEST_MNT_POINT_BASE, hashed)
volume_path = '%s/%s/%s' % (self.TEST_MNT_POINT_BASE,
hashed,
volume_file)
@@ -887,6 +955,7 @@
mox.StubOutWithMock(drv, '_write_info_file')
mox.StubOutWithMock(drv, '_get_backing_chain_for_path')
mox.StubOutWithMock(drv, 'get_active_image_from_info')
+ mox.StubOutWithMock(drv, '_ensure_share_writable')
mox.StubOutWithMock(image_utils, 'qemu_img_info')
info_file_dict = {self.SNAP_UUID_2: 'volume-%s.%s' %
@@ -894,8 +963,11 @@
self.SNAP_UUID: 'volume-%s.%s' %
(self.VOLUME_UUID, self.SNAP_UUID)}
+ drv._ensure_share_writable(volume_dir)
+
info_path = drv._local_path_volume(volume) + '.info'
- drv._read_info_file(info_path).AndReturn(info_file_dict)
+ drv._read_info_file(info_path, empty_if_missing=True).\
+ AndReturn(info_file_dict)
img_info = image_utils.QemuImgInfo(qemu_img_info_output_snap_1)
image_utils.qemu_img_info(snap_path).AndReturn(img_info)
@@ -930,6 +1002,44 @@
mox.VerifyAll()
+ def test_delete_snapshot_not_in_info(self):
+ """Snapshot not in info file / info file doesn't exist.
+
+ Snapshot creation failed so nothing is on-disk. Driver
+ should allow operation to succeed so the manager can
+ remove the snapshot record.
+
+ (Scenario: Snapshot object created in Cinder db but not
+ on backing storage.)
+
+ """
+ (mox, drv) = self._mox, self._driver
+
+ hashed = drv._get_hash_str(self.TEST_EXPORT1)
+ volume_dir = os.path.join(self.TEST_MNT_POINT_BASE, hashed)
+ volume_filename = 'volume-%s' % self.VOLUME_UUID
+ volume_path = os.path.join(volume_dir, volume_filename)
+ info_path = '%s%s' % (volume_path, '.info')
+
+ mox.StubOutWithMock(drv, '_read_file')
+ mox.StubOutWithMock(drv, '_read_info_file')
+ mox.StubOutWithMock(drv, '_ensure_share_writable')
+
+ snap_ref = {'name': 'test snap',
+ 'volume_id': self.VOLUME_UUID,
+ 'volume': self._simple_volume(),
+ 'id': self.SNAP_UUID_2}
+
+ drv._ensure_share_writable(volume_dir)
+
+ drv._read_info_file(info_path, empty_if_missing=True).AndReturn({})
+
+ mox.ReplayAll()
+
+ drv.delete_snapshot(snap_ref)
+
+ mox.VerifyAll()
+
def test_read_info_file(self):
(mox, drv) = self._mox, self._driver
@@ -1112,7 +1222,7 @@
snap_ref)
def test_delete_snapshot_online_1(self):
- """Delete the newest snapshot."""
+ """Delete the newest snapshot, with only one snap present."""
(mox, drv) = self._mox, self._driver
volume = self._simple_volume()
@@ -1128,6 +1238,7 @@
hashed = drv._get_hash_str(self.TEST_EXPORT1)
volume_file = 'volume-%s' % self.VOLUME_UUID
+ volume_dir = os.path.join(self.TEST_MNT_POINT_BASE, hashed)
volume_path = '%s/%s/%s' % (self.TEST_MNT_POINT_BASE,
hashed,
volume_file)
@@ -1143,11 +1254,15 @@
mox.StubOutWithMock(os.path, 'exists')
mox.StubOutWithMock(db, 'snapshot_get')
mox.StubOutWithMock(image_utils, 'qemu_img_info')
+ mox.StubOutWithMock(drv, '_ensure_share_writable')
snap_info = {'active': snap_file,
self.SNAP_UUID: snap_file}
- drv._read_info_file(info_path).AndReturn(snap_info)
+ drv._ensure_share_writable(volume_dir)
+
+ drv._read_info_file(info_path, empty_if_missing=True).\
+ AndReturn(snap_info)
os.path.exists(snap_path).AndReturn(True)
@@ -1158,15 +1273,25 @@
backing file: %s
""" % (snap_file, volume_file)
img_info = image_utils.QemuImgInfo(qemu_img_info_output)
+
+ vol_qemu_img_info_output = """image: %s
+ file format: raw
+ virtual size: 1.0G (1073741824 bytes)
+ disk size: 173K
+ """ % volume_file
+ volume_img_info = image_utils.QemuImgInfo(vol_qemu_img_info_output)
+
image_utils.qemu_img_info(snap_path).AndReturn(img_info)
+ image_utils.qemu_img_info(volume_path).AndReturn(volume_img_info)
+
drv._read_info_file(info_path, empty_if_missing=True).\
AndReturn(snap_info)
delete_info = {
'type': 'qcow2',
'merge_target_file': None,
- 'file_to_merge': volume_file,
+ 'file_to_merge': None,
'volume_id': self.VOLUME_UUID
}
@@ -1197,7 +1322,7 @@
drv.delete_snapshot(snap_ref)
def test_delete_snapshot_online_2(self):
- """Delete the middle snapshot."""
+ """Delete the middle of 3 snapshots."""
(mox, drv) = self._mox, self._driver
volume = self._simple_volume()
@@ -1213,6 +1338,7 @@
hashed = drv._get_hash_str(self.TEST_EXPORT1)
volume_file = 'volume-%s' % self.VOLUME_UUID
+ volume_dir = os.path.join(self.TEST_MNT_POINT_BASE, hashed)
volume_path = '%s/%s/%s' % (self.TEST_MNT_POINT_BASE,
hashed,
volume_file)
@@ -1230,12 +1356,16 @@
mox.StubOutWithMock(os.path, 'exists')
mox.StubOutWithMock(db, 'snapshot_get')
mox.StubOutWithMock(image_utils, 'qemu_img_info')
+ mox.StubOutWithMock(drv, '_ensure_share_writable')
snap_info = {'active': snap_file_2,
self.SNAP_UUID: snap_file,
self.SNAP_UUID_2: snap_file_2}
- drv._read_info_file(info_path).AndReturn(snap_info)
+ drv._ensure_share_writable(volume_dir)
+
+ drv._read_info_file(info_path, empty_if_missing=True).\
+ AndReturn(snap_info)
os.path.exists(snap_path).AndReturn(True)
@@ -1247,8 +1377,17 @@
""" % (snap_file, volume_file)
img_info = image_utils.QemuImgInfo(qemu_img_info_output)
+ vol_qemu_img_info_output = """image: %s
+ file format: raw
+ virtual size: 1.0G (1073741824 bytes)
+ disk size: 173K
+ """ % volume_file
+ volume_img_info = image_utils.QemuImgInfo(vol_qemu_img_info_output)
+
image_utils.qemu_img_info(snap_path).AndReturn(img_info)
+ image_utils.qemu_img_info(volume_path).AndReturn(volume_img_info)
+
drv._read_info_file(info_path, empty_if_missing=True).\
AndReturn(snap_info)
@@ -1318,7 +1457,8 @@
snap_info = {'active': snap_file,
self.SNAP_UUID: snap_file}
- drv._read_info_file(info_path).AndReturn(snap_info)
+ drv._read_info_file(info_path, empty_if_missing=True).\
+ AndReturn(snap_info)
os.path.exists(snap_path).AndReturn(True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.2.dev16.g77fade5/cinder/tests/test_utils.py new/cinder-2013.2.2.dev21.g240c81d/cinder/tests/test_utils.py
--- old/cinder-2013.2.2.dev16.g77fade5/cinder/tests/test_utils.py 2014-01-29 21:06:39.000000000 +0100
+++ new/cinder-2013.2.2.dev21.g240c81d/cinder/tests/test_utils.py 2014-02-02 07:47:48.000000000 +0100
@@ -513,6 +513,57 @@
self.mox.VerifyAll()
+ def _make_fake_stat(self, test_file, orig_os_stat):
+ """Create a fake method to stub out os.stat().
+
+ Generate a function that will return a particular
+ stat object for a given file.
+
+ :param: test_file: file to spoof stat() for
+ :param: orig_os_stat: pointer to original os.stat()
+ """
+
+ def fake_stat(path):
+ if path == test_file:
+ class stat_result:
+ st_mode = 0o777
+ st_gid = 33333
+ return stat_result
+ else:
+ return orig_os_stat(path)
+
+ return fake_stat
+
+ def test_get_file_mode(self):
+ test_file = '/var/tmp/made_up_file'
+
+ orig_os_stat = os.stat
+ os.stat = self._make_fake_stat(test_file, orig_os_stat)
+
+ self.mox.ReplayAll()
+
+ mode = utils.get_file_mode(test_file)
+ self.assertEqual(mode, 0o777)
+
+ self.mox.VerifyAll()
+
+ os.stat = orig_os_stat
+
+ def test_get_file_gid(self):
+ test_file = '/var/tmp/made_up_file'
+
+ orig_os_stat = os.stat
+ os.stat = self._make_fake_stat(test_file, orig_os_stat)
+
+ self.mox.ReplayAll()
+
+ gid = utils.get_file_gid(test_file)
+ self.assertEqual(gid, 33333)
+
+ self.mox.VerifyAll()
+
+ os.stat = orig_os_stat
+
class MonkeyPatchTestCase(test.TestCase):
"""Unit test for utils.monkey_patch()."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.2.dev16.g77fade5/cinder/utils.py new/cinder-2013.2.2.dev21.g240c81d/cinder/utils.py
--- old/cinder-2013.2.2.dev16.g77fade5/cinder/utils.py 2014-01-29 21:06:39.000000000 +0100
+++ new/cinder-2013.2.2.dev21.g240c81d/cinder/utils.py 2014-02-02 07:47:48.000000000 +0100
@@ -30,6 +30,7 @@
import random
import re
import shutil
+import stat
import sys
import tempfile
import time
@@ -820,3 +821,13 @@
raise exception.DriverNotInitialized(driver=driver_name)
return func(self, *args, **kwargs)
return wrapper
+
+
+def get_file_mode(path):
+ """This primarily exists to make unit testing easier."""
+ return stat.S_IMODE(os.stat(path).st_mode)
+
+
+def get_file_gid(path):
+ """This primarily exists to make unit testing easier."""
+ return os.stat(path).st_gid
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.2.dev16.g77fade5/cinder/volume/drivers/glusterfs.py new/cinder-2013.2.2.dev21.g240c81d/cinder/volume/drivers/glusterfs.py
--- old/cinder-2013.2.2.dev16.g77fade5/cinder/volume/drivers/glusterfs.py 2014-01-29 21:06:39.000000000 +0100
+++ new/cinder-2013.2.2.dev21.g240c81d/cinder/volume/drivers/glusterfs.py 2014-02-02 07:47:48.000000000 +0100
@@ -20,6 +20,8 @@
import json
import os
import re
+import stat
+import tempfile
import time
from oslo.config import cfg
@@ -108,6 +110,8 @@
else:
raise
+ self._ensure_shares_mounted()
+
def check_for_setup_error(self):
"""Just to override parent behavior."""
pass
@@ -545,6 +549,10 @@
If volume status is 'in-use', calculate what qcow2 files need to
merge, and call to Nova to perform this operation.
+ :raises: InvalidVolume if status not acceptable
+ :raises: GlusterfsException(msg) if operation fails
+ :returns: None
+
"""
LOG.debug(_('deleting snapshot %s') % snapshot['id'])
@@ -554,12 +562,24 @@
msg = _('Volume status must be "available" or "in-use".')
raise exception.InvalidVolume(msg)
+ self._ensure_share_writable(
+ self._local_volume_dir(snapshot['volume']))
+
# Determine the true snapshot file for this snapshot
# based on the .info file
info_path = self._local_path_volume(snapshot['volume']) + '.info'
- snap_info = self._read_info_file(info_path)
- snapshot_file = snap_info[snapshot['id']]
+ snap_info = self._read_info_file(info_path, empty_if_missing=True)
+ if snapshot['id'] not in snap_info:
+ # If snapshot info file is present, but snapshot record does not
+ # exist, do not attempt to delete.
+ # (This happens, for example, if snapshot_create failed due to lack
+ # of permission to write to the share.)
+ LOG.info(_('Snapshot record for %s is not present, allowing '
+ 'snapshot_delete to proceed.') % snapshot['id'])
+ return
+
+ snapshot_file = snap_info[snapshot['id']]
LOG.debug(_('snapshot_file for this snap is %s') % snapshot_file)
snapshot_path = '%s/%s' % (self._local_volume_dir(snapshot['volume']),
@@ -583,6 +603,12 @@
# file as base.
msg = _('No base file found for %s.') % snapshot_path
raise exception.GlusterfsException(msg)
+
+ base_path = os.path.join(
+ self._local_volume_dir(snapshot['volume']), base_file)
+ base_file_img_info = self._qemu_img_info(base_path)
+ new_base_file = base_file_img_info.backing_file
+
base_id = None
info_path = self._local_path_volume(snapshot['volume']) + '.info'
snap_info = self._read_info_file(info_path)
@@ -601,7 +627,8 @@
'active_file': active_file,
'snapshot_file': snapshot_file,
'base_file': base_file,
- 'base_id': base_id
+ 'base_id': base_id,
+ 'new_base_file': new_base_file
}
return self._delete_snapshot_online(context,
@@ -711,8 +738,15 @@
# info['base'] => snapshot_file
file_to_delete = info['base_file']
+ if info['base_id'] is None:
+ # Passing base=none to blockRebase ensures that
+ # libvirt blanks out the qcow2 backing file pointer
+ new_base = None
+ else:
+ new_base = info['new_base_file']
+ snap_info[info['base_id']] = info['snapshot_file']
- delete_info = {'file_to_merge': info['base_file'],
+ delete_info = {'file_to_merge': new_base,
'merge_target_file': None, # current
'type': 'qcow2',
'volume_id': snapshot['volume']['id']}
@@ -981,6 +1015,26 @@
LOG.debug(_('Available shares: %s') % str(self._mounted_shares))
+ def _ensure_share_writable(self, path):
+ """Ensure that the Cinder user can write to the share.
+
+ If not, raise an exception.
+
+ :param path: path to test
+ :raises: GlusterfsException
+ :returns: None
+ """
+
+ prefix = '.cinder-write-test-' + str(os.getpid()) + '-'
+
+ try:
+ tempfile.NamedTemporaryFile(prefix=prefix, dir=path)
+ except OSError:
+ msg = _('GlusterFS share at %(dir)s is not writable by the '
+ 'Cinder volume service. Snapshot operations will not be '
+ 'supported.') % {'dir': path}
+ raise exception.GlusterfsException(msg)
+
def _ensure_share_mounted(self, glusterfs_share):
"""Mount GlusterFS share.
:param glusterfs_share: string
@@ -988,6 +1042,21 @@
mount_path = self._get_mount_point_for_share(glusterfs_share)
self._mount_glusterfs(glusterfs_share, mount_path, ensure=True)
+ # Ensure we can write to this share
+ group_id = os.getegid()
+ current_group_id = utils.get_file_gid(mount_path)
+ current_mode = utils.get_file_mode(mount_path)
+
+ if group_id != current_group_id:
+ cmd = ['chgrp', group_id, mount_path]
+ self._execute(*cmd, run_as_root=True)
+
+ if not (current_mode & stat.S_IWGRP):
+ cmd = ['chmod', 'g+w', mount_path]
+ self._execute(*cmd, run_as_root=True)
+
+ self._ensure_share_writable(mount_path)
+
def _find_share(self, volume_size_for):
"""Choose GlusterFS share among available ones for given volume size.
Current implementation looks for greatest capacity.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.2.dev16.g77fade5/cinder.egg-info/PKG-INFO new/cinder-2013.2.2.dev21.g240c81d/cinder.egg-info/PKG-INFO
--- old/cinder-2013.2.2.dev16.g77fade5/cinder.egg-info/PKG-INFO 2014-01-29 21:08:23.000000000 +0100
+++ new/cinder-2013.2.2.dev21.g240c81d/cinder.egg-info/PKG-INFO 2014-02-02 07:49:46.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: cinder
-Version: 2013.2.2.dev16.g77fade5
+Version: 2013.2.2.dev21.g240c81d
Summary: OpenStack Block Storage
Home-page: http://www.openstack.org/
Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cinder-2013.2.2.dev16.g77fade5/etc/cinder/rootwrap.d/volume.filters new/cinder-2013.2.2.dev21.g240c81d/etc/cinder/rootwrap.d/volume.filters
--- old/cinder-2013.2.2.dev16.g77fade5/etc/cinder/rootwrap.d/volume.filters 2014-01-29 21:06:39.000000000 +0100
+++ new/cinder-2013.2.2.dev21.g240c81d/etc/cinder/rootwrap.d/volume.filters 2014-02-02 07:47:48.000000000 +0100
@@ -67,6 +67,7 @@
# cinder/volume/drivers/glusterfs.py
mv: CommandFilter, mv, root
+chgrp: CommandFilter, chgrp, root
# cinder/volumes/drivers/hds/hds.py:
hus-cmd: CommandFilter, hus-cmd, root
++++++ openstack-cinder.conf ++++++
d /var/run/openstack-cinder 0700 openstack-cinder openstack-cinder -
++++++ openstack-cinder.logrotate ++++++
--- /var/tmp/diff_new_pack.NtS2Rk/_old 2014-02-11 10:40:19.000000000 +0100
+++ /var/tmp/diff_new_pack.NtS2Rk/_new 2014-02-11 10:40:19.000000000 +0100
@@ -6,7 +6,7 @@
weekly
dateext
missingok
- notifyempty
+ notifempty
su openstack-cinder openstack-cinder
copytruncate
sharedscripts
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org