svn merge -r 12308:13112 https://svn.planet-lab.org/svn/Monitor/branches/2.0/
[monitor.git] / pcucontrol / models / ePowerSwitch.py
1 from pcucontrol.reboot import *
2
3 class ePowerSwitchNew(PCUControl):
4         # NOTE:
5         #               The old code used Python's HTTPPasswordMgrWithDefaultRealm()
6         #               For some reason this both doesn't work and in some cases, actually
7         #               hangs the PCU.  Definitely not what we want.
8         #               
9         #               The code below is much simpler.  Just letting things fail first,
10         #               and then, trying again with authentication string in the header.
11         #               
12         def run_http(self, node_port, dryrun):
13                 self.transport = None
14                 self.url = "http://%s:%d/" % (self.host,80)
15                 uri = "%s:%d" % (self.host,80)
16
17                 req = urllib2.Request(self.url)
18                 try:
19                         handle = urllib2.urlopen(req)
20                 except IOError, e:
21                         # NOTE: this is expected to fail initially
22                         pass
23                 else:
24                         print self.url
25                         print "-----------"
26                         print handle.read()
27                         print "-----------"
28                         return "ERROR: not protected by HTTP authentication"
29
30                 if not hasattr(e, 'code') or e.code != 401:
31                         return "ERROR: failed for: %s" % str(e)
32
33                 base64data = base64.encodestring("%s:%s" % (self.username, self.password))[:-1]
34                 # NOTE: assuming basic realm authentication.
35                 authheader = "Basic %s" % base64data
36                 req.add_header("Authorization", authheader)
37
38                 try:
39                         f = urllib2.urlopen(req)
40                 except IOError, e:
41                         # failing here means the User/passwd is wrong (hopefully)
42                         raise ExceptionPassword("Incorrect username/password")
43
44                 # NOTE: after verifying that the user/password is correct, 
45                 #               actually reboot the given node.
46                 if not dryrun:
47                         try:
48                                 data = urllib.urlencode({'P%d' % node_port : "r"})
49                                 req = urllib2.Request(self.url + "cmd.html")
50                                 req.add_header("Authorization", authheader)
51                                 # add data to handler,
52                                 f = urllib2.urlopen(req, data)
53                                 if self.transport.verbose: print f.read()
54                         except:
55                                 import traceback; traceback.print_exc()
56
57                                 # fetch url one more time on cmd.html, econtrol.html or whatever.
58                                 # pass
59                 else:
60                         if self.transport.verbose: print f.read()
61
62                 return 0
63
64 class ePowerSwitchOld(PCUControl):
65         def run_http(self, node_port, dryrun):
66                 self.url = "http://%s:%d/" % (self.host,80)
67                 uri = "%s:%d" % (self.host,80)
68
69                 # create authinfo
70                 authinfo = urllib2.HTTPPasswordMgrWithDefaultRealm()
71                 authinfo.add_password (None, uri, self.username, self.password)
72                 authhandler = urllib2.HTTPBasicAuthHandler( authinfo )
73
74                 # NOTE: it doesn't seem to matter whether this authinfo is here or not.
75                 transport = urllib2.build_opener(authinfo)
76                 f = transport.open(self.url)
77                 if self.transport.verbose: print f.read()
78
79                 if not dryrun:
80                         transport = urllib2.build_opener(authhandler)
81                         f = transport.open(self.url + "cmd.html", "P%d=r" % node_port)
82                         if self.transport.verbose: print f.read()
83
84                 self.transport.close()
85                 return 0
86
87 class ePowerSwitchOld(PCUControl):
88         supported_ports = [80]
89         def run_http(self, node_port, dryrun):
90                 self.url = "http://%s:%d/" % (self.host,80)
91                 uri = "%s:%d" % (self.host,80)
92
93                 # TODO: I'm still not sure what the deal is here.
94                 #               two independent calls appear to need to be made before the
95                 #               reboot will succeed.  It doesn't seem to be possible to do
96                 #               this with a single call.  I have no idea why.
97
98                 # create authinfo
99                 authinfo = urllib2.HTTPPasswordMgrWithDefaultRealm()
100                 authinfo.add_password (None, uri, self.username, self.password)
101                 authhandler = urllib2.HTTPBasicAuthHandler( authinfo )
102
103                 # NOTE: it doesn't seem to matter whether this authinfo is here or not.
104                 transport = urllib2.build_opener()
105                 f = transport.open(self.url + "elogin.html", "pwd=%s" % self.password)
106                 if self.transport.verbose: print f.read()
107
108                 if not dryrun:
109                         transport = urllib2.build_opener(authhandler)
110                         f = transport.open(self.url + "econtrol.html", "P%d=r" % node_port)
111                         if self.transport.verbose: print f.read()
112
113                 #       data= "P%d=r" % node_port
114                 #self.open(self.host, self.username, self.password)
115                 #self.sendHTTP("elogin.html", "pwd=%s" % self.password)
116                 #self.sendHTTP("econtrol.html", data)
117                 #self.sendHTTP("cmd.html", data)
118
119                 #self.close()
120                 return 0