1 <!DOCTYPE html PUBLIC 
"-//W3C//DTD XHTML 1.0 Strict//EN" 
   2           "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
   3 <html xmlns=
"http://www.w3.org/1999/xhtml" dir=
"ltr"> 
   5     <meta http-equiv=
"Content-Type" content=
"text/html;charset=utf-8" /> 
   6     <title>Petter Reinholdtsen: Automatically upgrading server firmware on Dell PowerEdge
</title> 
   7     <link rel=
"stylesheet" type=
"text/css" media=
"screen" href=
"http://people.skolelinux.org/pere/blog/style.css" /> 
   8     <link rel=
"stylesheet" type=
"text/css" media=
"screen" href=
"http://people.skolelinux.org/pere/blog/vim.css" /> 
  15      <a href=
"http://people.skolelinux.org/pere/blog/">Petter Reinholdtsen
</a> 
  23       <div class=
"title">Automatically upgrading server firmware on Dell PowerEdge
</div> 
  24       <div class=
"date">21st November 
2011</div> 
  25       <div class=
"body"><p>At work we have heaps of servers.  I believe the total count is
 
  26 around 
1000 at the moment.  To be able to get help from the vendors
 
  27 when something go wrong, we want to keep the firmware on the servers
 
  28 up to date.  If the firmware isn't the latest and greatest, the
 
  29 vendors typically refuse to start debugging any problems until the
 
  30 firmware is upgraded.  So before every reboot, we want to upgrade the
 
  31 firmware, and we would really like everyone handling servers at the
 
  32 university to do this themselves when they plan to reboot a machine.
 
  33 For that to happen we at the unix server admin group need to provide
 
  34 the tools to do so.
</p> 
  36 <p>To make firmware upgrading easier, I am working on a script to
 
  37 fetch and install the latest firmware for the servers we got.  Most of
 
  38 our hardware are from Dell and HP, so I have focused on these servers
 
  39 so far.  This blog post is about the Dell part.
</P> 
  41 <p>On the Dell FTP site I was lucky enough to find
 
  42 <a href=
"ftp://ftp.us.dell.com/catalog/Catalog.xml.gz">an XML file
</a> 
  43 with firmware information for all 
11th generation servers, listing
 
  44 which firmware should be used on a given model and where on the FTP
 
  45 site I can find it.  Using a simple perl XML parser I can then
 
  46 download the shell scripts Dell provides to do firmware upgrades from
 
  47 within Linux and reboot when all the firmware is primed and ready to
 
  48 be activated on the first reboot.
</p> 
  50 <p>This is the Dell related fragment of the perl code I am working on.
 
  51 Are there anyone working on similar tools for firmware upgrading all
 
  52 servers at a site?  Please get in touch and lets share resources.
</p> 
  58 use File::Temp qw(tempdir);
 
  60     # Install needed RHEL packages if missing
 
  62         'XML::Simple' =
