xref: /spdk/scripts/spdkcli.py (revision 712a3f69d32632bf6c862f00200f7f437d3f7529)
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