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): 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 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): resource_id = resource.id bank_section = checkpoint.get_resource_bank_section(resource_id) LOG.info("Creating freezer protection backup, resource_id: {0}".format( resource_id)) resource_metadata = bank_section.get_object('metadata') freezer_job_info = resource_metadata.get('job_info', None) if not freezer_job_info: raise exception.RestoreResourceFailed( name='Freezer Backup FreezerTask', reason='The content of freezer job is invalid.', resource_id=resource_id, resource_type=resource.type) freezer_task = FreezerTask(context) job_id, job_info = None, None try: job_id, job_info = freezer_task.create_restore_job( freezer_job_info) is_success = utils.status_poll(partial(get_job_status, freezer_task, 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.RestoreResourceFailed( 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("Restore freezer backup resource failed, resource_type:" "{0}, resource_id: {1}".format(resource.type, resource.id)) if job_id: freezer_task.delete(job_id) raise exception.RestoreResourceFailed( name="Freezer Backup FreezerTask", reason=e, resource_id=resource_id, resource_type=resource.type) LOG.debug('Finish restoring freezer backup resource') freezer_task.delete(job_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 on_complete(self, checkpoint, resource, context, parameters, **kwargs): original_server_id = resource.id LOG.info("Restoring server backup, server_id: %s.", original_server_id) update_method = None try: resource_definition = checkpoint.get_resource_bank_section( original_server_id).get_object("metadata") nova_client = ClientFactory.create_client("nova", context) new_resources = kwargs.get("new_resources") # restore server instance restore_net_id = parameters.get("restore_net_id", None) restore_flavor_id = parameters.get("restore_flavor_id", None) if restore_flavor_id: resource_definition["server_metadata"]['flavor'] = ( restore_flavor_id) new_server_id = self._restore_server_instance( nova_client, new_resources, original_server_id, parameters.get("restore_name", "karbor-restore-server"), restore_net_id, resource_definition) update_method = partial(utils.update_resource_restore_result, kwargs.get('restore'), resource.type, new_server_id) update_method(constants.RESOURCE_STATUS_RESTORING) self._wait_server_to_active(nova_client, new_server_id) # restore volume attachment self._restore_volume_attachment( nova_client, ClientFactory.create_client("cinder", context), new_resources, new_server_id, resource_definition) # restore floating ip association self._restore_floating_association(nova_client, new_server_id, resource_definition) new_resources[original_server_id] = new_server_id update_method(constants.RESOURCE_STATUS_AVAILABLE) LOG.info("Finish restore server, server_id: %s.", original_server_id) except Exception as e: if update_method: update_method(constants.RESOURCE_STATUS_ERROR, str(e)) LOG.exception("Restore server backup failed, server_id: %s.", original_server_id) raise exception.RestoreResourceFailed( name="Server Backup", reason=e, resource_id=original_server_id, resource_type=constants.SERVER_RESOURCE_TYPE)
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) resource_metadata = bank_section.get_object('metadata') cinder_client = ClientFactory.create_client('cinder', context) # create volume volume_property = { 'name': parameters.get('restore_name', '%s@%s' % (checkpoint.id, resource_id)) } if 'restore_description' in parameters: volume_property['description'] = parameters['restore_description'] backup_id = resource_metadata['backup_id'] try: volume_id = cinder_client.restores.restore(backup_id).volume_id cinder_client.volumes.update(volume_id, **volume_property) except Exception as ex: LOG.error( 'Error creating volume (backup_id: %(backup_id)s): ' '%(reason)s', { 'backup_id': backup_id, 'reason': ex }) raise # check and update status update_method = partial(utils.update_resource_restore_result, kwargs.get('restore'), resource.type, volume_id) update_method(constants.RESOURCE_STATUS_RESTORING) is_success = self._check_create_complete(cinder_client, volume_id) if is_success: update_method(constants.RESOURCE_STATUS_AVAILABLE) kwargs.get("new_resources")[resource_id] = volume_id else: reason = 'Error creating volume' update_method(constants.RESOURCE_STATUS_ERROR, reason) raise exception.RestoreResourceFailed(name="Volume Backup", reason=reason, resource_id=resource_id, resource_type=resource.type)
def on_complete(self, checkpoint, resource, context, parameters, **kwargs): original_pod_id = resource.id LOG.info("Restoring pod backup, pod_id: %s.", original_pod_id) update_method = None try: resource_definition = checkpoint.get_resource_bank_section( original_pod_id).get_object("metadata") LOG.debug("Restoring pod backup, metadata: %s.", resource_definition) k8s_client = ClientFactory.create_client("k8s", context) new_resources = kwargs.get("new_resources") # restore pod new_pod_name = self._restore_pod_instance( k8s_client, new_resources, original_pod_id, parameters.get( "restore_name", "karbor-restored-pod-%s" % uuidutils.generate_uuid()), resource_definition) update_method = partial(utils.update_resource_restore_result, kwargs.get('restore'), resource.type, new_pod_name) update_method(constants.RESOURCE_STATUS_RESTORING) pod_namespace = resource_definition["namespace"] self._wait_pod_to_running(k8s_client, new_pod_name, pod_namespace) new_resources[original_pod_id] = new_pod_name update_method(constants.RESOURCE_STATUS_AVAILABLE) LOG.info("Finish restore pod, pod_id: %s.", original_pod_id) except Exception as e: if update_method: update_method(constants.RESOURCE_STATUS_ERROR, str(e)) LOG.exception("Restore pod backup failed, pod_id: %s.", original_pod_id) raise exception.RestoreResourceFailed( name="Pod Backup", reason=e, resource_id=original_pod_id, resource_type=constants.POD_RESOURCE_TYPE)
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 = None try: resource_definition = bank_section.get_object('metadata') image_metadata = resource_definition['image_metadata'] objects = [ key.split("/")[-1] for key in bank_section.list_objects() if (key.split("/")[-1]).startswith("data_") ] # check the chunks_num chunks_num = resource_definition.get("chunks_num", 0) if len(objects) != int(chunks_num): LOG.debug('object num: {0}, chunk num: {1}'.format( len(objects), chunks_num)) raise exception.RestoreResourceFailed( name="Image Backup", reason=" The chunks_num of restored image is invalid.", resource_id=original_image_id, resource_type=constants.IMAGE_RESOURCE_TYPE) sorted_objects = sorted(objects, key=lambda s: int(s[5:])) image_data = ImageBankIO(bank_section, sorted_objects) disk_format = image_metadata["disk_format"] container_format = image_metadata["container_format"] image = glance_client.images.create( disk_format=disk_format, container_format=container_format, name=name) glance_client.images.upload(image.id, image_data) 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', '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) # check the checksum if image_info.checksum != image_metadata["checksum"]: raise exception.RestoreResourceFailed( name="Image Backup", reason=" The checksum of restored image is invalid.", resource_id=original_image_id, resource_type=constants.IMAGE_RESOURCE_TYPE) kwargs.get("new_resources")[original_image_id] = image.id except Exception as e: LOG.error("Restore image backup failed, image_id: %s.", original_image_id) if image is not None and hasattr(image, 'id'): LOG.info("Delete the failed image, image_id: %s.", image.id) glance_client.images.delete(image.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 on_main(self, checkpoint, resource, context, parameters, **kwargs): neutron_client = ClientFactory.create_client("neutron", context) network_id = get_network_id(context) public_network_id = parameters.get("public_network_id") bank_section = checkpoint.get_resource_bank_section(network_id) new_resources = kwargs['new_resources'] def _filter_resources(resources): ids = [] for obj_id, data in resources.items(): network = nets_meta.get(data['network_id']) if not network or network.get("router:external"): ids.append(obj_id) for obj_id in ids: resources.pop(obj_id) try: resource_definition = bank_section.get_object("metadata") # Config Net nets_meta = resource_definition.get("network_metadata") if nets_meta: self._restore_networks(neutron_client, new_resources, nets_meta) # Config Securiy-group sgs_meta = resource_definition.get("security-group_metadata") if sgs_meta: self._restore_securitygroups(neutron_client, new_resources, sgs_meta) # Config Subnet subs_meta = resource_definition.get("subnet_metadata") _filter_resources(subs_meta) if subs_meta: self._restore_subnets(neutron_client, new_resources, nets_meta, subs_meta) # Config Router routers_meta = resource_definition.get("router_metadata") if routers_meta: self._restore_routers(neutron_client, new_resources, public_network_id, routers_meta) # Config Port ports_meta = resource_definition.get("port_metadata") _filter_resources(ports_meta) if ports_meta: self._restore_ports(neutron_client, new_resources, nets_meta, subs_meta, ports_meta) # Config RouterInterface if all([i is not None for i in [subs_meta, routers_meta, ports_meta]]): self._restore_routerinterfaces( neutron_client, new_resources, subs_meta, routers_meta, ports_meta) except Exception as e: LOG.error("restore network backup failed, network_id: %s.", network_id) raise exception.RestoreResourceFailed( name="Network Backup", reason=six.text_type(e), resource_id=network_id, resource_type=constants.NETWORK_RESOURCE_TYPE )