File Coverage

lib/Rex/Inventory/DMIDecode.pm
Criterion Covered Total %
statement 127 144 88.1
branch 31 40 77.5
condition 5 9 55.5
subroutine 20 20 100.0
pod 0 8 0.0
total 183 221 82.8


line stmt bran cond sub pod time code
1             #
2             # (c) Jan Gehring
3             #
4              
5             package Rex::Inventory::DMIDecode;
6              
7 39     39   68774 use v5.12.5;
  39         147  
8 39     39   208 use warnings;
  39         77  
  39         1030  
9 39     39   857 use Data::Dumper;
  39         7188  
  39         2480  
10              
11             our $VERSION = '1.14.3'; # VERSION
12              
13 39     39   958 use Rex::Inventory::DMIDecode::BaseBoard;
  39         124  
  39         1703  
14 39     39   865 use Rex::Inventory::DMIDecode::Bios;
  39         123  
  39         1651  
15 39     39   884 use Rex::Inventory::DMIDecode::CPU;
  39         133  
  39         1664  
16 39     39   928 use Rex::Inventory::DMIDecode::Memory;
  39         108  
  39         1722  
17 39     39   884 use Rex::Inventory::DMIDecode::MemoryArray;
  39         102  
  39         1786  
18 39     39   947 use Rex::Inventory::DMIDecode::SystemInformation;
  39         120  
  39         1753  
19 39     39   800 use Rex::Commands::Run;
  39         99  
  39         326  
20 39     39   237 use Rex::Helper::Run;
  39         95  
  39         53852  
