From e481031059886ac29a6b2d95dc89b9578c427345 Mon Sep 17 00:00:00 2001 From: divisor Date: Thu, 20 Sep 2018 18:19:29 +0200 Subject: [PATCH] eva shell --- bin/eva-shell | 160 ++++++++++++++++++++++++++++++++++++++++++ lib/eva/client/cli.py | 27 +++++-- 2 files changed, 180 insertions(+), 7 deletions(-) create mode 100755 bin/eva-shell diff --git a/bin/eva-shell b/bin/eva-shell new file mode 100755 index 000000000..ed91ec6ad --- /dev/null +++ b/bin/eva-shell @@ -0,0 +1,160 @@ +#!/usr/bin/env python3 +# PYTHON_ARGCOMPLETE_OK + +__author__ = "Altertech Group, https://www.altertech.com/" +__copyright__ = "Copyright (C) 2012-2018 Altertech Group" +__license__ = "https://www.eva-ics.com/license" +__version__ = "3.1.0" + +import sys +sys.argv = [sys.argv[0]] + ['-I'] +import os + +dir_lib = os.path.dirname(os.path.realpath(__file__)) + '/../lib' +dir_etc = os.path.dirname(os.path.realpath(__file__)) + '/../etc' +dir_sbin = os.path.dirname(os.path.realpath(__file__)) + '/../sbin' +dir_bin = os.path.dirname(os.path.realpath(__file__)) + '/../bin' +sys.path.append(dir_lib) + +import eva.core +from eva.client.cli import GenericCLI + + +class ManagementCLI(GenericCLI): + + def add_functions(self): + super().add_functions() + self.process_configuration() + self.add_manager_common_functions() + self.add_manager_control_functions() + self.add_management_shells() + + def process_configuration(self): + self.products_configured = [] + for f in ['uc', 'lm', 'sfa']: + if os.path.isfile('{}/{}.ini'.format( + dir_etc, f)) and os.path.isfile('{}/{}_apikeys.ini'.format( + dir_etc, f)): + self.products_configured.append(f) + + def add_manager_control_functions(self): + if not self.products_configured: + return + ap_start = self.sp.add_parser('start', help='Start controller(s)') + ap_start.add_argument( + 'p', + metavar='CONTROLLER', + choices=self.products_configured, + nargs='?') + ap_stop = self.sp.add_parser('stop', help='Stop controller(s)') + ap_stop.add_argument( + 'p', + metavar='CONTROLLER', + choices=self.products_configured, + nargs='?') + ap_restart = self.sp.add_parser('restart', help='Stop controller(s)') + ap_restart.add_argument( + 'p', + metavar='CONTROLLER', + choices=self.products_configured, + nargs='?') + + def add_manager_common_functions(self): + ap_version = self.sp.add_parser( + 'version', help='Display version and build') + ap_shell = self.sp.add_parser('sh', help='Execute system shell') + ap_top = self.sp.add_parser('top', help='Execute top command') + + def add_management_shells(self): + for p in self.products_configured: + ap = self.sp.add_parser(p, help='{} shell'.format(p.upper())) + self.api_functions[p] = getattr(self, '{}_shell'.format(p)) + + def exec_control_script(self, product, command): + if product is None: script = 'eva-control' + else: script = '%s-control' % product + os.system('{}/{} {}'.format(dir_sbin, script, command)) + + def uc_shell(self, params): + if not self.start_shell('uc'): return self.local_func_result_failed + return self.local_func_result_empty + + def lm_shell(self, params): + if not self.start_shell('lm'): return self.local_func_result_failed + return self.local_func_result_empty + + def sfa_shell(self, params): + if not self.start_shell('sfa'): return self.local_func_result_failed + return self.local_func_result_empty + + def start_shell(self, p): + try: + c = open('{}/{}-cmd'.format(dir_bin, p)).read() + c = """import sys +import eva.client.cli +eva.client.cli.say_bye = False +sys.argv = ['{}/{}-cmd', '-I'] + +""".format(dir_bin, p) + c + try: + exec(c) + except SystemExit: + self.reset_argcomplete() + return True + except: + self.reset_argcomplete() + return False + self.reset_argcomplete() + return True + + def start_controller(self, params): + c = params['p'] + if c is not None and c not in self.products_configured: + return self.local_func_result_failed + self.exec_control_script(c, 'start') + return self.local_func_result_ok + + def stop_controller(self, params): + c = params['p'] + if c is not None and c not in self.products_configured: + return self.local_func_result_failed + self.exec_control_script(c, 'stop') + return self.local_func_result_ok + + def restart_controller(self, params): + c = params['p'] + if c is not None and c not in self.products_configured: + return self.local_func_result_failed + self.exec_control_script(c, 'restart') + return self.local_func_result_ok + + def print_version(self, params): + with os.popen('{}/eva-tinyapi -V; {}/eva-tinyapi -B'.format( + dir_sbin, dir_sbin)) as p: + data = p.readlines() + if len(data) != 2: + return self.local_func_result_failed + result = {'version': data[0].strip(), 'build': data[1].strip()} + return 0, result + + +_me = 'EVA ICS Management CLI version %s' % (__version__) + +cli = ManagementCLI('eva', _me, remote_api=False) + +_api_functions = { + 'start': cli.start_controller, + 'stop': cli.stop_controller, + 'restart': cli.restart_controller, + 'version': cli.print_version +} + +eva.core.set_product('eva-cmd', '-1') +cli.ap.prog = 'eva-cmd' +# cli.arg_sections += ['subscribe'] +cli.set_api_functions(_api_functions) +# cli.set_pd_cols(_pd_cols) +# cli.set_pd_idx(_pd_idx) +# cli.set_fancy_tabsp(_fancy_tabsp) +code = cli.run() +sys.exit(code) diff --git a/lib/eva/client/cli.py b/lib/eva/client/cli.py index 465460237..e7ae4b04c 100644 --- a/lib/eva/client/cli.py +++ b/lib/eva/client/cli.py @@ -20,6 +20,8 @@ from eva.client import apiclient from pygments import highlight, lexers, formatters +say_bye = True + class GenericCLI(object): @@ -45,6 +47,7 @@ def __init__(self, product, name, prog=None, remote_api=True): self.local_func_result_failed = (apiclient.result_func_failed, { 'result': 'ERROR' }) + self.local_func_result_empty = (apiclient.result_ok, '') if remote_api: self.always_print = ['cmd'] self.common_api_functions = { @@ -159,6 +162,7 @@ def print_interactive_help(self): print('sh: start system shell') print('top: display system processes') print('w: display uptime and who is online') + print('date: display system date and time') print() print('or command to execute') print() @@ -245,6 +249,13 @@ def load_argcomplete(self): except: pass + def reset_argcomplete(self): + if self.argcomplete: + completer = self.argcomplete.CompletionFinder(self.ap) + readline.set_completer_delims("") + readline.set_completer(completer.rl_complete) + readline.parse_and_bind("tab: complete") + def print_err(self, s): print(self.colored(s, color='red', attrs=[])) @@ -711,11 +722,7 @@ def run(self): return self.do_run() else: # interactive mode - if self.argcomplete: - completer = self.argcomplete.CompletionFinder(self.ap) - readline.set_completer_delims("") - readline.set_completer(completer.rl_complete) - readline.parse_and_bind("tab: complete") + self.reset_argcomplete() while True: d = None while not d: @@ -723,12 +730,12 @@ def run(self): d = shlex.split(input(self.get_prompt())) except EOFError: print() - print('Bye') + if say_bye: print('Bye') return 0 except: self.print_err('parse error') if d[0] in ['q', 'quit', 'exit', 'bye']: - print('Bye') + if say_bye: print('Bye') return 0 elif d[0] == 'a' and self.remote_api: print('API uri: %s' % (self.apiuri @@ -791,6 +798,12 @@ def run(self): os.system('w') except: self.print_err('Failed to run system "w" command') + elif d[0] == 'date': + try: + os.system('date') + except: + self.print_err( + 'Failed to run system "date command') elif d[0] == 'sh': print('Executing system shell') shell = os.environ.get('SHELL')