mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
#8366: Add started field to JobResult
This commit is contained in:
@@ -385,8 +385,8 @@ class JobResultSerializer(BaseModelSerializer):
|
||||
class Meta:
|
||||
model = JobResult
|
||||
fields = [
|
||||
'id', 'url', 'display', 'status', 'created', 'scheduled', 'completed', 'name', 'obj_type', 'user', 'data',
|
||||
'job_id',
|
||||
'id', 'url', 'display', 'status', 'created', 'scheduled', 'started', 'completed', 'name', 'obj_type',
|
||||
'user', 'data', 'job_id',
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -503,15 +503,6 @@ class JobResultFilterSet(BaseFilterSet):
|
||||
field_name='created',
|
||||
lookup_expr='gte'
|
||||
)
|
||||
completed = django_filters.DateTimeFilter()
|
||||
completed__before = django_filters.DateTimeFilter(
|
||||
field_name='completed',
|
||||
lookup_expr='lte'
|
||||
)
|
||||
completed__after = django_filters.DateTimeFilter(
|
||||
field_name='completed',
|
||||
lookup_expr='gte'
|
||||
)
|
||||
scheduled = django_filters.DateTimeFilter()
|
||||
scheduled__before = django_filters.DateTimeFilter(
|
||||
field_name='scheduled',
|
||||
@@ -521,6 +512,24 @@ class JobResultFilterSet(BaseFilterSet):
|
||||
field_name='scheduled',
|
||||
lookup_expr='gte'
|
||||
)
|
||||
started = django_filters.DateTimeFilter()
|
||||
started__before = django_filters.DateTimeFilter(
|
||||
field_name='started',
|
||||
lookup_expr='lte'
|
||||
)
|
||||
started__after = django_filters.DateTimeFilter(
|
||||
field_name='started',
|
||||
lookup_expr='gte'
|
||||
)
|
||||
completed = django_filters.DateTimeFilter()
|
||||
completed__before = django_filters.DateTimeFilter(
|
||||
field_name='completed',
|
||||
lookup_expr='lte'
|
||||
)
|
||||
completed__after = django_filters.DateTimeFilter(
|
||||
field_name='completed',
|
||||
lookup_expr='gte'
|
||||
)
|
||||
status = django_filters.MultipleChoiceFilter(
|
||||
choices=JobResultStatusChoices,
|
||||
null_value=None
|
||||
@@ -528,9 +537,7 @@ class JobResultFilterSet(BaseFilterSet):
|
||||
|
||||
class Meta:
|
||||
model = JobResult
|
||||
fields = [
|
||||
'id', 'status', 'created', 'scheduled', 'completed', 'user', 'obj_type', 'name'
|
||||
]
|
||||
fields = ('id', 'status', 'user', 'obj_type', 'name')
|
||||
|
||||
def search(self, queryset, name, value):
|
||||
if not value.strip():
|
||||
|
||||
@@ -73,11 +73,10 @@ class JobResultFilterForm(SavedFiltersMixin, FilterForm):
|
||||
(None, ('q', 'filter_id')),
|
||||
('Attributes', ('obj_type', 'status')),
|
||||
('Creation', (
|
||||
'created__before', 'created__after', 'completed__before', 'completed__after', 'scheduled__before',
|
||||
'scheduled__after', 'user',
|
||||
'created__before', 'created__after', 'scheduled__before', 'scheduled__after', 'started__before',
|
||||
'started__after', 'completed__before', 'completed__after', 'user',
|
||||
)),
|
||||
)
|
||||
|
||||
obj_type = ContentTypeChoiceField(
|
||||
label=_('Object Type'),
|
||||
queryset=ContentType.objects.all(),
|
||||
@@ -96,14 +95,6 @@ class JobResultFilterForm(SavedFiltersMixin, FilterForm):
|
||||
required=False,
|
||||
widget=DateTimePicker()
|
||||
)
|
||||
completed__after = forms.DateTimeField(
|
||||
required=False,
|
||||
widget=DateTimePicker()
|
||||
)
|
||||
completed__before = forms.DateTimeField(
|
||||
required=False,
|
||||
widget=DateTimePicker()
|
||||
)
|
||||
scheduled__after = forms.DateTimeField(
|
||||
required=False,
|
||||
widget=DateTimePicker()
|
||||
@@ -112,6 +103,22 @@ class JobResultFilterForm(SavedFiltersMixin, FilterForm):
|
||||
required=False,
|
||||
widget=DateTimePicker()
|
||||
)
|
||||
started__after = forms.DateTimeField(
|
||||
required=False,
|
||||
widget=DateTimePicker()
|
||||
)
|
||||
started__before = forms.DateTimeField(
|
||||
required=False,
|
||||
widget=DateTimePicker()
|
||||
)
|
||||
completed__after = forms.DateTimeField(
|
||||
required=False,
|
||||
widget=DateTimePicker()
|
||||
)
|
||||
completed__before = forms.DateTimeField(
|
||||
required=False,
|
||||
widget=DateTimePicker()
|
||||
)
|
||||
user = DynamicModelMultipleChoiceField(
|
||||
queryset=User.objects.all(),
|
||||
required=False,
|
||||
|
||||
@@ -13,6 +13,11 @@ class Migration(migrations.Migration):
|
||||
name='scheduled',
|
||||
field=models.DateTimeField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='jobresult',
|
||||
name='started',
|
||||
field=models.DateTimeField(blank=True, null=True),
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='jobresult',
|
||||
options={'ordering': ['-created']},
|
||||
@@ -12,7 +12,7 @@ class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contenttypes', '0002_remove_content_type_name'),
|
||||
('extras', '0079_jobresult_scheduled'),
|
||||
('extras', '0079_scheduled_jobs'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
|
||||
@@ -585,6 +585,10 @@ class JobResult(models.Model):
|
||||
null=True,
|
||||
blank=True
|
||||
)
|
||||
started = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True
|
||||
)
|
||||
completed = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True
|
||||
@@ -639,9 +643,18 @@ class JobResult(models.Model):
|
||||
|
||||
return f"{int(minutes)} minutes, {seconds:.2f} seconds"
|
||||
|
||||
def start(self):
|
||||
"""
|
||||
Record the job's start time and update its status to "running."
|
||||
"""
|
||||
if self.started is None:
|
||||
self.started = timezone.now()
|
||||
self.status = JobResultStatusChoices.STATUS_RUNNING
|
||||
JobResult.objects.filter(pk=self.pk).update(started=self.started, status=self.status)
|
||||
|
||||
def set_status(self, status):
|
||||
"""
|
||||
Helper method to change the status of the job result. If the target status is terminal, the completion
|
||||
Helper method to change the status of the job result. If the target status is terminal, the completion
|
||||
time is also set.
|
||||
"""
|
||||
self.status = status
|
||||
|
||||
@@ -83,6 +83,7 @@ def run_report(job_result, *args, **kwargs):
|
||||
report = get_report(module_name, report_name)
|
||||
|
||||
try:
|
||||
job_result.start()
|
||||
report.run(job_result)
|
||||
except Exception as e:
|
||||
job_result.set_status(JobResultStatusChoices.STATUS_ERRORED)
|
||||
|
||||
@@ -433,16 +433,14 @@ def is_variable(obj):
|
||||
def run_script(data, request, commit=True, *args, **kwargs):
|
||||
"""
|
||||
A wrapper for calling Script.run(). This performs error handling and provides a hook for committing changes. It
|
||||
exists outside of the Script class to ensure it cannot be overridden by a script author.
|
||||
exists outside the Script class to ensure it cannot be overridden by a script author.
|
||||
"""
|
||||
job_result = kwargs.pop('job_result')
|
||||
job_result.start()
|
||||
|
||||
module, script_name = job_result.name.split('.', 1)
|
||||
|
||||
script = get_script(module, script_name)()
|
||||
|
||||
job_result.status = JobResultStatusChoices.STATUS_RUNNING
|
||||
job_result.save()
|
||||
|
||||
logger = logging.getLogger(f"netbox.scripts.{module}.{script_name}")
|
||||
logger.info(f"Running script (commit={commit})")
|
||||
|
||||
|
||||
@@ -49,9 +49,11 @@ class JobResultTable(NetBoxTable):
|
||||
class Meta(NetBoxTable.Meta):
|
||||
model = JobResult
|
||||
fields = (
|
||||
'pk', 'id', 'name', 'obj_type', 'status', 'created', 'scheduled', 'completed', 'user', 'job_id',
|
||||
'pk', 'id', 'name', 'obj_type', 'status', 'created', 'scheduled', 'started', 'completed', 'user', 'job_id',
|
||||
)
|
||||
default_columns = (
|
||||
'pk', 'id', 'name', 'obj_type', 'status', 'created', 'scheduled', 'started', 'completed', 'user',
|
||||
)
|
||||
default_columns = ('pk', 'id', 'name', 'obj_type', 'status', 'created', 'scheduled', 'completed', 'user',)
|
||||
|
||||
|
||||
class CustomLinkTable(NetBoxTable):
|
||||
|
||||
@@ -726,7 +726,7 @@ class ReportResultView(ContentTypePermissionRequiredMixin, View):
|
||||
'report': report,
|
||||
'result': result,
|
||||
})
|
||||
if result.completed:
|
||||
if result.completed or not result.started:
|
||||
response.status_code = 286
|
||||
return response
|
||||
|
||||
@@ -860,7 +860,7 @@ class ScriptResultView(ContentTypePermissionRequiredMixin, GetScriptMixin, View)
|
||||
'script': script,
|
||||
'result': result,
|
||||
})
|
||||
if result.completed:
|
||||
if result.completed or not result.started:
|
||||
response.status_code = 286
|
||||
return response
|
||||
|
||||
|
||||
Reference in New Issue
Block a user