mirror of
https://github.com/ansible/awx.git
synced 2026-02-09 21:54:43 -03:30
Compare commits
3 Commits
AAP-44075
...
priority_t
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d65ab1c5ac | ||
|
|
a2decc7c60 | ||
|
|
97d03e434e |
@@ -682,11 +682,12 @@ class EmptySerializer(serializers.Serializer):
|
|||||||
class UnifiedJobTemplateSerializer(BaseSerializer):
|
class UnifiedJobTemplateSerializer(BaseSerializer):
|
||||||
# As a base serializer, the capabilities prefetch is not used directly,
|
# As a base serializer, the capabilities prefetch is not used directly,
|
||||||
# instead they are derived from the Workflow Job Template Serializer and the Job Template Serializer, respectively.
|
# instead they are derived from the Workflow Job Template Serializer and the Job Template Serializer, respectively.
|
||||||
|
priority = serializers.IntegerField(required=False, min_value=0, max_value=32000)
|
||||||
capabilities_prefetch = []
|
capabilities_prefetch = []
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = UnifiedJobTemplate
|
model = UnifiedJobTemplate
|
||||||
fields = ('*', 'last_job_run', 'last_job_failed', 'next_job_run', 'status', 'execution_environment')
|
fields = ('*', 'last_job_run', 'last_job_failed', 'next_job_run', 'status', 'priority', 'execution_environment')
|
||||||
|
|
||||||
def get_related(self, obj):
|
def get_related(self, obj):
|
||||||
res = super(UnifiedJobTemplateSerializer, self).get_related(obj)
|
res = super(UnifiedJobTemplateSerializer, self).get_related(obj)
|
||||||
@@ -2996,6 +2997,7 @@ class JobOptionsSerializer(LabelsListMixin, BaseSerializer):
|
|||||||
'scm_branch',
|
'scm_branch',
|
||||||
'forks',
|
'forks',
|
||||||
'limit',
|
'limit',
|
||||||
|
'priority',
|
||||||
'verbosity',
|
'verbosity',
|
||||||
'extra_vars',
|
'extra_vars',
|
||||||
'job_tags',
|
'job_tags',
|
||||||
@@ -3118,6 +3120,7 @@ class JobTemplateMixin(object):
|
|||||||
class JobTemplateSerializer(JobTemplateMixin, UnifiedJobTemplateSerializer, JobOptionsSerializer):
|
class JobTemplateSerializer(JobTemplateMixin, UnifiedJobTemplateSerializer, JobOptionsSerializer):
|
||||||
show_capabilities = ['start', 'schedule', 'copy', 'edit', 'delete']
|
show_capabilities = ['start', 'schedule', 'copy', 'edit', 'delete']
|
||||||
capabilities_prefetch = ['admin', 'execute', {'copy': ['project.use', 'inventory.use']}]
|
capabilities_prefetch = ['admin', 'execute', {'copy': ['project.use', 'inventory.use']}]
|
||||||
|
priority = serializers.IntegerField(required=False, min_value=0, max_value=32000)
|
||||||
|
|
||||||
status = serializers.ChoiceField(choices=JobTemplate.JOB_TEMPLATE_STATUS_CHOICES, read_only=True, required=False)
|
status = serializers.ChoiceField(choices=JobTemplate.JOB_TEMPLATE_STATUS_CHOICES, read_only=True, required=False)
|
||||||
|
|
||||||
@@ -3125,6 +3128,7 @@ class JobTemplateSerializer(JobTemplateMixin, UnifiedJobTemplateSerializer, JobO
|
|||||||
model = JobTemplate
|
model = JobTemplate
|
||||||
fields = (
|
fields = (
|
||||||
'*',
|
'*',
|
||||||
|
'priority',
|
||||||
'host_config_key',
|
'host_config_key',
|
||||||
'ask_scm_branch_on_launch',
|
'ask_scm_branch_on_launch',
|
||||||
'ask_diff_mode_on_launch',
|
'ask_diff_mode_on_launch',
|
||||||
@@ -3252,6 +3256,7 @@ class JobSerializer(UnifiedJobSerializer, JobOptionsSerializer):
|
|||||||
'diff_mode',
|
'diff_mode',
|
||||||
'job_slice_number',
|
'job_slice_number',
|
||||||
'job_slice_count',
|
'job_slice_count',
|
||||||
|
'priority',
|
||||||
'webhook_service',
|
'webhook_service',
|
||||||
'webhook_credential',
|
'webhook_credential',
|
||||||
'webhook_guid',
|
'webhook_guid',
|
||||||
@@ -3702,6 +3707,7 @@ class WorkflowJobTemplateWithSpecSerializer(WorkflowJobTemplateSerializer):
|
|||||||
|
|
||||||
class WorkflowJobSerializer(LabelsListMixin, UnifiedJobSerializer):
|
class WorkflowJobSerializer(LabelsListMixin, UnifiedJobSerializer):
|
||||||
limit = serializers.CharField(allow_blank=True, allow_null=True, required=False, default=None)
|
limit = serializers.CharField(allow_blank=True, allow_null=True, required=False, default=None)
|
||||||
|
priority = serializers.IntegerField(required=False, min_value=0, max_value=32000)
|
||||||
scm_branch = serializers.CharField(allow_blank=True, allow_null=True, required=False, default=None)
|
scm_branch = serializers.CharField(allow_blank=True, allow_null=True, required=False, default=None)
|
||||||
|
|
||||||
skip_tags = serializers.CharField(allow_blank=True, allow_null=True, required=False, default=None)
|
skip_tags = serializers.CharField(allow_blank=True, allow_null=True, required=False, default=None)
|
||||||
@@ -3722,6 +3728,7 @@ class WorkflowJobSerializer(LabelsListMixin, UnifiedJobSerializer):
|
|||||||
'-controller_node',
|
'-controller_node',
|
||||||
'inventory',
|
'inventory',
|
||||||
'limit',
|
'limit',
|
||||||
|
'priority',
|
||||||
'scm_branch',
|
'scm_branch',
|
||||||
'webhook_service',
|
'webhook_service',
|
||||||
'webhook_credential',
|
'webhook_credential',
|
||||||
@@ -3839,6 +3846,7 @@ class LaunchConfigurationBaseSerializer(BaseSerializer):
|
|||||||
job_type = serializers.ChoiceField(allow_blank=True, allow_null=True, required=False, default=None, choices=NEW_JOB_TYPE_CHOICES)
|
job_type = serializers.ChoiceField(allow_blank=True, allow_null=True, required=False, default=None, choices=NEW_JOB_TYPE_CHOICES)
|
||||||
job_tags = serializers.CharField(allow_blank=True, allow_null=True, required=False, default=None)
|
job_tags = serializers.CharField(allow_blank=True, allow_null=True, required=False, default=None)
|
||||||
limit = serializers.CharField(allow_blank=True, allow_null=True, required=False, default=None)
|
limit = serializers.CharField(allow_blank=True, allow_null=True, required=False, default=None)
|
||||||
|
priority = serializers.IntegerField(required=False, min_value=0, max_value=32000)
|
||||||
skip_tags = serializers.CharField(allow_blank=True, allow_null=True, required=False, default=None)
|
skip_tags = serializers.CharField(allow_blank=True, allow_null=True, required=False, default=None)
|
||||||
diff_mode = serializers.BooleanField(required=False, allow_null=True, default=None)
|
diff_mode = serializers.BooleanField(required=False, allow_null=True, default=None)
|
||||||
verbosity = serializers.ChoiceField(allow_null=True, required=False, default=None, choices=VERBOSITY_CHOICES)
|
verbosity = serializers.ChoiceField(allow_null=True, required=False, default=None, choices=VERBOSITY_CHOICES)
|
||||||
@@ -3857,6 +3865,7 @@ class LaunchConfigurationBaseSerializer(BaseSerializer):
|
|||||||
'job_tags',
|
'job_tags',
|
||||||
'skip_tags',
|
'skip_tags',
|
||||||
'limit',
|
'limit',
|
||||||
|
'priority',
|
||||||
'skip_tags',
|
'skip_tags',
|
||||||
'diff_mode',
|
'diff_mode',
|
||||||
'verbosity',
|
'verbosity',
|
||||||
@@ -4350,6 +4359,7 @@ class JobLaunchSerializer(BaseSerializer):
|
|||||||
job_type = serializers.ChoiceField(required=False, choices=NEW_JOB_TYPE_CHOICES, write_only=True)
|
job_type = serializers.ChoiceField(required=False, choices=NEW_JOB_TYPE_CHOICES, write_only=True)
|
||||||
skip_tags = serializers.CharField(required=False, write_only=True, allow_blank=True)
|
skip_tags = serializers.CharField(required=False, write_only=True, allow_blank=True)
|
||||||
limit = serializers.CharField(required=False, write_only=True, allow_blank=True)
|
limit = serializers.CharField(required=False, write_only=True, allow_blank=True)
|
||||||
|
priority = serializers.IntegerField(required=False, write_only=False, min_value=0, max_value=32000)
|
||||||
verbosity = serializers.ChoiceField(required=False, choices=VERBOSITY_CHOICES, write_only=True)
|
verbosity = serializers.ChoiceField(required=False, choices=VERBOSITY_CHOICES, write_only=True)
|
||||||
execution_environment = serializers.PrimaryKeyRelatedField(queryset=ExecutionEnvironment.objects.all(), required=False, write_only=True)
|
execution_environment = serializers.PrimaryKeyRelatedField(queryset=ExecutionEnvironment.objects.all(), required=False, write_only=True)
|
||||||
labels = serializers.PrimaryKeyRelatedField(many=True, queryset=Label.objects.all(), required=False, write_only=True)
|
labels = serializers.PrimaryKeyRelatedField(many=True, queryset=Label.objects.all(), required=False, write_only=True)
|
||||||
@@ -4367,6 +4377,7 @@ class JobLaunchSerializer(BaseSerializer):
|
|||||||
'inventory',
|
'inventory',
|
||||||
'scm_branch',
|
'scm_branch',
|
||||||
'limit',
|
'limit',
|
||||||
|
'priority',
|
||||||
'job_tags',
|
'job_tags',
|
||||||
'skip_tags',
|
'skip_tags',
|
||||||
'job_type',
|
'job_type',
|
||||||
@@ -4552,6 +4563,7 @@ class WorkflowJobLaunchSerializer(BaseSerializer):
|
|||||||
extra_vars = VerbatimField(required=False, write_only=True)
|
extra_vars = VerbatimField(required=False, write_only=True)
|
||||||
inventory = serializers.PrimaryKeyRelatedField(queryset=Inventory.objects.all(), required=False, write_only=True)
|
inventory = serializers.PrimaryKeyRelatedField(queryset=Inventory.objects.all(), required=False, write_only=True)
|
||||||
limit = serializers.CharField(required=False, write_only=True, allow_blank=True)
|
limit = serializers.CharField(required=False, write_only=True, allow_blank=True)
|
||||||
|
priority = serializers.IntegerField(required=False, write_only=False, min_value=0, max_value=32000)
|
||||||
scm_branch = serializers.CharField(required=False, write_only=True, allow_blank=True)
|
scm_branch = serializers.CharField(required=False, write_only=True, allow_blank=True)
|
||||||
workflow_job_template_data = serializers.SerializerMethodField()
|
workflow_job_template_data = serializers.SerializerMethodField()
|
||||||
|
|
||||||
@@ -4691,13 +4703,14 @@ class BulkJobLaunchSerializer(serializers.Serializer):
|
|||||||
)
|
)
|
||||||
inventory = serializers.PrimaryKeyRelatedField(queryset=Inventory.objects.all(), required=False, write_only=True)
|
inventory = serializers.PrimaryKeyRelatedField(queryset=Inventory.objects.all(), required=False, write_only=True)
|
||||||
limit = serializers.CharField(write_only=True, required=False, allow_blank=False)
|
limit = serializers.CharField(write_only=True, required=False, allow_blank=False)
|
||||||
|
# priority = serializers.IntegerField(write_only=True, required=False, min_value=0, max_value=32000)
|
||||||
scm_branch = serializers.CharField(write_only=True, required=False, allow_blank=False)
|
scm_branch = serializers.CharField(write_only=True, required=False, allow_blank=False)
|
||||||
skip_tags = serializers.CharField(write_only=True, required=False, allow_blank=False)
|
skip_tags = serializers.CharField(write_only=True, required=False, allow_blank=False)
|
||||||
job_tags = serializers.CharField(write_only=True, required=False, allow_blank=False)
|
job_tags = serializers.CharField(write_only=True, required=False, allow_blank=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = WorkflowJob
|
model = WorkflowJob
|
||||||
fields = ('name', 'jobs', 'description', 'extra_vars', 'organization', 'inventory', 'limit', 'scm_branch', 'skip_tags', 'job_tags')
|
fields = ('name', 'jobs', 'description', 'extra_vars', 'organization', 'inventory', 'limit', 'priority', 'scm_branch', 'skip_tags', 'job_tags')
|
||||||
read_only_fields = ()
|
read_only_fields = ()
|
||||||
|
|
||||||
def validate(self, attrs):
|
def validate(self, attrs):
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# Generated by Django 4.2.16 on 2025-03-11 14:40
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('main', '0201_delete_token_cleanup_job'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='unifiedjob',
|
||||||
|
name='priority',
|
||||||
|
field=models.PositiveIntegerField(
|
||||||
|
default=0,
|
||||||
|
editable=False,
|
||||||
|
help_text='Relative priority to other jobs. The higher the number, the higher the priority. Jobs with equivalent prioirty are started based on available capacity and launch time.',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='unifiedjobtemplate',
|
||||||
|
name='priority',
|
||||||
|
field=models.PositiveIntegerField(default=0),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -298,6 +298,7 @@ class JobTemplate(
|
|||||||
'organization',
|
'organization',
|
||||||
'survey_passwords',
|
'survey_passwords',
|
||||||
'labels',
|
'labels',
|
||||||
|
'priority',
|
||||||
'credentials',
|
'credentials',
|
||||||
'job_slice_number',
|
'job_slice_number',
|
||||||
'job_slice_count',
|
'job_slice_count',
|
||||||
@@ -1175,7 +1176,7 @@ class SystemJobTemplate(UnifiedJobTemplate, SystemJobOptions):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_unified_job_field_names(cls):
|
def _get_unified_job_field_names(cls):
|
||||||
return ['name', 'description', 'organization', 'job_type', 'extra_vars']
|
return ['name', 'description', 'organization', 'priority', 'job_type', 'extra_vars']
|
||||||
|
|
||||||
def get_absolute_url(self, request=None):
|
def get_absolute_url(self, request=None):
|
||||||
return reverse('api:system_job_template_detail', kwargs={'pk': self.pk}, request=request)
|
return reverse('api:system_job_template_detail', kwargs={'pk': self.pk}, request=request)
|
||||||
|
|||||||
@@ -354,7 +354,7 @@ class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin, CustomVirtualEn
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_unified_job_field_names(cls):
|
def _get_unified_job_field_names(cls):
|
||||||
return set(f.name for f in ProjectOptions._meta.fields) | set(['name', 'description', 'organization'])
|
return set(f.name for f in ProjectOptions._meta.fields) | set(['name', 'description', 'priority', 'organization'])
|
||||||
|
|
||||||
def clean_organization(self):
|
def clean_organization(self):
|
||||||
if self.pk:
|
if self.pk:
|
||||||
|
|||||||
@@ -118,6 +118,11 @@ class UnifiedJobTemplate(PolymorphicModel, CommonModelNameNotUnique, ExecutionEn
|
|||||||
default=None,
|
default=None,
|
||||||
editable=False,
|
editable=False,
|
||||||
)
|
)
|
||||||
|
priority = models.PositiveIntegerField(
|
||||||
|
null=False,
|
||||||
|
default=0,
|
||||||
|
editable=True,
|
||||||
|
)
|
||||||
current_job = models.ForeignKey(
|
current_job = models.ForeignKey(
|
||||||
'UnifiedJob',
|
'UnifiedJob',
|
||||||
null=True,
|
null=True,
|
||||||
@@ -585,6 +590,13 @@ class UnifiedJob(
|
|||||||
default=None,
|
default=None,
|
||||||
editable=False,
|
editable=False,
|
||||||
)
|
)
|
||||||
|
priority = models.PositiveIntegerField(
|
||||||
|
default=0,
|
||||||
|
editable=False,
|
||||||
|
help_text=_(
|
||||||
|
"Relative priority to other jobs. The higher the number, the higher the priority. Jobs with equivalent prioirty are started based on available capacity and launch time."
|
||||||
|
),
|
||||||
|
)
|
||||||
emitted_events = models.PositiveIntegerField(
|
emitted_events = models.PositiveIntegerField(
|
||||||
default=0,
|
default=0,
|
||||||
editable=False,
|
editable=False,
|
||||||
|
|||||||
@@ -416,7 +416,7 @@ class WorkflowJobOptions(LaunchTimeConfigBase):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def _get_unified_job_field_names(cls):
|
def _get_unified_job_field_names(cls):
|
||||||
r = set(f.name for f in WorkflowJobOptions._meta.fields) | set(
|
r = set(f.name for f in WorkflowJobOptions._meta.fields) | set(
|
||||||
['name', 'description', 'organization', 'survey_passwords', 'labels', 'limit', 'scm_branch', 'job_tags', 'skip_tags']
|
['name', 'description', 'organization', 'survey_passwords', 'labels', 'limit', 'scm_branch', 'priority', 'job_tags', 'skip_tags']
|
||||||
)
|
)
|
||||||
r.remove('char_prompts') # needed due to copying launch config to launch config
|
r.remove('char_prompts') # needed due to copying launch config to launch config
|
||||||
return r
|
return r
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ class TaskBase:
|
|||||||
UnifiedJob.objects.filter(**filter_args)
|
UnifiedJob.objects.filter(**filter_args)
|
||||||
.exclude(launch_type='sync')
|
.exclude(launch_type='sync')
|
||||||
.exclude(polymorphic_ctype_id=wf_approval_ctype_id)
|
.exclude(polymorphic_ctype_id=wf_approval_ctype_id)
|
||||||
.order_by('created')
|
.order_by('-priority', 'created')
|
||||||
.prefetch_related('dependent_jobs')
|
.prefetch_related('dependent_jobs')
|
||||||
)
|
)
|
||||||
self.all_tasks = [t for t in qs]
|
self.all_tasks = [t for t in qs]
|
||||||
@@ -286,7 +286,7 @@ class WorkflowManager(TaskBase):
|
|||||||
|
|
||||||
@timeit
|
@timeit
|
||||||
def get_tasks(self, filter_args):
|
def get_tasks(self, filter_args):
|
||||||
self.all_tasks = [wf for wf in WorkflowJob.objects.filter(**filter_args)]
|
self.all_tasks = [wf for wf in WorkflowJob.objects.filter(**filter_args).order_by('-priority', 'created')]
|
||||||
|
|
||||||
@timeit
|
@timeit
|
||||||
def _schedule(self):
|
def _schedule(self):
|
||||||
@@ -336,12 +336,14 @@ class DependencyManager(TaskBase):
|
|||||||
|
|
||||||
return bool(((update.finished + timedelta(seconds=cache_timeout))) < tz_now())
|
return bool(((update.finished + timedelta(seconds=cache_timeout))) < tz_now())
|
||||||
|
|
||||||
def get_or_create_project_update(self, project_id):
|
def get_or_create_project_update(self, task):
|
||||||
|
project_id = task.project_id
|
||||||
|
priority = task.priority
|
||||||
project = self.all_projects.get(project_id, None)
|
project = self.all_projects.get(project_id, None)
|
||||||
if project is not None:
|
if project is not None:
|
||||||
latest_project_update = project.project_updates.filter(job_type='check').order_by("-created").first()
|
latest_project_update = project.project_updates.filter(job_type='check').order_by("-created").first()
|
||||||
if self.should_update_again(latest_project_update, project.scm_update_cache_timeout):
|
if self.should_update_again(latest_project_update, project.scm_update_cache_timeout):
|
||||||
project_task = project.create_project_update(_eager_fields=dict(launch_type='dependency'))
|
project_task = project.create_project_update(_eager_fields=dict(launch_type='dependency', priority=priority))
|
||||||
project_task.signal_start()
|
project_task.signal_start()
|
||||||
return [project_task]
|
return [project_task]
|
||||||
else:
|
else:
|
||||||
@@ -349,7 +351,7 @@ class DependencyManager(TaskBase):
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
def gen_dep_for_job(self, task):
|
def gen_dep_for_job(self, task):
|
||||||
dependencies = self.get_or_create_project_update(task.project_id)
|
dependencies = self.get_or_create_project_update(task)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
start_args = json.loads(decrypt_field(task, field_name="start_args"))
|
start_args = json.loads(decrypt_field(task, field_name="start_args"))
|
||||||
@@ -361,7 +363,7 @@ class DependencyManager(TaskBase):
|
|||||||
continue
|
continue
|
||||||
latest_inventory_update = inventory_source.inventory_updates.order_by("-created").first()
|
latest_inventory_update = inventory_source.inventory_updates.order_by("-created").first()
|
||||||
if self.should_update_again(latest_inventory_update, inventory_source.update_cache_timeout):
|
if self.should_update_again(latest_inventory_update, inventory_source.update_cache_timeout):
|
||||||
inventory_task = inventory_source.create_inventory_update(_eager_fields=dict(launch_type='dependency'))
|
inventory_task = inventory_source.create_inventory_update(_eager_fields=dict(launch_type='dependency', priority=task.priority))
|
||||||
inventory_task.signal_start()
|
inventory_task.signal_start()
|
||||||
dependencies.append(inventory_task)
|
dependencies.append(inventory_task)
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user