# Copyright 2013 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. 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 class API(base_api.API): """GCE Snapshot API.""" KIND = "snapshot" _status_map = { 'creating': 'CREATING', 'available': 'READY', 'active': 'READY', 'deleting': 'DELETING', 'deleted': 'DELETING', 'error': 'FAILED'} def __init__(self, *args, **kwargs): super(API, self).__init__(*args, **kwargs) operation_api.API().register_get_progress_method( "snapshot-add", self._get_add_item_progress) operation_api.API().register_get_progress_method( "snapshot-delete", self._get_delete_item_progress) def _get_type(self): return self.KIND def get_item(self, context, name, scope=None): client = clients.cinder(context) snapshots = client.volume_snapshots.list( search_opts={"display_name": name}) if snapshots and len(snapshots) == 1: return self._prepare_item(client, utils.to_dict(snapshots[0])) raise exception.NotFound def get_items(self, context, scope=None): client = clients.cinder(context) snapshots = [utils.to_dict(item) for item in client.volume_snapshots.list()] for snapshot in snapshots: self._prepare_item(client, snapshot) return snapshots def delete_item(self, context, name, scope=None): client = clients.cinder(context).volume_snapshots snapshots = client.list(search_opts={"display_name": name}) if not snapshots or len(snapshots) != 1: raise exception.NotFound operation_util.start_operation(context, self._get_delete_item_progress, snapshots[0].id) client.delete(snapshots[0]) def add_item(self, context, body, scope=None): name = body["name"] disk_name = body["disk_name"] client = clients.cinder(context) volumes = client.volumes.list(search_opts={"display_name": disk_name}) if not volumes or len(volumes) != 1: raise exception.NotFound operation_util.start_operation(context, self._get_add_item_progress) snapshot = client.volume_snapshots.create( volumes[0].id, True, name, body["description"]) operation_util.set_item_id(context, snapshot.id, self.KIND) return self._prepare_item(client, utils.to_dict(snapshot)) def _prepare_item(self, client, item): item["name"] = item["display_name"] try: item["disk"] = utils.to_dict(client.volumes.get(item["volume_id"])) except Exception: pass item["status"] = self._status_map.get(item["status"], item["status"]) return item def _get_add_item_progress(self, context, snapshot_id): client = clients.cinder(context) try: snapshot = client.volume_snapshots.get(snapshot_id) except clients.cinderclient.exceptions.NotFound: return operation_util.get_final_progress() if (snapshot.status != "creating"): return operation_util.get_final_progress(snapshot.status == "error") return None def _get_delete_item_progress(self, context, snapshot_id): client = clients.cinder(context) try: snapshot = client.volume_snapshots.get(snapshot_id) except clients.cinderclient.exceptions.NotFound: return operation_util.get_final_progress() if snapshot.status not in ["deleting", "deleted"]: return operation_util.get_final_progress(True) return None