]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/ceph_mgr_repl.py
import quincy beta 17.1.0
[ceph.git] / ceph / src / pybind / ceph_mgr_repl.py
1 #!/usr/bin/python3
2 # -*- mode:python -*-
3 # vim: ts=4 sw=4 smarttab expandtab
4
5 __all__ = ['ConsoleOptions', 'MgrModuleInterpreter']
6
7 import readline
8 import sys
9 from code import InteractiveConsole
10 from collections import namedtuple
11 from pathlib import Path
12
13 from ceph_argparse import json_command
14
15
16 ConsoleOptions = namedtuple('ConsoleOptions',
17 ['name', 'conffile', 'prefix', 'timeout'])
18
19
20 class MgrModuleInteractiveConsole(InteractiveConsole):
21 def __init__(self, rados, opt, filename="<console>"):
22 super().__init__(filename)
23 self.cmd_prefix = opt.prefix
24 self.timeout = opt.timeout
25 self.cluster = rados.Rados(name=opt.name,
26 conffile=opt.conffile)
27 self.cluster.connect(timeout=opt.timeout)
28
29 def _do_runsource(self, source):
30 ret, buf, s = json_command(self.cluster,
31 prefix=self.cmd_prefix,
32 target=('mon-mgr',),
33 inbuf=source.encode(),
34 timeout=self.timeout)
35 if ret == 0:
36 # TODO: better way to encode the outputs
37 sys.stdout.write(buf.decode())
38 sys.stderr.write(s)
39 else:
40 # needs more
41 self.write("the input is not complete")
42
43 def runsource(self, source, filename='<input>', symbol='single'):
44 try:
45 # just validate the syntax
46 code = self.compile(source, filename, symbol)
47 except (OverflowError, SyntaxError, ValueError):
48 # Case 1
49 self.showsyntaxerror(filename)
50 return False
51
52 if code is None:
53 # Case 2
54 return True
55
56 # Case 3
57 self._do_runsource(source)
58 return False
59
60 def runcode(self, code):
61 # code object cannot be pickled
62 raise NotImplementedError()
63
64
65 def show_env():
66 prog = Path(__file__).resolve()
67 ceph_dir = prog.parents[2]
68 python_path = ':'.join([f'{ceph_dir}/src/pybind',
69 f'{ceph_dir}/build/lib/cython_modules/lib.3',
70 f'{ceph_dir}/src/python-common',
71 '$PYTHONPATH'])
72 ld_library_path = ':'.join([f'{ceph_dir}/build/lib',
73 '$LD_LIBRARY_PATH'])
74 return f'''
75 $ export PYTHONPATH={python_path}
76 $ export LD_LIBRARY_PATH={ld_library_path}'''.strip('\n')
77
78
79 def main():
80 import argparse
81 try:
82 import rados
83 except ImportError:
84 print(f'''Unable to import rados python binding.
85 Please set the environment variables first:
86 {show_env()}''',
87 file=sys.stderr)
88 exit(1)
89
90 prog = Path(__file__).name
91 epilog = f'''Usage:
92 {prog} -c "print(mgr.release_name)"'''
93 parser = argparse.ArgumentParser(epilog=epilog)
94 parser.add_argument('--name', action='store',
95 default='client.admin',
96 help='user name for connecting to cluster')
97 parser.add_argument('--conffile', action='store',
98 default=rados.Rados.DEFAULT_CONF_FILES,
99 help='path to ceph.conf')
100 parser.add_argument('--prefix', action='store',
101 default='mgr self-test eval',
102 help='command prefix for eval the source')
103 parser.add_argument('--timeout', action='store',
104 type=int,
105 default=10,
106 help='timeout in seconds')
107 parser.add_argument('--show-env', action='store_true',
108 help='show instructions to set environment variables')
109 group = parser.add_mutually_exclusive_group()
110 group.add_argument('-c', action='store',
111 help='optional statement',
112 dest='command')
113 group.add_argument('script', nargs='?', type=argparse.FileType('r'))
114 args = parser.parse_args()
115 options = ConsoleOptions(name=args.name,
116 conffile=args.conffile,
117 prefix=args.prefix,
118 timeout=args.timeout)
119 console = MgrModuleInteractiveConsole(rados, options)
120 if args.show_env:
121 print(show_env())
122 elif args.command:
123 console.runsource(args.command)
124 elif args.script:
125 console.runsource(args.script.read())
126 else:
127 sys.ps1 = f'[{args.prefix}] >>> '
128 console.interact()
129
130
131 if __name__ == '__main__':
132 main()