Andrey Pavlov 75905790e5 update gce api to current OpenStack
- add devstack plugin
- update openstack common
- move unit tests to unit folder
- update infrastructural files

Change-Id: Id72006f70110dbd1762f42b582470ac5f3439f2a
2015-09-03 17:16:30 +03:00

150 lines
5.5 KiB
Python

# Copyright 2014
# The Cloudscaling Group, Inc.
#
# 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.
try:
from glanceclient import exc as glanceclient_exc
except ImportError:
glanceclient_exc = None
from gceapi.api import base_api
from gceapi.api import clients
from gceapi.api import operation_api
from gceapi.api import operation_util
from gceapi.api import utils
from gceapi import exception
from gceapi.i18n import _
class API(base_api.API):
"""GCE Image API."""
KIND = "image"
PERSISTENT_ATTRIBUTES = ["id", "description", "image_ref"]
_status_map = {
"queued": "PENDING",
"saving": "PENDING",
"active": "READY",
"killed": "FAILED",
# "deleted": "",
# "pending_delete": ""
}
_deleted_statuses = ["deleted", "pending_delete"]
def __init__(self, *args, **kwargs):
super(API, self).__init__(*args, **kwargs)
operation_api.API().register_get_progress_method(
"image-add",
self._get_add_item_progress)
operation_api.API().register_get_progress_method(
"image-delete",
self._get_delete_item_progress)
def _get_type(self):
return self.KIND
def _get_persistent_attributes(self):
return self.PERSISTENT_ATTRIBUTES
def get_item(self, context, name, scope=None):
image_service = clients.glance(context).images
images = image_service.list(
filters={"name": name, "disk_format": "raw"})
result = None
for image in images:
if image.status in self._deleted_statuses:
continue
if result:
msg = _("Image resource '%s' found more than once") % name
raise exception.NotFound(msg)
result = self._prepare_image(utils.to_dict(image))
db_image = self._get_db_item_by_id(context, result["id"])
self._prepare_item(result, db_image)
if not result:
msg = _("Image resource '%s' could not be found") % name
raise exception.NotFound(msg)
return result
def get_items(self, context, scope=None):
image_service = clients.glance(context).images
# NOTE(apavlov): Currently glance doesn't report "killed" images in
# list which causes incompatibility with GCE which reports
# corresponding "FAILED" images if upload has failed.
images = image_service.list(filters={"disk_format": "raw"})
items = list()
gce_images = self._get_db_items_dict(context)
for image in images:
result = self._prepare_image(utils.to_dict(image))
self._prepare_item(result, gce_images.get(result["id"]))
items.append(result)
self._purge_db(context, items, gce_images)
return items
def _prepare_image(self, item):
item["status"] = self._status_map.get(item["status"], item["status"])
return item
def delete_item(self, context, name, scope=None):
"""Delete an image, if allowed."""
image = self.get_item(context, name, scope)
image_service = clients.glance(context).images
operation_util.start_operation(context,
self._get_delete_item_progress,
image["id"])
image_service.delete(image["id"])
self._delete_db_item(context, image)
def add_item(self, context, name, body, scope=None):
name = body['name']
image_ref = body['rawDisk']['source']
meta = {
'name': name,
'disk_format': 'raw',
'container_format': 'bare',
'min_disk': 0,
'min_ram': 0,
'copy_from': image_ref,
}
image_service = clients.glance(context).images
operation_util.start_operation(context, self._get_add_item_progress)
image = image_service.create(**meta)
operation_util.set_item_id(context, image.id, self.KIND)
new_image = self._prepare_image(utils.to_dict(image))
new_image["description"] = body.get("description", "")
new_image["image_ref"] = image_ref
new_image = self._add_db_item(context, new_image)
return new_image
def _get_add_item_progress(self, context, image_id):
image_service = clients.glance(context).images
try:
image = image_service.get(image_id)
except glanceclient_exc.HTTPNotFound:
return operation_util.get_final_progress()
if image.status not in ["queued", "saving"]:
return operation_util.get_final_progress(image.status == "killed")
return None
def _get_delete_item_progress(self, context, image_id):
image_service = clients.glance(context).images
try:
image = image_service.get(image_id)
if image.status in self._deleted_statuses:
return operation_util.get_final_progress()
except glanceclient_exc.HTTPNotFound:
return operation_util.get_final_progress()
return None