21              
22             sub new {
23 54     54 0 583 my $that = shift;
24 54   33     747 my $proto = ref($that) || $that;
25 54         238 my $self = {@_};
26              
27 54         221 bless( $self, $proto );
28              
29 54         700 $self->_read_dmidecode();
30              
31 54         1698 return $self;
32             }
33              
34             sub get_tree {
35 122     122 0 414 my ( $self, $section ) = @_;
36              
37 122 50       342 if ($section) {
38 122         742 return $self->{"__dmi"}->{$section};
39             }
40              
41 0         0 return $self->{"__dmi"};
42             }
43              
44             sub get_base_board {
45 3     3 0 1331 my ($self) = @_;
46              
47 3         15 return Rex::Inventory::DMIDecode::BaseBoard->new( dmi => $self );
48             }
49              
50             sub get_bios {
51 3     3 0 16 my ($self) = @_;
52              
53 3         12 return Rex::Inventory::DMIDecode::Bios->new( dmi => $self );
54             }
55              
56             sub get_system_information {
57 54     54 0 398 my ($self) = @_;
58              
59 54         1734 return Rex::Inventory::DMIDecode::SystemInformation->new( dmi => $self );
60             }
61              
62             sub get_cpus {
63              
64 3     3 0 16 my ($self) = @_;
65 3         5 my @cpus = ();
66 3         39 my $tree = $self->get_tree("Processor Information");
67 3         5 my $idx = 0;
68 3         4 for my $cpu ( @{$tree} ) {
  3         7  
69 3 50       14 if ( $cpu->{"Status"} =~ m/Populated/ ) {
70 3         121 push( @cpus,
71             Rex::Inventory::DMIDecode::CPU->new( dmi => $self, index => $idx ) );
72             }
73 3         7 ++$idx;
74             }
75              
76 3         12 return @cpus;
77              
78             }
79              
80             sub get_memory_modules {
81              
82 3     3 0 11 my ($self) = @_;
83 3         3 my @mems = ();
84 3         7 my $tree = $self->get_tree("Memory Device");
85 3         5 my $idx = 0;
86 3         5 for my $mem ( @{$tree} ) {
  3         5  
87 12 100       36 if ( $mem->{"Size"} =~ m/\d+/ ) {
88 3         13 push( @mems,
89             Rex::Inventory::DMIDecode::Memory->new( dmi => $self, index => $idx ) );
90             }
91 12         18 ++$idx;
92             }
93              
94 3         10 return @mems;
95              
96             }
97              
98             sub get_memory_arrays {
99              
100 3     3 0 15 my ($self) = @_;
101 3         5 my @mems = ();
102 3         5 my $tree = $self->get_tree("Physical Memory Array");
103 3         5 my $idx = 0;
104 3         5 for my $mema ( @{$tree} ) {
  3         5  
105 3         12 push(
106             @mems,
107             Rex::Inventory::DMIDecode::MemoryArray->new(
108             dmi => $self,
109             index => $idx
110             )
111             );
112 3         5 ++$idx;
113             }
114              
115 3         25 return @mems;
116              
117             }
118              
119             sub _read_dmidecode {
120              
121 54     54   210 my ($self) = @_;
122              
123 54         192 my @lines;
124 54 100       303 if ( $self->{lines} ) {
125 3         6 @lines = @{ $self->{lines} };
  3         117  
126             }
127             else {
128 51 50       316 unless ( can_run("dmidecode") ) {
129 51         1408 Rex::Logger::debug("Please install dmidecode on the target system.");
130 51         653 return;
131             }
132              
133 0         0 eval { @lines = i_run "dmidecode"; };
  0         0  
134              
135 0 0       0 if ($@) {
136 0         0 Rex::Logger::debug("Error running dmidecode");
137 0         0 return;
138             }
139             }
140 3         33 chomp @lines;
141              
142 3         7 my %section = ();
143 3         5 my $section = "";
144 3         4 my $new_section = 0;
145 3         5 my $sub_section = "";
146              
147 3         8 for my $l (@lines) {
148              
149 735 100       1379 next if $l =~ m/^Handle/;
150 675 100       1077 next if $l =~ m/^#/;
151 672 100       1150 next if $l =~ m/^SMBIOS/;
152 669 100       1281 next if $l =~ m/^$/;
153 609 100       986 last if $l =~ m/^End Of Table$/;
154              
155             # for openbsd
156 606         882 $l =~ s/ /\t/g;
157              
158 606 100       1202 unless ( substr( $l, 0, 1 ) eq "\t" ) {
159 66         88 $section = $l;
160 66         87 $new_section = 1;
161 66         97 next;
162             }
163              
164 540         742 my $line = $l;
165 540         1448 $line =~ s/^\t+//g;
166 540         1174 $line =~ s/\s+$//g;
167              
168 540 50       1064 next if $l =~ m/^$/;
169              
170 540 100       1081 if ( $l =~ m/^\t[a-zA-Z0-9]/ ) {
    50          
171 489 50 66     2149 if ( exists $section{$section} && !ref( $section{$section} ) ) {
    100 66        
172 0         0 my $content = $section{$section};
173 0         0 $section{$section} = [];
174 0         0 my @arr = ();
175 0         0 my ( $key, $val ) = split( /: /, $line, 2 );
176 0         0 $key =~ s/:$//;
177 0         0 $sub_section = $key;
178              
179             #push (@{$section{$section}}, $content);
180 0         0 push( @{ $section{$section} }, { $key => $val } );
  0         0  
181 0         0 $new_section = 0;
182 0         0 next;
183             }
184             elsif ( exists $section{$section} && ref( $section{$section} ) ) {
185 453 100       805 if ($new_section) {
186 24         38 push( @{ $section{$section} }, {} );
  24         56  
187 24         34 $new_section = 0;
188             }
189 453         1084 my ( $key, $val ) = split( /: /, $line, 2 );
190 453         754 $key =~ s/:$//;
191 453         598 $sub_section = $key;
192 453         646 my $href = $section{$section}->[-1];
193              
194             #push (@{$section{$section}}, {$key => $val});
195 453         836 $href->{$key} = $val;
196 453         809 next;
197             }
198              
199 36         99 my ( $key, $val ) = split( /: /, $line, 2 );
200 36 50       73 if ( !$val ) { $key =~ s/:$//; }
  0         0  
201 36         51 $sub_section = $key;
202 36         112 $section{$section} = [ { $key => $val } ];
203 36         70 $new_section = 0;
204             }
205             elsif ( $l =~ m/^\t\t[a-zA-Z0-9]/ ) {
206 51         81 my $href = $section{$section}->[-1];
207 51 100       97 if ( !ref( $href->{$sub_section} ) ) {
208 21         41 $href->{$sub_section} = [];
209             }
210              
211 51         64 push( @{ $href->{$sub_section} }, $line );
  51         131  
212             }
213              
214             }
215              
216 3         48 $self->{"__dmi"} = \%section;
217              
218             }
219              
220             1;