5
5
import random
6
6
import re
7
7
import socket
8
- try :
9
- import cStringIO as StringIO
10
- except ImportError :
11
- import io as StringIO
12
8
import subprocess
13
9
import sys
10
+ import warnings
11
+ import hpilo_fw
12
+
13
+ PY3 = sys .version_info [0 ] >= 3
14
+ if PY3 :
15
+ import io as StringIO
16
+ b = lambda x : bytes (x , 'ascii' )
17
+ class Bogus (Exception ): pass
18
+ socket .sslerror = Bogus
19
+ basestring = str
20
+ else :
21
+ import cStringIO as StringIO
22
+ b = lambda x : x
23
+
14
24
try :
15
25
import ssl
16
26
except ImportError :
@@ -20,12 +30,10 @@ class ssl:
20
30
@staticmethod
21
31
def wrap_socket (sock , * args , ** kwargs ):
22
32
return socket .ssl (sock )
23
- import warnings
24
33
try :
25
34
import xml .etree .cElementTree as etree
26
35
except ImportError :
27
36
import cElementTree as etree
28
- import hpilo_fw
29
37
30
38
# Which protocol to use
31
39
ILO_RAW = 1
@@ -63,7 +71,7 @@ class Ilo(object):
63
71
and use hponcfg instead. Username and password are ignored for ILO_LOCAL
64
72
connections."""
65
73
66
- XML_HEADER = '<?xml version="1.0"?>\r \n '
74
+ XML_HEADER = b ( '<?xml version="1.0"?>\r \n ' )
67
75
HTTP_HEADER = "POST /ribcl HTTP/1.1\r \n Host: localhost\r \n Content-Length: %d\r \n Connection: Close%s\r \n \r \n "
68
76
HTTP_UPLOAD_HEADER = "POST /cgi-bin/uploadRibclFiles HTTP/1.1\r \n Host: localhost\r \n Connection: Close\r \n Content-Length: %d\r \n Content-Type: multipart/form-data; boundary=%s\r \n \r \n "
69
77
BLOCK_SIZE = 4096
@@ -83,12 +91,14 @@ def __str__(self):
83
91
return "iLO interface of %s" % self .hostname
84
92
85
93
def _debug (self , level , message ):
94
+ if message .__class__ .__name__ == 'bytes' :
95
+ message = message .decode ('latin-1' )
86
96
if self .debug >= level :
97
+ sys .stderr .write (re .sub (r'PASSWORD=".*"' , 'PASSWORD="********"' , message ))
87
98
if message .startswith ('\r ' ):
88
- sys .stderr .write (re .sub (r'PASSWORD=".*"' ,'PASSWORD="********"' , message ))
89
99
sys .stderr .flush ()
90
100
else :
91
- print >> sys .stderr , re . sub ( r'PASSWORD=".*"' , 'PASSWORD="********"' , message )
101
+ sys .stderr . write ( ' \n ' )
92
102
93
103
def _request (self , xml , progress = None ):
94
104
"""Given an ElementTree.Element, serialize it and do the request.
@@ -99,7 +109,7 @@ def _request(self, xml, progress=None):
99
109
100
110
# Serialize the XML
101
111
if hasattr (etree , 'tostringlist' ):
102
- xml = "\r \n " .join (etree .tostringlist (xml )) + '\r \n '
112
+ xml = b ( "\r \n " ) .join (etree .tostringlist (xml )) + b ( '\r \n ' )
103
113
else :
104
114
xml = etree .tostring (xml )
105
115
@@ -135,28 +145,28 @@ def _detect_protocol(self):
135
145
# Do a bogus request, using the HTTP protocol. If there is no
136
146
# header (see special case in communicate(), we should be using the
137
147
# raw protocol
138
- header , data = self ._communicate ('<RIBCL VERSION="2.0"></RIBCL>' , ILO_HTTP )
148
+ header , data = self ._communicate (b ( '<RIBCL VERSION="2.0"></RIBCL>' ) , ILO_HTTP )
139
149
if header :
140
150
self .protocol = ILO_HTTP
141
151
else :
142
152
self .protocol = ILO_RAW
143
153
144
154
def _upload_file (self , filename , progress ):
145
155
firmware = open (filename , 'rb' ).read ()
146
- boundary = '------hpiLO3t' + str (random .randint (100000 ,1000000 )) + 'z'
156
+ boundary = b ( '------hpiLO3t' + str (random .randint (100000 ,1000000 )) + 'z' )
147
157
while boundary in firmware :
148
- boundary = '------hpiLO3t' + str (random .randint (100000 ,1000000 )) + 'z'
158
+ boundary = b ( '------hpiLO3t' + str (random .randint (100000 ,1000000 )) + 'z' )
149
159
parts = [
150
- """--%s \r \n Content-Disposition: form-data; name="fileType"\r \n \r \n """ % boundary ,
151
- """ \r \n --%s \r \n Content-Disposition: form-data; name="fwimgfile"; filename="%s "\r \n Content-Type: application/octet-stream\r \n \r \n """ % ( boundary , filename ),
160
+ b ( "--" ) + boundary + b ( """ \r \n Content-Disposition: form-data; name="fileType"\r \n \r \n """) ,
161
+ b ( " \r \n --" ) + boundary + b ( ''' \r \n Content-Disposition: form-data; name="fwimgfile"; filename="''' ) + b ( filename ) + b ( ''' "\r \n Content-Type: application/octet-stream\r \n \r \n ''' ),
152
162
firmware ,
153
- """ \r \n --%s --\r \n """ % boundary
163
+ b ( " \r \n --" ) + boundary + b ( " --\r \n "),
154
164
]
155
165
total_bytes = sum ([len (x ) for x in parts ])
156
166
sock = self ._get_socket ()
157
167
158
- self ._debug (2 , self .HTTP_UPLOAD_HEADER % (total_bytes , boundary ))
159
- sock .write (self .HTTP_UPLOAD_HEADER % (total_bytes , boundary ))
168
+ self ._debug (2 , self .HTTP_UPLOAD_HEADER % (total_bytes , boundary . decode ( 'ascii' ) ))
169
+ sock .write (b ( self .HTTP_UPLOAD_HEADER % (total_bytes , boundary . decode ( 'ascii' )) ))
160
170
for part in parts :
161
171
if len (part ) < 2048 :
162
172
self ._debug (2 , part )
@@ -182,7 +192,7 @@ def _upload_file(self, filename, progress):
182
192
try :
183
193
while True :
184
194
d = sock .read ()
185
- data += d
195
+ data += d . decode ( 'latin-1' )
186
196
if not d :
187
197
break
188
198
except socket .sslerror : # Connection closed
@@ -237,15 +247,15 @@ def _communicate(self, xml, protocol, progress=None):
237
247
238
248
if protocol == ILO_HTTP :
239
249
self ._debug (2 , http_header )
240
- sock .write (http_header )
250
+ sock .write (b ( http_header ) )
241
251
242
252
self ._debug (2 , self .XML_HEADER + xml )
243
253
244
254
# XML header and data need to arrive in 2 distinct packets
245
255
if self .protocol != ILO_LOCAL :
246
256
sock .write (self .XML_HEADER )
247
- if '$EMBED' in xml :
248
- pre , name , post = re .compile (r'(.*)\$EMBED:(.*)\$(.*)' , re .DOTALL ).match (xml ).groups ()
257
+ if b ( '$EMBED' ) in xml :
258
+ pre , name , post = re .compile (b ( r'(.*)\$EMBED:(.*)\$(.*)' ) , re .DOTALL ).match (xml ).groups ()
249
259
sock .write (pre )
250
260
sent = 0
251
261
fwlen = os .path .getsize (name )
@@ -273,7 +283,7 @@ def _communicate(self, xml, protocol, progress=None):
273
283
data = ''
274
284
try :
275
285
while True :
276
- d = sock .read ()
286
+ d = sock .read (). decode ( 'latin-1' )
277
287
data += d
278
288
if not d :
279
289
break
@@ -411,7 +421,7 @@ def _element_children_to_dict(self, element):
411
421
def _element_to_dict (self , element ):
412
422
"""Returns a dict with tag attributes as items"""
413
423
retval = {}
414
- for key , val in element .attrib .iteritems ():
424
+ for key , val in element .attrib .items ():
415
425
retval [key .lower ()] = self ._coerce (val )
416
426
return retval
417
427
0 commit comments