Skip to content

Instantly share code, notes, and snippets.

@leucos
Created June 28, 2012 09:05
Show Gist options
  • Select an option

  • Save leucos/3010079 to your computer and use it in GitHub Desktop.

Select an option

Save leucos/3010079 to your computer and use it in GitHub Desktop.
Poor-man's inventory script
#!/usr/bin/perl
use strict;
use threads;
use Thread::Queue::Any;
use Net::OpenSSH;
use Parse::DMIDecode::Constants qw(@TYPES);
use Parse::DMIDecode qw();
use Data::Dumper;
$| = 1;
sub inventory() {
my ($host, $tqueue) = @_;
my $remote = 'root@' . $host;
$SIG{'KILL'} = sub { threads->exit(); };
my $ssh = Net::OpenSSH->new($remote, timeout => 6);
if ($ssh->error) {
print STDERR "ERROR : couldn't establish SSH connection to $host: ". $ssh->error;
$tqueue->enqueue("| [[$host]] |cannot connect|||||\n");
threads->exit();
}
my $result = $ssh->capture("dmidecode");
if (! $result) {
print STDERR "ERROR : remote command failed on $host: " . $ssh->error;
$tqueue->enqueue("| [[$host]] |no dmidecode|||||\n");
threads->exit();
}
my $dmi = Parse::DMIDecode->new( nowarnings => 1 );
$dmi->parse($result);
my $physical_cpus = 0;
my $cpu_slots = 0;
my $total_ram = 0;
my $rammap = "";
for my $handle ($dmi->get_handles(group => "processor")) {
my $type = ($handle->keyword("processor-type") or "");
next unless $type =~ /Central Processor/i;
# Check the status of the cpu
my $status = ($handle->keyword("processor-status") or "");
if ($status !~ /Unpopulated/i) {
$physical_cpus++;
$cpu_slots++;
} else {
$cpu_slots++;
}
}
for my $handle ($dmi->get_handles( group => "memory" )) {
if ($TYPES[$handle->dmitype] eq "Memory Device") {
for my $keyword ($handle->keywords) {
if ($keyword eq "memory-size") {
if ($handle->keyword($keyword) eq "No Module Installed") {
$rammap .= "/0";
} else {
my $ramsize = $handle->keyword($keyword);
$ramsize =~ s/ MB//g;
$total_ram += $ramsize;
$rammap .= "/" . $ramsize;
}
}
}
}
}
$rammap = substr($rammap, 1, length($rammap) - 1);
$rammap =~ s/ MB//g;
my $cpu_type = $dmi->keyword("processor-version");
if ($cpu_type eq "Not Specified") {
$cpu_type = $ssh->capture("cat /proc/cpuinfo | grep 'model name' | head -1 | cut -f2 -d':'") or
die "remote command failed: " . $ssh->error;
chomp($cpu_type);
$cpu_type = substr($cpu_type, 1, length($cpu_type) - 1);
}
my %descr;
$descr{"hostname"} = $host;
$descr{"system-manufacturer"} = $dmi->keyword("system-manufacturer");
$descr{"system-product-name"} = $dmi->keyword("system-product-name");
$descr{"cpu-count"} = $physical_cpus;
$descr{"cpu-slots"} = $cpu_slots;
$descr{"cpu-type"} = $cpu_type;
$descr{"ram-total"} = $total_ram;
$descr{"ram-map"} = $rammap;
$descr{"system-serial-number"} = $dmi->keyword("system-serial-number");
$tqueue->enqueue(%descr);
threads->exit();
}
sub main() {
my $tqueue = Thread::Queue::Any->new;
my @joinable;
my $thr;
my %results;
my $starttime = time();
my $TIMEOUT = 10; # secs
foreach my $server (@ARGV) {
my $thr = threads->create(\&inventory, $server, $tqueue);
}
while (threads->list()) {
last if ((time() - $starttime) > $TIMEOUT);
@joinable = threads->list(threads::joinable);
foreach my $thr (@joinable) { $thr->join(); }
}
my @leftovers = threads->list();
foreach my $thr (@leftovers) { $thr->kill('KILL')->detach(); }
while ($tqueue->pending()) {
my %data = $tqueue->dequeue();
$results{$data{'hostname'}} = { %data };
}
print "\n^ Hostname ^ Model ^ CPU ^ RAM ^ Serial ^ iLO IP ^\n";
foreach my $host (sort keys %results) {
my $line = "| [[" . $host . "]] | ";
$line .= $results{$host}{'system-manufacturer'} . " " . $results{$host}{'system-product-name'} . " | ";
$line .= $results{$host}{'cpu-count'} . "(/" . $results{$host}{'cpu-slots'} . ') x ' . $results{$host}{'cpu-type'} . ' | ';
$line .= $results{$host}{'ram-total'} . " MB (" . $results{$host}{'ram-map'} . ') | ';
$line .= $results{$host}{'system-serial-number'} . ' | | ';
$line .= "\n";
print $line;
}
}
&main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment