File Coverage

blib/lib/FusionInventory/Agent/Task/Inventory/Virtualization/Vmsystem.pm
Criterion Covered Total %
statement 15 90 16.6
branch 0 64 0.0
condition 0 12 0.0
subroutine 5 12 41.6
pod 0 2 0.0
total 20 180 11.1


line stmt bran cond sub pod time code
1             package FusionInventory::Agent::Task::Inventory::Virtualization::Vmsystem;
2              
3 1     1   38306353 use strict;
  1         17  
  1         73  
4 1     1   6 use warnings;
  1         1  
  1         69  
5              
6 1     1   406 use FusionInventory::Agent::Tools;
  1         2  
  1         138  
7 1     1   393 use FusionInventory::Agent::Tools::Solaris;
  1         2  
  1         1011  
8              
9             my @vmware_patterns = (
10             'VMware vmxnet virtual NIC driver',
11             'Vendor: VMware\s+Model: Virtual disk',
12             'Vendor: VMware,\s+Model: VMware Virtual ',
13             ': VMware Virtual IDE CDROM Drive'
14             );
15             my $vmware_pattern = _assemblePatterns(@vmware_patterns);
16              
17             my @qemu_patterns = (
18             ' QEMUAPIC ',
19             'QEMU Virtual CPU',
20             ': QEMU HARDDISK,',
21             ': QEMU CD-ROM,'
22             );
23             my $qemu_pattern = _assemblePatterns(@qemu_patterns);
24              
25             my @virtual_machine_patterns = (
26             ': Virtual HD,',
27             ': Virtual CD,'
28             );
29             my $virtual_machine_pattern = _assemblePatterns(@virtual_machine_patterns);
30              
31             my @virtualbox_patterns = (
32             ' VBOXBIOS ',
33             ': VBOX HARDDISK,',
34             ': VBOX CD-ROM,',
35             );
36             my $virtualbox_pattern = _assemblePatterns(@virtualbox_patterns);
37              
38             my @xen_patterns = (
39             'Hypervisor signature: xen',
40             'Xen virtual console successfully installed',
41             'Xen reported:',
42             'Xen: \d+ - \d+',
43             'xen-vbd: registered block device',
44             'ACPI: [A-Z]{4} \(v\d+\s+Xen ',
45             );
46             my $xen_pattern = _assemblePatterns(@xen_patterns);
47              
48             my %module_patterns = (
49             '^vmxnet\s' => 'VMware',
50             '^xen_\w+front\s' => 'Xen',
51             );
52              
53             sub isEnabled {
54 0     0 0 0 return 1;
55             }
56              
57             sub doInventory {
58 0     0 0 0 my (%params) = @_;
59              
60 0         0 my $inventory = $params{inventory};
61 0         0 my $logger = $params{logger};
62              
63             # return immediatly if vm type has already been found
64 0 0       0 return if $inventory->{content}{HARDWARE}{VMSYSTEM} ne "Physical";
65              
66 0         0 my $type = _getType($logger);
67              
68             # for consistency with HVM domU
69 0 0 0     0 if (
70             $type eq 'Xen' &&
71             !$inventory->{h}{CONTENT}{BIOS}{SMANUFACTURER}
72             ) {
73 0         0 $inventory->setBios({
74             SMANUFACTURER => 'Xen',
75             SMODEL => 'PVM domU'
76             });
77             }
78              
79 0 0       0 my $vmid = $type eq 'Virtuozzo' ?
80             _getOpenVZVmID(logger => $logger) : undef;
81              
82 0 0       0 my $uuid = $type eq 'Xen' ? _getXenUUID(logger => $logger) :
    0          
83             $type eq 'LXC' ? _getLibvirtLXC_UUID(logger => $logger) :
84             undef;
85              
86 0         0 $inventory->setHardware({
87             VMSYSTEM => $type,
88             UUID => $uuid,
89             VMID => $vmid
90             });
91             }
92              
93             sub _getType {
94 0     0   0 my ($logger) = @_;
95              
96 0 0       0 if (-f '/.dockerinit') {
97 0         0 return 'Docker';
98             }
99              
100             # Solaris zones
101 0 0       0 if (canRun('/usr/sbin/zoneadm')) {
102 0         0 my $zone = getZone();
103 0 0       0 return 'SolarisZone' if $zone ne 'global';
104             }
105              
106             # Xen PV host
107 0 0 0     0 if (
108             -d '/proc/xen' ||
109             getFirstMatch(
110             file => '/sys/devices/system/clocksource/clocksource0/available_clocksource',
111             pattern => qr/xen/
112             )
113             ) {
114 0 0       0 if (getFirstMatch(
115             file => '/proc/xen/capabilities',
116             pattern => qr/control_d/
117             )) {
118             # dom0 host
119 0         0 return 'Physical';
120             } else {
121             # domU PV host
122 0         0 return 'Xen';
123             }
124             }
125              
126 0         0 my $result;
127              
128 0 0       0 if (canRun('/sbin/sysctl')) {
129 0         0 my $handle = getFileHandle(
130             command => '/sbin/sysctl -n security.jail.jailed',
131             logger => $logger
132             );
133 0         0 my $line = <$handle>;
134 0         0 close $handle;
135 0 0 0     0 return 'BSDJail' if $line && $line == 1;
136             }
137              
138             # loaded modules
139              
140 0 0       0 if (-f '/proc/modules') {
141 0         0 my $handle = getFileHandle(
142             file => '/proc/modules',
143             logger => $logger
144             );
145 0         0 while (my $line = <$handle>) {
146 0         0 foreach my $pattern (keys %module_patterns) {
147 0 0       0 next unless $line =~ /$pattern/;
148 0         0 $result = $module_patterns{$pattern};
149 0         0 last;
150             }
151             }
152 0         0 close $handle;
153             }
154 0 0       0 return $result if $result;
155              
156             # dmesg
157              
158 0         0 my $handle;
159 0 0       0 if (-r '/var/log/dmesg') {
    0          
    0          
160 0         0 $handle = getFileHandle(file => '/var/log/dmesg', logger => $logger);
161             } elsif (-x '/bin/dmesg') {
162 0         0 $handle = getFileHandle(command => '/bin/dmesg', logger => $logger);
163             } elsif (-x '/sbin/dmesg') {
164             # On OpenBSD, dmesg is in sbin
165             # http://forge.fusioninventory.org/issues/402
166 0         0 $handle = getFileHandle(command => '/sbin/dmesg', logger => $logger);
167             }
168              
169 0 0       0 if ($handle) {
170 0         0 $result = _matchPatterns($handle);
171 0         0 close $handle;
172 0 0       0 return $result if $result;
173             }
174              
175             # scsi
176              
177 0 0       0 if (-f '/proc/scsi/scsi') {
178 0         0 my $handle = getFileHandle(
179             file => '/proc/scsi/scsi',
180             logger => $logger
181             );
182 0         0 $result = _matchPatterns($handle);
183 0         0 close $handle;
184             }
185 0 0       0 return $result if $result;
186              
187 0 0       0 if (getFirstMatch(
188             file => '/proc/1/environ',
189             pattern => qr/container=lxc/
190             )) {
191 0         0 return 'lxc';
192             }
193              
194             # OpenVZ
195 0 0       0 if (-f '/proc/self/status') {
196 0         0 my $handle = getFileHandle(
197             file => '/proc/self/status',
198             logger => $logger
199             );
200 0         0 while (my $line = <$handle>) {
201 0         0 my ($key, $value) = split(/:/, $line);
202 0 0 0     0 $result = "Virtuozzo" if $key eq 'envID' && $value > 0;
203             }
204             }
205 0 0       0 return $result if $result;
206              
207 0         0 return 'Physical';
208             }
209              
210             sub _assemblePatterns {
211 5     5   6 my (@patterns) = @_;
212              
213 5         12 my $pattern = '(?:' . join('|', @patterns) . ')';
214 5         206 return qr/$pattern/;
215             }
216              
217             sub _matchPatterns {
218 0     0     my ($handle) = @_;
219              
220 0           while (my $line = <$handle>) {
221 0 0         return 'VMware' if $line =~ $vmware_pattern;
222 0 0         return 'QEMU' if $line =~ $qemu_pattern;
223 0 0         return 'Virtual Machine' if $line =~ $virtual_machine_pattern;
224 0 0         return 'VirtualBox' if $line =~ $virtualbox_pattern;
225 0 0         return 'Xen' if $line =~ $xen_pattern;
226             }
227             }
228              
229             sub _getOpenVZVmID {
230 0     0     return getFirstMatch(
231             file => '/proc/self/status',
232             pattern => qr/^envID:\s*(\d+)/,
233             @_
234             );
235             }
236              
237             sub _getXenUUID {
238 0     0     return getFirstLine(
239             file => '/sys/hypervisor/uuid',
240             @_
241             );
242             }
243              
244             sub _getLibvirtLXC_UUID {
245 0     0     my (%params) = (
246             file => '/proc/1/environ',
247             @_
248             );
249              
250 0           my @environ = split( '\0', getAllLines( %params ) );
251              
252 0           foreach my $variable (@environ) {
253 0 0         next unless $variable =~ /^LIBVIRT_LXC_UUID/;
254 0           my (undef, $value) = split('=', $variable);
255 0           return $value;
256             }
257              
258             ## no critic (ExplicitReturnUndef)
259 0           return undef;
260             }
261              
262             1;