3 # Interactive shell for testing PLCAPI
5 # Mark Huang <mlhuang@cs.princeton.edu>
6 # Copyright (C) 2005 The Trustees of Princeton University
11 from socket import gethostname
12 from optparse import OptionParser
13 from getpass import getpass
14 from traceback import print_exc
16 sys.path.append(os.path.dirname(os.path.realpath(sys.argv[0])))
17 from PLC.Shell import Shell
19 usage="""Usage: %prog [options]
20 runs an interactive shell
21 Usage: %prog [options] script script-arguments
22 Usage: %prog script [plcsh-options --] script arguments
25 parser = OptionParser(usage=usage,add_help_option = False)
26 parser.add_option("-f", "--config", help = "PLC configuration file")
27 parser.add_option("-h", "--url", help = "API URL")
28 parser.add_option("-c", "--cacert", help = "API SSL certificate")
29 parser.add_option("-k", "--insecure", help = "Do not check SSL certificate")
30 parser.add_option("-m", "--method", help = "API authentication method")
31 parser.add_option("-s", "--session", help = "API session key")
32 parser.add_option("-u", "--user", help = "API user name")
33 parser.add_option("-p", "--password", help = "API password")
34 parser.add_option("-r", "--role", help = "API role")
35 parser.add_option("-x", "--xmlrpc", action = "store_true",
36 default = False, help = "Use XML-RPC interface")
37 # pass this to the invoked shell if any
38 parser.add_option("--help", action = "store_true", dest="help", default=False,
39 help = "show this help message and exit")
40 (options, args) = parser.parse_args()
42 if not args and options.help:
46 # If user is specified but password is not
47 if options.user is not None and options.password is None:
49 options.password = getpass()
50 except (EOFError, KeyboardInterrupt):
54 # Initialize a single global instance (scripts may re-initialize
55 # this instance and/or create additional instances).
57 shell = Shell(globals = globals(),
58 config = options.config,
59 url = options.url, xmlrpc = options.xmlrpc, cacert = options.cacert,
60 method = options.method, role = options.role,
61 user = options.user, password = options.password,
62 session = options.session)
63 # Register a few more globals for backward compatibility
67 except Exception as err:
73 # If called by a script
75 if not os.path.exists(args[0]):
76 print('File %s not found'%args[0])
80 # re-append --help if provided
83 # use args as sys.argv for the next shell, so our own options get removed for the next script
86 # Add of script to sys.path
87 path = os.path.dirname(os.path.abspath(script))
89 with open(script) as feed:
92 # Otherwise, run an interactive shell environment
94 if shell.server is None:
95 print("PlanetLab Central Direct API Access")
97 elif shell.auth['AuthMethod'] == "anonymous":
98 prompt = "[anonymous]"
99 print("Connected anonymously")
100 elif shell.auth['AuthMethod'] == "session":
101 # XXX No way to tell node and user sessions apart from the
102 # client point of view.
103 prompt = "[%s]" % gethostname()
104 print("%s connected using session authentication" % gethostname())
106 prompt = "[%s]" % shell.auth['Username']
107 print("%s connected using %s authentication" % \
108 (shell.auth['Username'], shell.auth['AuthMethod']))
110 # Readline and tab completion support
115 print('Type "system.listMethods()" or "help(method)" for more information.')
116 # Load command history
117 history_path = os.path.join(os.environ["HOME"], ".plcapi_history")
119 # check directory: pretend to open
120 with open(history_path, 'a') as check:
122 readline.read_history_file(history_path)
123 atexit.register(readline.write_history_file, history_path)
127 # Enable tab completion
128 readline.parse_and_bind("tab: complete")
140 line = input(prompt + sep)
142 except KeyboardInterrupt:
147 # Build up multi-line command
150 # Blank line or first line does not end in :
151 if line == "" or (command == line and line[-1] != ':'):
154 command += os.linesep
160 elif command in ["q", "quit", "exit"]:
165 # Try evaluating as an expression and printing the result
166 result = eval(command)
167 if result is not None:
170 # Fall back to executing as a statement
172 except Exception as err: