예제 #1
0
def initialize_logging(instance_id: str = None,
                       instance: Instance = None,
                       system: System = None) -> Instance:
    """Initialize logging of Instance.

    Args:
        instance_id: The Instance ID
        instance: The Instance
        system: The System

    Returns:
        The Instance
    """
    system, instance = _from_kwargs(system=system,
                                    instance=instance,
                                    instance_id=instance_id)

    logger.debug(f"Initializing logging for instance {system}[{instance}]")

    requests.process_request(
        Request.from_template(
            initialize_logging_request,
            namespace=system.namespace,
            system=system.name,
            system_version=system.version,
            instance_name=instance.name,
        ),
        is_admin=True,
        priority=1,
    )

    return instance
예제 #2
0
 def test_from_template_overrides(self, bg_request_template):
     request = Request.from_template(bg_request_template,
                                     command_type="INFO")
     assert request.command_type == "INFO"
     for key in bg_request_template.__dict__:
         if key != "command_type":
             assert getattr(request,
                            key) == getattr(bg_request_template, key)
예제 #3
0
def publish_start(system, instance):
    requests.process_request(
        Request.from_template(
            start_request,
            namespace=system.namespace,
            system=system.name,
            system_version=system.version,
            instance_name=instance.name,
        ),
        is_admin=True,
        priority=1,
    )
예제 #4
0
def publish_stop(system, instance=None):
    request_args = {
        "namespace": system.namespace,
        "system": system.name,
        "system_version": system.version,
    }

    if instance:
        request_args["instance_name"] = instance.name

    requests.process_request(Request.from_template(stop_request,
                                                   **request_args),
                             is_admin=True,
                             priority=1)
예제 #5
0
def read_logs(
    instance_id: str = None,
    instance: Instance = None,
    system: System = None,
    start_line: int = None,
    end_line: int = None,
    wait_event: threading.Event = None,
) -> Request:
    """Read lines from an Instance's log file.

    Args:
        instance_id: The Instance ID
        instance: The Instance
        system: The System
        start_line: Start reading log file at
        end_line: Stop reading log file at
        wait_event: Wait event for response

    Returns:
        Request object with logs as output
    """
    system, instance = _from_kwargs(system=system,
                                    instance=instance,
                                    instance_id=instance_id)

    logger.debug(f"Reading Logs from instance {system}[{instance}]")

    request = requests.process_request(
        Request.from_template(
            read_logs_request,
            namespace=system.namespace,
            system=system.name,
            system_version=system.version,
            instance_name=instance.name,
            parameters={
                "start_line": start_line,
                "end_line": end_line
            },
        ),
        is_admin=True,
        wait_event=wait_event,
    )

    return request
예제 #6
0
def process_request(
    new_request: Union[Request, RequestTemplate],
    wait_event: threading.Event = None,
    is_admin: bool = False,
    priority: int = 0,
) -> Request:
    """Validates and publishes a Request.

    Args:
        new_request: The Request
        wait_event: Event that will be added to the local event_map. Event will be set
        when the request completes.
        is_admin: Flag indicating this request should be published on the admin queue
        priority: Number between 0 and 1, inclusive. High numbers equal higher priority

    Returns:
        The processed Request

    """
    if type(new_request) == Request:
        request = new_request
    elif type(new_request) == RequestTemplate:
        request = Request.from_template(new_request)
    else:
        raise TypeError(
            f"new_request type is {type(new_request)}, expected "
            "brewtils.models.Request or brewtils.models.RequestTemplate,")

    # Validation is only required for non Admin commands because Admin commands
    # are hard coded to map Plugin functions
    if not is_admin:
        try:
            request = _validate_request(request)
        except ModelValidationError:
            invalid_request(request)
            raise

    if request.command_type == "EPHEMERAL":
        logger.debug(f"Publishing {request!r}")
    else:
        # Save after validation since validate can modify the request
        request = create_request(request)

        logger.info(f"Publishing {request!r}")

        if wait_event:
            request_map[request.id] = wait_event

    try:
        _publish_request(request, is_admin=is_admin, priority=priority)
    except Exception as ex:
        # An error publishing means this request will never complete, so remove it
        if not request.command_type == "EPHEMERAL":
            db.delete(request)

            if wait_event:
                request_map.pop(request.id, None)

        raise RequestPublishException(
            f"Error while publishing {request!r} to message broker") from ex

    # Metrics
    request_created(request)

    return request
예제 #7
0
 def test_from_template(self, bg_request_template):
     request = Request.from_template(bg_request_template)
     for key in bg_request_template.__dict__:
         assert getattr(request, key) == getattr(bg_request_template, key)
