def _create_server_snapshot(self, context, glance_client, parameters, resource, resource_definition, resource_id): server_id = resource.extra_info.get('server_id') resource_definition['resource_id'] = resource_id resource_definition['server_id'] = server_id nova_client = ClientFactory.create_client('nova', context) is_success = utils.status_poll( partial(get_server_status, nova_client, server_id), interval=self._interval, success_statuses={'ACTIVE', 'STOPPED', 'SUSPENDED', 'PAUSED'}, failure_statuses={ 'DELETED', 'ERROR', 'RESIZED', 'SHELVED', 'SHELVED_OFFLOADED', 'SOFT_DELETED', 'RESCUED', 'not-found' }, ignore_statuses={'BUILDING'}, ) if not is_success: raise exception.CreateResourceFailed( name="Image Backup", reason='The parent server of the image is not in valid' ' status', resource_id=resource_id, resource_type=constants.IMAGE_RESOURCE_TYPE) temp_image_name = 'Temp_image_name_for_karbor' + server_id try: image_uuid = nova_client.servers.create_image( server_id, temp_image_name, parameters) except Exception as e: msg = "Failed to create the server snapshot: %s" % e LOG.exception(msg) raise exception.CreateResourceFailed( name="Image Backup", reason=msg, resource_id=resource_id, resource_type=constants.IMAGE_RESOURCE_TYPE) else: is_success = utils.status_poll( partial(get_image_status, glance_client, image_uuid), interval=self._interval, success_statuses={'active'}, failure_statuses={ 'killed', 'deleted', 'pending_delete', 'deactivated' }, ignore_statuses={'queued', 'saving', 'uploading'}) if not is_success: msg = "Image has been created, but fail to become " \ "active, so delete it and raise exception." LOG.error(msg) glance_client.images.delete(image_uuid) image_uuid = None if not image_uuid: raise exception.CreateResourceFailed( name="Image Backup", reason="Create parent server snapshot failed.", resource_id=resource_id, resource_type=constants.IMAGE_RESOURCE_TYPE) return image_uuid
def _create_temporary_image(self, cinder_client, glance_client, temporary_volume): LOG.info("Start creating image from volume({0})." "".format(temporary_volume.id)) image = cinder_client.volumes.upload_to_image( volume=temporary_volume, force=True, image_name='temporary_image_of_{0}'.format(temporary_volume.id), container_format="bare", disk_format="raw", visibility="private", protected=False ) image_id = image[1]['os-volume_upload_image']['image_id'] is_success = utils.status_poll( partial(get_image_status, glance_client, image_id), interval=self._interval, success_statuses={'active'}, ignore_statuses={'queued', 'saving'}, failure_statuses={'killed', 'deleted', 'pending_delete', 'deactivated', 'NotFound'} ) image_info = glance_client.images.get(image_id) if is_success is not True: LOG.error("The status of image (id: %s) is invalid.", image_id) reason = "Invalid status: %s of temporary image." % \ image_info.status raise exception.CreateResourceFailed( name="Volume Glance Backup", reason=reason, resource_id=image_id, resource_type=constants.IMAGE_RESOURCE_TYPE) LOG.info("Create image({0}) from volume({1}) " "success.".format(image_id, temporary_volume.id)) return image_id
def _wait_server_to_active(self, nova_client, server_id): def _get_server_status(): try: server = self._fetch_server(nova_client, server_id) return server.status.split('(')[0] if server else 'BUILD' except Exception as ex: LOG.error( 'Fetch server(%(server_id)s) failed, ' 'reason: %(reason)s', { 'server_id': server_id, 'reason': ex }) return 'ERROR' is_success = utils.status_poll( _get_server_status, interval=self._interval, success_statuses={ 'ACTIVE', }, failure_statuses={ 'ERROR', }, ignore_statuses={ 'BUILD', 'HARD_REBOOT', 'PASSWORD', 'REBOOT', 'RESCUE', 'RESIZE', 'REVERT_RESIZE', 'SHUTOFF', 'SUSPENDED', 'VERIFY_RESIZE' }, ) if not is_success: raise Exception('The server does not start successfully')
def _create_volume_from_image(self, cinder_client, temporary_image, restore_name, original_vol_id, volume_size, description): volume = cinder_client.volumes.create( size=volume_size, imageRef=temporary_image.id, name=restore_name, description=description ) is_success = utils.status_poll( partial(get_volume_status, cinder_client, volume.id), interval=self._interval, success_statuses=VOLUME_SUCCESS_STATUSES, failure_statuses=VOLUME_FAILURE_STATUSES, ignore_statuses=VOLUME_IGNORE_STATUSES ) if not is_success: LOG.error("Restore volume glance backup failed, volume_id: %s.", original_vol_id) if volume is not None and hasattr(volume, 'id'): LOG.info("Delete the failed volume, volume_id: %s.", volume.id) cinder_client.volumes.delete(volume.id) raise exception.CreateResourceFailed( name="Volume Glance Backup", reason='Restored Volume is in erroneous state', resource_id=volume.id, resource_type=constants.VOLUME_RESOURCE_TYPE, )
def _wait_pod_to_running(self, k8s_client, pod_name, pod_namespace): def _get_pod_status(): try: pod = k8s_client.read_namespaced_pod(name=pod_name, namespace=pod_namespace) return pod.status.phase except Exception as ex: LOG.error( 'Fetch pod(%(pod_name)s) failed, ' 'reason: %(reason)s', { 'pod_name': pod_name, 'reason': ex }) return 'ERROR' is_success = utils.status_poll( _get_pod_status, interval=self._interval, success_statuses={ 'Running', }, failure_statuses={'ERROR', 'Failed', 'Unknown'}, ignore_statuses={'Pending'}, ) if not is_success: raise Exception('The pod does not run successfully')
def _create_backup(self, cinder_client, volume_id, backup_name, description, snapshot_id=None, incremental=False, container=None, force=False): backup = cinder_client.backups.create( volume_id=volume_id, name=backup_name, description=description, force=force, snapshot_id=snapshot_id, incremental=incremental, container=container ) backup_id = backup.id is_success = utils.status_poll( partial(get_backup_status, cinder_client, backup_id), interval=self._interval, success_statuses={'available'}, failure_statuses={'error'}, ignore_statuses={'creating'}, ) if not is_success: try: backup = cinder_client.backups.get(backup_id) except Exception: reason = 'Unable to find backup' else: reason = backup.fail_reason raise Exception(reason) return backup_id
def _create_snapshot(self, manila_client, share_id, snapshot_name, description, force): snapshot = manila_client.share_snapshots.create( share=share_id, name=snapshot_name, description=description, force=force) snapshot_id = snapshot.id is_success = utils.status_poll(partial(get_snapshot_status, manila_client, snapshot_id), interval=self._interval, success_statuses={'available'}, failure_statuses={'error'}, ignore_statuses={'creating'}, ignore_unexpected=True) if not is_success: try: snapshot = manila_client.share_snapshots.get(snapshot_id) except Exception: reason = 'Unable to find snapshot.' else: reason = 'The status of snapshot is %s' % snapshot.status raise exception.CreateResourceFailed( name="Share Snapshot", reason=reason, resource_id=share_id, resource_type=constants.SHARE_RESOURCE_TYPE) return snapshot_id
def _create_snapshot(self, cinder_client, volume_id, snapshot_name, description, force): snapshot = cinder_client.volume_snapshots.create( volume_id=volume_id, name=snapshot_name, description=description, force=force ) snapshot_id = snapshot.id is_success = utils.status_poll( partial(get_snapshot_status, cinder_client, snapshot_id), interval=self._interval, success_statuses={'available'}, failure_statuses={'error', 'error_deleting', 'deleting', 'not-found'}, ignore_statuses={'creating'}, ignore_unexpected=True ) if not is_success: try: snapshot = cinder_client.volume_snapshots.get(snapshot_id) except Exception: reason = 'Unable to find volume snapshot.' else: reason = 'The status of snapshot is %s' % snapshot.status raise exception.CreateResourceFailed( name="Volume Snapshot", reason=reason, resource_id=volume_id, resource_type=constants.VOLUME_RESOURCE_TYPE) return snapshot_id
def _create_temporary_volume(self, cinder_client, snapshot_id): LOG.info("Start creating volume from snapshot({0}) success" "".format(snapshot_id)) snapshot = cinder_client.volume_snapshots.get(snapshot_id) volume = cinder_client.volumes.create( size=snapshot.size, snapshot_id=snapshot_id, name='temporary_volume_of_{0}'.format(snapshot_id) ) is_success = utils.status_poll( partial(get_volume_status, cinder_client, volume.id), interval=self._interval, success_statuses=VOLUME_SUCCESS_STATUSES, failure_statuses=VOLUME_FAILURE_STATUSES, ignore_statuses=VOLUME_IGNORE_STATUSES, ) volume = cinder_client.volumes.get(volume.id) if is_success is not True: LOG.error('The status of temporary volume is invalid. status:%s', volume.status) reason = 'Invalid status: %s of temporary volume.' % volume.status raise exception.CreateResourceFailed( name="Volume Glance Backup", reason=reason, resource_id=volume.id, resource_type=constants.VOLUME_RESOURCE_TYPE, ) LOG.info("Create volume from snapshot({0}) success, " "volume({1})".format(snapshot_id, volume.id)) return volume
def _check_complete(self, neutron_client, resources, resource_type): success_statuses = ('ACTIVE', 'DOWN') failure_statuses = ('ERROR', 'DEGRADED') ignore_statuses = ('BUILD') get_resource_func = getattr(neutron_client, "show_%s" % resource_type) def _get_resource_status(resource_id): return get_resource_func(resource_id)[resource_type]['status'] def _get_all_resource_status(): recheck_resources = set() for r in resources: status = _get_resource_status(r) if status in success_statuses: continue elif status in failure_statuses: return status elif status in ignore_statuses: recheck_resources.add(r) else: return status if recheck_resources: resources.difference_update(recheck_resources) return ignore_statuses[0] return success_statuses[0] return utils.status_poll(_get_all_resource_status, self._interval, success_statuses, failure_statuses, ignore_statuses)
def on_main(self, checkpoint, resource, context, parameters, **kwargs): instance_id = resource.id bank_section = checkpoint.get_resource_bank_section(instance_id) trove_client = ClientFactory.create_client('trove', context) LOG.info('creating database instance backup, instance_id: %s', instance_id) bank_section.update_object('status', constants.RESOURCE_STATUS_PROTECTING) instance_info = trove_client.instances.get(instance_id) if instance_info.status != "ACTIVE": is_success = utils.status_poll( partial(get_database_instance_status, trove_client, instance_id), interval=self._interval, success_statuses={'ACTIVE'}, failure_statuses=DATABASE_FAILURE_STATUSES, ignore_statuses=DATABASE_IGNORE_STATUSES, ) if not is_success: bank_section.update_object('status', constants.RESOURCE_STATUS_ERROR) raise exception.CreateResourceFailed( name="Database instance Backup", reason='Database instance is in a error status.', resource_id=instance_id, resource_type=constants.DATABASE_RESOURCE_TYPE, ) resource_metadata = { 'instance_id': instance_id, 'datastore': instance_info.datastore, 'flavor': instance_info.flavor, 'size': instance_info.volume['size'], } backup_name = parameters.get('backup_name', 'backup%s' % (instance_id)) description = parameters.get('description', None) try: backup_id = self._create_backup(trove_client, instance_id, backup_name, description) except exception.CreateResourceFailed as e: LOG.error( 'Error creating backup (instance_id: %(instance_id)s ' ': %(reason)s', { 'instance_id': instance_id, 'reason': e }) bank_section.update_object('status', constants.RESOURCE_STATUS_ERROR) raise resource_metadata['backup_id'] = backup_id bank_section.update_object('metadata', resource_metadata) bank_section.update_object('status', constants.RESOURCE_STATUS_AVAILABLE) LOG.info( 'Backup database instance (instance_id: %(instance_id)s ' 'backup_id: %(backup_id)s ) successfully', { 'instance_id': instance_id, 'backup_id': backup_id })
def _create_backup(self, trove_client, instance_id, backup_name, description): backup = trove_client.backups.create( backup_name, instance=instance_id, description=description ) backup_id = backup.id is_success = utils.status_poll( partial(get_backup_status, trove_client, backup_id), interval=self._interval, success_statuses={'COMPLETED'}, failure_statuses={'FAILED'}, ignore_statuses={'BUILDING'}, ignore_unexpected=True ) if not is_success: try: backup = trove_client.backups.get(backup_id) except Exception: reason = 'Unable to find backup.' else: reason = 'The status of backup is %s' % backup.status raise exception.CreateResourceFailed( name="Database Instance Backup", reason=reason, resource_id=instance_id, resource_type=constants.DATABASE_RESOURCE_TYPE) return backup_id
def _wait_volume_to_attached(self, cinder_client, volume_id): def _get_volume_status(): try: return cinder_client.volumes.get(volume_id).status except Exception as ex: LOG.error( 'Fetch volume(%(volume_id)s) status failed, ' 'reason: %(reason)s', { 'volume_id': volume_id, 'reason': ex }) return 'ERROR' is_success = utils.status_poll( _get_volume_status, interval=self._interval, success_statuses={ 'in-use', }, failure_statuses={ 'ERROR', }, ignore_statuses={'available', 'attaching'}) if not is_success: raise Exception('Attach the volume to server failed')
def on_main(self, checkpoint, resource, context, parameters, **kwargs): volume_id = resource.id bank_section = checkpoint.get_resource_bank_section(volume_id) cinder_client = ClientFactory.create_client('cinder', context) LOG.info('Creating volume snapshot, volume_id: %s', volume_id) bank_section.update_object('status', constants.RESOURCE_STATUS_PROTECTING) volume_info = cinder_client.volumes.get(volume_id) is_success = utils.status_poll( partial(get_volume_status, cinder_client, volume_id), interval=self._interval, success_statuses={ 'available', 'in-use', 'error_extending', 'error_restoring' }, failure_statuses=VOLUME_FAILURE_STATUSES, ignore_statuses=VOLUME_IGNORE_STATUSES, ) if not is_success: bank_section.update_object('status', constants.RESOURCE_STATUS_ERROR) raise exception.CreateResourceFailed( name="Volume Snapshot", reason='Volume is in a error status.', resource_id=volume_id, resource_type=constants.VOLUME_RESOURCE_TYPE, ) resource_metadata = {'volume_id': volume_id, 'size': volume_info.size} snapshot_name = parameters.get('snapshot_name', None) description = parameters.get('description', None) force = parameters.get('force', False) try: snapshot_id = self._create_snapshot(cinder_client, volume_id, snapshot_name, description, force) except Exception as e: LOG.error( 'Error creating snapshot (volume_id: %(volume_id)s ' ': %(reason)s', { 'volume_id': volume_id, 'reason': e }) bank_section.update_object('status', constants.RESOURCE_STATUS_ERROR) raise exception.CreateResourceFailed( name="Volume Snapshot", reason=e, resource_id=volume_id, resource_type=constants.VOLUME_RESOURCE_TYPE, ) resource_metadata['snapshot_id'] = snapshot_id bank_section.update_object('metadata', resource_metadata) bank_section.update_object('status', constants.RESOURCE_STATUS_AVAILABLE) LOG.info( 'Snapshot volume (volume_id: %(volume_id)s snapshot_id: ' '%(snapshot_id)s ) successfully', { 'volume_id': volume_id, 'snapshot_id': snapshot_id })
def _create_snapshot(self, cinder_client, volume_id): LOG.info("Start creating snapshot of volume({0}).".format(volume_id)) snapshot = cinder_client.volume_snapshots.create( volume_id, name='temporary_snapshot_of_{0}'.format(volume_id), force=True ) snapshot_id = snapshot.id is_success = utils.status_poll( partial(get_snapshot_status, cinder_client, snapshot_id), interval=self._interval, success_statuses={'available', }, failure_statuses={'error', 'error_deleting', 'deleting', 'not-found'}, ignore_statuses={'creating', }, ) if is_success is not True: try: snapshot = cinder_client.volume_snapshots.get(snapshot_id) except Exception: reason = 'Unable to find volume snapshot.' else: reason = 'The status of snapshot is %s' % snapshot.status raise exception.CreateResourceFailed( name="Volume Glance Backup", reason=reason, resource_id=volume_id, resource_type=constants.VOLUME_RESOURCE_TYPE ) LOG.info("Create snapshot of volume({0}) success, " "snapshot_id({1})".format(volume_id, snapshot_id)) return snapshot_id
def _check_create_complete(self, cinder_client, volume_id): return utils.status_poll( partial(get_volume_status, cinder_client, volume_id), interval=self._interval, success_statuses=VOLUME_SUCCESS_STATUSES, failure_statuses=VOLUME_FAILURE_STATUSES, ignore_statuses=VOLUME_IGNORE_STATUSES )
def _check_create_complete(self, cinder_client, volume_id): return utils.status_poll( partial(get_volume_status, cinder_client, volume_id), interval=self._interval, success_statuses={'available'}, failure_statuses={'error', 'not-found'}, ignore_statuses={'creating', 'restoring-backup', 'downloading'}, )
def on_main(self, checkpoint, resource, context, parameters, **kwargs): original_instance_id = resource.id bank_section = checkpoint.get_resource_bank_section( original_instance_id) trove_client = ClientFactory.create_client('trove', context) resource_metadata = bank_section.get_object('metadata') restore_name = parameters.get( 'restore_name', '%s@%s' % (checkpoint.id, original_instance_id)) flavor = resource_metadata['flavor'] size = resource_metadata['size'] backup_id = resource_metadata['backup_id'] restore = kwargs.get('restore') LOG.info( "Restoring a database instance from backup, " "original_instance_id: %s.", original_instance_id) try: instance_info = trove_client.instances.create( restore_name, flavor["id"], volume={"size": size}, restorePoint={"backupRef": backup_id}) is_success = utils.status_poll( partial(get_database_instance_status, trove_client, instance_info.id), interval=self._interval, success_statuses={'ACTIVE'}, failure_statuses=DATABASE_FAILURE_STATUSES, ignore_statuses=DATABASE_IGNORE_STATUSES) if is_success is not True: LOG.error( 'The status of database instance is ' 'invalid. status:%s', instance_info.status) restore.update_resource_status( constants.DATABASE_RESOURCE_TYPE, instance_info.id, instance_info.status, "Invalid status.") restore.save() raise exception.RestoreResourceFailed( name="Database instance Backup", reason="Invalid status.", resource_id=original_instance_id, resource_type=constants.DATABASE_RESOURCE_TYPE) restore.update_resource_status(constants.DATABASE_RESOURCE_TYPE, instance_info.id, instance_info.status) restore.save() except Exception as e: LOG.error( "Restore Database instance from backup " "failed, instance_id: %s.", original_instance_id) raise exception.RestoreResourceFailed( name="Database instance Backup", reason=e, resource_id=original_instance_id, resource_type=constants.DATABASE_RESOURCE_TYPE) LOG.info( "Finish restoring a Database instance from backup," "instance_id: %s.", original_instance_id)
def on_main(self, checkpoint, resource, context, parameters, **kwargs): resource_id = resource.id bank_section = checkpoint.get_resource_bank_section(resource_id) LOG.info("Deleting freezer protection backup, resource_id: {0}".format( resource_id)) bank_section.update_object('status', constants.RESOURCE_STATUS_DELETING) resource_metadata = bank_section.get_object('metadata') freezer_task_info = resource_metadata.get('job_info', None) if not freezer_task_info: raise exception.DeleteResourceFailed( name='Freezer Backup FreezerTask', reason='The content of freezer job is invalid.', resource_id=resource_id, resource_type=resource.type) freezer_job_operation = FreezerTask(context) job_id, job_info = None, None try: job_id, job_info = freezer_job_operation.create_delete_job( freezer_task_info) is_success = utils.status_poll(partial(get_job_status, freezer_job_operation, job_id), interval=self._poll_interval, success_statuses={'success'}, failure_statuses={'fail'}, ignore_statuses={'aborted', ''}, ignore_unexpected=True) if is_success is not True: LOG.error( "The status of freezer job (id: {0}) is invalid.".format( job_id)) raise exception.CreateResourceFailed( name="Freezer Backup FreezerTask", reason="The status of freezer job is invalid.", resource_id=resource_id, resource_type=resource.type) except Exception as e: LOG.error("Delete freezer backup resource failed, resource_type:" "{0}, resource_id: {1}".format(resource.type, resource.id)) if job_id: freezer_job_operation.delete(job_id) raise exception.DeleteResourceFailed( name="Freezer Backup FreezerTask", reason=e, resource_id=resource_id, resource_type=resource.type) LOG.debug('Finish deleting freezer backup resource') bank_section.delete_object('metadata') bank_section.update_object('status', constants.RESOURCE_STATUS_DELETED) freezer_job_operation.delete(job_id)
def on_main(self, checkpoint, resource, context, parameters, **kwargs): original_share_id = resource.id bank_section = checkpoint.get_resource_bank_section(original_share_id) manila_client = ClientFactory.create_client('manila', context) resource_metadata = bank_section.get_object('metadata') restore_name = parameters.get( 'restore_name', '%s@%s' % (checkpoint.id, original_share_id)) restore_description = parameters.get('restore_description', None) snapshot_id = resource_metadata['snapshot_id'] share_proto = resource_metadata['share_proto'] size = resource_metadata['size'] share_type = resource_metadata['share_type'] share_network_id = resource_metadata['share_network_id'] restore = kwargs.get('restore') LOG.info("Restoring a share from snapshot, " "original_share_id: %s.", original_share_id) try: share = manila_client.shares.create( share_proto, size, snapshot_id=snapshot_id, name=restore_name, description=restore_description, share_network=share_network_id, share_type=share_type) is_success = utils.status_poll( partial(get_share_status, manila_client, share.id), interval=self._interval, success_statuses={'available'}, failure_statuses=SHARE_FAILURE_STATUSES, ignore_statuses=SHARE_IGNORE_STATUSES) if is_success is not True: LOG.error('The status of share is invalid. status:%s', share.status) restore.update_resource_status(constants.SHARE_RESOURCE_TYPE, share.id, share.status, "Invalid status.") restore.save() raise exception.RestoreResourceFailed( name="Share Snapshot", reason="Invalid status.", resource_id=original_share_id, resource_type=constants.SHARE_RESOURCE_TYPE) restore.update_resource_status(constants.SHARE_RESOURCE_TYPE, share.id, share.status) restore.save() except Exception as e: LOG.error("Restore share from snapshot failed, share_id: %s.", original_share_id) raise exception.RestoreResourceFailed( name="Share Snapshot", reason=e, resource_id=original_share_id, resource_type=constants.SHARE_RESOURCE_TYPE) LOG.info("Finish restoring a share from snapshot, share_id: %s.", original_share_id)
def _delete_snapshot(self, cinder_client, snapshot_id): LOG.info('Cleaning up snapshot (snapshot_id: %s)', snapshot_id) cinder_client.volume_snapshots.delete(snapshot_id) return utils.status_poll( partial(get_snapshot_status, cinder_client, snapshot_id), interval=self._interval, success_statuses={'not-found', }, failure_statuses={'error', 'error_deleting', 'creating'}, ignore_statuses={'deleting', }, )
def on_main(self, checkpoint, resource, context, parameters, **kwargs): original_volume_id = resource.id bank_section = checkpoint.get_resource_bank_section(original_volume_id) cinder_client = ClientFactory.create_client('cinder', context) resource_metadata = bank_section.get_object('metadata') restore_name = parameters.get( 'restore_name', 'volume-%s@%s' % (checkpoint.id, original_volume_id)) restore_description = parameters.get('restore_description', None) snapshot_id = resource_metadata['snapshot_id'] size = resource_metadata['size'] restore = kwargs.get('restore') LOG.info("Restoring a volume from snapshot, " "original_volume_id: %s", original_volume_id) try: volume = cinder_client.volumes.create( size, snapshot_id=snapshot_id, name=restore_name, description=restore_description) is_success = utils.status_poll( partial(get_volume_status, cinder_client, volume.id), interval=self._interval, success_statuses={ 'available', 'in-use', 'error_extending', 'error_restoring' }, failure_statuses=VOLUME_FAILURE_STATUSES, ignore_statuses=VOLUME_IGNORE_STATUSES, ) volume = cinder_client.volumes.get(volume.id) if is_success is not True: LOG.error('The status of volume is invalid. status:%s', volume.status) reason = 'Invalid status: %s' % volume.status restore.update_resource_status(constants.VOLUME_RESOURCE_TYPE, volume.id, volume.status, reason) restore.save() raise exception.RestoreResourceFailed( name="Volume Snapshot", resource_id=original_volume_id, resource_type=constants.VOLUME_RESOURCE_TYPE) restore.update_resource_status(constants.VOLUME_RESOURCE_TYPE, volume.id, volume.status) restore.save() except Exception as e: LOG.error("Restore volume from snapshot failed, volume_id: %s", original_volume_id) raise exception.RestoreResourceFailed( name="Volume Snapshot", reason=e, resource_id=original_volume_id, resource_type=constants.VOLUME_RESOURCE_TYPE) LOG.info("Finish restoring a volume from snapshot, volume_id: %s", original_volume_id)
def on_main(self, checkpoint, resource, context, parameters, **kwargs): image_id = resource.id bank_section = checkpoint.get_resource_bank_section(image_id) resource_definition = {"resource_id": image_id} glance_client = ClientFactory.create_client('glance', context) LOG.info("Creating image backup, image_id: %s.", image_id) try: bank_section.update_object("status", constants.RESOURCE_STATUS_PROTECTING) image_info = glance_client.images.get(image_id) if image_info.status != "active": is_success = utils.status_poll( partial(get_image_status, glance_client, image_info.id), interval=self._interval, success_statuses={'active'}, ignore_statuses={'queued', 'saving'}, failure_statuses={ 'killed', 'deleted', 'pending_delete', 'deactivated', 'NotFound' }) if is_success is not True: LOG.error("The status of image (id: %s) is invalid.", image_id) raise exception.CreateResourceFailed( name="Image Backup", reason="The status of image is invalid.", resource_id=image_id, resource_type=constants.IMAGE_RESOURCE_TYPE) image_metadata = { "disk_format": image_info.disk_format, "container_format": image_info.container_format, "checksum": image_info.checksum } resource_definition["image_metadata"] = image_metadata bank_section.update_object("metadata", resource_definition) except Exception as err: LOG.error("Create image backup failed, image_id: %s.", image_id) bank_section.update_object("status", constants.RESOURCE_STATUS_ERROR) raise exception.CreateResourceFailed( name="Image Backup", reason=err, resource_id=image_id, resource_type=constants.IMAGE_RESOURCE_TYPE) self._create_backup(glance_client, bank_section, image_id)
def _create_snapshot(self, cinder_client, volume_id): snapshot = cinder_client.volume_snapshots.create(volume_id, force=True) snapshot_id = snapshot.id is_success = utils.status_poll( partial(get_snapshot_status, cinder_client, snapshot_id), interval=self._interval, success_statuses={'available', }, failure_statuses={'error', 'error_deleting', 'deleting', 'not-found'}, ignore_statuses={'creating', }, ) if not is_success: raise Exception return snapshot_id
def on_main(self, checkpoint, resource, context, parameters, **kwargs): original_image_id = resource.id name = parameters.get("restore_name", "karbor-restore-image") LOG.info("Restoring image backup, image_id: %s.", original_image_id) glance_client = ClientFactory.create_client('glance', context) bank_section = checkpoint.get_resource_bank_section(original_image_id) image_info = None try: image_info = utils.restore_image_from_bank(glance_client, bank_section, name) if image_info.status != "active": is_success = utils.status_poll( partial(get_image_status, glance_client, image_info.id), interval=self._interval, success_statuses={'active'}, ignore_statuses={'queued', 'saving'}, failure_statuses={ 'killed', 'deleted', 'pending_delete', 'deactivated', 'not-found' }) if is_success is not True: LOG.error('The status of image is invalid. status:%s', image_info.status) raise exception.RestoreResourceFailed( name="Image Backup", resource_id=image_info.id, resource_type=constants.IMAGE_RESOURCE_TYPE) kwargs.get("new_resources")[original_image_id] = image_info.id except Exception as e: LOG.error("Restore image backup failed, image_id: %s.", original_image_id) if image_info is not None and hasattr(image_info, 'id'): LOG.info("Delete the failed image, image_id: %s.", image_info.id) glance_client.images.delete(image_info.id) raise exception.RestoreResourceFailed( name="Image Backup", reason=e, resource_id=original_image_id, resource_type=constants.IMAGE_RESOURCE_TYPE) LOG.info("Finish restoring image backup, image_id: %s.", original_image_id)
def _create_temporary_image(self, bank_section, glance_client, original_volume_id): image_info = None try: image_info = utils.restore_image_from_bank( glance_client, bank_section, 'temporary_image_of_{0}'.format(original_volume_id)) if image_info.status != "active": is_success = utils.status_poll( partial(get_image_status, glance_client, image_info.id), interval=self._interval, success_statuses={'active'}, ignore_statuses={'queued', 'saving'}, failure_statuses={ 'killed', 'deleted', 'pending_delete', 'deactivated', 'not-found' }) if is_success is not True: LOG.error('The status of image is invalid. status:%s', image_info.status) raise exception.RestoreResourceFailed( name="Volume Glance Backup", reason="Create temporary image failed", resource_id=original_volume_id, resource_type=constants.VOLUME_RESOURCE_TYPE) return image_info except Exception as e: LOG.error( "Create temporary image of volume failed, " "volume_id: %s.", original_volume_id) LOG.exception(e) if image_info is not None and hasattr(image_info, 'id'): LOG.info("Delete the failed image, image_id: %s.", image_info.id) glance_client.images.delete(image_info.id) raise exception.RestoreResourceFailed( name="Volume Glance Backup", reason=e, resource_id=original_volume_id, resource_type=constants.VOLUME_RESOURCE_TYPE)
def on_main(self, checkpoint, resource, context, parameters, **kwargs): resource_id = resource.id bank_section = checkpoint.get_resource_bank_section(resource_id) backup_id = None try: bank_section.update_object('status', constants.RESOURCE_STATUS_DELETING) resource_metadata = bank_section.get_object('metadata') backup_id = resource_metadata['backup_id'] trove_client = ClientFactory.create_client('trove', context) try: backup = trove_client.backups.get(backup_id) trove_client.backups.delete(backup) except trove_exc.NotFound: LOG.info('Backup id: %s not found. Assuming deleted', backup_id) is_success = utils.status_poll( partial(get_backup_status, trove_client, backup_id), interval=self._interval, success_statuses={'not-found'}, failure_statuses={'FAILED', 'DELETE_FAILED'}, ignore_statuses={'COMPLETED'}, ignore_unexpected=True ) if not is_success: raise exception.NotFound() bank_section.delete_object('metadata') bank_section.update_object('status', constants.RESOURCE_STATUS_DELETED) except Exception as e: LOG.error('Delete Database instance Backup failed, backup_id: %s', backup_id) bank_section.update_object('status', constants.RESOURCE_STATUS_ERROR) raise exception.DeleteResourceFailed( name="Database instance Backup", reason=six.text_type(e), resource_id=resource_id, resource_type=constants.DATABASE_RESOURCE_TYPE )
def on_main(self, checkpoint, resource, context, parameters, **kwargs): resource_id = resource.id bank_section = checkpoint.get_resource_bank_section(resource_id) snapshot_id = None try: bank_section.update_object('status', constants.RESOURCE_STATUS_DELETING) resource_metadata = bank_section.get_object('metadata') snapshot_id = resource_metadata['snapshot_id'] cinder_client = ClientFactory.create_client('cinder', context) try: snapshot = cinder_client.volume_snapshots.get(snapshot_id) cinder_client.volume_snapshots.delete(snapshot) except cinder_exc.NotFound: LOG.info('Snapshot id: %s not found. Assuming deleted', snapshot_id) is_success = utils.status_poll( partial(get_snapshot_status, cinder_client, snapshot_id), interval=self._interval, success_statuses={'deleted', 'not-found'}, failure_statuses={'error', 'error_deleting'}, ignore_statuses={'deleting'}, ignore_unexpected=True ) if not is_success: raise exception.NotFound() bank_section.delete_object('metadata') bank_section.update_object('status', constants.RESOURCE_STATUS_DELETED) except Exception as e: LOG.error('Delete volume snapshot failed, snapshot_id: %s', snapshot_id) bank_section.update_object('status', constants.RESOURCE_STATUS_ERROR) raise exception.DeleteResourceFailed( name="Volume Snapshot", reason=six.text_type(e), resource_id=resource_id, resource_type=constants.VOLUME_RESOURCE_TYPE )
def on_main(self, checkpoint, resource, context, parameters, **kwargs): LOG.debug('Start creating image backup, resource info: %s', resource.to_dict()) resource_id = resource.id bank_section = checkpoint.get_resource_bank_section(resource_id) glance_client = ClientFactory.create_client('glance', context) bank_section.update_object("status", constants.RESOURCE_STATUS_PROTECTING) resource_definition = {'resource_id': resource_id} if resource.extra_info and self._enable_server_snapshot: image_id = self._create_server_snapshot(context, glance_client, parameters, resource, resource_definition, resource_id) need_delete_temp_image = True else: image_id = resource_id need_delete_temp_image = False LOG.info("Creating image backup, image_id: %s.", image_id) try: image_info = glance_client.images.get(image_id) if image_info.status != "active": is_success = utils.status_poll( partial(get_image_status, glance_client, image_info.id), interval=self._interval, success_statuses={'active'}, ignore_statuses={'queued', 'saving'}, failure_statuses={ 'killed', 'deleted', 'pending_delete', 'deactivated', 'NotFound' }) if is_success is not True: LOG.error("The status of image (id: %s) is invalid.", image_id) raise exception.CreateResourceFailed( name="Image Backup", reason="The status of image is invalid.", resource_id=image_id, resource_type=constants.IMAGE_RESOURCE_TYPE) image_metadata = { "disk_format": image_info.disk_format, "container_format": image_info.container_format, "checksum": image_info.checksum, } resource_definition["image_metadata"] = image_metadata bank_section.update_object("metadata", resource_definition) except Exception as err: LOG.error("Create image backup failed, image_id: %s.", image_id) bank_section.update_object("status", constants.RESOURCE_STATUS_ERROR) raise exception.CreateResourceFailed( name="Image Backup", reason=err, resource_id=image_id, resource_type=constants.IMAGE_RESOURCE_TYPE) self._create_backup(glance_client, bank_section, image_id) if need_delete_temp_image: try: glance_client.images.delete(image_id) except Exception as error: LOG.warning('Failed to delete temporary image: %s', error) else: LOG.debug('Delete temporary image(%s) success', image_id)
def on_main(self, checkpoint, resource, context, parameters, **kwargs): share_id = resource.id bank_section = checkpoint.get_resource_bank_section(share_id) manila_client = ClientFactory.create_client('manila', context) LOG.info('creating share snapshot, share_id: %s', share_id) bank_section.update_object('status', constants.RESOURCE_STATUS_PROTECTING) share_info = manila_client.shares.get(share_id) if share_info.status != "available": is_success = utils.status_poll( partial(get_share_status, manila_client, share_id), interval=self._interval, success_statuses={'available'}, failure_statuses=SHARE_FAILURE_STATUSES, ignore_statuses=SHARE_IGNORE_STATUSES, ) if not is_success: bank_section.update_object('status', constants.RESOURCE_STATUS_ERROR) raise exception.CreateResourceFailed( name="Share Snapshot", reason='Share is in a error status.', resource_id=share_id, resource_type=constants.SHARE_RESOURCE_TYPE, ) resource_metadata = { 'share_id': share_id, 'size': share_info.size, 'share_proto': share_info.share_proto, 'share_type': share_info.share_type, 'share_network_id': share_info.share_network_id } snapshot_name = parameters.get('snapshot_name', None) description = parameters.get('description', None) force = parameters.get('force', False) try: snapshot_id = self._create_snapshot(manila_client, share_id, snapshot_name, description, force) except exception.CreateResourceFailed as e: LOG.error( 'Error creating snapshot (share_id: %(share_id)s ' ': %(reason)s', { 'share_id': share_id, 'reason': e }) bank_section.update_object('status', constants.RESOURCE_STATUS_ERROR) raise resource_metadata['snapshot_id'] = snapshot_id bank_section.update_object('metadata', resource_metadata) bank_section.update_object('status', constants.RESOURCE_STATUS_AVAILABLE) LOG.info( 'Snapshot share (share_id: %(share_id)s snapshot_id: ' '%(snapshot_id)s ) successfully', { 'share_id': share_id, 'snapshot_id': snapshot_id })