Sponsoring The Perl Toolchain Summit 2025: Help make this important event another success Learn more

#
# (c) Jan Gehring <jan.gehring@gmail.com>
#
use v5.12.5;
our $VERSION = '1.16.0'; # VERSION
use English qw(-no_match_vars);
use Rex;
require Rex::Hardware;
sub get {
my $cache = Rex::get_cache();
my $cache_key_name = $cache->gen_key_name("hardware.host");
if ( $cache->valid($cache_key_name) ) {
return $cache->get($cache_key_name);
}
my $bios = Rex::Inventory::Bios::get();
my $os = get_operating_system();
my ( $domain, $hostname );
if ( $os eq "Windows" ) {
my @env = i_run('set');
($hostname) = map { /^COMPUTERNAME=(.*)$/ } @env;
($domain) = map { /^USERDOMAIN=(.*)$/ } @env;
}
elsif ( $os eq "NetBSD" || $os eq "OpenBSD" || $os eq 'FreeBSD' ) {
( $hostname, $domain ) =
split( /\./, ( eval { i_run("hostname") } || "unknown.nodomain" ), 2 );
}
elsif ( $os eq "SunOS" ) {
($hostname) =
map { /^([^\.]+)$/ } ( eval { i_run("hostname"); } || "unknown" );
($domain) = eval { i_run("domainname"); } || ("nodomain");
}
elsif ( $os eq "OpenWrt" ) {
($hostname) = eval { i_run("uname -n"); } || ("unknown");
($domain) =
eval { i_run("cat /proc/sys/kernel/domainname"); } || ("unknown");
}
else {
my @out = i_run "hostname -f 2>/dev/null", fail_ok => 1;
if ( $? == 0 ) {
( $hostname, $domain ) = split( /\./, $out[0], 2 );
}
else {
Rex::Logger::debug(
"Error getting hostname and domainname. There is something wrong with your /etc/hosts file."
);
($hostname) = eval { i_run("hostname -s"); } || ("unknown");
($domain) = eval { i_run("hostname -d"); } || ("nodomain");
}
}
my $kernelname = q();
if ( can_run('uname') ) {
$kernelname = i_run 'uname -s';
}
my $operating_system_version = get_operating_system_version();
my $data = {
manufacturer => $bios->get_system_information()->get_manufacturer() || "",
hostname => $hostname || "",
domain => $domain || "",
operatingsystem => $os || "",
operating_system => $os || "",
operatingsystemrelease => $operating_system_version,
operating_system_release => $operating_system_version,
kernelname => $kernelname,
};
$cache->set( $cache_key_name, $data );
return $data;
}
sub get_operating_system {
my $cache = Rex::get_cache();
if ( $cache->valid("hardware.host") ) {
my $host_cache = $cache->get("hardware.host");
if ( exists $host_cache->{operatingsystem} ) {
return $host_cache->{operatingsystem};
}
}
# use lsb_release if available
my $is_lsb = can_run("lsb_release");
if ($is_lsb) {
if ( my $ret = i_run "lsb_release -s -i" ) {
if ( $ret =~ m/SUSE/i ) {
$ret = "SuSE";
}
elsif ( $ret eq "ManjaroLinux" ) {
$ret = "Manjaro";
}
return $ret;
}
}
if ( is_dir("c:/") ) {
# windows
return "Windows";
}
if ( is_file("/etc/system-release") ) {
my $content = cat "/etc/system-release";
if ( $content =~ m/Amazon/sm ) {
return "Amazon";
}
}
if ( is_file("/etc/debian_version") ) {
return "Debian";
}
if ( is_file("/etc/SuSE-release") or is_file("/etc/SUSE-brand") ) {
return "SuSE";
}
if ( is_file("/etc/mageia-release") ) {
return "Mageia";
}
if ( is_file("/etc/fedora-release") ) {
return "Fedora";
}
if ( is_file("/etc/gentoo-release") ) {
return "Gentoo";
}
if ( is_file("/etc/altlinux-release") ) {
return "ALT";
}
if ( is_file("/etc/redhat-release") ) {
my $fh = file_read("/etc/redhat-release");
my $content = $fh->read_all;
$fh->close;
chomp $content;
if ( $content =~ m/CentOS/ ) {
return "CentOS";
}
elsif ( $content =~ m/Scientific/ ) {
return "Scientific";
}
else {
return "Redhat";
}
}
if ( is_file("/etc/openwrt_release") ) {
return "OpenWrt";
}
if ( is_file("/etc/arch-release") ) {
return "Arch";
}
if ( is_file("/etc/manjaro-release") ) {
return "Manjaro";
}
my $os_string = i_run("uname -s");
return $os_string; # return the plain os
}
sub get_operating_system_version {
my $cache = Rex::get_cache();
if ( $cache->valid("hardware.host") ) {
my $host_cache = $cache->get("hardware.host");
if ( exists $host_cache->{operatingsystemrelease} ) {
return $host_cache->{operatingsystemrelease};
}
}
my $op = get_operating_system();
my $is_lsb = can_run("lsb_release");
# use lsb_release if available
if ($is_lsb) {
if ( my $ret = i_run "lsb_release -r -s" ) {
my $os_check = i_run "lsb_release -d";
unless ( $os_check =~ m/SUSE\sLinux\sEnterprise/ ) {
return $ret;
}
}
}
if ( $op eq "Debian" ) {
my $fh = file_read("/etc/debian_version");
my $content = $fh->read_all;
$fh->close;
chomp $content;
return $content;
}
elsif ( $op eq "Ubuntu" ) {
my @l = i_run "lsb_release -r -s", fail_ok => 1;
return $l[0];
}
elsif ( lc($op) eq "redhat"
or lc($op) eq "centos"
or lc($op) eq "scientific"
or lc($op) eq "fedora" )
{
my $fh = file_read("/etc/redhat-release");
my $content = $fh->read_all;
$fh->close;
chomp $content;
$content =~ m/(\d+(\.\d+)?)/;
return $1;
}
elsif ( $op eq "Mageia" ) {
my $fh = file_read("/etc/mageia-release");
my $content = $fh->read_all;
$fh->close;
chomp $content;
$content =~ m/(\d+)/;
return $1;
}
elsif ( $op eq "Gentoo" ) {
my $fh = file_read("/etc/gentoo-release");
my $content = $fh->read_all;
$fh->close;
chomp $content;
return [ split( /\s+/, $content ) ]->[-1];
}
elsif ( $op eq "SuSE" ) {
my ( $version, $release );
my $release_file;
if ( is_file("/etc/os-release") ) {
$release_file = "/etc/os-release";
}
else {
$release_file = "/etc/SuSE-release";
}
my $fh = file_read($release_file);
my $content = $fh->read_all;
$fh->close;
chomp $content;
if ( $content =~ m/VERSION_ID/m ) {
($version) = $content =~ m/VERSION_ID="(\d+(?:\.)?\d+)"/m;
}
else {
($version) = $content =~ m/VERSION = (\d+\.\d+)/m;
}
return $version;
}
elsif ( $op eq "ALT" ) {
my $fh = file_read("/etc/altlinux-release");
my $content = $fh->read_all;
$fh->close;
chomp $content;
$content =~ m/(\d+(\.\d+)*)/;
return $1;
}
elsif ( $op =~ /BSD/ ) {
my ($version) = map { /(\d+\.\d+)/ } i_run "uname -r";
return $version;
}
elsif ( $op eq "OpenWrt" ) {
my $fh = file_read("/etc/openwrt_version");
my $content = $fh->read_all;
$fh->close;
chomp $content;
return $content;
}
elsif ( $op eq "Arch" ) {
my $available_updates = i_run "checkupdates", fail_ok => 1;
if ( $available_updates eq "" ) {
return "latest";
}
else {
return "outdated";
}
}
elsif ( $op eq 'Windows' ) {
my $version = i_run 'ver', fail_ok => 1;
if ( $CHILD_ERROR == 0 ) {
return $version;
}
}
return [ i_run("uname -r") ]->[0];
}
1;