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