1
0
mirror of https://github.com/ansible/awx.git synced 2024-11-02 01:21:21 +03:00

Implement model/view/launch paradigm for shard/split job templates

This commit is contained in:
Matthew Jones 2018-08-14 12:12:07 -04:00 committed by AlanCoding
parent 89c2038ea3
commit 0b1776098b
No known key found for this signature in database
GPG Key ID: FD2C3C012A72926B
7 changed files with 82 additions and 6 deletions

View File

@ -3011,7 +3011,7 @@ class JobTemplateSerializer(JobTemplateMixin, UnifiedJobTemplateSerializer, JobO
fields = ('*', 'host_config_key', 'ask_diff_mode_on_launch', 'ask_variables_on_launch', 'ask_limit_on_launch', 'ask_tags_on_launch',
'ask_skip_tags_on_launch', 'ask_job_type_on_launch', 'ask_verbosity_on_launch', 'ask_inventory_on_launch',
'ask_credential_on_launch', 'survey_enabled', 'become_enabled', 'diff_mode',
'allow_simultaneous', 'custom_virtualenv')
'allow_simultaneous', 'custom_virtualenv', 'job_shard_count')
def get_related(self, obj):
res = super(JobTemplateSerializer, self).get_related(obj)

View File

@ -2903,7 +2903,7 @@ class JobTemplateLaunch(RetrieveAPIView):
raise PermissionDenied()
passwords = serializer.validated_data.pop('credential_passwords', {})
new_job = obj.create_unified_job(**serializer.validated_data)
new_job = obj.create_job(**serializer.validated_data)
result = new_job.signal_start(**passwords)
if not result:
@ -2914,7 +2914,10 @@ class JobTemplateLaunch(RetrieveAPIView):
data = OrderedDict()
data['job'] = new_job.id
data['ignored_fields'] = self.sanitize_for_response(ignored_fields)
data.update(JobSerializer(new_job, context=self.get_serializer_context()).to_representation(new_job))
if isinstance(new_job, WorkflowJob):
data.update(WorkflowJobSerializer(new_job, context=self.get_serializer_context()).to_representation(new_job))
else:
data.update(JobSerializer(new_job, context=self.get_serializer_context()).to_representation(new_job))
headers = {'Location': new_job.get_absolute_url(request)}
return Response(data, status=status.HTTP_201_CREATED, headers=headers)

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-08-14 13:43
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('main', '0047_v330_activitystream_instance'),
]
operations = [
migrations.AddField(
model_name='jobtemplate',
name='job_shard_count',
field=models.IntegerField(blank=True,
default=0,
help_text='The number of jobs to split into at runtime. Will cause the Job Template to launch a workflow.'),
),
]

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2018-08-14 16:04
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('main', '0048_v340_split_jobs'),
]
operations = [
migrations.AddField(
model_name='workflowjob',
name='job_template',
field=models.ForeignKey(blank=True,
default=None,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name='sharded_jobs', to='main.JobTemplate'),
),
]

View File

@ -277,6 +277,12 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour
default=False,
allows_field='credentials'
)
job_shard_count = models.IntegerField(
blank=True,
default=0,
help_text=_("The number of jobs to split into at runtime. Will cause the Job Template to launch a workflow."),
)
admin_role = ImplicitRoleField(
parent_role=['project.organization.job_template_admin_role', 'inventory.organization.job_template_admin_role']
)
@ -318,6 +324,11 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour
'''
Create a new job based on this template.
'''
if self.job_shard_count > 1:
# A sharded Job Template will generate a WorkflowJob rather than a Job
from awx.main.models.workflow import WorkflowJobTemplate
kwargs['_unified_job_class'] = WorkflowJobTemplate._get_unified_job_class()
kwargs['_unified_job_field_names'] = WorkflowJobTemplate._get_unified_job_field_names()
return self.create_unified_job(**kwargs)
def get_absolute_url(self, request=None):

View File

@ -328,6 +328,8 @@ class UnifiedJobTemplate(PolymorphicModel, CommonModelNameNotUnique, Notificatio
'''
Create a new unified job based on this unified job template.
'''
from awx.main.models import JobTemplate, WorkflowJob
new_job_passwords = kwargs.pop('survey_passwords', {})
eager_fields = kwargs.pop('_eager_fields', None)
@ -336,8 +338,10 @@ class UnifiedJobTemplate(PolymorphicModel, CommonModelNameNotUnique, Notificatio
password_list = self.survey_password_variables()
encrypt_dict(kwargs.get('extra_vars', {}), password_list)
unified_job_class = self._get_unified_job_class()
fields = self._get_unified_job_field_names()
unified_job_class = kwargs.pop("_unified_job_class", self._get_unified_job_class())
fields = kwargs.pop("_unified_job_field_names", self._get_unified_job_field_names())
print("UJC: {}".format(unified_job_class))
print("fields: {}".format(fields))
unallowed_fields = set(kwargs.keys()) - set(fields)
if unallowed_fields:
logger.warn('Fields {} are not allowed as overrides.'.format(unallowed_fields))
@ -350,7 +354,11 @@ class UnifiedJobTemplate(PolymorphicModel, CommonModelNameNotUnique, Notificatio
setattr(unified_job, fd, val)
# Set the unified job template back-link on the job
parent_field_name = unified_job_class._get_parent_field_name()
# TODO: fix this hack properly before merge matburt
if isinstance(self, JobTemplate) and isinstance(unified_job, WorkflowJob):
parent_field_name = "job_template"
else:
parent_field_name = unified_job_class._get_parent_field_name()
setattr(unified_job, parent_field_name, self)
# For JobTemplate-based jobs with surveys, add passwords to list for perma-redaction

View File

@ -433,6 +433,14 @@ class WorkflowJob(UnifiedJob, WorkflowJobOptions, SurveyJobMixin, JobNotificatio
default=None,
on_delete=models.SET_NULL,
)
job_template = models.ForeignKey(
'JobTemplate',
related_name='sharded_jobs',
blank=True,
null=True,
default=None,
on_delete=models.SET_NULL,
)
@property
def workflow_nodes(self):