xref: /spdk/scripts/spdkcli.py (revision 17538bdc67021ec097536c683124234db1aac374)
1b96f97cfSPawel Wodkowski#!/usr/bin/env python3
2*17538bdcSpaul luse#  SPDX-License-Identifier: BSD-3-Clause
3*17538bdcSpaul luse#  Copyright (C) 2018 Intel Corporation
4*17538bdcSpaul luse#  All rights reserved.
5*17538bdcSpaul luse#
6*17538bdcSpaul luse
77610bc38SKonrad Sztyberimport os
883795a16SKarol Lateckiimport sys
983795a16SKarol Lateckiimport argparse
10223810e9SPawel Kaminskifrom configshell_fb import ConfigShell, shell, ExecutionError
11ad06d03aSKarol Lateckifrom pyparsing import (alphanums, Optional, Suppress, Word, Regex,
12ad06d03aSKarol Latecki                       removeQuotes, dblQuotedString, OneOrMore)
137610bc38SKonrad Sztyber
147610bc38SKonrad Sztybersys.path.append(os.path.dirname(__file__) + '/../python')
157610bc38SKonrad Sztyber
167610bc38SKonrad Sztyberfrom spdk.rpc.client import JSONRPCException, JSONRPCClient  # noqa
177610bc38SKonrad Sztyberfrom spdk.spdkcli import UIRoot  # noqa
18ad06d03aSKarol Latecki
19ad06d03aSKarol Latecki
20ad06d03aSKarol Lateckidef add_quotes_to_shell(spdk_shell):
21ad06d03aSKarol Latecki    command = shell.locatedExpr(Word(alphanums + '_'))('command')
22ad06d03aSKarol Latecki    value = dblQuotedString.addParseAction(removeQuotes)
230c93fc73SJames Bergsten    value_word = Word(alphanums + r';,=_\+/.<>()~@:-%[]')
240c93fc73SJames Bergsten    keyword = Word(alphanums + r'_\-')
25ad06d03aSKarol Latecki    kparam = shell.locatedExpr(keyword + Suppress('=') +
26ad06d03aSKarol Latecki                               Optional(value | value_word, default=''))('kparams*')
27ad06d03aSKarol Latecki    pparam = shell.locatedExpr(value | value_word)('pparams*')
28ad06d03aSKarol Latecki    parameters = OneOrMore(kparam | pparam)
290c93fc73SJames Bergsten    bookmark = Regex(r'@([A-Za-z0-9:_.]|-)+')
300c93fc73SJames Bergsten    pathstd = Regex(r'([A-Za-z0-9:_.\[\]]|-)*' + '/' + r'([A-Za-z0-9:_.\[\]/]|-)*') \
31ad06d03aSKarol Latecki        | '..' | '.'
32ad06d03aSKarol Latecki    path = shell.locatedExpr(bookmark | pathstd | '*')('path')
33ad06d03aSKarol Latecki    spdk_shell._parser = Optional(path) + Optional(command) + Optional(parameters)
3483795a16SKarol Latecki
3583795a16SKarol Latecki
3683795a16SKarol Lateckidef main():
3783795a16SKarol Latecki    """
3883795a16SKarol Latecki    Start SPDK CLI
3983795a16SKarol Latecki    :return:
4083795a16SKarol Latecki    """
41ad06d03aSKarol Latecki    spdk_shell = ConfigShell("~/.scripts")
426a35d0fdSPawel Kaminski    spdk_shell.interactive = True
43ad06d03aSKarol Latecki    add_quotes_to_shell(spdk_shell)
4483795a16SKarol Latecki
4583795a16SKarol Latecki    parser = argparse.ArgumentParser(description="SPDK command line interface")
46390542a3SMike Carlin    parser.add_argument('-s', dest='server_addr',
47390542a3SMike Carlin                        help='RPC domain socket path or IP address', default='/var/tmp/spdk.sock')
48390542a3SMike Carlin    parser.add_argument('-p', dest='port',
49390542a3SMike Carlin                        help='RPC port number (if server_addr is IP address)',
50390542a3SMike Carlin                        default=None, type=int)
51bfae2c7eSKarol Latecki    parser.add_argument("-v", dest="verbose", help="Print request/response JSON for configuration calls",
52bfae2c7eSKarol Latecki                        default=False, action="store_true")
5383795a16SKarol Latecki    parser.add_argument("commands", metavar="command", type=str, nargs="*", default="",
5483795a16SKarol Latecki                        help="commands to execute by SPDKCli as one-line command")
5583795a16SKarol Latecki    args = parser.parse_args()
5683795a16SKarol Latecki
576ef78fe6SVitaliy Mysak    try:
582f05fbb6SKarol Latecki        client = JSONRPCClient(args.server_addr, port=args.port)
596ef78fe6SVitaliy Mysak    except JSONRPCException as e:
606ef78fe6SVitaliy Mysak        spdk_shell.log.error("%s. SPDK not running?" % e)
616ef78fe6SVitaliy Mysak        sys.exit(1)
626ef78fe6SVitaliy Mysak
636ef78fe6SVitaliy Mysak    with client:
645c6ca5b6SPawel Wodkowski        root_node = UIRoot(client, spdk_shell)
65bfae2c7eSKarol Latecki        root_node.verbose = args.verbose
6683795a16SKarol Latecki        try:
6783795a16SKarol Latecki            root_node.refresh()
68b7322649SJohn Meneghini        except BaseException:
6983795a16SKarol Latecki            pass
7083795a16SKarol Latecki
712f05fbb6SKarol Latecki        if args.commands:
72223810e9SPawel Kaminski            try:
736a35d0fdSPawel Kaminski                spdk_shell.interactive = False
74ad06d03aSKarol Latecki                spdk_shell.run_cmdline(" ".join(args.commands))
75223810e9SPawel Kaminski            except Exception as e:
76223810e9SPawel Kaminski                sys.stderr.write("%s\n" % e)
77223810e9SPawel Kaminski                sys.exit(1)
7883795a16SKarol Latecki            sys.exit(0)
7983795a16SKarol Latecki
80ad06d03aSKarol Latecki        spdk_shell.con.display("SPDK CLI v0.1")
81ad06d03aSKarol Latecki        spdk_shell.con.display("")
822f05fbb6SKarol Latecki
838c883b97Syidong0635        while not spdk_shell._exit:
84223810e9SPawel Kaminski            try:
85ad06d03aSKarol Latecki                spdk_shell.run_interactive()
8653e25260SPawel Kaminski            except (JSONRPCException, ExecutionError) as e:
87223810e9SPawel Kaminski                spdk_shell.log.error("%s" % e)
889fd7f219SVitaliy Mysak            except BrokenPipeError as e:
899fd7f219SVitaliy Mysak                spdk_shell.log.error("Lost connection with SPDK: %s" % e)
9083795a16SKarol Latecki
9183795a16SKarol Latecki
9283795a16SKarol Lateckiif __name__ == "__main__":
9383795a16SKarol Latecki    main()
94