Make rbd store's pool handling more universal

Currently we ignore the pool part of the location throughout the rbd store code.
If there is a pool specified, use that. Otherwise we can still fall back to the
configured pool.

This is a required change if we want to support ephemeral disk snapshotting later on
as in that scenario the ephemeral pool might be a different pool from images pool,
yet we're going to need to reference the snapshot of a disk in the ephemeral pool.

Change-Id: Ie415667a809975948c8cfb71ec63a0905995fa67
Closes-Bug: 1368128
This commit is contained in:
Flavio Percoco 2014-09-23 17:55:13 +02:00 committed by Flavio Percoco
parent 70725be505
commit 312e93eb16
2 changed files with 22 additions and 13 deletions

View File

@ -144,9 +144,10 @@ class ImageIterator(object):
Reads data from an RBD image, one chunk at a time.
"""
def __init__(self, name, store):
def __init__(self, pool, name, snapshot, store):
self.pool = pool or store.pool
self.name = name
self.pool = store.pool
self.snapshot = snapshot
self.user = store.user
self.conf_file = store.conf_file
self.chunk_size = store.chunk_size
@ -156,7 +157,8 @@ class ImageIterator(object):
with rados.Rados(conffile=self.conf_file,
rados_id=self.user) as conn:
with conn.open_ioctx(self.pool) as ioctx:
with rbd.Image(ioctx, self.name) as image:
with rbd.Image(ioctx, self.name,
snapshot=self.snapshot) as image:
img_info = image.stat()
size = img_info['size']
bytes_left = size
@ -211,7 +213,8 @@ class Store(glance.store.base.Store):
:raises `glance.exception.NotFound` if image does not exist
"""
loc = location.store_location
return (ImageIterator(loc.image, self), self.get_size(location))
return (ImageIterator(loc.pool, loc.image, loc.snapshot, self),
self.get_size(location))
def get_size(self, location):
"""
@ -223,9 +226,12 @@ class Store(glance.store.base.Store):
:raises `glance.exception.NotFound` if image does not exist
"""
loc = location.store_location
# if there is a pool specific in the location, use it; otherwise
# we fall back to the default pool specified in the config
target_pool = loc.pool or self.pool
with rados.Rados(conffile=self.conf_file,
rados_id=self.user) as conn:
with conn.open_ioctx(self.pool) as ioctx:
with conn.open_ioctx(target_pool) as ioctx:
try:
with rbd.Image(ioctx, loc.image,
snapshot=loc.snapshot) as image:
@ -260,7 +266,7 @@ class Store(glance.store.base.Store):
librbd.create(ioctx, image_name, size, order, old_format=True)
return StoreLocation({'image': image_name})
def _delete_image(self, image_name, snapshot_name=None):
def _delete_image(self, target_pool, image_name, snapshot_name=None):
"""
Delete RBD image and snapshot.
@ -271,7 +277,7 @@ class Store(glance.store.base.Store):
InUseByStore if image is in use or snapshot unprotect failed
"""
with rados.Rados(conffile=self.conf_file, rados_id=self.user) as conn:
with conn.open_ioctx(self.pool) as ioctx:
with conn.open_ioctx(target_pool) as ioctx:
try:
# First remove snapshot.
if snapshot_name is not None:
@ -387,4 +393,5 @@ class Store(glance.store.base.Store):
InUseByStore if image is in use or snapshot unprotect failed
"""
loc = location.store_location
self._delete_image(loc.image, loc.snapshot)
target_pool = loc.pool or self.pool
self._delete_image(target_pool, loc.image, loc.snapshot)

View File

@ -37,7 +37,8 @@ class TestStore(base.StoreClearingUnitTest):
self.store.chunk_size = 2
self.called_commands_actual = []
self.called_commands_expected = []
self.store_specs = {'image': 'fake_image',
self.store_specs = {'pool': 'fake_pool',
'image': 'fake_image',
'snapshot': 'fake_snapshot'}
self.location = StoreLocation(self.store_specs)
# Provide enough data to get more than one chunk iteration.
@ -99,7 +100,7 @@ class TestStore(base.StoreClearingUnitTest):
self.called_commands_actual.append('remove')
self.stubs.Set(mock_rbd.RBD, 'remove', _fake_remove)
self.store._delete_image(self.location)
self.store._delete_image('fake_pool', self.location)
self.called_commands_expected = ['remove']
def test__delete_image_w_snap(self):
@ -115,7 +116,8 @@ class TestStore(base.StoreClearingUnitTest):
self.stubs.Set(mock_rbd.RBD, 'remove', _fake_remove)
self.stubs.Set(mock_rbd.Image, 'unprotect_snap', _fake_unprotect_snap)
self.stubs.Set(mock_rbd.Image, 'remove_snap', _fake_remove_snap)
self.store._delete_image(self.location, snapshot_name='snap')
self.store._delete_image('fake_pool', self.location,
snapshot_name='snap')
self.called_commands_expected = ['unprotect_snap', 'remove_snap',
'remove']
@ -127,7 +129,7 @@ class TestStore(base.StoreClearingUnitTest):
self.stubs.Set(mock_rbd.Image, 'unprotect_snap', _fake_unprotect_snap)
self.assertRaises(exception.NotFound, self.store._delete_image,
self.location, snapshot_name='snap')
'fake_pool', self.location, snapshot_name='snap')
self.called_commands_expected = ['unprotect_snap']
@ -138,7 +140,7 @@ class TestStore(base.StoreClearingUnitTest):
self.stubs.Set(mock_rbd.RBD, 'remove', _fake_remove)
self.assertRaises(exception.NotFound, self.store._delete_image,
self.location, snapshot_name='snap')
'fake_pool', self.location, snapshot_name='snap')
self.called_commands_expected = ['remove']