Added new squence for apc_reboot()
[monitor.git] / reboot.py
1 #!/usr/bin/python
2 #
3 # Reboot specified nodes
4 #
5
6 import getpass, getopt
7 import os, sys
8 import xml, xmlrpclib
9 import errno, time, traceback
10 import urllib2
11 import threading, popen2
12 import array, struct
13 #from socket import *
14 import socket
15 import plc
16
17 plc_lock = threading.Lock()
18
19 # Use our versions of telnetlib and pyssh
20 sys.path.insert(0, os.path.dirname(sys.argv[0]))
21 import telnetlib
22 sys.path.insert(0, os.path.dirname(sys.argv[0]) + "/pyssh")    
23 import pyssh
24
25 # Timeouts in seconds
26 TELNET_TIMEOUT = 30
27
28 # Event class ID from pcu events
29 #NODE_POWER_CONTROL = 3
30
31 # Monitor user ID
32 #MONITOR_USER_ID = 11142
33
34 import logging
35 logger = logging.getLogger("monitor")
36 verbose = 1
37 #dryrun = 0;
38
39 class ExceptionNotFound(Exception): pass
40 class ExceptionPassword(Exception): pass
41 class ExceptionTimeout(Exception): pass
42 class ExceptionPrompt(Exception): pass
43 class ExceptionPort(Exception): pass
44
45 def telnet_answer(telnet, expected, buffer):
46         global verbose
47
48         output = telnet.read_until(expected, TELNET_TIMEOUT)
49         #if verbose:
50         #       logger.debug(output)
51         if output.find(expected) == -1:
52                 raise ExceptionNotFound, "'%s' not found" % expected
53         else:
54                 telnet.write(buffer + "\r\n")
55
56
57 # PCU has model, host, preferred-port, user, passwd, 
58
59 class PCUExpect:
60         def __init__(self, protocol, verbose, dryrun):
61                 self.verbose = verbose
62                 self.protocol = protocol
63                 self.dryrun = dryrun
64
65         def telnet_answer(telnet, expected, buffer):
66                 global verbose
67
68                 output = telnet.read_until(expected, TELNET_TIMEOUT)
69                 #if verbose:
70                 #       logger.debug(output)
71                 if output.find(expected) == -1:
72                         raise ExceptionNotFound, "'%s' not found" % expected
73                 else:
74                         telnet.write(buffer + "\r\n")
75         
76         def _run(self, host, user, passwd, node_port, protocols):
77                 self.run()
78
79         def run(self):
80                 pass
81                 
82         
83
84 def ipal_reboot(ip, password, port, dryrun):
85         global verbose
86         global plc_lock
87
88
89         telnet = None
90
91         try:
92                 #plc_lock.acquire()
93                 #print "lock acquired"
94
95                 #try:
96                         #telnet = telnetlib.Telnet(ip) # , timeout=TELNET_TIMEOUT)
97                 telnet = telnetlib.Telnet(ip, timeout=TELNET_TIMEOUT)
98                 #except:
99                 #       import traceback
100                 #       traceback.print_exc()
101
102
103                 telnet.set_debuglevel(verbose)
104
105                 # XXX Some iPals require you to hit Enter a few times first
106                 telnet_answer(telnet, "Password >", "\r\n\r\n")
107
108                 # Login
109                 telnet_answer(telnet, "Password >", password)
110
111                 # XXX Some iPals require you to hit Enter a few times first
112                 telnet.write("\r\n\r\n")
113
114                 # P# - Pulse relay
115                 if not dryrun:
116                         telnet_answer(telnet, "Enter >", "P%d" % port)
117
118                 telnet.read_until("Enter >", TELNET_TIMEOUT)
119
120                 # Close
121                 telnet.close()
122
123                 #print "lock released"
124                 #plc_lock.release()
125                 return 0
126
127         except EOFError, err:
128                 if verbose:
129                         logger.debug("ipal_reboot: EOF")
130                         logger.debug(err)
131                 telnet.close()
132                 import traceback
133                 traceback.print_exc()
134                 #print "lock released"
135                 #plc_lock.release()
136                 return errno.ECONNRESET
137         except socket.error, err:
138                 logger.debug("ipal_reboot: Socket Error")
139                 logger.debug(err)
140                 import traceback
141                 traceback.print_exc()
142
143                 return errno.ETIMEDOUT
144                 
145         except Exception, err:
146                 if verbose:
147                         logger.debug("ipal_reboot: Exception")
148                         logger.debug(err)
149                 if telnet:
150                         telnet.close()
151                 import traceback
152                 traceback.print_exc()
153                 #print "lock released"
154                 #plc_lock.release()
155                 return  "ipal error"
156
157
158 def apc_reboot(ip, username, password, port, protocol, dryrun):
159         global verbose
160
161         transport = None
162
163         # TODO: I may need to differentiate between different models of APC
164         # hardware...
165         #       for instance, the original code didn't work for:
166         #               planetdev03.fm.intel.com
167         #                       American Power Conversion               
168         #                                       Network Management Card AOS      v3.3.0
169         #                       (c) Copyright 2005 All Rights Reserved  
170         #                                       Rack PDU APP                     v3.3.1
171
172
173         try:
174                 #if "ssh" in protocol:
175                 if "22" in protocol and protocol['22'] == "open":
176                         transport = pyssh.Ssh(username, ip)
177                         transport.open()
178                         # Login
179                         telnet_answer(transport, "password:", password)
180                 #elif "telnet" in protocol:
181                 elif "23" in protocol and protocol['23'] == "open":
182                         transport = telnetlib.Telnet(ip, timeout=TELNET_TIMEOUT)
183                         #transport = telnetlib.Telnet(ip)
184                         transport.set_debuglevel(verbose)
185                         # Login
186                         telnet_answer(transport, "User Name", username)
187                         telnet_answer(transport, "Password", password)
188                 else:
189                         logger.debug("Unknown protocol %s" %protocol)
190                         raise "Closed protocol ports!"
191
192
193                 # 1- Device Manager
194                 # 2- Network
195                 # 3- System
196                 # 4- Logout
197
198                 # 1- Device Manager
199                 telnet_answer(transport, "\r\n> ", "1")
200
201                 # 1- Phase Monitor/Configuration
202                 # 2- Outlet Restriction Configuration
203                 # 3- Outlet Control/Config
204                 # 4- Power Supply Status
205
206                 # 3- Outlet Control/Config
207                 telnet_answer(transport, "\r\n> ", "2")
208                 telnet_answer(transport, "\r\n> ", "1")
209
210                 # 3- Outlet Control/Config
211                 #telnet_answer(transport, "\r\n> ", "3")
212
213                 # 1- Outlet 1
214                 # 2- Outlet 2
215                 # ...
216
217                 # n- Outlet n
218                 telnet_answer(transport, "\r\n> ", str(port))
219                 
220                 # 1- Control Outlet
221                 # 2- Configure Outlet
222
223                 # 1- Control Outlet
224                 telnet_answer(transport, "\r\n> ", "1")
225
226                 # 1- Immediate On                         
227                 # 2- Immediate Off                       
228                 # 3- Immediate Reboot             
229                 # 4- Delayed On                         
230                 # 5- Delayed Off                           
231                 # 6- Delayed Reboot                     
232                 # 7- Cancel                                     
233
234                 # 3- Immediate Reboot             
235                 telnet_answer(transport, "\r\n> ", "3")
236
237                 if not dryrun:
238                         telnet_answer(transport, 
239                                 "Enter 'YES' to continue or <ENTER> to cancel", "YES\r\n")
240                         telnet_answer(transport, 
241                                 "Press <ENTER> to continue...", "")
242
243                 # Close
244                 transport.close()
245                 return 0
246
247         except EOFError, err:
248                 if verbose:
249                         logger.debug(err)
250                 if transport:
251                         transport.close()
252                 return errno.ECONNRESET
253         except socket.error, err:
254                 if verbose:
255                         logger.debug(err)
256                 return errno.ETIMEDOUT
257
258         except Exception, err:
259                 import traceback
260                 traceback.print_exc()
261                 if verbose:
262                         logger.debug(err)
263                 if transport:
264                         transport.close()
265                 return "apc error: check password"
266
267 def drac_reboot(ip, username, password, dryrun):
268         global verbose
269         ssh = None
270         try:
271                 ssh = pyssh.Ssh(username, ip)
272                 ssh.set_debuglevel(verbose)
273                 ssh.open()
274                 # Login
275                 print "password"
276                 telnet_answer(ssh, "password:", password)
277
278                 # Testing Reboot ?
279                 print "reset or power"
280                 if dryrun:
281                         telnet_answer(ssh, "[%s]#" % username, "getsysinfo")
282                 else:
283                         # Reset this machine
284                         telnet_answer(ssh, "[%s]#" % username, "serveraction powercycle")
285
286                 print "exit"
287                 telnet_answer(ssh, "[%s]#" % username, "exit")
288
289                 # Close
290                 print "close"
291                 output = ssh.close()
292                 return 0
293
294         except socket.error, err:
295                 print "exception"
296                 import traceback
297                 traceback.print_exc()
298                 if verbose:
299                         logger.debug(err)
300                 if ssh:
301                         output = ssh.close()
302                         if verbose:
303                                 logger.debug(err)
304                 return errno.ETIMEDOUT
305         except Exception, err:
306                 print "exception"
307                 import traceback
308                 traceback.print_exc()
309                 if verbose:
310                         logger.debug(err)
311                 if ssh:
312                         output = ssh.close()
313                         if verbose:
314                                 logger.debug(err)
315                 return "drac error: check password"
316
317 def ilo_reboot(ip, username, password, dryrun):
318         global verbose
319
320         ssh = None
321
322         try:
323                 ssh = pyssh.Ssh(username, ip)
324                 ssh.set_debuglevel(verbose)
325                 ssh.open()
326                 # Login
327                 print "password"
328                 telnet_answer(ssh, "password:", password)
329
330                 # User:vici logged-in to ILOUSE701N7N4.CS.Princeton.EDU(128.112.154.171)
331                 # iLO Advanced 1.26 at 10:01:40 Nov 17 2006
332                 # Server Name: USE701N7N400
333                 # Server Power: On
334                 # 
335                 # </>hpiLO-> 
336                 print "cd system1"
337                 telnet_answer(ssh, "</>hpiLO->", "cd system1")
338
339                 # Reboot Outlet  N        (Y/N)?
340                 print "reset or power"
341                 if dryrun:
342                         telnet_answer(ssh, "</system1>hpiLO->", "POWER")
343                 else:
344                         # Reset this machine
345                         telnet_answer(ssh, "</system1>hpiLO->", "reset")
346
347                 print "exit"
348                 telnet_answer(ssh, "</system1>hpiLO->", "exit")
349
350                 # Close
351                 print "close"
352                 output = ssh.close()
353                 return 0
354
355         except socket.error, err:
356                 print "exception"
357                 import traceback
358                 traceback.print_exc()
359                 if verbose:
360                         logger.debug(err)
361                 if ssh:
362                         output = ssh.close()
363                         if verbose:
364                                 logger.debug(err)
365                 return errno.ETIMEDOUT
366         except Exception, err:
367                 print "exception"
368                 import traceback
369                 traceback.print_exc()
370                 if verbose:
371                         logger.debug(err)
372                 if ssh:
373                         output = ssh.close()
374                         if verbose:
375                                 logger.debug(err)
376                 return "ilo error: check password"
377
378 def baytech_reboot(ip, username, password, port, dryrun):
379         global verbose
380
381         ssh = None
382
383         #verbose = 1 
384         try:
385                 ssh = pyssh.Ssh(username, ip)
386                 ssh.set_debuglevel(verbose)
387                 ssh.open()
388
389                 # Login
390                 telnet_answer(ssh, "password:", password)
391
392                 # PL1 comm output  (2 ,1).........1
393                 # PL2 comm output  (2 ,2).........2
394                 # PL3 comm output  (2 ,3).........3
395                 # no machine       (2 ,4).........4
396                 # Control Outlets  (5 ,1).........5
397                 # Logout..........................T
398
399                 # Control Outlets  (5 ,1).........5
400                 telnet_answer(ssh, "Enter Request :", "5")
401
402                 # Reboot N
403                 try:
404                         telnet_answer(ssh, "DS-RPC>", "Reboot %d" % port)
405                 except ExceptionNotFound, msg:
406                         # one machine is configured to ask for a username,
407                         # even after login...
408                         print "msg: %s" % msg
409                         ssh.write(username + "\r\n")
410                         telnet_answer(ssh, "DS-RPC>", "Reboot %d" % port)
411                         
412
413                 # Reboot Outlet  N        (Y/N)?
414                 if dryrun:
415                         telnet_answer(ssh, "(Y/N)?", "N")
416                 else:
417                         telnet_answer(ssh, "(Y/N)?", "Y")
418                 telnet_answer(ssh, "DS-RPC>", "")
419
420                 # Close
421                 output = ssh.close()
422                 return 0
423
424         except socket.error, err:
425                 print "exception"
426                 import traceback
427                 traceback.print_exc()
428                 if verbose:
429                         logger.debug(err)
430                 if ssh:
431                         output = ssh.close()
432                         if verbose:
433                                 logger.debug(err)
434                 return errno.ETIMEDOUT
435         except Exception, err:
436                 print "exception"
437                 import traceback
438                 traceback.print_exc()
439                 if verbose:
440                         logger.debug(err)
441                 if ssh:
442                         output = ssh.close()
443                         if verbose:
444                                 logger.debug(err)
445                 return "baytech error: check password"
446
447 ### rebooting european BlackBox PSE boxes
448 # Thierry Parmentelat - May 11 2005
449 # tested on 4-ports models known as PSE505-FR
450 # uses http to POST a data 'P<port>=r'
451 # relies on basic authentication within http1.0
452 # first curl-based script was
453 # curl --http1.0 --basic --user <username>:<password> --data P<port>=r \
454 #       http://<hostname>:<http_port>/cmd.html && echo OK
455
456 def bbpse_reboot (pcu_ip,username,password,port_in_pcu,http_port, dryrun):
457
458         global verbose
459
460         url = "http://%s:%d/cmd.html" % (pcu_ip,http_port)
461         data= "P%d=r" % port_in_pcu
462         if verbose:
463                 logger.debug("POSTing '%s' on %s" % (data,url))
464
465         authinfo = urllib2.HTTPPasswordMgrWithDefaultRealm()
466         uri = "%s:%d" % (pcu_ip,http_port)
467         authinfo.add_password (None, uri, username, password)
468         authhandler = urllib2.HTTPBasicAuthHandler( authinfo )
469
470         opener = urllib2.build_opener(authhandler)
471         urllib2.install_opener(opener)
472
473         if (dryrun):
474                 return 0
475
476         try:
477                 f = urllib2.urlopen(url,data)
478
479                 r= f.read()
480                 if verbose:
481                         logger.debug(r)
482                 return 0
483
484         except urllib2.URLError,err:
485                 logger.info('Could not open http connection', err)
486                 return "bbpse error"
487
488 ### rebooting x10toggle based systems addressed by port
489 # Marc E. Fiuczynski - May 31 2005
490 # tested on 4-ports models known as PSE505-FR
491 # uses ssh and password to login to an account
492 # that will cause the system to be powercycled.
493
494 def x10toggle_reboot(ip, username, password, port, dryrun):
495         global verbose
496
497         ssh = None
498         try:
499                 ssh = pyssh.Ssh(username, ip)
500                 ssh.open()
501
502                 # Login
503                 telnet_answer(ssh, "password:", password)
504
505                 if not dryrun:
506                         # Reboot
507                         telnet_answer(ssh, "x10toggle>", "A%d" % port)
508
509                 # Close
510                 output = ssh.close()
511                 if verbose:
512                         logger.debug(output)
513                 return 0
514
515         except Exception, err:
516                 if verbose:
517                         logger.debug(err)
518                 if ssh:
519                         output = ssh.close()
520                         if verbose:
521                                 logger.debug(output)
522                 return errno.ETIMEDOUT
523
524 ### rebooting Dell systems via RAC card
525 # Marc E. Fiuczynski - June 01 2005
526 # tested with David Lowenthal's itchy/scratchy nodes at UGA
527 #
528
529 def runcmd(command, args, username, password, timeout = None):
530
531         result = [None]
532         result_ready = threading.Condition()
533
534         def set_result(x):
535
536                 result_ready.acquire()
537                 try:
538                         result[0] = x
539                 finally:
540                         result_ready.notify()
541                         result_ready.release()
542
543         def do_command(command, username, password):
544
545                 try:
546                         # Popen4 is a popen-type class that combines stdout and stderr
547                         p = popen2.Popen4(command)
548
549                         # read all output data
550                         p.tochild.write("%s\n" % username)
551                         p.tochild.write("%s\n" % password)
552                         p.tochild.close()
553                         data = p.fromchild.read()
554
555                         while True:
556                                 # might get interrupted by a signal in poll() or waitpid()
557                                 try:
558                                         retval = p.wait()
559                                         set_result((retval, data))
560                                         break
561                                 except OSError, ex:
562                                         if ex.errno == errno.EINTR:
563                                                 continue
564                                         raise ex
565                 except Exception, ex:
566                         set_result(ex)
567
568         if args:
569                 command = " ".join([command] + args)
570
571         worker = threading.Thread(target = do_command, args = (command, username, password, ))
572         worker.setDaemon(True)
573         result_ready.acquire()
574         worker.start()
575         result_ready.wait(timeout)
576         try:
577                 if result == [None]:
578                         raise Exception, "command timed-out: '%s'" % command
579         finally:
580                 result_ready.release()
581         result = result[0]
582
583         if isinstance(result, Exception):
584                 raise result
585         else:
586                 (retval, data) = result
587                 if os.WIFEXITED(retval) and os.WEXITSTATUS(retval) == 0:
588                         return data
589                 else:
590                         out = "system command ('%s') " % command
591                         if os.WIFEXITED(retval):
592                                 out += "failed, rc = %d" % os.WEXITSTATUS(retval)
593                         else:
594                                 out += "killed by signal %d" % os.WTERMSIG(retval)
595                         if data:
596                                 out += "; output follows:\n" + data
597                         raise Exception, out
598
599 def racadm_reboot(ip, username, password, port, dryrun):
600         global verbose
601
602         try:
603                 cmd = "/usr/sbin/racadm"
604                 os.stat(cmd)
605                 if not dryrun:
606                         output = runcmd(cmd, ["-r %s -i serveraction powercycle" % ip],
607                                 username, password)
608                 else:
609                         output = "dryrun of racadm command"
610
611                 logger.debug("runcmd returned without output %s" % output)
612                 if verbose:
613                         logger.debug(output)
614                 return 0
615
616         except Exception, err:
617                 logger.debug("runcmd raised exception %s" % err)
618                 if verbose:
619                         logger.debug(err)
620                 return errno.ETIMEDOUT
621
622 def pcu_name(pcu):
623         if pcu['hostname'] is not None and pcu['hostname'] is not "":
624                 return pcu['hostname']
625         elif pcu['ip'] is not None and pcu['ip'] is not "":
626                 return pcu['ip']
627         else:
628                 return None
629
630 def get_pcu_values(pcu_id):
631         # TODO: obviously, this shouldn't be loaded each time...
632         import soltesz
633         fb =soltesz.dbLoad("findbadpcus")
634
635         try:
636                 values = fb['nodes']["id_%s" % pcu_id]['values']
637         except:
638                 values = None
639
640         return values
641
642 def reboot_new(nodename, continue_probe, dryrun):
643
644         pcu = plc.getpcu(nodename)
645         if not pcu:
646                 return False
647
648         values = get_pcu_values(pcu['pcu_id'])
649         if values == None:
650                 return False
651         
652         # Try the PCU first
653         logger.debug("Trying PCU %s %s" % (pcu['hostname'], pcu['model']))
654
655         # DataProbe iPal (many sites)
656         if  continue_probe and values['model'].find("Dataprobe IP-41x/IP-81x") >= 0:
657                 if values['portstatus']['23'] == "open":
658                         rb_ret = ipal_reboot(pcu_name(values),
659                                                                         values['password'],
660                                                                         pcu[nodename],
661                                                                         dryrun)
662                 else:
663                         rb_ret = "Unsupported_Port"
664                         
665
666         # APC Masterswitch (Berkeley)
667         elif continue_probe and values['model'].find("APC AP79xx/Masterswitch") >= 0:
668                 if  values['portstatus']['22'] == "open" or \
669                         values['portstatus']['23'] == "open":
670                         rb_ret = apc_reboot(pcu_name(values),
671                                                                         values['username'],
672                                                                         values['password'], 
673                                                                         pcu[nodename],
674                                                                         values['portstatus'], 
675                                                                         dryrun)
676                 else:
677                         rb_ret = "Unsupported_Port"
678         # BayTech DS4-RPC
679         elif continue_probe and values['model'].find("Baytech DS4-RPC") >= 0:
680                 if values['portstatus']['22'] == "open":
681                         rb_ret = baytech_reboot(pcu_name(values),
682                                                                            values['username'],
683                                                                            values['password'], 
684                                                                            pcu[nodename],
685                                                                            dryrun)
686                 else:
687                         rb_ret = "Unsupported_Port"
688                         
689
690         # iLO
691         elif continue_probe and values['model'].find("HP iLO") >= 0:
692                 if values['portstatus']['22'] == "open":
693                         rb_ret = ilo_reboot(pcu_name(values),
694                                                                            values['username'],
695                                                                            values['password'], 
696                                                                            dryrun)
697                 else:
698                         rb_ret = "Unsupported_Port"
699                         
700         # DRAC ssh
701         elif continue_probe and values['model'].find("Dell RAC") >= 0:
702                 if values['portstatus']['22'] == "open":
703                         rb_ret = drac_reboot(pcu_name(values),
704                                                                            values['username'],
705                                                                            values['password'], 
706                                                                            dryrun)
707                 else:
708                         rb_ret = "Unsupported_Port"
709                         
710
711         # BlackBox PSExxx-xx (e.g. PSE505-FR)
712         elif continue_probe and \
713                 (values['model'].find("BlackBox PS5xx") >= 0 or
714                  values['model'].find("ePowerSwitch 1/4/8x") >=0 ):
715                 if values['portstatus']['80'] == "open":
716                         rb_ret = bbpse_reboot(pcu_name(values),
717                                                         values['username'], 
718                                                         values['password'], 
719                                                         pcu[nodename],
720                                                         80,
721                                                         dryrun)
722                 else:
723                         rb_ret = "Unsupported_PCU"
724                         
725         # x10toggle
726         elif    continue_probe and values['protocol'] == "ssh" and \
727                         values['model'] == "x10toggle":
728                 rb_ret = x10toggle_reboot(pcu_name(values),
729                                                                                 values['username'],
730                                                                                 values['password'], 
731                                                                                 pcu[nodename],
732                                                                                 dryrun)
733         # ????
734         elif continue_probe and values['protocol'] == "racadm" and \
735                         values['model'] == "RAC":
736                 rb_ret = racadm_reboot(pcu_name(values),
737                                                                           values['username'],
738                                                                           values['password'],
739                                                                           pcu[nodename],
740                                                                           dryrun)
741         elif continue_probe:
742                 rb_ret = "Unsupported_PCU"
743
744         elif continue_probe == False:
745                 if 'portstatus' in values:
746                         rb_ret = "NetDown"
747                 else:
748                         rb_ret = "Not_Run"
749         else:
750                 rb_ret = -1
751         
752         if rb_ret != 0:
753                 return False
754         else:
755                 return True
756
757
758 # Returns true if rebooted via PCU
759 def reboot(nodename, dryrun):
760         pcu = plc.getpcu(nodename)
761         if not pcu:
762                 plc.nodePOD(nodename)
763                 return False
764         # Try the PCU first
765         logger.debug("Trying PCU %s %s" % (pcu['hostname'], pcu['model']))
766
767         # APC Masterswitch (Berkeley)
768         if pcu['model'] == "APC Masterswitch":
769                 err = apc_reboot(pcu['ip'], pcu['username'],pcu['password'], 
770                                 pcu[nodename], pcu['protocol'], dryrun)
771
772         # DataProbe iPal (many sites)
773         elif pcu['protocol'] == "telnet" and pcu['model'].find("IP-4") >= 0:
774                 err = ipal_reboot(pcu['ip'],pcu['password'], pcu[nodename], dryrun)
775
776         # BayTech DS4-RPC
777         elif pcu['protocol'] == "ssh" and \
778         (pcu['model'].find("Baytech") >= 0 or pcu['model'].find("DS4") >= 0):
779                 err = baytech_reboot(pcu['ip'], pcu['username'],pcu['password'], pcu[nodename], dryrun)
780
781         # BlackBox PSExxx-xx (e.g. PSE505-FR)
782         elif pcu['protocol'] == "http" and (pcu['model'] == "bbpse"):
783                 err = bbpse_reboot(pcu['ip'], pcu['username'], pcu['password'], pcu[nodename],80, dryrun)
784
785         # x10toggle
786         elif pcu['protocol'] == "ssh" and (pcu['model'] == "x10toggle"):
787                 err = x10toggle_reboot(pcu['ip'], pcu['username'],pcu['password'], pcu[nodename], dryrun)
788
789         # 
790         elif pcu['protocol'] == "racadm" and (pcu['model'] == "RAC"):
791                 err = racadm_reboot(pcu['ip'], pcu['username'],pcu['password'], pcu_[nodename], dryrun)
792
793         # Unknown or unsupported
794         else:
795                 err = errno.EPROTONOSUPPORT
796                 return False
797         return True 
798
799 #def get_suggested(suggestion_id,db):
800 #
801 #       sql= """select node_id,pcu_id from nodes where suggestion = %d """\
802 #                       % (suggestion_id)
803 #       try:
804 #               nodes = db.query(sql).dictresult()
805 #       except pg.ProgrammingError, err:
806 #               print( "Database error for query: %s\n%s" % (sql,err) )
807 #               sys.exit(1)
808 #       return nodes
809
810 #def get_pcu_info(node_id,pcu_id,db):
811 #       sql= """select port_number from pcu_ports where node_id = %d and pcu_id = %d """\
812 #                       % (node_id,pcu_id)
813 #       try:
814 #          port_number = db.query(sql).dictresult()
815 #       except pg.ProgrammingError, err:
816 #               print( "Database error for query: %s\n%s" % (sql,err) )
817 #               sys.exit(1)
818 #       
819 #       sql= """select * from pcu where pcu_id = %d """\
820 #                       % (pcu_id)
821 #       try:
822 #               pcu = db.query(sql).dictresult()
823 #       except pg.ProgrammingError, err:
824 #               print( "Database error for query: %s\n%s" % (sql,err) )
825 #               sys.exit(1)
826 #
827 #       result = {'node_id':node_id,'pcu_id':pcu_id,'port_number':port_number[0]['port_number'], 
828 #                         'ip':pcu[0]['ip'],'username':pcu[0]['username'],'password':pcu[0]['password'],\
829 #                         'model':pcu[0]['model'],'protocol':pcu[0]['protocol'],'hostname':pcu[0]['hostname']}
830 #
831 #       return result
832
833 #def add_plc_event(node_id,err,db):
834 #       site_id = plc_db_utils.get_site_from_node_id(node_id,db)
835 #       message = "PCU reboot by monitor-msgs@planet-lab.org: %s" % os.strerror(err)
836 #
837 #       sql = """insert into events (event_class_id,message,person_id,node_id,site_id) values """\
838 #                 """(%d,'%s',%d,%d,%d)""" % (NODE_POWER_CONTROL,message,MONITOR_USER_ID,node_id,site_id)
839 #       print sql
840 #
841 #       try:
842 #               db.query(sql)
843 #       except pg.ProgrammingError, err:
844 #               print( "Database error for: %s\n%s" % (sql,err) )
845 #               sys.exit(1)
846
847
848 def main():
849         logger.setLevel(logging.DEBUG)
850         ch = logging.StreamHandler()
851         ch.setLevel(logging.DEBUG)
852         formatter = logging.Formatter('LOGGER - %(message)s')
853         ch.setFormatter(formatter)
854         logger.addHandler(ch)
855
856
857         try:
858                 reboot("planetlab2.cs.uchicago.edu")
859                 reboot("alice.cs.princeton.edu")
860         except Exception, err:
861                 print err
862         # used later for pretty printing
863 #       pp = pprint.PrettyPrinter(indent=2)
864
865 #       user = "Monitor"
866 #       password = None
867
868 #       plc_db = plc_dbs.open_plc_db_write()
869 #       mon_db = plc_dbs.open_mon_db()
870
871         # 5 = needs script reboot - fix this later
872 #       nodes = get_suggested(5,mon_db)
873
874 #       for row in nodes:
875                 
876 #               pcu = get_pcu_info(row['node_id'],row['pcu_id'],plc_db)
877 #               add_plc_event(row['node_id'],err,plc_db)
878
879 if __name__ == '__main__':
880         import plc
881         logger = logging.getLogger("monitor")
882         main()