Add support to skip either kernel or ramdisk

Currently, glance.create_or_find_kernel_and_ramdisk() will raise an
exception if either the kernel or ramdisk are not found in Glance.
This makes it fairly awkward for others to use the API if they need
to deal with a missing kernel, but an existing ramdisk since the
function will never check, because the exception is raised when the
kernel isn't found.

Change-Id: I872a080846c7a191039e89afaa587cafbd853fe4
This commit is contained in:
Steve Kowalik 2015-02-06 16:05:09 +11:00
parent c32e19d27e
commit 304b4c03d1
2 changed files with 41 additions and 6 deletions

View File

@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import collections
import logging
from glanceclient.openstack.common.apiclient import exceptions
@ -21,7 +22,8 @@ LOG = logging.getLogger(__name__)
def create_or_find_kernel_and_ramdisk(glanceclient, kernel_name, ramdisk_name,
kernel_path=None, ramdisk_path=None):
kernel_path=None, ramdisk_path=None,
skip_missing=False):
"""Find or create a given kernel and ramdisk in Glance.
If either kernel_path or ramdisk_path is None, they will not be created,
@ -32,17 +34,21 @@ def create_or_find_kernel_and_ramdisk(glanceclient, kernel_name, ramdisk_name,
:param ramdisk_name: Name to search for or create for the ramdisk.
:param kernel_path: Path to the kernel on disk.
:param ramdisk_path: Path to the ramdisk on disk.
:param skip_missing: If `True', do not raise an exception if either the
kernel or ramdisk image is not found.
:returns: A dictionary mapping kernel or ramdisk to the ID in Glance.
"""
kernel_image = _upload_file(glanceclient, kernel_name, kernel_path,
'aki', 'Kernel')
'aki', 'Kernel', skip_missing=skip_missing)
ramdisk_image = _upload_file(glanceclient, ramdisk_name, ramdisk_path,
'ari', 'Ramdisk')
'ari', 'Ramdisk', skip_missing=skip_missing)
return {'kernel': kernel_image.id, 'ramdisk': ramdisk_image.id}
def _upload_file(glanceclient, name, path, disk_format, type_name):
def _upload_file(glanceclient, name, path, disk_format, type_name,
skip_missing=False):
image_tuple = collections.namedtuple('image', ['id'])
try:
image = glanceclient.images.find(name=name, disk_format=disk_format)
except exceptions.NotFound:
@ -50,6 +56,9 @@ def _upload_file(glanceclient, name, path, disk_format, type_name):
image = glanceclient.images.create(
name=name, disk_format=disk_format, is_public=True,
data=open(path, 'rb'))
else:
if skip_missing:
image = image_tuple(None)
else:
raise ValueError("%s image not found in Glance, and no path "
"specified." % type_name)

View File

@ -56,6 +56,32 @@ class GlanceTest(base.TestCase):
glance.create_or_find_kernel_and_ramdisk(client, 'bm-kernel',
'bm-ramdisk')
def test_skip_missing_no_kernel(self):
client = mock.MagicMock()
client.images.find.side_effect = (exceptions.NotFound,
self.image('bbb'))
expected = {'kernel': None, 'ramdisk': 'bbb'}
ids = glance.create_or_find_kernel_and_ramdisk(
client, 'bm-kernel', 'bm-ramdisk', skip_missing=True)
self.assertEqual(ids, expected)
def test_skip_missing_no_ramdisk(self):
client = mock.MagicMock()
client.images.find.side_effect = (self.image('aaa'),
exceptions.NotFound)
expected = {'kernel': 'aaa', 'ramdisk': None}
ids = glance.create_or_find_kernel_and_ramdisk(
client, 'bm-kernel', 'bm-ramdisk', skip_missing=True)
self.assertEqual(ids, expected)
def test_skip_missing_kernel_and_ramdisk(self):
client = mock.MagicMock()
client.images.find.side_effect = exceptions.NotFound
expected = {'kernel': None, 'ramdisk': None}
ids = glance.create_or_find_kernel_and_ramdisk(
client, 'bm-kernel', 'bm-ramdisk', skip_missing=True)
self.assertEqual(ids, expected)
def test_create_kernel_and_ramdisk(self):
client = mock.MagicMock()
client.images.find.side_effect = exceptions.NotFound