- add default auth structure
[plcapi.git] / Shell.py
1 #!/usr/bin/python
2 #
3 # Interactive shell for testing PLCAPI
4 #
5 # Mark Huang <mlhuang@cs.princeton.edu>
6 # Copyright (C) 2005 The Trustees of Princeton University
7 #
8 # $Id: Shell.py,v 1.1 2006/09/06 15:33:59 mlhuang Exp $
9 #
10
11 import os, sys
12 import traceback
13 import getopt
14 import pydoc
15
16 from PLC.API import PLCAPI
17 from PLC.Method import Method
18
19 # Defaults
20 config = "/etc/planetlab/plc_config"
21
22 def usage():
23     print "Usage: %s [OPTION]..." % sys.argv[0]
24     print "Options:"
25     print "     -f, --config=FILE       PLC configuration file (default: %s)" % config
26     print "     -h, --help              This message"
27     sys.exit(1)
28
29 # Get options
30 try:
31     (opts, argv) = getopt.getopt(sys.argv[1:], "f:h", ["config=", "help"])
32 except getopt.GetoptError, err:
33     print "Error: " + err.msg
34     usage()
35
36 for (opt, optval) in opts:
37     if opt == "-f" or opt == "--config":
38         config = optval
39     elif opt == "-h" or opt == "--help":
40         usage()
41
42 api = PLCAPI(config)
43
44 auth = {'AuthMethod': "capability",
45         'Username': api.config.PLC_API_MAINTENANCE_USER,
46         'AuthString': api.config.PLC_API_MAINTENANCE_PASSWORD,
47         'Role': "admin"}
48
49 class Dummy:
50     """
51     Dummy class to support tab completion of API methods with dots in
52     their names (e.g., system.listMethods).
53     """
54     pass
55         
56 # Define all methods in the global namespace to support tab completion
57 for method in api.methods:
58     paths = method.split(".")
59     if len(paths) > 1:
60         first = paths.pop(0)
61         if first not in globals():
62             globals()[first] = Dummy()
63         obj = globals()[first]
64         for path in paths:
65             if not hasattr(obj, path):
66                 if path == paths[-1]:
67                     setattr(obj, path, api.callable(method))
68                 else:
69                     setattr(obj, path, Dummy())
70             obj = getattr(obj, path)
71     else:
72         globals()[method] = api.callable(method)
73
74 pyhelp = help
75 def help(thing):
76     """
77     Override builtin help() function to support calling help(method).
78     """
79
80     if isinstance(thing, Method):
81         return pydoc.pager(thing.help())
82     else:
83         return pyhelp(thing)
84
85 # If a file is specified
86 if argv:
87     execfile(argv[0])
88     sys.exit(0)
89
90 # Otherwise, create an interactive shell environment
91
92 print "PlanetLab Central Direct API Access"
93 prompt = ""
94 print 'Type "system.listMethods()" or "help(method)" for more information.'
95
96 # Readline and tab completion support
97 import atexit
98 import readline
99 import rlcompleter
100
101 # Load command history
102 history_path = os.path.join(os.environ["HOME"], ".plcapi_history")
103 try:
104     file(history_path, 'a').close()
105     readline.read_history_file(history_path)
106     atexit.register(readline.write_history_file, history_path)
107 except IOError:
108     pass
109
110 # Enable tab completion
111 readline.parse_and_bind("tab: complete")
112
113 try:
114     while True:
115         command = ""
116         while True:
117             # Get line
118             try:
119                 if command == "":
120                     sep = ">>> "
121                 else:
122                     sep = "... "
123                 line = raw_input(prompt + sep)
124             # Ctrl-C
125             except KeyboardInterrupt:
126                 command = ""
127                 print
128                 break
129
130             # Build up multi-line command
131             command += line
132
133             # Blank line or first line does not end in :
134             if line == "" or (command == line and line[-1] != ':'):
135                 break
136
137             command += os.linesep
138
139         # Blank line
140         if command == "":
141             continue
142         # Quit
143         elif command in ["q", "quit", "exit"]:
144             break
145
146         try:
147             try:
148                 # Try evaluating as an expression and printing the result
149                 result = eval(command)
150                 if result is not None:
151                     print result
152             except:
153                 # Fall back to executing as a statement
154                 exec command
155         except Exception, err:
156             traceback.print_exc()
157
158 except EOFError:
159     print
160     pass