# # (c) Jan Gehring <jan.gehring@gmail.com> # # vim: set ts=2 sw=2 tw=0: # vim: set expandtab: package Rex::Hardware::Host; use strict; use warnings; our $VERSION = '1.7.0'; # VERSION use Rex; use Rex::Commands::Run; use Rex::Helper::Run; use Rex::Commands::Fs; use Rex::Commands::File; use Rex::Logger; use Rex::Inventory::Bios; 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); } if ( Rex::is_ssh || $^O !~ m/^MSWin/i ) { my $bios = Rex::Inventory::Bios::get(); my $os = get_operating_system(); my ( $domain, $hostname ); if ( $os eq "Windows" ) { my @env = i_run("env"); ($hostname) = map { /^COMPUTERNAME=(.*)$/ } split( /\r?\n/, @env ); ($domain) = map { /^USERDOMAIN=(.*)$/ } split( /\r?\n/, @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 = eval { i_run("hostname -f 2>/dev/null"); } || ("unknown.nodomain"); ( $hostname, $domain ) = split( /\./, $out[0], 2 ); if ( !$hostname || $hostname eq "" ) { Rex::Logger::debug( "Error getting hostname and domainname. There is something wrong with your /etc/hosts file." ); ($hostname) = eval { i_run("hostname"); } || ("unknown"); } } my $data = { manufacturer => $bios->get_system_information()->get_manufacturer() || "", hostname => $hostname || "", domain => $domain || "", operatingsystem => $os || "", operating_system => $os || "", operatingsystemrelease => get_operating_system_version(), operating_system_release => get_operating_system_version(), kernelname => [ i_run "uname -s" ]->[0], }; $cache->set( $cache_key_name, $data ); return $data; } else { return { operatingsystem => $^O, }; } } 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"; } } return [ i_run("uname -r") ]->[0]; } 1;