PVE-mods/PveSensorsV2/PVEMod_Collectors/systemInformation.pm

97 lines
2.6 KiB
Perl

package PVE::PVEMod::Collector::SystemInformation;
use strict;
use warnings;
use Exporter 'import';
use PVE::PVEMod::Config qw(%config);
use PVE::PVEMod::Utils qw(debug);
our @EXPORT_OK = qw(
get_system_information_data
);
# ============================================================================
# System Information — one-time dmidecode call
# ============================================================================
sub get_system_information_data {
unless ($config{system_info}{enabled}) {
debug(__LINE__, "System information collection is disabled");
return {};
}
my $raw_type = $config{system_info}{type};
# Taint-safe: only allow type 1 (System) or 2 (Baseboard/Motherboard)
my $type;
if (defined $raw_type && $raw_type =~ /^([12])$/) {
$type = $1;
} else {
debug(__LINE__, "Invalid system_info type '${\($raw_type // 'undef')}', defaulting to 1");
$type = 1;
}
debug(__LINE__, "Collecting system information via dmidecode -t $type");
return _get_system_info($type);
}
# ============================================================================
# Internal — run dmidecode and parse output
# ============================================================================
sub _get_system_info {
my ($type) = @_;
my $output = `/usr/sbin/dmidecode -t $type 2>/dev/null`;
unless (defined $output && length($output) > 0) {
debug(__LINE__, "No output from dmidecode -t $type");
return {};
}
my %fields;
my @field_order;
for my $line (split /\n/, $output) {
if ($line =~ /^\s+(Manufacturer|Product Name|Serial Number):\s*(.+)$/) {
my ($key, $value) = ($1, $2);
$value =~ s/^\s+|\s+$//g;
my $field_key = lc($key);
$field_key =~ s/ /_/g;
unless (exists $fields{$field_key}) {
push @field_order, $field_key;
$fields{$field_key} = $value;
}
}
}
unless (%fields) {
debug(__LINE__, "No recognised fields found in dmidecode output");
return {};
}
# Build display string: "Manufacturer: X | Product Name: Y | Serial Number: Z"
my %pretty_key = (
manufacturer => 'Manufacturer',
product_name => 'Product Name',
serial_number => 'Serial Number',
);
my @parts;
for my $key (@field_order) {
my $label = $pretty_key{$key} // $key;
push @parts, "$label: $fields{$key}";
}
$fields{display_string} = join(' | ', @parts);
debug(__LINE__, "System information: $fields{display_string}");
return \%fields;
}
1;