> 'perl-XML-Simple',
 
  64     for my $module (keys %rhelmodules) {
 
  67             my $pkg = $rhelmodules{$module};
 
  68             system("yum install -y $pkg");
 
  73 my $errorsto = 'pere@hungry.com';
 
  79 sub run_firmware_script {
 
  80     my ($opts, $script) = @_;
 
  82         print STDERR "fail: missing script name\n";
 
  85     print STDERR "Running $script\n\n";
 
  87     if (
0 == system("sh $script $opts")) { # FIXME correct exit code handling
 
  88         print STDERR "success: firmware script ran succcessfully\n";
 
  90         print STDERR "fail: firmware script returned error\n";
 
  94 sub run_firmware_scripts {
 
  95     my ($opts, @dirs) = @_;
 
  96     # Run firmware packages
 
  98         print STDERR "info: Running scripts in $dir\n";
 
  99         opendir(my $dh, $dir) or die "Unable to open directory $dir: $!";
 
 100         while (my $s = readdir $dh) {
 
 101             next if $s =~ m/^\.\.?/;
 
 102             run_firmware_script($opts, "$dir/$s");
 
 110     print STDERR "info: Downloading $url\n";
 
 111     system("wget --quiet \"$url\"");
 
 116     my $product = `dmidecode -s system-product-name`;
 
 119     if ($product =~ m/PowerEdge/) {
 
 121         # on RHEL, these pacakges are needed by the firwmare upgrade scripts
 
 122         system('yum install -y compat-libstdc++-
33.i686 libstdc++.i686 libxml2.i686 procmail');
 
 124         my $tmpdir = tempdir(
 
 128         fetch_dell_fw('catalog/Catalog.xml.gz');
 
 129         system('gunzip Catalog.xml.gz');
 
 130         my @paths = fetch_dell_fw_list('Catalog.xml');
 
 131         # -q is quiet, disabling interactivity and reducing console output
 
 134             for my $url (@paths) {
 
 137             run_firmware_scripts($fwopts, $tmpdir);
 
 139             print STDERR 
"error: Unsupported Dell model '$product'.\n";
 
 140             print STDERR 
"error: Please report to $errorsto.\n";
 
 144         print STDERR 
"error: Unsupported Dell model '$product'.\n";
 
 145         print STDERR 
"error: Please report to $errorsto.\n";
 
 151     my $url = 
"ftp://ftp.us.dell.com/$path";
 
 155 # Using ftp://ftp.us.dell.com/catalog/Catalog.xml.gz, figure out which
 
 156 # firmware packages to download from Dell.  Only work for Linux
 
 157 # machines and 
11th generation Dell servers.
 
 158 sub fetch_dell_fw_list {
 
 159     my $filename = shift;
 
 161     my $product = `dmidecode -s system-product-name`;
 
 163     my ($mybrand, $mymodel) = split(/\s+/, $product);
 
 165     print STDERR 
"Finding firmware bundles for $mybrand $mymodel\n";
 
 167     my $xml = XMLin($filename);
 
 169     for my $bundle (@{$xml-
>{SoftwareBundle}}) {
 
 170         my $brand = $bundle-
>{TargetSystems}-
>{Brand}-
>{Display}-
>{content};
 
 171         my $model = $bundle-
>{TargetSystems}-
>{Brand}-
>{Model}-
>{Display}-
>{content};
 
 173         if ("ARRAY" eq ref $bundle-
>{TargetOSes}-
>{OperatingSystem}) {
 
 174             $oscode = $bundle-
>{TargetOSes}-
>{OperatingSystem}[
0]-
>{osCode};
 
 176             $oscode = $bundle-
>{TargetOSes}-
>{OperatingSystem}-
>{osCode};
 
 178         if ($mybrand eq $brand && $mymodel eq $model && "LIN" eq $oscode)
 
 180             @paths = map { $_-
>{path} } @{$bundle-
>{Contents}-
>{Package}};
 
 183     for my $component (@{$xml-
>{SoftwareComponent}}) {
 
 184         my $componenttype = $component-
>{ComponentType}-
>{value};
 
 186         # Drop application packages, only firmware and BIOS
 
 187         next if 'APAC' eq $componenttype;
 
 189         my $cpath = $component-
>{path};
 
 190         for my $path (@paths) {
 
 191             if ($cpath =~ m%/$path$%) {
 
 192                 push(@paths, $cpath);
 
 200 <p>The code is only tested on RedHat Enterprise Linux, but I suspect
 
 201 it could work on other platforms with some tweaking.  Anyone know a
 
 202 index like Catalog.xml is available from HP for HP servers?  At the
 
 203 moment I maintain a similar list manually and it is quickly getting
 
 207       <div class=
"tags">Tags: 
<a href=
"http://people.skolelinux.org/pere/blog/tags/debian">debian
</a>, 
<a href=
"http://people.skolelinux.org/pere/blog/tags/english">english
</a>.
</div> 
 225 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2013/01/">January (
11)
</a></li> 
 227 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2013/02/">February (
9)
</a></li> 
 229 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2013/03/">March (
9)
</a></li> 
 231 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2013/04/">April (
6)
</a></li> 
 233 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2013/05/">May (
9)
</a></li> 
 235 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2013/06/">June (
10)
</a></li> 
 237 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2013/07/">July (
7)
</a></li> 
 239 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2013/08/">August (
3)
</a></li> 
 241 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2013/09/">September (
2)
</a></li> 
 248 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2012/01/">January (
7)
</a></li> 
 250 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2012/02/">February (
10)
</a></li> 
 252 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2012/03/">March (
17)
</a></li> 
 254 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2012/04/">April (
12)
</a></li> 
 256 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2012/05/">May (
12)
</a></li> 
 258 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2012/06/">June (
20)
</a></li> 
 260 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2012/07/">July (
17)
</a></li> 
 262 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2012/08/">August (
6)
</a></li> 
 264 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2012/09/">September (
9)
</a></li> 
 266 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2012/10/">October (
17)
</a></li> 
 268 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2012/11/">November (
10)
</a></li> 
 270 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2012/12/">December (
7)
</a></li> 
 277 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2011/01/">January (
16)
</a></li> 
 279 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2011/02/">February (
6)
</a></li> 
 281 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2011/03/">March (
6)
</a></li> 
 283 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2011/04/">April (
7)
</a></li> 
 285 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2011/05/">May (
3)
</a></li> 
 287 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2011/06/">June (
2)
</a></li> 
 289 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2011/07/">July (
7)
</a></li> 
 291 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2011/08/">August (
6)
</a></li> 
 293 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2011/09/">September (
4)
</a></li> 
 295 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2011/10/">October (
2)
</a></li> 
 297 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2011/11/">November (
3)
</a></li> 
 299 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2011/12/">December (
1)
</a></li> 
 306 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2010/01/">January (
2)
</a></li> 
 308 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2010/02/">February (
