3 # Helper functions that minipulate the PLC api.
5 # Faiyaz Ahmed <faiyaza@cs.princeton.edu>
6 # Copyright (C) 2006, 2007 The Trustees of Princeton University
8 # $Id: plc.py,v 1.2 2007/01/24 19:29:44 mef Exp $
11 from emailTxt import *
16 import getpass, getopt
19 logger = logging.getLogger("monitor")
20 XMLRPC_SERVER = 'https://www.planet-lab.org/PLCAPI/'
21 api = xmlrpclib.Server(XMLRPC_SERVER, verbose=False)
26 """Returns list of nodes in dbg as reported by PLC"""
28 global api, anon, auth
30 allnodes = api.AnonAdmGetNodes(anon, [], ['hostname','boot_state'])
32 if node['boot_state'] == 'dbg': dbgNodes.append(node['hostname'])
33 logger.info("%s nodes in debug according to PLC." %len(dbgNodes))
38 """Returns loginbase for given nodename"""
40 global api, anon, auth
42 site_id = api.AnonAdmQuerySite (anon, {"node_hostname": nodename})
44 loginbase = api.AnonAdmGetSites (anon, site_id, ["login_base"])
45 return loginbase[0]['login_base']
48 """Returns list of slices for a site."""
50 global api, anon, auth
53 printUsage("requires admin privs")
55 return api.SliceListNames (auth, loginbase)
58 """Returns dict of PCU info of a given node."""
60 global api, anon, auth
61 nodename = argv[0].lower()
63 printUsage("requires admin privs")
67 site_id = api.AnonAdmQuerySite (anon, {"node_hostname": nodename})
70 sitepcus = api.AdmGetSitePowerControlUnits(auth, site_id[0])
71 for sitepcu in sitepcus:
72 sitepcuports = api.AdmGetPowerControlUnitNodes(auth, sitepcu['pcu_id'])
73 for sitepcuport in sitepcuports:
74 node_id = [sitepcuport['node_id']]
75 node = api.AnonAdmGetNodes(anon,node_id,["hostname"])
79 hostname = node['hostname'].lower()
80 if hostname == nodename:
81 sitepcu['port_number']=sitepcuport['port_number']
84 except Exception, err:
85 logger.debug("getpcu: %s" % err)
88 logger.info("Cant find site for %s" % nodename)
91 def getSiteNodes(argv):
92 """Returns all site nodes for site id (loginbase)."""
93 global api, anon, auth
97 site_id = api.AnonAdmQuerySite(anon, {'site_loginbase': "%s" % loginbase})
98 node_ids = api.AnonAdmGetSiteNodes(anon, site_id)
99 for node in api.AnonAdmGetNodes(anon, node_ids["%s" % site_id[0]], ["hostname"]):
100 nodelist.append(node['hostname'])
101 except Exception, exc:
102 logger.info("getSiteNodes: %s" % exc)
106 def nodeBootState(argv):
107 """Sets boot state of a node."""
109 global api, anon, auth
111 printUsage("not enough arguments")
118 printUsage("requires admin privs")
121 node_id = api.AnonAdmQueryNode(anon, {'node_hostname' : nodename})
122 if len(node_id) == 1:
123 logger.info("Setting node %s to %s" %(nodename, state))
126 api.AdmUpdateNode(auth, node_id[0], {'boot_state': state})
127 except Exception, exc:
128 logger.info("nodeBootState: %s" % exc)
130 logger.info("Cant find node %s to toggle boot state" % nodename)
133 """Sends Ping Of Death to node."""
135 global api, anon, auth
138 printUsage("requires admin privs")
141 node_id = api.AnonAdmQueryNode(anon, {'node_hostname' : nodename})
142 if len(node_id) == 1:
143 logger.info("Sending POD to %s" % nodename)
146 api.AdmRebootNode(auth, node_id[0])
147 except Exception, exc:
148 logger.info("nodePOD: %s" % exc)
150 logger.info("Cant find node %s to send POD." % nodename)
152 def suspendSlices(argv):
153 """Freeze all site slices."""
155 global api, anon, auth
157 printUsage("requires admin privs")
160 if argv[0].find(".") <> -1: siteslices = slices([siteId(argv)])
161 else: siteslices = slices(argv)
163 for slice in siteslices:
164 logger.info("Suspending slice %s" % slice)
167 api.SliceAttributeAdd(auth, slice, "plc_slice_state",
168 {"state" : "suspended"})
169 except Exception, exc:
170 logger.info("suspendSlices: %s" % exc)
173 def enableSlices(argv):
174 """Enable suspended site slices."""
176 global api, anon, auth
178 printUsage("requires admin privs")
181 api = xmlrpclib.Server(XMLRPC_SERVER, verbose=False)
183 if argv[0].find(".") <> -1: siteslices = slices([siteId(argv)])
184 else: siteslices = slices(argv)
186 for slice in siteslices:
187 logger.info("unfreezing slice %s" % slice)
188 api.SliceAttributeDelete(auth, slice, "plc_slice_state")
191 def removeSliceCreation(argv):
192 """Removes ability to create slices. Returns previous max_slices"""
194 global api, anon, auth
196 printUsage("requires admin privs")
200 if name.find(".") <> -1:
201 siteid = api.AnonAdmQuerySite (anon, {"node_hostname": name})
202 loginbase = siteId(name)
204 siteid = api.AnonAdmQuerySite (anon, {"site_loginbase": name})
207 numslices = api.AdmGetSites(auth, siteid, ["max_slices"])[0]['max_slices']
209 logger.info("Removing slice creation for site %s" % loginbase)
212 api.AdmUpdateSite(auth, siteid[0], {'max_slices': 0})
214 except Exception, exc:
215 logger.info("removeSliceCreation: %s" % exc)
217 logger.debug("Cant find site for %s. Cannot revoke creation." % loginbase)
219 def enableSliceCreation(argv):
222 global api, anon, auth
224 printUsage("requires admin privs")
228 printUsage("requires maxslice arg")
231 maxslices = int(argv[1])
233 if name.find(".") <> -1:
234 siteid = api.AnonAdmQuerySite (anon, {"node_hostname": name})
235 loginbase = siteId(name)
237 siteid = api.AnonAdmQuerySite (anon, {"site_loginbase": name})
241 logger.info("Enabling slice creation for site %s" % loginbase)
244 api.AdmUpdateSite(auth, siteid[0], {"max_slices" : maxslices})
245 except Exception, exc:
246 logger.info("API: %s" % exc)
248 logger.debug("Cant find site for %s. Cannot enable creation." % loginbase)
253 Usage: %s [-u user] [-p password] [-r role] CMD
256 -u PLC account username
257 -p PLC account password
262 def printUsage(error = None):
265 print "%s %s" %(sys.argv[0],error)
268 for name,function in funclist:
269 print "%20s\t%20s" % (name, function.__doc__)
272 global api, auth, anon
274 anon = {"AuthMethod":"anonymous"}
280 (opts, argv) = getopt.getopt(sys.argv[1:], "u:p:r:h")
285 for (opt, optval) in opts:
299 password = getpass.getpass()
300 except (EOFError, KeyboardInterrupt):
304 auth['Username'] = user
305 auth['AuthMethod'] = "password"
306 auth['AuthString'] = password
309 cmd = functbl.get(argv[0], None)
314 logger.setLevel(logging.DEBUG)
315 ch = logging.StreamHandler()
316 ch.setLevel(logging.DEBUG)
317 formatter = logging.Formatter('logger - %(message)s')
318 ch.setFormatter(formatter)
319 logger.addHandler(ch)
320 result = cmd(argv[1:])
323 funclist = (("nodesDbg",nodesDbg),
327 ("siteNodes", getSiteNodes),
328 ("nodeBootState", nodeBootState),
329 ("nodePOD", nodePOD),
330 ("freezeSlices", suspendSlices),
331 ("unfreezeSlices", enableSlices),
332 ("disableSliceCreation",removeSliceCreation),
333 ("enableSliceCreation", enableSliceCreation))
339 if __name__=="__main__":