예제 #1
0
    def _power_off_instances(self, power_off_time):
        """
        Mark all running instances belonging to this CloudAccount as powered off.

        Args:
            power_off_time (datetime.datetime): time to set when stopping the instances
        """
        from api.util import recalculate_runs  # Avoid circular import.

        instances = self.instance_set.all()
        for instance in instances:
            last_event = (
                InstanceEvent.objects.filter(instance=instance)
                .order_by("-occurred_at")
                .first()
            )
            if last_event and last_event.event_type != InstanceEvent.TYPE.power_off:
                content_object_class = last_event.content_object.__class__
                cloud_specific_event = content_object_class.objects.create()
                event = InstanceEvent.objects.create(
                    event_type=InstanceEvent.TYPE.power_off,
                    occurred_at=power_off_time,
                    instance=instance,
                    content_object=cloud_specific_event,
                )
                recalculate_runs(event)
예제 #2
0
def recalculate_runs_from_events(events):
    """
    Run recalculate_runs on multiple events.

    Args:
        events (list(model.InstanceEvents)): events to recalculate

    """
    for event in events:
        recalculate_runs(event)
예제 #3
0
def process_instance_event(event):
    """
    Process instance events that have been saved during log analysis.

    Note:
        When processing power_on type events, this triggers a recalculation of
        ConcurrentUsage objects. If the event is at some point in the
        not-too-recent past, this may take a while as every day since the event
        will get recalculated and saved. We do not anticipate this being a real
        problem in practice, but this has the potential to slow down unit test
        execution over time since their occurred_at values are often static and
        will recede father into the past from "today", resulting in more days
        needing to recalculate. This effect could be mitigated in tests by
        patching parts of the datetime module that are used to find "today".
    """
    after_run = Q(start_time__gt=event.occurred_at)
    during_run = Q(start_time__lte=event.occurred_at,
                   end_time__gt=event.occurred_at)
    during_run_no_end = Q(start_time__lte=event.occurred_at, end_time=None)

    filters = after_run | during_run | during_run_no_end
    instance = Instance.objects.get(id=event.instance_id)

    if Run.objects.filter(filters, instance=instance).exists():
        recalculate_runs(event)
    elif event.event_type == InstanceEvent.TYPE.power_on:
        normalized_runs = normalize_runs([event])
        runs = []
        for index, normalized_run in enumerate(normalized_runs):
            logger.info("Processing run {} of {}".format(
                index + 1, len(normalized_runs)))
            run = Run(
                start_time=normalized_run.start_time,
                end_time=normalized_run.end_time,
                machineimage_id=normalized_run.image_id,
                instance_id=normalized_run.instance_id,
                instance_type=normalized_run.instance_type,
                memory=normalized_run.instance_memory,
                vcpu=normalized_run.instance_vcpu,
            )
            run.save()
            runs.append(run)
        calculate_max_concurrent_usage_from_runs(runs)