Esempio n. 1
0
class InstanceGroup(models.Model):
    """A model representing a Queue/Group of AWX Instances."""
    objects = InstanceGroupManager()

    name = models.CharField(max_length=250, unique=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    instances = models.ManyToManyField(
        'Instance',
        related_name='rampart_groups',
        editable=False,
        help_text=_('Instances that are members of this InstanceGroup'),
    )
    controller = models.ForeignKey(
        'InstanceGroup',
        related_name='controlled_groups',
        help_text=_('Instance Group to remotely control this group.'),
        editable=False,
        default=None,
        null=True)

    def get_absolute_url(self, request=None):
        return reverse('api:instance_group_detail',
                       kwargs={'pk': self.pk},
                       request=request)

    @property
    def capacity(self):
        return sum([inst.capacity for inst in self.instances.all()])

    class Meta:
        app_label = 'main'
Esempio n. 2
0
class InstanceGroup(models.Model, RelatedJobsMixin):
    """A model representing a Queue/Group of AWX Instances."""
    objects = InstanceGroupManager()

    name = models.CharField(max_length=250, unique=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    instances = models.ManyToManyField(
        'Instance',
        related_name='rampart_groups',
        editable=False,
        help_text=_('Instances that are members of this InstanceGroup'),
    )
    controller = models.ForeignKey(
        'InstanceGroup',
        related_name='controlled_groups',
        help_text=_('Instance Group to remotely control this group.'),
        editable=False,
        default=None,
        null=True)
    policy_instance_percentage = models.IntegerField(
        default=0,
        help_text=_(
            "Percentage of Instances to automatically assign to this group"))
    policy_instance_minimum = models.IntegerField(
        default=0,
        help_text=
        _("Static minimum number of Instances to automatically assign to this group"
          ))
    policy_instance_list = JSONField(
        default=[],
        blank=True,
        help_text=
        _("List of exact-match Instances that will always be automatically assigned to this group"
          ))

    def get_absolute_url(self, request=None):
        return reverse('api:instance_group_detail',
                       kwargs={'pk': self.pk},
                       request=request)

    @property
    def capacity(self):
        return sum([inst.capacity for inst in self.instances.all()])

    '''
    RelatedJobsMixin
    '''

    def _get_related_jobs(self):
        return UnifiedJob.objects.filter(instance_group=self)

    class Meta:
        app_label = 'main'
Esempio n. 3
0
class InstanceGroup(HasPolicyEditsMixin, BaseModel, RelatedJobsMixin):
    """A model representing a Queue/Group of AWX Instances."""
    objects = InstanceGroupManager()

    name = models.CharField(max_length=250, unique=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    instances = models.ManyToManyField(
        'Instance',
        related_name='rampart_groups',
        editable=False,
        help_text=_('Instances that are members of this InstanceGroup'),
    )
    controller = models.ForeignKey(
        'InstanceGroup',
        related_name='controlled_groups',
        help_text=_('Instance Group to remotely control this group.'),
        editable=False,
        default=None,
        null=True,
        on_delete=models.CASCADE)
    policy_instance_percentage = models.IntegerField(
        default=0,
        help_text=_(
            "Percentage of Instances to automatically assign to this group"))
    policy_instance_minimum = models.IntegerField(
        default=0,
        help_text=
        _("Static minimum number of Instances to automatically assign to this group"
          ))
    policy_instance_list = JSONField(
        default=[],
        blank=True,
        help_text=
        _("List of exact-match Instances that will always be automatically assigned to this group"
          ))

    POLICY_FIELDS = frozenset(
        ('policy_instance_list', 'policy_instance_minimum',
         'policy_instance_percentage', 'controller'))

    def get_absolute_url(self, request=None):
        return reverse('api:instance_group_detail',
                       kwargs={'pk': self.pk},
                       request=request)

    @property
    def capacity(self):
        return sum([inst.capacity for inst in self.instances.all()])

    @property
    def jobs_running(self):
        return UnifiedJob.objects.filter(status__in=('running', 'waiting'),
                                         instance_group=self).count()

    @property
    def jobs_total(self):
        return UnifiedJob.objects.filter(instance_group=self).count()

    @property
    def is_controller(self):
        return self.controlled_groups.exists()

    @property
    def is_isolated(self):
        return bool(self.controller)

    '''
    RelatedJobsMixin
    '''

    def _get_related_jobs(self):
        return UnifiedJob.objects.filter(instance_group=self)

    class Meta:
        app_label = 'main'

    def fit_task_to_most_remaining_capacity_instance(self, task):
        instance_most_capacity = None
        for i in self.instances.filter(capacity__gt=0,
                                       enabled=True).order_by('hostname'):
            if i.remaining_capacity >= task.task_impact and \
                    (instance_most_capacity is None or
                     i.remaining_capacity > instance_most_capacity.remaining_capacity):
                instance_most_capacity = i
        return instance_most_capacity

    def find_largest_idle_instance(self):
        largest_instance = None
        for i in self.instances.filter(capacity__gt=0,
                                       enabled=True).order_by('hostname'):
            if i.jobs_running == 0:
                if largest_instance is None:
                    largest_instance = i
                elif i.capacity > largest_instance.capacity:
                    largest_instance = i
        return largest_instance

    def choose_online_controller_node(self):
        return random.choice(
            list(
                self.controller.instances.filter(
                    capacity__gt=0, enabled=True).values_list('hostname',
                                                              flat=True)))
Esempio n. 4
0
File: ha.py Progetto: lj020326/awx
class InstanceGroup(HasPolicyEditsMixin, BaseModel, RelatedJobsMixin):
    """A model representing a Queue/Group of AWX Instances."""

    objects = InstanceGroupManager()

    name = models.CharField(max_length=250, unique=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    instances = models.ManyToManyField(
        'Instance',
        related_name='rampart_groups',
        editable=False,
        help_text=_('Instances that are members of this InstanceGroup'),
    )
    is_container_group = models.BooleanField(default=False)
    credential = models.ForeignKey(
        'Credential',
        related_name='%(class)ss',
        blank=True,
        null=True,
        default=None,
        on_delete=models.SET_NULL,
    )
    pod_spec_override = prevent_search(
        models.TextField(
            blank=True,
            default='',
        ))
    policy_instance_percentage = models.IntegerField(
        default=0,
        help_text=_(
            "Percentage of Instances to automatically assign to this group"))
    policy_instance_minimum = models.IntegerField(
        default=0,
        help_text=
        _("Static minimum number of Instances to automatically assign to this group"
          ))
    policy_instance_list = JSONBlob(
        default=list,
        blank=True,
        help_text=
        _("List of exact-match Instances that will always be automatically assigned to this group"
          ))

    POLICY_FIELDS = frozenset(
        ('policy_instance_list', 'policy_instance_minimum',
         'policy_instance_percentage'))

    def get_absolute_url(self, request=None):
        return reverse('api:instance_group_detail',
                       kwargs={'pk': self.pk},
                       request=request)

    @property
    def capacity(self):
        return sum(inst.capacity for inst in self.instances.all())

    @property
    def jobs_running(self):
        return UnifiedJob.objects.filter(status__in=('running', 'waiting'),
                                         instance_group=self).count()

    @property
    def jobs_total(self):
        return UnifiedJob.objects.filter(instance_group=self).count()

    '''
    RelatedJobsMixin
    '''

    def _get_related_jobs(self):
        return UnifiedJob.objects.filter(instance_group=self)

    class Meta:
        app_label = 'main'

    @staticmethod
    def fit_task_to_most_remaining_capacity_instance(
            task,
            instances,
            impact=None,
            capacity_type=None,
            add_hybrid_control_cost=False):
        impact = impact if impact else task.task_impact
        capacity_type = capacity_type if capacity_type else task.capacity_type
        instance_most_capacity = None
        most_remaining_capacity = -1
        for i in instances:
            if i.node_type not in (capacity_type, 'hybrid'):
                continue
            would_be_remaining = i.remaining_capacity - impact
            # hybrid nodes _always_ control their own tasks
            if add_hybrid_control_cost and i.node_type == 'hybrid':
                would_be_remaining -= settings.AWX_CONTROL_NODE_TASK_IMPACT
            if would_be_remaining >= 0 and (
                    instance_most_capacity is None
                    or would_be_remaining > most_remaining_capacity):
                instance_most_capacity = i
                most_remaining_capacity = would_be_remaining
        return instance_most_capacity

    @staticmethod
    def find_largest_idle_instance(instances, capacity_type='execution'):
        largest_instance = None
        for i in instances:
            if i.node_type not in (capacity_type, 'hybrid'):
                continue
            if i.jobs_running == 0:
                if largest_instance is None:
                    largest_instance = i
                elif i.capacity > largest_instance.capacity:
                    largest_instance = i
        return largest_instance

    def set_default_policy_fields(self):
        self.policy_instance_list = []
        self.policy_instance_minimum = 0
        self.policy_instance_percentage = 0