141 lines
3.9 KiB
Python
141 lines
3.9 KiB
Python
# 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 occi import exceptions
|
|
|
|
# Connection to the nova APIs
|
|
from 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
|
|
"""
|
|
# TODO: exception handling!
|
|
# TODO(dizz): 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 = str(int(float(size)))
|
|
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
|
|
|
|
new_volume = VOLUME_API.create(context,
|
|
size,
|
|
disp_name,
|
|
disp_descr)
|
|
return new_volume
|
|
|
|
|
|
def delete_storage_instance(uid, context):
|
|
"""
|
|
Delete a storage instance.
|
|
|
|
uid -- Id of the volume.
|
|
context -- The os context.
|
|
"""
|
|
# TODO: exception handling!
|
|
instance = get_storage(uid, context)
|
|
VOLUME_API.delete(context, instance)
|
|
|
|
|
|
def snapshot_storage_instance(uid, name, description, context):
|
|
"""
|
|
Snapshots an storage instance.
|
|
|
|
uid -- Id of the volume.
|
|
context -- The os context.
|
|
"""
|
|
# TODO: exception handling!
|
|
instance = get_storage(uid, context)
|
|
VOLUME_API.create_snapshot(context, instance, name, description)
|
|
|
|
|
|
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
|