2013-05-14 15:17:30 +02:00

167 lines
4.7 KiB
Python

# coding=utf-8
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright (c) 2012, Intel Performance Learning Solutions Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
Storage related glue :-)
"""
import random
from nova import exception
from nova import volume
from nova.image import glance
from cinder import exception as cinder_ex
from occi import exceptions
# Connection to the nova APIs
from occi_os_api.nova_glue import vm
VOLUME_API = volume.API()
IMAGE_API = glance.get_default_image_service()
def create_storage(size, context, name=None, description=None):
"""
Create a storage instance.
size -- Size of the storage. ('occi.storage.size')
context -- The os context.
name -- defaults to a random number if needed.
description -- defaults to the name
"""
# L8R: A blueprint?
# OpenStack deals with size in terms of integer.
# Need to convert float to integer for now and only if the float
# can be losslessly converted to integer
# e.g. See nova/quota.py:allowed_volumes(...)
if not float(size).is_integer:
raise AttributeError('Volume sizes cannot be specified as fractional'
' floats.')
size = int(float(size))
disp_name = ''
if name is not None:
disp_name = name
else:
disp_name = str(random.randrange(0, 99999999)) + '-storage.occi-wg.org'
if description is not None:
disp_descr = description
else:
disp_descr = disp_name
try:
return VOLUME_API.create(context,
size,
disp_name,
disp_descr)
except cinder_ex.VolumeSizeExceedsAvailableQuota:
raise AttributeError('The volume size quota has been reached!')
except cinder_ex.VolumeLimitExceeded:
raise AttributeError('The # of volumes quota has been reached!')
def delete_storage_instance(uid, context):
"""
Delete a storage instance.
uid -- Id of the volume.
context -- The os context.
"""
try:
instance = get_storage(uid, context)
VOLUME_API.delete(context, instance)
except cinder_ex.InvalidVolume:
raise AttributeError('Volume is in wrong state or still attached!')
def snapshot_storage_instance(uid, name, description, context):
"""
Snapshots an storage instance.
uid -- Id of the volume.
context -- The os context.
"""
try:
instance = get_storage(uid, context)
VOLUME_API.create_snapshot(context, instance, name, description)
except cinder_ex.InvalidVolume:
raise AttributeError('Volume is in wrong state!')
def get_image(uid, context):
"""
Return details on an image.
"""
try:
return IMAGE_API.show(context, uid)
except exception.ImageNotFound as err:
raise AttributeError(str(err))
def get_image_architecture(uid, context):
"""
Extract architecture from either:
- image name, title or metadata. The architecture is sometimes
encoded in the image's name
- db::glance::image_properties could be used reliably so long as the
information is supplied when registering an image with glance.
- else return a default of x86
uid -- id of the instance!
context -- The os context.
"""
instance = vm.get_vm(uid, context)
arch = ''
uid = instance['image_ref']
img = IMAGE_API.show(context, uid)
img_properties = img['properties']
if 'arch' in img_properties:
arch = img['properties']['arch']
elif 'architecture' in img_properties:
arch = img['properties']['architecture']
if arch == '':
# if all attempts fail set it to a default value
arch = 'x86'
return arch
def get_storage(uid, context):
"""
Retrieve an Volume instance from nova.
uid -- id of the instance
context -- the os context
"""
try:
instance = VOLUME_API.get(context, uid)
except exception.NotFound:
raise exceptions.HTTPError(404, 'Volume not found!')
return instance
def get_storage_volumes(context):
"""
Retrieve all storage entities from user.
"""
return VOLUME_API.get_all(context)