1#!/usr/bin/env python3 2import sys 3import argparse 4import configshell_fb 5from os import getuid 6from rpc.client import JSONRPCException 7from configshell_fb import ConfigShell, shell, ExecutionError 8from spdkcli import UIRoot 9import rpc.client 10from pyparsing import (alphanums, Optional, Suppress, Word, Regex, 11 removeQuotes, dblQuotedString, OneOrMore) 12 13 14def add_quotes_to_shell(spdk_shell): 15 command = shell.locatedExpr(Word(alphanums + '_'))('command') 16 value = dblQuotedString.addParseAction(removeQuotes) 17 value_word = Word(alphanums + r';,=_\+/.<>()~@:-%[]') 18 keyword = Word(alphanums + r'_\-') 19 kparam = shell.locatedExpr(keyword + Suppress('=') + 20 Optional(value | value_word, default=''))('kparams*') 21 pparam = shell.locatedExpr(value | value_word)('pparams*') 22 parameters = OneOrMore(kparam | pparam) 23 bookmark = Regex(r'@([A-Za-z0-9:_.]|-)+') 24 pathstd = Regex(r'([A-Za-z0-9:_.\[\]]|-)*' + '/' + r'([A-Za-z0-9:_.\[\]/]|-)*') \ 25 | '..' | '.' 26 path = shell.locatedExpr(bookmark | pathstd | '*')('path') 27 spdk_shell._parser = Optional(path) + Optional(command) + Optional(parameters) 28 29 30def main(): 31 """ 32 Start SPDK CLI 33 :return: 34 """ 35 spdk_shell = ConfigShell("~/.scripts") 36 spdk_shell.interactive = True 37 add_quotes_to_shell(spdk_shell) 38 39 parser = argparse.ArgumentParser(description="SPDK command line interface") 40 parser.add_argument("-s", dest="socket", help="RPC socket path", default="/var/tmp/spdk.sock") 41 parser.add_argument("-v", dest="verbose", help="Print request/response JSON for configuration calls", 42 default=False, action="store_true") 43 parser.add_argument("commands", metavar="command", type=str, nargs="*", default="", 44 help="commands to execute by SPDKCli as one-line command") 45 args = parser.parse_args() 46 47 try: 48 client = rpc.client.JSONRPCClient(args.socket) 49 except JSONRPCException as e: 50 spdk_shell.log.error("%s. SPDK not running?" % e) 51 sys.exit(1) 52 53 with client: 54 root_node = UIRoot(client, spdk_shell) 55 root_node.verbose = args.verbose 56 try: 57 root_node.refresh() 58 except BaseException: 59 pass 60 61 if len(args.commands) > 0: 62 try: 63 spdk_shell.interactive = False 64 spdk_shell.run_cmdline(" ".join(args.commands)) 65 except Exception as e: 66 sys.stderr.write("%s\n" % e) 67 sys.exit(1) 68 sys.exit(0) 69 70 spdk_shell.con.display("SPDK CLI v0.1") 71 spdk_shell.con.display("") 72 while not spdk_shell._exit: 73 try: 74 spdk_shell.run_interactive() 75 except (JSONRPCException, ExecutionError) as e: 76 spdk_shell.log.error("%s" % e) 77 except BrokenPipeError as e: 78 spdk_shell.log.error("Lost connection with SPDK: %s" % e) 79 break 80 81 82if __name__ == "__main__": 83 main() 84