Jelajahi Sumber

Merge pull request #9028 from kkthxbye-code/job-timeout

Fixes #5479 - Allow setting individual timeouts on scripts and reports
Jeremy Stretch 3 tahun lalu
induk
melakukan
84c30580aa

+ 4 - 0
docs/customization/custom-scripts.md

@@ -89,6 +89,10 @@ The checkbox to commit database changes when executing a script is checked by de
 commit_default = False
 ```
 
+### `job_timeout`
+
+Set the allowed runtime of a script. If not set the `RQ_DEFAULT_TIMEOUT` will be used.
+
 ## Accessing Request Data
 
 Details of the current HTTP request (the one being made to execute the script) are available as the instance attribute `self.request`. This can be used to infer, for example, the user executing the script and the client IP address:

+ 4 - 2
netbox/extras/api/views.py

@@ -236,7 +236,8 @@ class ReportViewSet(ViewSet):
             run_report,
             report.full_name,
             report_content_type,
-            request.user
+            request.user,
+            job_timeout=report.job_timeout
         )
         report.result = job_result
 
@@ -320,7 +321,8 @@ class ScriptViewSet(ViewSet):
                 request.user,
                 data=data,
                 request=copy_safe_request(request),
-                commit=commit
+                commit=commit,
+                job_timeout=script.job_timeout,
             )
             script.result = job_result
             serializer = serializers.ScriptDetailSerializer(script, context={'request': request})

+ 2 - 1
netbox/extras/management/commands/runreport.py

@@ -35,7 +35,8 @@ class Command(BaseCommand):
                         run_report,
                         report.full_name,
                         report_content_type,
-                        None
+                        None,
+                        job_timeout=report.job_timeout
                     )
 
                     # Wait on the job to finish

+ 3 - 1
netbox/extras/models/models.py

@@ -13,6 +13,7 @@ from django.urls import reverse
 from django.utils import timezone
 from django.utils.formats import date_format
 from rest_framework.utils.encoders import JSONEncoder
+import django_rq
 
 from extras.choices import *
 from extras.constants import *
@@ -550,7 +551,8 @@ class JobResult(models.Model):
             job_id=uuid.uuid4()
         )
 
-        func.delay(*args, job_id=str(job_result.job_id), job_result=job_result, **kwargs)
+        queue = django_rq.get_queue("default")
+        queue.enqueue(func, job_id=str(job_result.job_id), job_result=job_result, **kwargs)
 
         return job_result
 

+ 1 - 0
netbox/extras/reports.py

@@ -119,6 +119,7 @@ class Report(object):
     }
     """
     description = None
+    job_timeout = None
 
     def __init__(self):
 

+ 4 - 1
netbox/extras/scripts.py

@@ -298,6 +298,10 @@ class BaseScript:
     def module(cls):
         return cls.__module__
 
+    @classproperty
+    def job_timeout(self):
+        return getattr(self.Meta, 'job_timeout', None)
+
     @classmethod
     def _get_vars(cls):
         vars = {}
@@ -414,7 +418,6 @@ def is_variable(obj):
     return isinstance(obj, ScriptVariable)
 
 
-@job('default')
 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

+ 5 - 2
netbox/extras/views.py

@@ -588,7 +588,8 @@ class ReportView(ContentTypePermissionRequiredMixin, View):
             run_report,
             report.full_name,
             report_content_type,
-            request.user
+            request.user,
+            job_timeout=report.job_timeout
         )
 
         return redirect('extras:report_result', job_result_pk=job_result.pk)
@@ -708,6 +709,7 @@ class ScriptView(ContentTypePermissionRequiredMixin, GetScriptMixin, View):
             commit = form.cleaned_data.pop('_commit')
 
             script_content_type = ContentType.objects.get(app_label='extras', model='script')
+
             job_result = JobResult.enqueue_job(
                 run_script,
                 script.full_name,
@@ -715,7 +717,8 @@ class ScriptView(ContentTypePermissionRequiredMixin, GetScriptMixin, View):
                 request.user,
                 data=form.cleaned_data,
                 request=copy_safe_request(request),
-                commit=commit
+                commit=commit,
+                job_timeout=script.job_timeout,
             )
 
             return redirect('extras:script_result', job_result_pk=job_result.pk)