예제 #8
0
def process_request(
    new_request: Union[Request, RequestTemplate],
    wait_event: threading.Event = None,
    is_admin: bool = False,
    priority: int = 0,
) -> Request:
    """Validates and publishes a Request.

    Args:
        new_request: The Request
        wait_event: Event that will be added to the local event_map. Event will be set
        when the request completes.
        is_admin: Flag indicating this request should be published on the admin queue
        priority: Number between 0 and 1, inclusive. High numbers equal higher priority

    Returns:
        The processed Request

    """
    if type(new_request) == Request:
        request = new_request
    elif type(new_request) == RequestTemplate:
        request = Request.from_template(new_request)
    else:
        raise TypeError(
            f"new_request type is {type(new_request)}, expected "
            f"brewtils.models.Request or brewtils.models.RequestTemplate,")

    # Validates the request based on what is in the database.
    # This includes the validation of the request parameters,
    # systems are there, commands are there etc.
    # Validation is only required for non Admin commands because Admin commands
    # are hard coded to map Plugin functions
    if not is_admin:
        request = RequestValidator.instance().validate_request(request)

    # Save after validation since validate can modify the request
    if not request.command_type == "EPHEMERAL":
        request = create_request(request)

    if wait_event:
        request_map[request.id] = wait_event

    try:
        if logger.isEnabledFor(logging.DEBUG):
            logger.debug(f"Publishing {request!r}")
        else:
            if not request.command_type == "EPHEMERAL":
                logger.info(f"Publishing {request!r}")

        queue.put(
            request,
            is_admin=is_admin,
            priority=priority,
            confirm=True,
            mandatory=True,
            delivery_mode=pika.spec.PERSISTENT_DELIVERY_MODE,
        )
    except Exception as ex:
        # An error publishing means this request will never complete, so remove it
        if not request.command_type == "EPHEMERAL":
            db.delete(request)

        if wait_event:
            request_map.pop(request.id, None)

        raise RequestPublishException(
            f"Error while publishing {request!r} to message broker") from ex

    # Metrics
    request_created(request)

    return request
예제 #9
0
def run_job(job_id, request_template, **kwargs):
    """Spawned by the scheduler, this will kick off a new request.

    This method is meant to be run in a separate process.

    Args:
        job_id: The Beer-Garden job ID that triggered this event.
        request_template: Request template specified by the job.
    """
    import beer_garden.router

    request_template.metadata["_bg_job_id"] = job_id

    # Attempt to inject information into the request template
    if "event" in kwargs and kwargs["event"] is not None:
        try:
            # This overloads the __missing__ function to allow partial injections
            injection_dict = InjectionDict()
            build_injection_dict(injection_dict,
                                 kwargs["event"],
                                 prefix="event")

            try:
                db_job = db.query_unique(Job, id=job_id)
                if db_job:
                    build_injection_dict(injection_dict,
                                         db_job.trigger,
                                         prefix="trigger")

            except Exception as ex:
                logger.exception(
                    f"Could not fetch job for parameter injection: {ex}")

            inject_values(request_template.parameters, injection_dict)
        except Exception as ex:
            logger.exception(f"Could not inject parameters: {ex}")

    db_job = db.query_unique(Job, id=job_id)
    wait_event = threading.Event()

    # I'm not sure what would cause this, but just be safe
    if not db_job:
        logger.error(
            f"Could not find job {job_id} in database, job will not be run")
        return

    try:
        logger.debug(f"About to execute {db_job!r}")

        request = beer_garden.router.route(
            Operation(
                operation_type="REQUEST_CREATE",
                model=Request.from_template(request_template),
                model_type="Request",
                kwargs={"wait_event": wait_event},
            ))

        # Wait for the request to complete
        timeout = db_job.timeout or None
        if not wait_event.wait(timeout=timeout):
            logger.warning(f"Execution of job {db_job} timed out.")
            return

        request = get_request(request.id)

        updates = {}
        if request.status == "ERROR":
            updates["inc__error_count"] = 1
            logger.debug(f"{db_job!r} request completed with ERROR status")
        elif request.status == "SUCCESS":
            logger.debug(f"{db_job!r} request completed with SUCCESS status")
            updates["inc__success_count"] = 1

        if updates != {}:
            db.modify(db_job, **updates)
    except Exception as ex:
        logger.error(f"Error executing {db_job}: {ex}")
        db.modify(db_job, inc__error_count=1)

    # Be a little careful here as the job could have been removed or paused
    job = beer_garden.application.scheduler.get_job(job_id)
    if (job and job.next_run_time is not None
            and getattr(job.trigger, "reschedule_on_finish", False)):
        # This essentially resets the timer on this job, which has the effect of
        # making the wait time start whenever the job finishes
        beer_garden.application.scheduler.reschedule_job(job_id,
                                                         trigger=job.trigger)