*** empty log message ***
[monitor.git] / plc.py
1 #
2 # plc.py
3 #
4 # Helper functions that minipulate the PLC api.
5
6 # Faiyaz Ahmed <faiyaza@cs.princeton.edu
7 #
8 # $Id: $
9 #
10
11 from emailTxt import *
12 import xml, xmlrpclib
13 import logging
14 import auth
15 import time
16 import config
17
18 logger = logging.getLogger("monitor")
19
20 XMLRPC_SERVER = 'https://www.planet-lab.org/PLCAPI/'
21
22 '''
23 Returns list of nodes in dbg as reported by PLC
24 '''
25 def nodesDbg():
26         dbgNodes = []
27         api = xmlrpclib.Server(XMLRPC_SERVER, verbose=False)
28         anon = {'AuthMethod': "anonymous"}
29         allnodes = api.AnonAdmGetNodes(anon, [], ['hostname','boot_state'])
30         for node in allnodes:
31                 if node['boot_state'] == 'dbg': dbgNodes.append(node['hostname'])
32         logger.info("%s nodes in debug according to PLC." %len(dbgNodes))
33         return dbgNodes
34
35
36 '''
37 Returns loginbase for given nodename
38 '''
39 def siteId(nodename):
40         api = xmlrpclib.Server(XMLRPC_SERVER, verbose=False)
41         anon = {'AuthMethod': "anonymous"}
42         site_id = api.AnonAdmQuerySite (anon, {"node_hostname": nodename})
43         if len(site_id) == 1:
44                 loginbase = api.AnonAdmGetSites (anon, site_id, ["login_base"])
45                 return loginbase[0]['login_base']
46
47 '''
48 Returns list of slices for a site.
49 '''
50 def slices(loginbase):
51         api = xmlrpclib.Server(XMLRPC_SERVER, verbose=False)
52         return api.SliceListNames (auth.auth, loginbase)
53
54 '''
55 Returns dict of PCU info of a given node.
56 '''
57 def getpcu(nodename):
58         api = xmlrpclib.Server(XMLRPC_SERVER, verbose=False)
59         anon = {'AuthMethod': "anonymous"}
60         nodes = []
61         site_id = api.AnonAdmQuerySite (anon, {"node_hostname": nodename})
62         if len(site_id) == 1:
63                 # PCU uname, pw, etc
64                 try:
65                         sitepcu = api.AdmGetSitePowerControlUnits(auth.auth, site_id[0])[0]
66                         # returns node_id and port
67                         sitepcuports = api.AdmGetPowerControlUnitNodes(auth.auth, sitepcu['pcu_id'])
68                         # Joining feilds
69                         for nodeidports in sitepcuports:
70                                 nodeidports.update(api.AnonAdmGetNodes(anon, 
71                                 [nodeidports['node_id']], ["node_id", "hostname"])[0])
72                                 nodes.append(nodeidports)
73
74                         # WHY THE FUCK DOES EVERY XMl+RPC RETURN A FUCKING ARRAY?????
75                         # FURTHER, WHY THE FUCK WOULD YOU RETURN A NODE-ID WHEN SANITY WOULD SUGGEST
76                         # FQDN???? /RANT
77                         for node in nodes:
78                                 sitepcu[node['hostname']] = node['port_number']
79
80                         # Sanity Check.  Make sure the node is in the return, if not, barf.
81                         if nodename in sitepcu.keys():
82                                 return sitepcu
83                         else:
84                                 raise Exception
85                 except Exception, err:
86                         logger.debug("getpcu: %s" % err)
87                         return
88         else:
89                 logger.info("Cant find site for %s" % nodename)
90
91
92 '''
93 Returns all site nodes for site id (loginbase).
94 '''
95 def getSiteNodes(loginbase):
96         api = xmlrpclib.Server(XMLRPC_SERVER, verbose=False)
97         nodelist = []
98         anon = {'AuthMethod': "anonymous"}
99         try:
100                 site_id = api.AnonAdmQuerySite(anon, {'site_loginbase': "%s" % loginbase})
101                 node_ids = api.AnonAdmGetSiteNodes(anon, site_id)
102                 for node in api.AnonAdmGetNodes(anon, node_ids["%s" % site_id[0]], ["hostname"]):
103                         nodelist.append(node['hostname'])
104         except Exception, exc:
105                 logger.info("getSiteNodes:  %s" % exc)
106         return nodelist
107
108 '''
109 Sets boot state of a node.
110 '''
111 def nodeBootState(nodename, state):
112         api = xmlrpclib.Server(XMLRPC_SERVER, verbose=False)
113         anon = {'AuthMethod': "anonymous"}
114         node_id = api.AnonAdmQueryNode(anon, {'node_hostname' : nodename})
115         if len(node_id) == 1:
116                 logger.info("Setting node %s to %s" %(nodename, state))
117                 try:
118                         if not config.debug:
119                                 api.AdmUpdateNode(auth.auth, node_id[0], {'boot_state': state})
120                 except Exception, exc:
121                         logger.info("nodeBootState:  %s" % exc)
122         else:
123                 logger.info("Cant find node %s to toggle boot state" % nodename)
124
125 '''
126 Sends Ping Of Death to node.
127 '''
128 def nodePOD(nodename):
129         api = xmlrpclib.Server(XMLRPC_SERVER, verbose=False)
130         anon = {'AuthMethod': "anonymous"}
131         node_id = api.AnonAdmQueryNode(anon, {'node_hostname' : nodename})
132         if len(node_id) == 1:
133                 logger.info("Sending POD to %s" % nodename)
134                 try:
135                         if not config.debug:
136                                 api.AdmRebootNode(auth.auth, node_id[0])
137                 except Exception, exc:
138                         logger.info("nodePOD:  %s" % exc)
139         else:
140                 logger.info("Cant find node %s to send POD." % nodename)
141
142 '''
143 Freeze all site slices.
144 '''
145 def suspendSlices(nodename):
146         api = xmlrpclib.Server(XMLRPC_SERVER, verbose=False)
147         for slice in slices(siteId(nodename)):
148                 logger.info("Suspending slice %s" % slice)
149                 try:
150                         if not config.debug:
151                                 api.SliceAttributeAdd(auth.auth, slice, "plc_slice_state", 
152                                 {"state" : "suspended"})
153                 except Exception, exc:
154                         logger.info("suspendSlices:  %s" % exc)
155
156
157 #I'm commenting this because this really should be a manual process.  
158 #'''
159 #Enable suspended site slices.
160 #'''
161 #def enableSlices(nodename, slicelist):
162 #       api = xmlrpclib.Server(XMLRPC_SERVER, verbose=False)
163 #       for slice in  slices(siteId(nodename)):
164 #               logger.info("Suspending slice %s" % slice)
165 #               api.SliceAttributeAdd(auth.auth, slice, "plc_slice_state", {"state" : "suspended"})
166 #
167
168 '''
169 Removes ability to create slices. Returns previous max_slices
170 '''
171 def removeSliceCreation(nodename):
172         api = xmlrpclib.Server(XMLRPC_SERVER, verbose=False)
173         anon = {'AuthMethod': "anonymous"}
174         siteid = api.AnonAdmQuerySite (anon, {"node_hostname": nodename})
175         numslices = api.AdmGetSites(auth.auth, siteid, ["max_slices"])[0]['max_slices']
176         if len(siteid) == 1:
177                 logger.info("Removing slice creation for site %s" % siteId(nodename))
178                 try:
179                         if not config.debug:
180                                 api.AdmUpdateSite(auth.auth, siteid[0], {'max_slices': 0})
181                         return numslices
182                 except Exception, exc:
183                         logger.info("removeSliceCreation:  %s" % exc)
184         else:
185                 logger.debug("Cant find site for %s.  Cannot revoke creation." % nodename)
186
187 '''
188 QED
189 '''
190 def enableSliceCreation(nodename, maxslices):
191         api = xmlrpclib.Server(XMLRPC_SERVER, verbose=False)
192         anon = {'AuthMethod': "anonymous"}
193         siteid = api.AnonAdmQuerySite (anon, {"node_hostname": nodename})
194         if len(siteid) == 1:
195                 logger.info("Enabling slice creation for site %s" % siteId(nodename))
196                 try:
197                         if not config.debug:
198                                 api.AdmUpdateSite(auth.auth, siteid[0], {"max_slices" : maxslices})
199                 except Exception, exc:
200                         logger.info("API:  %s" % exc)
201         else:
202                 logger.debug("Cant find site for %s.  Cannot enable creation." % nodename)
203
204 def main():
205         logger.setLevel(logging.DEBUG)
206         ch = logging.StreamHandler()
207         ch.setLevel(logging.DEBUG)
208         formatter = logging.Formatter('logger - %(message)s')
209         ch.setFormatter(formatter)
210         logger.addHandler(ch)
211         #print getpcu("kupl2.ittc.ku.edu")
212         #print getpcu("planetlab1.cse.msu.edu")
213         #print getpcu("alice.cs.princeton.edu")
214         #print nodesDbg()
215         #nodeBootState("alice.cs.princaeton.edu", "boot")
216         #freezeSite("alice.cs.princeton.edu")
217         #removeSliceCreation("alice.cs.princeton.edu")
218         #enableSliceCreation("alice.cs.princeton.edu", 1024)
219         print getSiteNodes("princeton")
220         #print siteId("alice.cs.princeton.edu")
221         #print nodePOD("planetlab5.warsaw.rd.tp.pl")
222
223 if __name__=="__main__":
224         import reboot
225         main()