mirror of https://github.com/openspug/spug
A 新增终止任务执行功能
parent
35506a5690
commit
9fc7571422
|
@ -16,13 +16,13 @@ def exec_worker_handler(job):
|
||||||
|
|
||||||
|
|
||||||
class Job:
|
class Job:
|
||||||
def __init__(self, key, name, hostname, port, username, pkey, command, interpreter, params=None, token=None,
|
def __init__(self, token, key, name, hostname, port, username, pkey, command, interpreter, params=None, term=None):
|
||||||
term=None):
|
|
||||||
self.ssh = SSH(hostname, port, username, pkey, term=term)
|
self.ssh = SSH(hostname, port, username, pkey, term=term)
|
||||||
self.key = key
|
self.key = key
|
||||||
self.command = self._handle_command(command, interpreter)
|
self.command = self._handle_command(command, interpreter)
|
||||||
self.token = token
|
self.token = token
|
||||||
self.rds = get_redis_connection()
|
self.rds = get_redis_connection()
|
||||||
|
self.rds_key = f'PID:{self.token}:{self.key}'
|
||||||
self.env = dict(
|
self.env = dict(
|
||||||
SPUG_HOST_ID=str(self.key),
|
SPUG_HOST_ID=str(self.key),
|
||||||
SPUG_HOST_NAME=name,
|
SPUG_HOST_NAME=name,
|
||||||
|
@ -50,14 +50,12 @@ class Job:
|
||||||
self._send({'key': self.key, 'status': code})
|
self._send({'key': self.key, 'status': code})
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
if not self.token:
|
|
||||||
with self.ssh:
|
|
||||||
return self.ssh.exec_command(self.command, self.env)
|
|
||||||
flag = time.time()
|
flag = time.time()
|
||||||
self.send('\r\n\x1b[36m### Executing ...\x1b[0m\r\n')
|
self.send('\r\n\x1b[36m### Executing ...\x1b[0m\r\n')
|
||||||
code = -1
|
code = -1
|
||||||
try:
|
try:
|
||||||
with self.ssh:
|
with self.ssh:
|
||||||
|
self.rds.set(self.rds_key, self.ssh.get_pid(), 7200)
|
||||||
for code, out in self.ssh.exec_command_with_stream(self.command, self.env):
|
for code, out in self.ssh.exec_command_with_stream(self.command, self.env):
|
||||||
self.send(out)
|
self.send(out)
|
||||||
human_time = human_seconds_time(time.time() - flag)
|
human_time = human_seconds_time(time.time() - flag)
|
||||||
|
@ -70,4 +68,5 @@ class Job:
|
||||||
self.send(f'\r\n\x1b[31m### Exception {e}\x1b[0m')
|
self.send(f'\r\n\x1b[31m### Exception {e}\x1b[0m')
|
||||||
raise e
|
raise e
|
||||||
finally:
|
finally:
|
||||||
|
self.rds.delete(self.rds_key)
|
||||||
self.send_status(code)
|
self.send_status(code)
|
||||||
|
|
|
@ -3,11 +3,12 @@
|
||||||
# Released under the AGPL-3.0 License.
|
# Released under the AGPL-3.0 License.
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
|
||||||
from apps.exec.views import *
|
from apps.exec.views import TemplateView, TaskView, handle_terminate
|
||||||
from apps.exec.transfer import TransferView
|
from apps.exec.transfer import TransferView
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'template/$', TemplateView.as_view()),
|
url(r'template/$', TemplateView.as_view()),
|
||||||
url(r'do/$', TaskView.as_view()),
|
url(r'do/$', TaskView.as_view()),
|
||||||
url(r'transfer/$', TransferView.as_view()),
|
url(r'transfer/$', TransferView.as_view()),
|
||||||
|
url(r'terminate/$', handle_terminate),
|
||||||
]
|
]
|
||||||
|
|
|
@ -120,4 +120,19 @@ class TaskView(View):
|
||||||
return json_response(error=error)
|
return json_response(error=error)
|
||||||
|
|
||||||
|
|
||||||
|
@auth('exec.task.do')
|
||||||
|
def handle_terminate(request):
|
||||||
|
form, error = JsonParser(
|
||||||
|
Argument('token', help='参数错误'),
|
||||||
|
Argument('host_id', type=int, help='参数错误')
|
||||||
|
).parse(request.body)
|
||||||
|
if error is None:
|
||||||
|
host = Host.objects.get(pk=form.host_id)
|
||||||
|
rds = get_redis_connection()
|
||||||
|
rds_key = f'PID:{form.token}:{host.id}'
|
||||||
|
pid = rds.get(rds_key)
|
||||||
|
if pid:
|
||||||
|
with host.get_ssh() as ssh:
|
||||||
|
ssh.exec_command_raw(f'kill -9 {pid.decode()}')
|
||||||
|
rds.delete(rds_key)
|
||||||
|
return json_response(error=error)
|
||||||
|
|
|
@ -58,6 +58,7 @@ class SSH:
|
||||||
self.sftp = None
|
self.sftp = None
|
||||||
self.exec_file = None
|
self.exec_file = None
|
||||||
self.term = term or {}
|
self.term = term or {}
|
||||||
|
self.pid = None
|
||||||
self.eof = 'Spug EOF 2108111926'
|
self.eof = 'Spug EOF 2108111926'
|
||||||
self.default_env = default_env
|
self.default_env = default_env
|
||||||
self.regex = re.compile(r'Spug EOF 2108111926 (-?\d+)[\r\n]?')
|
self.regex = re.compile(r'Spug EOF 2108111926 (-?\d+)[\r\n]?')
|
||||||
|
@ -174,6 +175,12 @@ class SSH:
|
||||||
sftp = self._get_sftp()
|
sftp = self._get_sftp()
|
||||||
sftp.remove(path)
|
sftp.remove(path)
|
||||||
|
|
||||||
|
def get_pid(self):
|
||||||
|
if self.pid:
|
||||||
|
return self.pid
|
||||||
|
self._get_channel()
|
||||||
|
return self.pid
|
||||||
|
|
||||||
def _get_channel(self):
|
def _get_channel(self):
|
||||||
if self.channel:
|
if self.channel:
|
||||||
return self.channel
|
return self.channel
|
||||||
|
@ -183,13 +190,17 @@ class SSH:
|
||||||
command = '[ -n "$BASH_VERSION" ] && set +o history\n'
|
command = '[ -n "$BASH_VERSION" ] && set +o history\n'
|
||||||
command += '[ -n "$ZSH_VERSION" ] && set +o zle && set -o no_nomatch\n'
|
command += '[ -n "$ZSH_VERSION" ] && set +o zle && set -o no_nomatch\n'
|
||||||
command += 'export PS1= && stty -echo\n'
|
command += 'export PS1= && stty -echo\n'
|
||||||
command = self._handle_command(command, self.default_env)
|
command += f'echo {self.eof} $$\n'
|
||||||
self.channel.sendall(command)
|
self.channel.sendall(command)
|
||||||
out = ''
|
out = ''
|
||||||
while True:
|
while True:
|
||||||
if self.channel.recv_ready():
|
if self.channel.recv_ready():
|
||||||
out += self._decode(self.channel.recv(8196))
|
out += self._decode(self.channel.recv(8196))
|
||||||
if self.regex.search(out):
|
match = self.regex.search(out)
|
||||||
|
if match:
|
||||||
|
self.pid = int(match.group(1))
|
||||||
|
if self.pid <= 1:
|
||||||
|
raise Exception('Failed to get process pid')
|
||||||
self.stdout = self.channel.makefile('r')
|
self.stdout = self.channel.makefile('r')
|
||||||
break
|
break
|
||||||
elif counter >= 100:
|
elif counter >= 100:
|
||||||
|
|
Loading…
Reference in New Issue