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