diff --git a/Dockerfile b/Dockerfile index 3742a47f5..f7a9c3513 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ COPY ./requirements /tmp/requirements RUN yum -y install epel-release openldap-clients telnet && cd /tmp/requirements && \ yum -y install $(cat rpm_requirements.txt) -RUN cd /tmp/requirements && pip install -r requirements.txt +RUN cd /tmp/requirements && pip install -i https://mirrors.aliyun.com/pypi/simple/ -r requirements.txt || pip install -r requirements.txt COPY . /opt/jumpserver RUN echo > config.yml diff --git a/apps/assets/templates/assets/asset_list.html b/apps/assets/templates/assets/asset_list.html index c560c8e6b..edd82cf0f 100644 --- a/apps/assets/templates/assets/asset_list.html +++ b/apps/assets/templates/assets/asset_list.html @@ -311,6 +311,7 @@ function onRename(event, treeId, treeNode, isCancel){ function onSelected(event, treeNode) { current_node = treeNode; current_node_id = treeNode.meta.node.id; + zTree.expandNode(current_node, true); var url = asset_table.ajax.url(); url = setUrlParam(url, "node_id", current_node_id); url = setUrlParam(url, "show_current_asset", getCookie('show_current_asset')); diff --git a/apps/common/api.py b/apps/common/api.py index 98924930f..6a2017cd4 100644 --- a/apps/common/api.py +++ b/apps/common/api.py @@ -206,6 +206,14 @@ class LogTailApi(generics.RetrieveAPIView): def get_log_path(self): raise NotImplementedError() + def filter_line(self, line): + """ + 过滤行,可能替换一些信息 + :param line: + :return: + """ + return line + def get(self, request, *args, **kwargs): mark = request.query_params.get("mark") or str(uuid.uuid4()) log_path = self.get_log_path() @@ -224,9 +232,16 @@ class LogTailApi(generics.RetrieveAPIView): offset = cache.get(mark, 0) f.seek(offset) data = f.read(self.buff_size).replace('\n', '\r\n') + mark = str(uuid.uuid4()) cache.set(mark, f.tell(), 5) if data == '' and self.is_file_finish_write(): self.end = True - return Response({"data": data, 'end': self.end, 'mark': mark}) + _data = '' + for line in data.split('\r\n'): + new_line = self.filter_line(line) + if line == '': + continue + _data += new_line + '\r\n' + return Response({"data": _data, 'end': self.end, 'mark': mark}) diff --git a/apps/jumpserver/settings.py b/apps/jumpserver/settings.py index 019bf5748..e5f555e65 100644 --- a/apps/jumpserver/settings.py +++ b/apps/jumpserver/settings.py @@ -218,10 +218,9 @@ LOGGING = { 'file': { 'encoding': 'utf8', 'level': 'DEBUG', - 'class': 'logging.handlers.TimedRotatingFileHandler', - 'when': "D", - 'interval': 1, - "backupCount": 7, + 'class': 'logging.handlers.RotatingFileHandler', + 'maxBytes': 1024*1024*100, + 'backupCount': 7, 'formatter': 'main', 'filename': JUMPSERVER_LOG_FILE, }, diff --git a/apps/ops/api/celery.py b/apps/ops/api/celery.py index d2053f9cb..caffff601 100644 --- a/apps/ops/api/celery.py +++ b/apps/ops/api/celery.py @@ -2,6 +2,8 @@ # import os +import re + from celery.result import AsyncResult from rest_framework import generics @@ -19,12 +21,18 @@ class CeleryTaskLogApi(LogTailApi): permission_classes = (IsValidUser,) task = None task_id = '' + pattern = re.compile(r'Task .* succeeded in \d+\.\d+s.*') def get(self, request, *args, **kwargs): self.task_id = str(kwargs.get('pk')) self.task = AsyncResult(self.task_id) return super().get(request, *args, **kwargs) + def filter_line(self, line): + if self.pattern.match(line): + line = self.pattern.sub(line, '') + return line + def get_log_path(self): new_path = get_celery_task_log_path(self.task_id) if new_path and os.path.isfile(new_path): diff --git a/apps/ops/api/command.py b/apps/ops/api/command.py index 9d83d1464..29f1b742c 100644 --- a/apps/ops/api/command.py +++ b/apps/ops/api/command.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # from rest_framework import viewsets +from django.db import transaction from common.permissions import IsValidUser from ..models import CommandExecution @@ -11,7 +12,6 @@ from ..tasks import run_command_execution class CommandExecutionViewSet(viewsets.ModelViewSet): serializer_class = CommandExecutionSerializer permission_classes = (IsValidUser,) - task = None def get_queryset(self): return CommandExecution.objects.filter( @@ -22,6 +22,6 @@ class CommandExecutionViewSet(viewsets.ModelViewSet): instance = serializer.save() instance.user = self.request.user instance.save() - run_command_execution.apply_async( + transaction.on_commit(lambda: run_command_execution.apply_async( args=(instance.id,), task_id=str(instance.id) - ) + )) diff --git a/apps/ops/tasks.py b/apps/ops/tasks.py index f50f17946..07a86a3be 100644 --- a/apps/ops/tasks.py +++ b/apps/ops/tasks.py @@ -41,7 +41,10 @@ def run_ansible_task(tid, callback=None, **kwargs): @shared_task def run_command_execution(cid, **kwargs): execution = get_object_or_none(CommandExecution, id=cid) - return execution.run() + if execution: + execution.run() + else: + logger.error("Not found the execution id: {}".format(cid)) @shared_task diff --git a/apps/ops/templates/ops/command_execution_create.html b/apps/ops/templates/ops/command_execution_create.html index 17a01e5c4..178c1ad7a 100644 --- a/apps/ops/templates/ops/command_execution_create.html +++ b/apps/ops/templates/ops/command_execution_create.html @@ -170,8 +170,8 @@ function initResultTerminal() { term = new Terminal({ cursorBlink: false, screenKeys: false, - fontFamily: '"Monaco", "Consolas", "monospace"', - fontSize: 13, + fontFamily: '"Consolas", "monospace"', + fontSize: 14, rightClickSelectsWord: true, disableStdin: true, theme: { diff --git a/apps/terminal/models.py b/apps/terminal/models.py index ac912e82a..32166bf9f 100644 --- a/apps/terminal/models.py +++ b/apps/terminal/models.py @@ -168,7 +168,7 @@ class Session(OrgModelMixin): upload_to = 'replay' ACTIVE_CACHE_KEY_PREFIX = 'SESSION_ACTIVE_{}' - def get_rel_replay_path(self, version=2): + def get_rel_replay_path(self, version=3): """ 获取session日志的文件路径 :param version: 原来后缀是 .gz,为了统一新版本改为 .replay.gz @@ -177,10 +177,13 @@ class Session(OrgModelMixin): suffix = '.replay.gz' if version == 1: suffix = '.gz' - date = self.date_start.strftime('%Y-%m-%d') + if version <= 2: + date = self.date_start.strftime('%Y-%m-%d') + else: + date = self.date_start.utcnow().strftime('%Y-%m-%d') return os.path.join(date, str(self.id) + suffix) - def get_local_path(self, version=2): + def get_local_path(self, version=3): rel_path = self.get_rel_replay_path(version=version) if version == 2: local_path = os.path.join(self.upload_to, rel_path) diff --git a/jms b/jms index afd1b2552..0138df26a 100755 --- a/jms +++ b/jms @@ -176,7 +176,7 @@ def start_celery(): cmd = [ 'celery', 'worker', '-A', 'ops', - '-l', LOG_LEVEL.lower(), + '-l', 'INFO', '--pidfile', pid_file, '--autoscale', '20,4', ] diff --git a/requirements/requirements.txt b/requirements/requirements.txt index c956bc9d4..5002762c9 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -14,7 +14,7 @@ coreapi==2.3.3 coreschema==0.0.4 cryptography==2.3.1 decorator==4.1.2 -Django==2.1 +Django==2.1.7 django-auth-ldap==1.7.0 django-bootstrap3==9.1.0 django-celery-beat==1.1.1