From 0546c47762c09d540d94be835e716ec05c5d9198 Mon Sep 17 00:00:00 2001 From: vapao Date: Sat, 9 Jul 2022 23:20:27 +0800 Subject: [PATCH] =?UTF-8?q?U=20=E4=BC=98=E5=8C=96=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=88=86=E5=8F=91=E8=BF=9B=E5=BA=A6=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spug_api/apps/exec/transfer.py | 39 +++++++++++++++++++++++----------- spug_api/libs/utils.py | 25 ++++++++++++---------- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/spug_api/apps/exec/transfer.py b/spug_api/apps/exec/transfer.py index 42fcd5e..948e015 100644 --- a/spug_api/apps/exec/transfer.py +++ b/spug_api/apps/exec/transfer.py @@ -10,13 +10,14 @@ from apps.account.utils import has_host_perm from apps.host.models import Host from apps.setting.utils import AppSetting from libs import json_response, JsonParser, Argument, auth -from libs.utils import str_decode +from libs.utils import str_decode, human_seconds_time from concurrent import futures from threading import Thread import subprocess import tempfile import uuid import json +import time import os @@ -97,7 +98,10 @@ def _dispatch_sync(task): for t in futures.as_completed(threads): exc = t.exception() if exc: - rds.publish(t.token, json.dumps({'key': t.key, 'status': -1, 'data': f'\x1b[31mException: {exc}\x1b[0m'})) + rds.publish( + t.token, + json.dumps({'key': t.key, 'status': -1, 'data': f'\x1b[31mException: {exc}\x1b[0m'}) + ) if task.host_id: command = f'umount -f {task.src_dir} && rm -rf {task.src_dir}' else: @@ -113,20 +117,31 @@ def _do_sync(rds, task, host): fp.write(host.pkey or AppSetting.get('private_key')) fp.flush() + flag = time.time() options = '-azv --progress' if task.host_id else '-rzv --progress' argument = f'{task.src_dir}/ {host.username}@{host.hostname}:{task.dst_dir}' command = f'rsync {options} -h -e "ssh -p {host.port} -o StrictHostKeyChecking=no -i {fp.name}" {argument}' task = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + message = b'' while True: - message = task.stdout.readline() - if not message: + output = task.stdout.read(1) + if not output: break - message = str_decode(message).rstrip('\r\n') - if 'rsync: command not found' in message: - data = '\r\n\x1b[31m检测到该主机未安装rsync,可通过批量执行/执行任务模块进行以下命令批量安装\x1b[0m' - data += '\r\nCentos/Redhat: yum install -y rsync' - data += '\r\nUbuntu/Debian: apt install -y rsync' - rds.publish(token, json.dumps({'key': host.id, 'data': data})) - break - rds.publish(token, json.dumps({'key': host.id, 'data': message + '\r\n'})) + if output in (b'\r', b'\n'): + message += b'\r\n' if output == b'\n' else b'\r' + message = str_decode(message) + if 'rsync: command not found' in message: + data = '\r\n\x1b[31m检测到该主机未安装rsync,可通过批量执行/执行任务模块进行以下命令批量安装\x1b[0m' + data += '\r\nCentos/Redhat: yum install -y rsync' + data += '\r\nUbuntu/Debian: apt install -y rsync' + rds.publish(token, json.dumps({'key': host.id, 'data': data})) + break + rds.publish(token, json.dumps({'key': host.id, 'data': message})) + message = b'' + else: + message += output + status = task.wait() + if status == 0: + human_time = human_seconds_time(time.time() - flag) + rds.publish(token, json.dumps({'key': host.id, 'data': f'\r\n\x1b[32m** 分发完成,总耗时:{human_time} **\x1b[0m'})) rds.publish(token, json.dumps({'key': host.id, 'status': task.wait()})) diff --git a/spug_api/libs/utils.py b/spug_api/libs/utils.py index 788b3ce..050d944 100644 --- a/spug_api/libs/utils.py +++ b/spug_api/libs/utils.py @@ -58,17 +58,20 @@ def parse_time(value): # 传两个时间得到一个时间差 -def human_diff_time(time1, time2): - time1 = parse_time(time1) - time2 = parse_time(time2) - delta = time1 - time2 if time1 > time2 else time2 - time1 - if delta.seconds < 60: - text = '%d秒' % delta.seconds - elif delta.seconds < 3600: - text = '%d分' % (delta.seconds / 60) - else: - text = '%d小时' % (delta.seconds / 3600) - return '%d天%s' % (delta.days, text) if delta.days else text +def human_seconds_time(seconds): + text = '' + if seconds >= 3600: + text += '%d小时' % (seconds / 3600) + seconds = seconds % 3600 + if seconds >= 60: + text += '%d分' % (seconds / 60) + seconds = seconds % 60 + if seconds > 0: + if text or isinstance(seconds, int): + text += '%.d秒' % seconds + else: + text += '%.1f秒' % seconds + return text # 字符串模版渲染