perf: 终断批量快捷命令执行的任务

This commit is contained in:
wangruidong 2024-02-19 14:47:32 +08:00 committed by Bryan
parent f592f19b08
commit 135fb7c6f9
4 changed files with 42 additions and 1 deletions

View File

@ -1,3 +1,4 @@
import os
from collections import defaultdict from collections import defaultdict
from functools import reduce from functools import reduce
@ -29,6 +30,8 @@ class DefaultCallback:
) )
self.status = 'running' self.status = 'running'
self.finished = False self.finished = False
self.local_pid = 0
self.private_data_dir = None
@property @property
def host_results(self): def host_results(self):
@ -45,6 +48,9 @@ class DefaultCallback:
event = data.get('event', None) event = data.get('event', None)
if not event: if not event:
return return
pid = data.get('pid', None)
if pid:
self.write_pid(pid)
event_data = data.get('event_data', {}) event_data = data.get('event_data', {})
host = event_data.get('remote_addr', '') host = event_data.get('remote_addr', '')
task = event_data.get('task', '') task = event_data.get('task', '')
@ -152,3 +158,11 @@ class DefaultCallback:
def status_handler(self, data, **kwargs): def status_handler(self, data, **kwargs):
status = data.get('status', '') status = data.get('status', '')
self.status = self.STATUS_MAPPER.get(status, 'unknown') self.status = self.STATUS_MAPPER.get(status, 'unknown')
rc = kwargs.get('runner_config', None)
self.private_data_dir = rc.private_data_dir if rc else '/tmp/'
def write_pid(self, pid):
pid_filepath = os.path.join(self.private_data_dir, 'local.pid')
with open(pid_filepath, 'w') as f:
f.write(str(pid))

View File

@ -16,7 +16,7 @@ from common.const.http import POST
from common.permissions import IsValidUser from common.permissions import IsValidUser
from ops.const import Types from ops.const import Types
from ops.models import Job, JobExecution from ops.models import Job, JobExecution
from ops.serializers.job import JobSerializer, JobExecutionSerializer, FileSerializer from ops.serializers.job import JobSerializer, JobExecutionSerializer, FileSerializer, JobTaskStopSerializer
__all__ = [ __all__ = [
'JobViewSet', 'JobExecutionViewSet', 'JobRunVariableHelpAPIView', 'JobViewSet', 'JobExecutionViewSet', 'JobRunVariableHelpAPIView',
@ -187,6 +187,17 @@ class JobExecutionViewSet(OrgBulkModelViewSet):
queryset = queryset.filter(creator=self.request.user) queryset = queryset.filter(creator=self.request.user)
return queryset return queryset
@action(methods=[POST], detail=False, serializer_class=JobTaskStopSerializer, permission_classes=[IsValidUser, ],
url_path='stop')
def stop(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
if not serializer.is_valid():
return Response({'error': serializer.errors}, status=400)
task_id = serializer.validated_data['task_id']
instance = get_object_or_404(JobExecution, task_id=task_id, creator=request.user)
instance.stop()
return Response({'task_id': task_id}, status=200)
class JobAssetDetail(APIView): class JobAssetDetail(APIView):
rbac_perms = { rbac_perms = {

View File

@ -554,6 +554,15 @@ class JobExecution(JMSOrgBaseModel):
finally: finally:
ssh_tunnel.local_gateway_clean(runner) ssh_tunnel.local_gateway_clean(runner)
def stop(self):
with open(os.path.join(self.private_dir, 'local.pid')) as f:
try:
pid = f.read()
os.kill(int(pid), 9)
except Exception as e:
print(e)
self.set_error('Job stop by "kill -9 {}"'.format(pid))
class Meta: class Meta:
verbose_name = _("Job Execution") verbose_name = _("Job Execution")
ordering = ['-date_created'] ordering = ['-date_created']

View File

@ -57,6 +57,13 @@ class FileSerializer(serializers.Serializer):
ref_name = "JobFileSerializer" ref_name = "JobFileSerializer"
class JobTaskStopSerializer(serializers.Serializer):
task_id = serializers.CharField(max_length=128)
class Meta:
ref_name = "JobTaskStopSerializer"
class JobExecutionSerializer(BulkOrgResourceModelSerializer): class JobExecutionSerializer(BulkOrgResourceModelSerializer):
creator = ReadableHiddenField(default=serializers.CurrentUserDefault()) creator = ReadableHiddenField(default=serializers.CurrentUserDefault())
job_type = serializers.ReadOnlyField(label=_("Job type")) job_type = serializers.ReadOnlyField(label=_("Job type"))