# Dealing with iLO firmware updates

One of the key features of python_hpilo is that it makes iLO firmware updates painless. It can download the firmware for you, or you can feed it the .bin or .scexe files HP ships.

## From the CLI

The method to call is `update_rib_firmware()`. To tell it which firmware version to install, you can specify a version or a filename. To install the latest version, you can use `latest` as version. Information about available version numbers can be found in firmware.conf.

Some example commands:

    hpilo_cli example-server.int.kaarsemaker.net update_rib_firmware version=1.28
    hpilo_cli example-server.int.kaarsemaker.net update_rib_firmware version=latest
    hpilo_cli example-server.int.kaarsemaker.net update_rib_firmware filename=CP007684.scexe
    hpilo_cli example-server.int.kaarsemaker.net update_rib_firmware filename=ilo2_225.bin

If you just want to download the firmware, you can make `hpilo_cli` do that too:

    hpilo_cli download_rib_firmware all        # Download latest firmware for all iLO types
    hpilo_cli download_rib_firmware ilo4       # Download latest iLO 4 firmware
    hpilo_cli download_rib_firmware ilo4 1.50  # Download a specific firmware version
    hpilo_cli download_rib_firmware ilo4 all   # Download all firmware versions for iLO 4
    hpilo_cli download_rib_firmware all all    # Download all firmware versions for all iLO types

## Using the API

As the CLI is merely a thin wrapper around the API, using the API is as expected:

    ilo = hpilo.Ilo(hostname, login, password)
    ilo.update_rib_firmware(version='latest')

But since firmware updates may take a while, the iLO can provide progress messages, which your code may in turn show to your users. To receive these progress message, pass a callable to the `update_rib_firmware()` function. It will be called with single-line messages about the progress of the firmware download, upload and flash processes. This example shows them to the user, constantly overwriting the previous message:

    def print_progress(text):
        sys.stdout.write('\r\033[K' + text)
        sys.stdout.flush()

    ilo = hpilo.Ilo(hostname, login, password)
    ilo.update_rib_firmware(version='latest', progress=print_progress)
    print("")

Of course the firmware downloader can be used from the API as well:

    import hpilo_fw
    hpilo_fw.download('ilo4', path='/var/cache/ilo_fw/', progress=print_progress)
    hpilo_fw.download('ilo3 1.28', path='/var/cache/ilo_fw', progress=print_progress)

## Using a local firmware mirror

The firmware download functions connect to the internet to download firmware. While they can be made to use a proxy, using the standard `https_proxy` and `http_proxy` variables, it may be desirable to only download data from inside your network.

To do this, you can set a variable in ilo.conf for the cli:

    [firmware]
    mirror = http://buildserver.example.com/ilo-firmware/

Or if you use the API, configure the firmware downloader, both the downloader and the updater will then use your mirror:

    import hpilo, hpilo_fw
    hpilo_fw.config(mirror='http://buildserver.example.com/ilo-firmware/')

    ilo = hpilo.Ilo(hostname, login, password)
    ilo.update_rib_firmware(version='latest', progress=print_progress)
    print("")

    hpilo_fw.download('ilo4', progress=print_progress)

Your mirror should contain both `firmware.conf`, and the `bin` files for all firmware versions you want to support. You can create (and auto-update via cron) such a mirror with a simple shellscript:

    #!/bin/sh

    cd /var/www/html/ilo-firmware
    wget -q https://raw.githubusercontent.com/seveas/python-hpilo/master/firmware.conf
    hpilo_cli -c /dev/null download_rib_firmware all all

This will download and extract the necessary files to `/var/www/html/ilo-firmware`.