- fix getpass() reference
[plcapi.git] / plcsh
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: plcsh,v 1.3 2007/01/11 20:45:29 mlhuang Exp $
9 #
10
11 import os
12 import sys
13 from optparse import OptionParser
14 from getpass import getpass
15 from traceback import print_exc
16
17 sys.path.append(os.path.dirname(os.path.realpath(sys.argv[0])))
18 from PLC.Shell import Shell
19
20 parser = OptionParser(add_help_option = False)
21 parser.add_option("-f", "--config", help = "PLC configuration file")
22 parser.add_option("-h", "--url", help = "API URL")
23 parser.add_option("-c", "--cacert", help = "API SSL certificate")
24 parser.add_option("-m", "--method", help = "API authentication method")
25 parser.add_option("-u", "--user", help = "API user name")
26 parser.add_option("-p", "--password", help = "API password")
27 parser.add_option("-r", "--role", help = "API role")
28 parser.add_option("-x", "--xmlrpc", action = "store_true", default = False, help = "Use XML-RPC interface")
29 parser.add_option("--help", action = "help", help = "show this help message and exit")
30 (options, args) = parser.parse_args()
31
32 # If user is specified but password is not
33 if options.user is not None and options.password is None:
34     try:
35         options.password = getpass()
36     except (EOFError, KeyboardInterrupt):
37         print
38         sys.exit(0)
39
40 # Initialize a single global instance (scripts may re-initialize
41 # this instance and/or create additional instances).
42 try:
43     shell = Shell(globals = globals(),
44                   config = options.config,
45                   url = options.url, xmlrpc = options.xmlrpc, cacert = options.cacert,
46                   method = options.method, role = options.role,
47                   user = options.user, password = options.password)
48     # Register a few more globals for backward compatibility
49     auth = shell.auth
50     api = shell.api
51     config = shell.config
52 except Exception, err:
53     print "Error:", err
54     print
55     parser.print_help()
56     sys.exit(1)
57
58 # If called by a script
59 if len(sys.argv) > 1 and os.path.exists(sys.argv[1]):
60     # Pop us off the argument stack
61     sys.argv.pop(0)
62     execfile(sys.argv[0])
63
64 # Otherwise, run an interactive shell environment
65 else:
66     if shell.server is None:
67         print "PlanetLab Central Direct API Access"
68         prompt = ""
69     elif shell.auth['AuthMethod'] == "anonymous":
70         prompt = "[anonymous]"
71         print "Connected anonymously"
72     else:
73         prompt = "[%s]" % shell.auth['Username']
74         print "%s connected using %s authentication" % \
75               (shell.auth['Username'], shell.auth['AuthMethod'])
76
77     # Readline and tab completion support
78     import atexit
79     import readline
80     import rlcompleter
81
82     print 'Type "system.listMethods()" or "help(method)" for more information.'
83     # Load command history
84     history_path = os.path.join(os.environ["HOME"], ".plcapi_history")
85     try:
86         file(history_path, 'a').close()
87         readline.read_history_file(history_path)
88         atexit.register(readline.write_history_file, history_path)
89     except IOError:
90         pass
91
92     # Enable tab completion
93     readline.parse_and_bind("tab: complete")
94
95     try:
96         while True:
97             command = ""
98             while True:
99                 # Get line
100                 try:
101                     if command == "":
102                         sep = ">>> "
103                     else:
104                         sep = "... "
105                     line = raw_input(prompt + sep)
106                 # Ctrl-C
107                 except KeyboardInterrupt:
108                     command = ""
109                     print
110                     break
111
112                 # Build up multi-line command
113                 command += line
114
115                 # Blank line or first line does not end in :
116                 if line == "" or (command == line and line[-1] != ':'):
117                     break
118
119                 command += os.linesep
120
121             # Blank line
122             if command == "":
123                 continue
124             # Quit
125             elif command in ["q", "quit", "exit"]:
126                 break
127
128             try:
129                 try:
130                     # Try evaluating as an expression and printing the result
131                     result = eval(command)
132                     if result is not None:
133                         print result
134                 except SyntaxError:
135                     # Fall back to executing as a statement
136                     exec command
137             except Exception, err:
138                 print_exc()
139
140     except EOFError:
141         print
142         pass