| ######### |
| # Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved |
| # |
| # 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. |
| |
| import time |
| |
| from cloudify import ctx |
| from cloudify.decorators import operation |
| from cloudify import exceptions as cfy_exc |
| |
| from openstack_plugin_common import (delete_resource_and_runtime_properties, |
| with_cinder_client, |
| get_resource_id, |
| transform_resource_name, |
| use_external_resource, |
| validate_resource, |
| COMMON_RUNTIME_PROPERTIES_KEYS, |
| OPENSTACK_AZ_PROPERTY, |
| OPENSTACK_ID_PROPERTY, |
| OPENSTACK_TYPE_PROPERTY, |
| OPENSTACK_NAME_PROPERTY) |
| from glance_plugin.image import handle_image_from_relationship |
| |
| VOLUME_STATUS_CREATING = 'creating' |
| VOLUME_STATUS_DELETING = 'deleting' |
| VOLUME_STATUS_AVAILABLE = 'available' |
| VOLUME_STATUS_IN_USE = 'in-use' |
| VOLUME_STATUS_ERROR = 'error' |
| VOLUME_STATUS_ERROR_DELETING = 'error_deleting' |
| VOLUME_ERROR_STATUSES = (VOLUME_STATUS_ERROR, VOLUME_STATUS_ERROR_DELETING) |
| |
| # Note: The 'device_name' property should actually be a property of the |
| # relationship between a server and a volume; It'll move to that |
| # relationship type once relationship properties are better supported. |
| DEVICE_NAME_PROPERTY = 'device_name' |
| |
| VOLUME_OPENSTACK_TYPE = 'volume' |
| |
| RUNTIME_PROPERTIES_KEYS = COMMON_RUNTIME_PROPERTIES_KEYS |
| |
| |
| @operation |
| @with_cinder_client |
| def create(cinder_client, status_attempts, status_timeout, args, **kwargs): |
| |
| if use_external_resource(ctx, cinder_client, VOLUME_OPENSTACK_TYPE, |
| 'name'): |
| return |
| |
| name = get_resource_id(ctx, VOLUME_OPENSTACK_TYPE) |
| volume_dict = {'name': name} |
| volume_dict.update(ctx.node.properties['volume'], **args) |
| handle_image_from_relationship(volume_dict, 'imageRef', ctx) |
| volume_dict['name'] = transform_resource_name( |
| ctx, volume_dict['name']) |
| |
| v = cinder_client.volumes.create(**volume_dict) |
| |
| ctx.instance.runtime_properties[OPENSTACK_ID_PROPERTY] = v.id |
| ctx.instance.runtime_properties[OPENSTACK_TYPE_PROPERTY] = \ |
| VOLUME_OPENSTACK_TYPE |
| ctx.instance.runtime_properties[OPENSTACK_NAME_PROPERTY] = \ |
| volume_dict['name'] |
| wait_until_status(cinder_client=cinder_client, |
| volume_id=v.id, |
| status=VOLUME_STATUS_AVAILABLE, |
| num_tries=status_attempts, |
| timeout=status_timeout, |
| ) |
| ctx.instance.runtime_properties[OPENSTACK_AZ_PROPERTY] = \ |
| v.availability_zone |
| |
| |
| @operation |
| @with_cinder_client |
| def delete(cinder_client, **kwargs): |
| delete_resource_and_runtime_properties(ctx, cinder_client, |
| RUNTIME_PROPERTIES_KEYS) |
| |
| |
| @with_cinder_client |
| def wait_until_status(cinder_client, volume_id, status, num_tries, |
| timeout): |
| for _ in range(num_tries): |
| volume = cinder_client.volumes.get(volume_id) |
| |
| if volume.status in VOLUME_ERROR_STATUSES: |
| raise cfy_exc.NonRecoverableError( |
| "Volume {0} is in error state".format(volume_id)) |
| |
| if volume.status == status: |
| return volume, True |
| time.sleep(timeout) |
| |
| ctx.logger.warning("Volume {0} current state: '{1}', " |
| "expected state: '{2}'".format(volume_id, |
| volume.status, |
| status)) |
| return volume, False |
| |
| |
| @with_cinder_client |
| def get_attachment(cinder_client, volume_id, server_id): |
| volume = cinder_client.volumes.get(volume_id) |
| for attachment in volume.attachments: |
| if attachment['server_id'] == server_id: |
| return attachment |
| |
| |
| @operation |
| @with_cinder_client |
| def creation_validation(cinder_client, **kwargs): |
| validate_resource(ctx, cinder_client, VOLUME_OPENSTACK_TYPE, |
| 'name') |