From 6ccc5e86b8623416b4c1cbcec6e6fc8412e3f459 Mon Sep 17 00:00:00 2001 From: maning202007 Date: Tue, 15 Sep 2020 17:31:08 +0800 Subject: [PATCH] Add check_debugger_port to test if it is available for mindinsight Add debugger_port check function and move debugger start parameters to hook --- mindinsight/common/hook/debugger.py | 99 +++++++++++++++++++++++++++++ mindinsight/scripts/start.py | 61 ++++++------------ 2 files changed, 117 insertions(+), 43 deletions(-) create mode 100644 mindinsight/common/hook/debugger.py diff --git a/mindinsight/common/hook/debugger.py b/mindinsight/common/hook/debugger.py new file mode 100644 index 00000000..51d4f8c5 --- /dev/null +++ b/mindinsight/common/hook/debugger.py @@ -0,0 +1,99 @@ +# Copyright 2020 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""Debugger hook.""" + +import argparse + +from mindinsight.conf import settings +from mindinsight.utils.hook import BaseHook + + +def str2bool(string): + """Convert str to bool""" + if string.lower() == 'false': + return False + if string.lower() == 'true': + return True + raise ValueError + + +class EnableDebuggerAction(argparse.Action): + """Enable debugger action class definition.""" + + def __call__(self, parser, namespace, values, option_string=None): + """ + Inherited __call__ method from argparse.Action. + + Args: + parser (ArgumentParser): Passed-in argument parser. + namespace (Namespace): Namespace object to hold arguments. + values (object): Argument values with type depending on argument definition. + option_string (str): Optional string for specific argument name. Default: None. + """ + enable_debugger = values + setattr(namespace, self.dest, enable_debugger) + + +class PortAction(argparse.Action): + """Port action class definition.""" + + MIN_PORT = 1 + MAX_PORT = 65535 + + OPEN_PORT_LIMIT = 1024 + + def __call__(self, parser, namespace, values, option_string=None): + """ + Inherited __call__ method from argparse.Action. + + Args: + parser (ArgumentParser): Passed-in argument parser. + namespace (Namespace): Namespace object to hold arguments. + values (object): Argument values with type depending on argument definition. + option_string (str): Optional string for specific argument name. Default: None. + """ + port = values + if not self.MIN_PORT <= port <= self.MAX_PORT: + parser.error(f'{option_string} should be chosen from {self.MIN_PORT} to {self.MAX_PORT}') + + setattr(namespace, self.dest, port) + + +class Hook(BaseHook): + """Hook class definition.""" + + def register_startup_arguments(self, parser): + """ + Hook function to register startup arguments. + + Args: + parser (ArgumentParser): Specify parser to which arguments are added. + """ + parser.add_argument( + '--enable-debugger', + type=str2bool, + action=EnableDebuggerAction, + default=False, + help=""" + Enable debugger or not. + Default is False.""") + + parser.add_argument( + '--debugger-port', + type=int, + action=PortAction, + help=""" + Debugger port ranging from %s to %s. Default value is %s. + """ % (PortAction.MIN_PORT, PortAction.MAX_PORT, settings.DEBUGGER_PORT)) diff --git a/mindinsight/scripts/start.py b/mindinsight/scripts/start.py index ac843dc6..3fc0f900 100644 --- a/mindinsight/scripts/start.py +++ b/mindinsight/scripts/start.py @@ -18,6 +18,7 @@ import argparse import os import re import sys +import socket from importlib import import_module import psutil @@ -29,15 +30,6 @@ from mindinsight.utils.hook import HookUtils from mindinsight.utils.hook import init -def str2bool(string): - """Convert str to bool""" - if string.lower() == 'false': - return False - if string.lower() == 'true': - return True - raise ValueError - - class ConfigAction(argparse.Action): """Config action class definition.""" @@ -155,23 +147,6 @@ class UrlPathPrefixAction(argparse.Action): setattr(namespace, self.dest, prefix) -class EnableDebuggerAction(argparse.Action): - """SSL certificate action class definition.""" - - def __call__(self, parser, namespace, values, option_string=None): - """ - Inherited __call__ method from argparse.Action. - - Args: - parser (ArgumentParser): Passed-in argument parser. - namespace (Namespace): Namespace object to hold arguments. - values (object): Argument values with type depending on argument definition. - option_string (str): Optional string for specific argument name. Default: None. - """ - enable_debugger = values - setattr(namespace, self.dest, enable_debugger) - - class Command(BaseCommand): """ Start mindinsight service. @@ -212,14 +187,6 @@ class Command(BaseCommand): Custom port ranging from %s to %s. Default value is %s. """ % (PortAction.MIN_PORT, PortAction.MAX_PORT, settings.PORT)) - parser.add_argument( - '--debugger-port', - type=int, - action=PortAction, - help=""" - Debugger port ranging from %s to %s. Default value is %s. - """ % (PortAction.MIN_PORT, PortAction.MAX_PORT, settings.DEBUGGER_PORT)) - parser.add_argument( '--url-path-prefix', type=str, @@ -231,14 +198,6 @@ class Command(BaseCommand): dot or double dots. Default value is ''. """) - parser.add_argument( - '--enable-debugger', - type=str2bool, - action=EnableDebuggerAction, - default=False, - help=""" - Enable debugger or not. - Default is False.""") for hook in HookUtils.instance().hooks(): hook.register_startup_arguments(parser) @@ -269,6 +228,7 @@ class Command(BaseCommand): try: self.check_port() + self.check_debugger_port() except PortNotAvailableError as error: self.console.error(error.message) self.logfile.error(error.message) @@ -292,4 +252,19 @@ class Command(BaseCommand): if connection.status != 'LISTEN': continue if connection.laddr.port == settings.PORT: - raise PortNotAvailableError(f'Port {settings.PORT} is not available for MindInsight') + raise PortNotAvailableError(f'Port {settings.PORT} is no available for MindInsight') + + + def check_debugger_port(self): + """Check if the debugger_port is available""" + if not settings.ENABLE_DEBUGGER: + return + ip = settings.HOST + port = settings.DEBUGGER_PORT + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + s.connect((ip, int(port))) + s.shutdown(2) + raise PortNotAvailableError(f'Debugger-port {ip}:{port} is not available for MindInsight') + except socket.error: + return