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