Petter Reinholdtsen

Entries from November 2011.

Automatically upgrading server firmware on Dell PowerEdge
21st November 2011

At work we have heaps of servers. I believe the total count is around 1000 at the moment. To be able to get help from the vendors when something go wrong, we want to keep the firmware on the servers up to date. If the firmware isn't the latest and greatest, the vendors typically refuse to start debugging any problems until the firmware is upgraded. So before every reboot, we want to upgrade the firmware, and we would really like everyone handling servers at the university to do this themselves when they plan to reboot a machine. For that to happen we at the unix server admin group need to provide the tools to do so.

To make firmware upgrading easier, I am working on a script to fetch and install the latest firmware for the servers we got. Most of our hardware are from Dell and HP, so I have focused on these servers so far. This blog post is about the Dell part.

On the Dell FTP site I was lucky enough to find an XML file with firmware information for all 11th generation servers, listing which firmware should be used on a given model and where on the FTP site I can find it. Using a simple perl XML parser I can then download the shell scripts Dell provides to do firmware upgrades from within Linux and reboot when all the firmware is primed and ready to be activated on the first reboot.

This is the Dell related fragment of the perl code I am working on. Are there anyone working on similar tools for firmware upgrading all servers at a site? Please get in touch and lets share resources.

#!/usr/bin/perl
use strict;
use warnings;
use File::Temp qw(tempdir);
BEGIN {
    # Install needed RHEL packages if missing
    my %rhelmodules = (
        'XML::Simple' => 'perl-XML-Simple',
        );
    for my $module (keys %rhelmodules) {
        eval "use $module;";
        if ($@) {
            my $pkg = $rhelmodules{$module};
            system("yum install -y $pkg");
            eval "use $module;";
        }
    }
}
my $errorsto = 'pere@hungry.com';

upgrade_dell();

exit 0;

sub run_firmware_script {
    my ($opts, $script) = @_;
    unless ($script) {
        print STDERR "fail: missing script name\n";
        exit 1
    }
    print STDERR "Running $script\n\n";

    if (0 == system("sh $script $opts")) { # FIXME correct exit code handling
        print STDERR "success: firmware script ran succcessfully\n";
    } else {
        print STDERR "fail: firmware script returned error\n";
    }
}

sub run_firmware_scripts {
    my ($opts, @dirs) = @_;
    # Run firmware packages
    for my $dir (@dirs) {
        print STDERR "info: Running scripts in $dir\n";
        opendir(my $dh, $dir) or die "Unable to open directory $dir: $!";
        while (my $s = readdir $dh) {
            next if $s =~ m/^\.\.?/;
            run_firmware_script($opts, "$dir/$s");
        }
        closedir $dh;
    }
}

sub download {
    my $url = shift;
    print STDERR "info: Downloading $url\n";
    system("wget --quiet \"$url\"");
}

sub upgrade_dell {
    my @dirs;
    my $product = `dmidecode -s system-product-name`;
    chomp $product;

    if ($product =~ m/PowerEdge/) {

        # on RHEL, these pacakges are needed by the firwmare upgrade scripts
        system('yum install -y compat-libstdc++-33.i686 libstdc++.i686 libxml2.i686 procmail');

        my $tmpdir = tempdir(
            CLEANUP => 1
            );
        chdir($tmpdir);
        fetch_dell_fw('catalog/Catalog.xml.gz');
        system('gunzip Catalog.xml.gz');
        my @paths = fetch_dell_fw_list('Catalog.xml');
        # -q is quiet, disabling interactivity and reducing console output
        my $fwopts = "-q";
        if (@paths) {
            for my $url (@paths) {
                fetch_dell_fw($url);
            }
            run_firmware_scripts($fwopts, $tmpdir);
        } else {
            print STDERR "error: Unsupported Dell model '$product'.\n";
            print STDERR "error: Please report to $errorsto.\n";
        }
        chdir('/');
    } else {
        print STDERR "error: Unsupported Dell model '$product'.\n";
        print STDERR "error: Please report to $errorsto.\n";
    }
}

sub fetch_dell_fw {
    my $path = shift;
    my $url = "ftp://ftp.us.dell.com/$path";
    download($url);
}