1)
</a></li> 
 310 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2010/03/">March (
3)
</a></li> 
 312 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2010/04/">April (
3)
</a></li> 
 314 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2010/05/">May (
9)
</a></li> 
 316 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2010/06/">June (
14)
</a></li> 
 318 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2010/07/">July (
12)
</a></li> 
 320 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2010/08/">August (
13)
</a></li> 
 322 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2010/09/">September (
7)
</a></li> 
 324 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2010/10/">October (
9)
</a></li> 
 326 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2010/11/">November (
13)
</a></li> 
 328 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2010/12/">December (
12)
</a></li> 
 335 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2009/01/">January (
8)
</a></li> 
 337 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2009/02/">February (
8)
</a></li> 
 339 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2009/03/">March (
12)
</a></li> 
 341 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2009/04/">April (
10)
</a></li> 
 343 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2009/05/">May (
9)
</a></li> 
 345 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2009/06/">June (
3)
</a></li> 
 347 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2009/07/">July (
4)
</a></li> 
 349 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2009/08/">August (
3)
</a></li> 
 351 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2009/09/">September (
1)
</a></li> 
 353 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2009/10/">October (
2)
</a></li> 
 355 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2009/11/">November (
3)
</a></li> 
 357 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2009/12/">December (
3)
</a></li> 
 364 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2008/11/">November (
5)
</a></li> 
 366 <li><a href=
"http://people.skolelinux.org/pere/blog/archive/2008/12/">December (
7)
</a></li> 
 377  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/3d-printer">3d-printer (
13)
</a></li> 
 379  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/amiga">amiga (
1)
</a></li> 
 381  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/aros">aros (
1)
</a></li> 
 383  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/bankid">bankid (
4)
</a></li> 
 385  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/bitcoin">bitcoin (
7)
</a></li> 
 387  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/bootsystem">bootsystem (
12)
</a></li> 
 389  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/bsa">bsa (
2)
</a></li> 
 391  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/debian">debian (
85)
</a></li> 
 393  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/debian edu">debian edu (
139)
</a></li> 
 395  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/digistan">digistan (
10)
</a></li> 
 397  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/docbook">docbook (
10)
</a></li> 
 399  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/drivstoffpriser">drivstoffpriser (
4)
</a></li> 
 401  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/english">english (
214)
</a></li> 
 403  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/fiksgatami">fiksgatami (
21)
</a></li> 
 405  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/fildeling">fildeling (
12)
</a></li> 
 407  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/freeculture">freeculture (
12)
</a></li> 
 409  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/freedombox">freedombox (
1)
</a></li> 
 411  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/frikanalen">frikanalen (
11)
</a></li> 
 413  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/intervju">intervju (
37)
</a></li> 
 415  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/isenkram">isenkram (
7)
</a></li> 
 417  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/kart">kart (
18)
</a></li> 
 419  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/ldap">ldap (
8)
</a></li> 
 421  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/lenker">lenker (
6)
</a></li> 
 423  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/ltsp">ltsp (
1)
</a></li> 
 425  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/multimedia">multimedia (
25)
</a></li> 
 427  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/norsk">norsk (
235)
</a></li> 
 429  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/nuug">nuug (
153)
</a></li> 
 431  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/offentlig innsyn">offentlig innsyn (
8)
</a></li> 
 433  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/open311">open311 (
2)
</a></li> 
 435  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/opphavsrett">opphavsrett (
44)
</a></li> 
 437  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/personvern">personvern (
66)
</a></li> 
 439  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/raid">raid (
1)
</a></li> 
 441  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/reprap">reprap (
11)
</a></li> 
 443  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/rfid">rfid (
2)
</a></li> 
 445  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/robot">robot (
7)
</a></li> 
 447  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/rss">rss (
1)
</a></li> 
 449  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/ruter">ruter (
4)
</a></li> 
 451  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/scraperwiki">scraperwiki (
2)
</a></li> 
 453  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/sikkerhet">sikkerhet (
30)
</a></li> 
 455  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/sitesummary">sitesummary (
4)
</a></li> 
 457  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/skepsis">skepsis (
4)
</a></li> 
 459  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/standard">standard (
43)
</a></li> 
 461  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/stavekontroll">stavekontroll (
3)
</a></li> 
 463  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/stortinget">stortinget (
8)
</a></li> 
 465  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/surveillance">surveillance (
17)
</a></li> 
 467  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/sysadmin">sysadmin (
1)
</a></li> 
 469  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/valg">valg (
8)
</a></li> 
 471  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/video">video (
38)
</a></li> 
 473  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/vitenskap">vitenskap (
4)
</a></li> 
 475  <li><a href=
"http://people.skolelinux.org/pere/blog/tags/web">web (
27)
</a></li> 
 481     <p style=
"text-align: right"> 
 482  Created by 
<a href=
"http://steve.org.uk/Software/chronicle">Chronicle v4.6
</a>