def restore_backup(self, cntxt, checkpoint, **kwargs): resource_node = kwargs.get("node") resource_id = resource_node.value.id heat_template = kwargs.get("heat_template") name = kwargs.get("restore_name", "%s@%s" % (checkpoint.id, resource_id)) description = kwargs.get("restore_description") heat_resource_id = uuidutils.generate_uuid() heat_resource = HeatResource(heat_resource_id, constants.VOLUME_RESOURCE_TYPE) bank_section = checkpoint.get_resource_bank_section(resource_id) try: resource_definition = bank_section.get_object("metadata") backup_id = resource_definition["backup_id"] properties = {"backup_id": backup_id, "name": name} if description is not None: properties["description"] = description for key, value in properties.items(): heat_resource.set_property(key, value) heat_template.put_resource(resource_id, heat_resource) except Exception as e: LOG.error(_LE("restore volume backup failed, volume_id: %s."), resource_id) raise exception.RestoreBackupFailed( reason=six.text_type(e), resource_id=resource_id, resource_type=constants.VOLUME_RESOURCE_TYPE)
def _heat_restore_server_instance(self, heat_template, original_id, restore_name, resource_definition): server_metadata = resource_definition["server_metadata"] properties = { "availability_zone": server_metadata["availability_zone"], "flavor": server_metadata["flavor"], "name": restore_name, } # server boot device boot_metadata = resource_definition["boot_metadata"] boot_device_type = boot_metadata["boot_device_type"] if boot_device_type == "image": original_image_id = boot_metadata["boot_image_id"] image_id = heat_template.get_resource_reference( original_image_id) properties["image"] = image_id elif boot_device_type == "volume": original_volume_id = boot_metadata["boot_volume_id"] volume_id = heat_template.get_resource_reference( original_volume_id) properties["block_device_mapping_v2"] = [{ "volume_id": volume_id, "delete_on_termination": False, "boot_index": 0, }] else: LOG.exception("Restore server backup failed, server_id: %s.", original_id) raise exception.RestoreBackupFailed( reason="Can not find the boot device of the server.", resource_id=original_id, resource_type=constants.SERVER_RESOURCE_TYPE ) # server key_name, security_groups, networks if server_metadata["key_name"] is not None: properties["key_name"] = server_metadata["key_name"] if server_metadata["security_groups"] is not None: security_groups = [] for security_group in server_metadata["security_groups"]: security_groups.append(security_group["name"]) properties["security_groups"] = security_groups networks = [] for network in server_metadata["networks"]: networks.append({"network": network}) properties["networks"] = networks heat_resource_id = uuidutils.generate_uuid() heat_server_resource = HeatResource(heat_resource_id, constants.SERVER_RESOURCE_TYPE) for key, value in properties.items(): heat_server_resource.set_property(key, value) heat_template.put_resource(original_id, heat_server_resource)
def restore_backup(self, cntxt, checkpoint, **kwargs): resource_node = kwargs.get('node') original_image_id = resource_node.value.id heat_template = kwargs.get("heat_template") name = kwargs.get("restore_name", "karbor-restore-image") LOG.info(_LI("restoring image backup, image_id: %s."), original_image_id) glance_client = self._glance_client(cntxt) bank_section = checkpoint.get_resource_bank_section(original_image_id) 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() ] # get image_data image_data = BytesIO() for obj in objects: if obj.find("data_") == 0: data = bank_section.get_object(obj) image_data.write(data) image_data.seek(0, os.SEEK_SET) 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) retry_attempts = CONF.retry_attempts while image_info.status != "active" and retry_attempts != 0: sleep(60) image_info = glance_client.images.get(image.id) retry_attempts -= 1 if retry_attempts == 0: raise Exception heat_template.put_parameter(original_image_id, image.id) except Exception as e: LOG.error(_LE("restore image backup failed, image_id: %s."), original_image_id) raise exception.RestoreBackupFailed( reason=e, resource_id=original_image_id, resource_type=constants.IMAGE_RESOURCE_TYPE)
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) heat_template = kwargs.get("heat_template") # restore server instance new_server_id = self._restore_server_instance( nova_client, heat_template, original_server_id, parameters.get("restore_name", "karbor-restore-server"), 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), heat_template, new_server_id, resource_definition) # restore floating ip association self._restore_floating_association(nova_client, new_server_id, resource_definition) heat_template.put_parameter(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.RestoreBackupFailed( reason=e, resource_id=original_server_id, resource_type=constants.SERVER_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("heat_template").put_parameter(resource_id, volume_id) else: reason = 'Error creating volume' update_method(constants.RESOURCE_STATUS_ERROR, reason) raise exception.RestoreBackupFailed(reason=reason, resource_id=resource_id, resource_type=resource.type)
def restore_backup(self, cntxt, checkpoint, **kwargs): resource_node = kwargs.get("node") original_server_id = resource_node.value.id heat_template = kwargs.get("heat_template") restore_name = kwargs.get("restore_name", "karbor-restore-server") LOG.info(_LI("restoring server backup, server_id: %s."), original_server_id) bank_section = checkpoint.get_resource_bank_section(original_server_id) try: resource_definition = bank_section.get_object("metadata") # restore server snapshot image_id = self._restore_server_snapshot(bank_section, checkpoint, cntxt, original_server_id, resource_definition) # restore server instance self._heat_restore_server_instance(heat_template, image_id, original_server_id, restore_name, resource_definition) # restore volume attachment self._heat_restore_volume_attachment(heat_template, original_server_id, resource_definition) # restore floating ip association self._heat_restore_floating_association(heat_template, original_server_id, resource_definition) except Exception as e: LOG.error(_LE("restore server backup failed, server_id: %s."), original_server_id) raise exception.RestoreBackupFailed( reason=e, resource_id=original_server_id, resource_type=constants.SERVER_RESOURCE_TYPE)
def on_complete(self, checkpoint, resource, context, parameters, **kwargs): original_server_id = resource.id heat_template = kwargs.get("heat_template") restore_name = parameters.get("restore_name", "karbor-restore-server") LOG.info("Restoring server backup, server_id: %s.", original_server_id) bank_section = checkpoint.get_resource_bank_section(original_server_id) try: resource_definition = bank_section.get_object("metadata") # restore server instance self._heat_restore_server_instance(heat_template, original_server_id, restore_name, resource_definition) # restore volume attachment self._heat_restore_volume_attachment(heat_template, original_server_id, resource_definition) # restore floating ip association self._heat_restore_floating_association(heat_template, original_server_id, resource_definition) LOG.debug("Restoring server backup, heat_template: %s.", heat_template) LOG.info("Finish restore server, server_id: %s.", original_server_id) except Exception as e: LOG.exception("restore server backup failed, server_id: %s.", original_server_id) raise exception.RestoreBackupFailed( reason=e, resource_id=original_server_id, resource_type=constants.SERVER_RESOURCE_TYPE)
def on_main(self, checkpoint, resource, context, parameters, **kwargs): original_image_id = resource.id heat_template = kwargs.get("heat_template") 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.RestoreBackupFailed( 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.RestoreBackupFailed( resource_id=image_info.id, resource_type=constants.IMAGE_RESOURCE_TYPE) # check the checksum if image_info.checksum != image_metadata["checksum"]: raise exception.RestoreBackupFailed( reason=" The checksum of restored image is invalid.", resource_id=original_image_id, resource_type=constants.IMAGE_RESOURCE_TYPE) heat_template.put_parameter(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.RestoreBackupFailed( 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) heat_template = kwargs['heat_template'] 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, heat_template, nets_meta) # Config Securiy-group sgs_meta = resource_definition.get("security-group_metadata") if sgs_meta: self._restore_securitygroups(neutron_client, heat_template, sgs_meta) # Config Subnet subs_meta = resource_definition.get("subnet_metadata") _filter_resources(subs_meta) if subs_meta: self._restore_subnets(neutron_client, heat_template, nets_meta, subs_meta) # Config Router routers_meta = resource_definition.get("router_metadata") if routers_meta: self._restore_routers(neutron_client, heat_template, 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, heat_template, 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, heat_template, subs_meta, routers_meta, ports_meta) except Exception as e: LOG.error("restore network backup failed, network_id: %s.", network_id) raise exception.RestoreBackupFailed( reason=six.text_type(e), resource_id=network_id, resource_type=constants.NETWORK_RESOURCE_TYPE)