# Using ftp://ftp.us.dell.com/catalog/Catalog.xml.gz, figure out which
# firmware packages to download from Dell.  Only work for Linux
# machines and 11th generation Dell servers.
sub fetch_dell_fw_list {
    my $filename = shift;

    my $product = `dmidecode -s system-product-name`;
    chomp $product;
    my ($mybrand, $mymodel) = split(/\s+/, $product);

    print STDERR "Finding firmware bundles for $mybrand $mymodel\n";

    my $xml = XMLin($filename);
    my @paths;
    for my $bundle (@{$xml->{SoftwareBundle}}) {
        my $brand = $bundle->{TargetSystems}->{Brand}->{Display}->{content};
        my $model = $bundle->{TargetSystems}->{Brand}->{Model}->{Display}->{content};
        my $oscode;
        if ("ARRAY" eq ref $bundle->{TargetOSes}->{OperatingSystem}) {
            $oscode = $bundle->{TargetOSes}->{OperatingSystem}[0]->{osCode};
        } else {
            $oscode = $bundle->{TargetOSes}->{OperatingSystem}->{osCode};
        }
        if ($mybrand eq $brand && $mymodel eq $model && "LIN" eq $oscode)
        {
            @paths = map { $_->{path} } @{$bundle->{Contents}->{Package}};
        }
    }
    for my $component (@{$xml->{SoftwareComponent}}) {
        my $componenttype = $component->{ComponentType}->{value};

        # Drop application packages, only firmware and BIOS
        next if 'APAC' eq $componenttype;

        my $cpath = $component->{path};
        for my $path (@paths) {
            if ($cpath =~ m%/$path$%) {
                push(@paths, $cpath);
            }
        }
    }
    return @paths;
}

The code is only tested on RedHat Enterprise Linux, but I suspect it could work on other platforms with some tweaking. Anyone know a index like Catalog.xml is available from HP for HP servers? At the moment I maintain a similar list manually and it is quickly getting outdated.

Tags: debian, english.
Støtt Digitalt Personvern!
9th November 2011

Datalagringsdirektivet er et grotesk angrep på rettsstaten og da det ble vedtatt i Stortinget ble det klart at alle som mener det liberale demokrati bør forsvares måtte stå sammen for å kjempe tilbake de totalitære strømninger i landet. Jeg ble derfor glad over å se at den nyopprettede foreningen Digitalt Personvern startet innsamling 2011-10-18 for å gå til sak for å få prøvd lovligheten av direktivet. Direktivet er så langt prøvd for retten i flere land, blant annet Tsjekkia, Romania og Tyskland, og så vidt jeg vet har det hver gang blitt kjent ulovlig av høyesterett eller forfatningsdomstolen i landene. Jeg håper og tror det samme vil skje her i Norge.

Men for å finne ut av det må det finansiering til. Foreningen Digitalt Personvern tror det trengs minst 2 millioner kroner for å gå til sak og følge saken helt til ende, og i går fikk jeg endelig tid til å overføre min skjerv. Jeg har overført 3000,- til kampanjen, og oppfordrer hver og en av mine lesere å overføre minst like mye.

Besøk donasjonssiden til Digitalt Personvern for å finne kontonummer som kan brukes for å bidra.

Jeg rekker ikke skrive så mye om hvorfor datalagringsdirektivet må stoppes, så jeg nøyer meg denne gangen med en liten liste med lenker til aktuelle artikler og innlegg om temaet.

Tags: dld, norsk, personvern.
Hvordan enkelt laste ned filmer fra NRK
5th November 2011

Ofte har jeg lyst til å laste ned et innslag fra NRKs nettsted for å se det senere når jeg ikke er på nett, eller for å ha det tilgjengelig når jeg en gang i fremtiden ønsker å referere til innslaget selv om NRK har fjernet det fra sine nettsider. I dag fant jeg et lite script som fikser jobben.

Scriptet er laget av Jan Henning Thorsen og tilgjengelig fra github, og gjør det veldig enkelt å laste ned. Kjør nrk-downloader.sh http://www1.nrk.no/nett-tv/klipp/582810 for å hente ned et enkelt innslag eller nrk-downloader.sh http://www1.nrk.no/nett-tv/kategori/3521 for å laste ned alle episodene i en serie.

Det er ikke rakettforskning å laste ned NRK-"strømmer", og tidligere gjorde jeg dette manuelt med mplayer. Scriptet til Hr. Thorsen gjør det raskere og enklere for meg, men jeg vil ikke si at det er en revolusjonerende løsning. Jeg mener jo fortsatt at påstanden fra NRKs ansatte om at det er vesensforskjellig å legge tilgjengelig for nedlasting og for streaming er meningsløs.

Tags: multimedia, norsk, video, web.

RSS Feed

Created by Chronicle v4.6