3 # Interactive shell for testing PLCAPI
5 # Mark Huang <mlhuang@cs.princeton.edu>
6 # Copyright (C) 2005 The Trustees of Princeton University
8 # $Id: plcsh,v 1.4 2007/01/17 22:14:38 mlhuang Exp $
13 from socket import gethostname
14 from optparse import OptionParser
15 from getpass import getpass
16 from traceback import print_exc
18 sys.path.append(os.path.dirname(os.path.realpath(sys.argv[0])))
19 from PLC.Shell import Shell
21 parser = OptionParser(add_help_option = False)
22 parser.add_option("-f", "--config", help = "PLC configuration file")
23 parser.add_option("-h", "--url", help = "API URL")
24 parser.add_option("-c", "--cacert", help = "API SSL certificate")
25 parser.add_option("-m", "--method", help = "API authentication method")
26 parser.add_option("-s", "--session", help = "API session key")
27 parser.add_option("-u", "--user", help = "API user name")
28 parser.add_option("-p", "--password", help = "API password")
29 parser.add_option("-r", "--role", help = "API role")
30 parser.add_option("-x", "--xmlrpc", action = "store_true", default = False, help = "Use XML-RPC interface")
31 parser.add_option("--help", action = "help", help = "show this help message and exit")
32 (options, args) = parser.parse_args()
34 # If user is specified but password is not
35 if options.user is not None and options.password is None:
37 options.password = getpass()
38 except (EOFError, KeyboardInterrupt):
42 # Initialize a single global instance (scripts may re-initialize
43 # this instance and/or create additional instances).
45 shell = Shell(globals = globals(),
46 config = options.config,
47 url = options.url, xmlrpc = options.xmlrpc, cacert = options.cacert,
48 method = options.method, role = options.role,
49 user = options.user, password = options.password,
50 session = options.session)
51 # Register a few more globals for backward compatibility
55 except Exception, err:
61 # If called by a script
62 if len(sys.argv) > 1 and os.path.exists(sys.argv[1]):
63 # Pop us off the argument stack
67 # Otherwise, run an interactive shell environment
69 if shell.server is None:
70 print "PlanetLab Central Direct API Access"
72 elif shell.auth['AuthMethod'] == "anonymous":
73 prompt = "[anonymous]"
74 print "Connected anonymously"
75 elif shell.auth['AuthMethod'] == "session":
76 # XXX No way to tell node and user sessions apart from the
77 # client point of view.
78 prompt = "[%s]" % gethostname()
79 print "%s connected using session authentication" % gethostname()
81 prompt = "[%s]" % shell.auth['Username']
82 print "%s connected using %s authentication" % \
83 (shell.auth['Username'], shell.auth['AuthMethod'])
85 # Readline and tab completion support
90 print 'Type "system.listMethods()" or "help(method)" for more information.'
91 # Load command history
92 history_path = os.path.join(os.environ["HOME"], ".plcapi_history")
94 file(history_path, 'a').close()
95 readline.read_history_file(history_path)
96 atexit.register(readline.write_history_file, history_path)
100 # Enable tab completion
101 readline.parse_and_bind("tab: complete")
113 line = raw_input(prompt + sep)
115 except KeyboardInterrupt:
120 # Build up multi-line command
123 # Blank line or first line does not end in :
124 if line == "" or (command == line and line[-1] != ':'):
127 command += os.linesep
133 elif command in ["q", "quit", "exit"]:
138 # Try evaluating as an expression and printing the result
139 result = eval(command)
140 if result is not None:
143 # Fall back to executing as a statement
145 except Exception, err: