ansible-ops-management/files/usr/local/bin/dmidecode-pretty

186 lines
6.2 KiB
Perl

#!/usr/bin/perl -w
# Louis Abel <tucklesepk@gmail.com>
use strict;
# Check for version of dmidecode
my $dmi_test = `dmidecode -q 2>/dev/null; echo \$?`;
chomp($dmi_test);
our $dmi_ver = "rhel8";
our $dmidecode_cmd = "dmidecode -q";
if( $dmi_test eq "1" ) { $dmi_ver = "rhel4"; $dmidecode_cmd = "dmidecode"; }
# Figure out number of cores per cpu
my $c_cpuinfo = `grep -c processor /proc/cpuinfo`;
chomp($c_cpuinfo);
my $c_dmidecode = `$dmidecode_cmd | grep -c 'Processor Information'`;
chomp($c_dmidecode);
# Figure out hyperthreaded cores
my $htt;
my $lscpu_test = `lscpu 2>/dev/null; echo \$?`;
chomp($lscpu_test);
if( $lscpu_test eq "127" ) {
$htt = "Cannot Detect Threads";
} else {
$htt = `lscpu | awk -F':' '/Thread/ {print \$2}'`;
chomp($htt);
}
$htt =~ s/^\s+|\s+$//g;
my $cores;
if( $c_cpuinfo eq $c_dmidecode ) {
$cores = "single core";
} elsif ( $c_cpuinfo > $c_dmidecode ) {
my $num_cores = $c_cpuinfo / $c_dmidecode / $htt;
$cores = "$num_cores cores";
} else {
$cores = "failed to determine number of cores";
}
# Parse dmidecode output
our %manufacturer;
our %cpu;
our %memory;
our %network;
open( FH, "$dmidecode_cmd |") or die "Couldn't run $dmidecode_cmd: $!\n\n";
my ($section, $dim, $dim_size);
my $dims_used = 0;
my $dims_total = 0;
my $eths_section = 0;
my $eths_total = 0;
while( my $line = <FH> ) {
chomp($line);
# Store section information
if( $line =~ /^\S+/ ) { $section = $line; }
# Print Bios Information
if( $section eq "BIOS Information" || $section =~ /Handle 0x0000/ ) {
if( $line =~ /^\s+Version:\s+(.+)\s*$/ ) { $manufacturer{bios} = $1; }
}
# Print System Information
if( $section eq "System Information" || $section =~ /Handle 0x0100/ ) {
if( $line =~ /^\s+Manufacturer:\s+(.+)\s*$/ ) { if( $1 =~ /Dell Computer Corporation/ ) { $manufacturer{make} = "Dell Inc."; } else { $manufacturer{make} = $1; } }
if( $line =~ /^\s+Product Name:\s+(.+)\s*$/ ) { my $tmp = $1; $tmp =~ s/\s+$//g; $manufacturer{model} = $tmp; }
if( $line =~ /^\s+Serial Number:\s+(.+)\s*$/ ) { $manufacturer{serial} = $1; }
}
# Print Chassis Information
if( $section eq "Chassis Information" || $section =~ /Handle 0x0300/ ) {
if( $line =~ /^\s+Type:\s+(.+)\s*$/ ) { $manufacturer{chassis_type} = $1; }
if( $line =~ /^\s+Height:\s+(.+)\s*$/ ) { $manufacturer{chassis_height} = $1; }
}
# Print Processor Information
if( $section eq "Processor Information" || $section =~ /Handle 0x040/ ) {
if( $line =~ /^\s+Version:\s+(.+)\s*$/ ) {
my $cpu_model = $1;
if( $cpu_model =~ /Not Specified/ ) {
$cpu_model = `cat /proc/cpuinfo | grep 'model name' | awk -F: {'print \$2'} | head -n 1`;
chomp( $cpu_model );
$cpu_model =~ s/^\s*//g;
}
$cpu_model =~ s/\s+/ /g;
$cpu{physical} = $c_dmidecode;
$cpu{virtual} = $c_cpuinfo;
$cpu{model} = "$cpu_model ($cores) (Threads: $htt)";
}
if( $line =~ /^\s+Speed:\s+(.+)\s*$/ ) { $cpu{speed} = $1; }
}
# Print Physical Memory Array
if( $section eq "Physical Memory Array" || $section =~ /Handle 0x1000/ ) {
if( $line =~ /^\s+Error Correction Type:\s+(.+)\s*$/ ) { $memory{error} = $1; }
if( $line =~ /^\s+Maximum Capacity:\s+(.+)\s*$/ ) { $memory{max} = $1; }
if( $line =~ /^\s+Number Of Devices:\s+(.+)\s*$/ ) { $memory{count} = $1; }
}
# Print Memory Device
if( $section eq "Memory Device" || $section =~ /Handle 0x110/ ) {
if( $line =~ /^\s+Locator:\s+(.+)\s*$/ ) { $dim = $1; $dim =~ s/\s+//g; $dims_total++}
if( $line =~ /^\s+Size:\s+(.+)\s*$/ ) { $dim_size = $1; }
if( $line =~ /^\s+Speed:\s+(.+)\s*$/ ) { next if( $dim_size =~ /No Module Installed/ ); $memory{$dims_total}{location} = $dim; $memory{$dims_total}{size} = $dim_size; $memory{$dims_total}{speed} = $1; $dims_used++; }
if( $line =~ /^\s+Type:\s+(.+)\s*$/ ) { $memory{type} = $1; }
}
# Print Ethernet Devices
$network{total} = 0;
if( $section =~ /^On Board Device/ || $section =~ /Handle 0x0A00/ || $section =~ /^Onboard Device/ ) {
if( $line =~ /^\s+Type:\s+Ethernet\s*$/ ) { $eths_section = 1; $eths_total++; $network{total} = $eths_total; }
next if( $eths_section == 0 );
if( $line =~ /^\s+Status:\s+(.+)\s*$/ ) { $network{$eths_total}{status} = $1; }
if( $line =~ /^\s+Description:\s+(.+)\s*$/ ) { $network{$eths_total}{desc} = $1; }
}
}
close(FH);
# Clean up missing data
$manufacturer{chassis_height} = "<UNKNOWN>" unless( defined($manufacturer{chassis_height}) );
$memory{used} = $dims_total;
#Print Data
print "Make: $manufacturer{make}\n";
print "Model: $manufacturer{model}\n";
print "Serial: $manufacturer{serial}\n";
print "Bios Rev: $manufacturer{bios}\n";
print "Chassis Type: $manufacturer{chassis_type}\n";
print "Chassis Height: $manufacturer{chassis_height}\n";
print "$cpu{physical} x $cpu{model}\n";
print_memory_info();
print_network_info();
#### Functions ####
sub print_memory_info {
my ($maxsize, $max_unit) = $memory{max} =~ /^\s*(\d+)\s*(\w+)\s*$/;
my $dim_count = $memory{count};
my $max_per_dim = $maxsize / $dim_count;
my $size_error = "";
my $speed_error = "";
my $common_size;
my $common_speed;
for( my $i = 1; $i < $dims_used + 1; $i++ ) {
my $size = $memory{$i}{size} || 0;
my $speed = $memory{$i}{speed} || 0;
if( defined($common_size) && $common_size ne $size ) { $size_error = 1; }
else { $common_size = $size; }
if( defined($common_speed) && $common_speed ne $speed ) { $speed_error = 2; }
else { $common_speed = $speed; }
}
my ($mem_size, $mem_unit) = $common_size =~ /^\s*(\d+)\s*(\w+)\s*$/;
my $total_mem_unit = "MB";
if( $mem_unit eq "MB" ) { $total_mem_unit = "GB"; }
my $mem_total = ($mem_size * $dims_used) * 1024 ;
if( $common_size =~ /(\d+\.\d{2})\d+/ ) { $common_size = $1; }
if( $mem_size >= 1024 ) { my $gb_size = $mem_size / 1024; $common_size = "$gb_size GB"; }
print "$common_size @ $common_speed x $dims_used = $mem_total $total_mem_unit";
if( $size_error || $speed_error ) { print " $size_error$speed_error"; }
print "\n";
if( $max_per_dim =~ /(\d+\.\d{2})\d+/ ) { $max_per_dim = $1; }
print "$max_per_dim $max_unit x $dim_count dims = $maxsize $max_unit maximum capacity\n";
print "$memory{type}\n$memory{error}\n";
}
sub print_network_info {
my $num_devices = $network{total};
for( my $i=1; $i < $num_devices + 1; $i++ ) {
print "$network{$i}{desc} [$network{$i}{status}]\n";
}
}