-
Notifications
You must be signed in to change notification settings - Fork 102
/
hpilo_fw.py
81 lines (72 loc) · 2.43 KB
/
hpilo_fw.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# Downloader / extracter for latest iLO2 / iLO3 / iLO4 firmware
import tarfile
import os
import sys
PY3 = sys.version_info[0] >= 3
if PY3:
import urllib.request as urllib2
import configparser as ConfigParser
from io import BytesIO, StringIO
b = lambda x: bytes(x, 'ascii')
GZIP_CONSTANT = '\x1f\x8b'.encode('latin-1')
else:
import urllib2
import ConfigParser
from cStringIO import StringIO as StringIO
BytesIO = StringIO
b = lambda x: x
GZIP_CONSTANT = '\x1f\x8b'
_config = None
def config():
global _config
if not _config:
conf = _download('https://raw.github.com/seveas/python-hpilo/master/firmware.conf')
if PY3:
conf = conf.decode('ascii')
parser = ConfigParser.ConfigParser()
parser.readfp(StringIO(conf))
_config = {}
for section in parser.sections():
_config[section] = {}
for option in parser.options(section):
_config[section][option] = parser.get(section, option)
return _config
def _download(url):
req = urllib2.urlopen(url)
size = int(req.headers['Content-Length'])
if size < 4096:
return req.read()
downloaded = 0
data = b('')
while downloaded < size:
new = req.read(4096)
data += new
downloaded += len(new)
sys.stdout.write('\r\033[K%d/%d (%d%%)' % (downloaded, size, downloaded*100.0/size))
sys.stdout.flush()
print("")
return data
def download(ilo, path=None):
if not path:
path = os.getcwd()
conf = config()
if os.path.exists(os.path.join(path, conf[ilo]['file'])):
return
print("Downloading %s firmware version %s" % (ilo, conf[ilo]['version']))
scexe = _download(conf[ilo]['url'])
# An scexe is a shell script with an embedded compressed tarball. Find the tarball.
skip_start = scexe.index(b('_SKIP=')) + 6
skip_end = scexe.index(b('\n'), skip_start)
skip = int(scexe[skip_start:skip_end]) - 1
tarball = scexe.split(b('\n'), skip)[-1]
# Now uncompress it
if tarball[:2] != GZIP_CONSTANT:
raise ValueError("Downloaded scexe file seems corrupt")
tf = tarfile.open(name="bogus_name_for_old_python_versions", fileobj=BytesIO(tarball), mode='r:gz')
tf.extract(conf[ilo]['file'], path)
if __name__ == '__main__':
path = os.getcwd()
if len(sys.argv) > 1:
path = sys.argv[1]
conf = config()
[download(x, path) for x in conf]