示例#1
0
    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)
示例#2
0
    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)
示例#3
0
    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)
示例#6
0
    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)
示例#7
0
    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)