diff --git a/bin/cc-cli b/bin/cc-cli index cd8025165b99f60547427ae86310907377904d7a..f2fc9179372f04b683a7715a708ef39b9f36986c 100755 --- a/bin/cc-cli +++ b/bin/cc-cli @@ -128,11 +128,13 @@ try: except BadArgument as e: printer.error("Bad Argument: %s"%str(e)) oparser.print_help() +except cliError as e: + printer.error(str(e)) except KeyboardInterrupt: exit(1) except Exception as e: if cccli.debug: - printer.fatal(str(e), exitcode=-1) + printer.fatal(str(e), quit=False) raise printer.warn("This is a not expected error, please report it!") printer.fatal(str(e)) diff --git a/cccli/cli.py b/cccli/cli.py index fc80e916e72276a7f24bed7ab1f23d2d13061c5c..6607a0bce8aaa31db202214d617015a7100c2595 100644 --- a/cccli/cli.py +++ b/cccli/cli.py @@ -12,9 +12,9 @@ import subprocess import shlex import StringIO -from cccli import version, debug +import cccli from cccli.command import Command, Alias -from cccli.printer import Printer +from cccli.printer import Printer, color from cccli.exception import * from sjrpc.client import SimpleRpcClient @@ -70,29 +70,37 @@ class Cli(object): def _auth(self): '''Handle server authentification''' self.printer.debug("Authenticating...") - if self.rpc.authentify(self.settings["login"], self.settings["pass"]): - self.printer.debug("Authenticated.") - else: - self.printer.fatal("Autentification failed!") + try: + self.rpc.authentify(self.settings["login"], self.settings["pass"]) + except Exception: + raise cliError("Autentification failed!") + self.printer.debug("Authenticated.") def _parse(self): '''Parse a line''' - prompt = "> " if self.interactive else "" + if self.interactive: + prompt = "%s%s>%s "%(color["lwhite"],self.settings["login"],color["reset"]) + else: + prompt = "" while True: try: argv = shlex.split(self.printer.getline(prompt), comments=True) - # alias subsitution - if argv[0] in self.alias: - argv[0] = self.alias[argv[0]] except ValueError as e: + print type(e) self.printer.error("Lexer: %s"%str(e)) continue + except KeyboardInterrupt: + self.printer.out("") + continue except EOFError: break except SystemExit: break - except KeyboardInterrupt: - self.printer.out("") + if len(argv) == 0: + continue + # alias subsitution + if argv[0] in self.alias: + argv[0] = self.alias[argv[0]] self._exec_command(argv) if self.interactive: self.printer.out("tcho!") @@ -121,12 +129,15 @@ class Cli(object): self.printer.error("command: %s."%str(e)) else: self.printer.error("No command: %s."%argv[0]) - except RpcError as e: - if debug: raise - self.printer.error("sjRPC: %s"%str(e)) + except cmdWarning as e: + self.printer.warn("%s: %s"%(argv[0], str(e))) + except cmdError as e: + self.printer.error("%s: %s"%(argv[0], str(e))) except Exception as e: - if debug: raise - self.printer.error("%s: %s."%(argv[0], str(e))) + if cccli.debug: + raise + self.printer.error(str(e)) + self.printer.warn("This is a not expected error, please report it!") class CliHandler(RpcHandler): '''Handle RPC incoming request''' @@ -134,16 +145,8 @@ class CliHandler(RpcHandler): @pure def get_tags(self, tags=()): if "version" in tags: - return { "version": version } + return { "version": cccli.version } @pure def quit(self, rpc=None): - self.printer.fatal("Disconnected from server!") - -class CliLexer(object): - - def __init__(self, fd): - self.fd = fd - - def get_next_token(self): - pass + Printer().fatal("Disconnected from server!") diff --git a/cccli/command.py b/cccli/command.py index 7cee18323a86aec50b8291e025e86fa660a29b7c..1aedffee01be8d397820c75909a8c0309172688f 100644 --- a/cccli/command.py +++ b/cccli/command.py @@ -164,7 +164,7 @@ class Command(object): def cmd_history(self, argv): '''Show history of commands''' if not self.cli.history: - raise Exception("History is disabled") + raise cmdError("History is not available") for l in self.cli.history: self.printer.out(l) cmd_history.usage = "history" @@ -196,10 +196,10 @@ class Command(object): self.printer.out("%s"%item["id"]) self.printer.out("Count: %s"%len(items)) if self.printer.ask("Are you sure to %s? (yes/NO) "%argv[0]) != "yes": - raise Exception("Aborted") + raise cmdWarning("Aborted") if len(items) > 5: if self.printer.ask("You request is on more than 5 objets. Are you really sure to %s its? (Yes, I am) "%argv[0]) != "Yes, I am": - raise Exception("Aborted") + raise cmdWarning("Aborted") self.cli.rpc[argv[0]](tql) diff --git a/cccli/exception.py b/cccli/exception.py index 4c5599712ceeb35fc94af2642df059f608926a93..446e39e69f7a5f52df72fcf9328873254ae431a4 100644 --- a/cccli/exception.py +++ b/cccli/exception.py @@ -6,14 +6,24 @@ CloudControl CLI Exceptions Module ''' ################################################################################ -class cliError(Exception): +class cliException(Exception): + pass + +class cliError(cliException): pass class BadCommand(cliError): pass -class BadArgument(cliError): +################################################################################ +class cmdException(cliException): + pass + +class BadArgument(cmdException): + pass + +class cmdWarning(cmdException): pass -class cliWarning(Exception): +class cmdError(cmdException): pass diff --git a/cccli/printer.py b/cccli/printer.py index 93b95f0cf29ca7c74513c15bdfe4cf7b66ae02e6..c7ffe699bd1b4e05b2815176460bd7217147bd64 100644 --- a/cccli/printer.py +++ b/cccli/printer.py @@ -62,12 +62,12 @@ class Printer(object): def err(self, message, fd=sys.stderr, nl=os.linesep): self.out(message, fd, nl) - def fatal(self, message, exitcode=42, fd=sys.stderr, nl=os.linesep): + def fatal(self, message, quit=True, fd=sys.stderr, nl=os.linesep): self.out("%sFatal%s: %s%s"%(color["lred"],color["red"],message, color["reset"]), fd, nl) - if exitcode >= 0: - os._exit(exitcode) + if quit: + os.kill(0, 15) def error(self, message, fd=sys.stderr, nl=os.linesep): self.out("%sError%s: %s%s"%(color["lred"],color["red"],message,color["reset"]), @@ -83,19 +83,26 @@ class Printer(object): if cccli.debug: self.out(message, fd, nl) - def getline(self, msg, history=True): - s = raw_input(msg) - if not history: + def getline(self, prompt, history=True): + try: + s = raw_input(prompt) + except EOFError: + raise + except KeyboardInterrupt: + raise + except: + raise cliError + if not history and s: self.history.removelast() return s - def getpass(self, msg): + def getpass(self, prompt): '''Ask for a password. No echo. Not in history''' - return getpass.getpass(msg) + return getpass.getpass(prompt) - def ask(self, msg): + def ask(self, prompt): '''Used to ask a question. Default answer not saved to history''' - return self.getline(msg, history=False) + return self.getline(prompt, history=False) class History(object): @@ -145,7 +152,7 @@ class History(object): def removelast(self): '''Remove last history line''' - self.readline.remove_history_item(self.cli.readline.get_current_history_length()) + self.readline.remove_history_item(self.readline.get_current_history_length()) def clear(self): '''Clear history'''