1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
package Ocsinventory::Agent::Backend::Virtualization::Parallels;
use strict;
use warnings;
use XML::Simple;
sub check {
my $params = shift;
my $common = $params->{common};
return $common->can_run('prlctl')
}
sub run {
my $params = shift;
my $common = $params->{common};
my $config = $params->{config};
my %status_list = (
'running' => 'running',
'blocked' => 'blocked',
'paused' => 'paused',
'suspended' => 'suspended',
'crashed' => 'crashed',
'dying' => 'dying',
);
my $xmlfile = undef;
if (defined($config->{server}) && $config->{server}) {
my $dir = $config->{server};
$dir =~ s/\//_/g;
$config->{vardir} = $config->{basevardir}."/".$dir;
} elsif (defined($config->{local}) && $config->{local}) {
$config->{vardir} = $config->{basevardir}."/__LOCAL__";
}
if (-d $config->{vardir}) {
$xmlfile = $config->{vardir}."/uuid.xml";
}
my ($uuid,$mem,$status,$name,$subsys)=undef;
my $cpus = 1;
my @users = ();
# We don't want to scan user directories unless --scan-homedirs is used
return unless $config->{scanhomedirs};
foreach my $lsuser ( glob("/Users/*") ) {
$lsuser =~ s/.*\///; # Just keep the login
next if $lsuser =~ /Shared/i;
next if $lsuser =~ /^\./i; # Ignore hidden directory
next if $lsuser =~ /\ /; # Ignore directory with space in the name
next if $lsuser =~ /'/; # Ignore directory with space in the name
push(@users,$lsuser);
}
foreach my $user (@users) {
my @command = `su $user -c "prlctl list -a"`;
shift (@command);
foreach my $line ( @command ) {
chomp $line;
my @params = split(/ /, $line);
$uuid = $params[0];
$status = $params[1];
# Avoid security risk. Should never appends
next if $uuid =~ /(;\||&)/;
foreach my $infos ( `sudo -u $user prlctl list -i $uuid`) {
if ($infos =~ m/^\s\smemory\s(.*)Mb/) {
$mem = $1;
}
elsif ($infos =~ m/^\s\scpu\s([0-9]{1,2})/) {
$cpus= $1;
}
elsif ($infos =~ m/^Name:\s(.*)/) {
$name = $1;
}
elsif ($infos =~ m/^OS:\s(.*)/) {
$subsys = $1;
}
}
$uuid =~ s/{// if ($uuid =~ m/{/);
$uuid =~ s/}// if ($uuid =~ m/}/);
my ($hwUUID,$currentUUID)=undef;
# if vm is running, fetch the real uuid
if ($status eq 'running') {
my $command = "sudo -u $user prlctl exec $uuid /usr/sbin/ioreg -rd1 -c IOPlatformExpertDevice";
open(IOREG, "$command |") or die "Failed to run '$command': $!\n";
while(<IOREG>) {
if (/^[\s|]*"(\w+)"\s*=\s*(.*)$/) {
next unless $1 eq "IOPlatformUUID";
$currentUUID = $2;
$currentUUID =~ s/\"//g;
}
}
}
if (! -e $xmlfile) {
my $uuid_xml = {
'PARALLELS' => {
'VIRTUALMACHINES' => {
'NAME' => [$name],
'PARALLELSUUID' => [$uuid], # Damned random uuid value
'GUESTUUID' => [$currentUUID], # The true and great uuid value
},
},
};
my $xs = XML::Simple->new(
ForceArray => 1,
KeepRoot => 1,
XMLDecl => '<?xml version="1.0" encoding="UTF-8"?>');
my $xml = $xs->XMLout($uuid_xml);
open (MYFILE, "> $xmlfile");
print MYFILE "$xml"; # write xml output to the newly created file
close (MYFILE);
$hwUUID = $currentUUID; # fetch guest uuid value, even if it's empty (vm not currently running)
} else {
my $parallels = XML::Simple->new(
ForceArray => 1,
KeepRoot => 1,
XMLDecl => '<?xml version="1.0" encoding="UTF-8"?>',
);
my $vm = $parallels->XMLin($xmlfile);
my $numberOfVMs = 0;
my $boolean = 0;
while (defined $vm->{PARALLELS}[0]{VIRTUALMACHINES}[$numberOfVMs]) {
$numberOfVMs+=1;
}
for (my $counter=0; $counter<$numberOfVMs; $counter++) {
if ( $vm->{PARALLELS}[0]{VIRTUALMACHINES}[$counter]{NAME}[0] eq $name ) {
# if the vm with this name exists in the file, set its GUESTUUID value, if the currentUUID isn't empty
if ( defined ($currentUUID)) {
$vm->{PARALLELS}[0]{VIRTUALMACHINES}[$counter]{GUESTUUID}[0] = $currentUUID;
}
$vm->{PARALLELS}[0]{VIRTUALMACHINES}[$counter]{PARALLELSUUID}[0] = $uuid; # if vm re-registered, parallels uuid changes
$boolean = 1;
if ( defined ($vm->{PARALLELS}[0]{VIRTUALMACHINES}[$counter]{GUESTUUID}[0])) {
$hwUUID = $vm->{PARALLELS}[0]{VIRTUALMACHINES}[$counter]{GUESTUUID}[0];
}
}
}
unless ($boolean) {
# if vm doesn't exist, push it to the file
push @{$vm->{PARALLELS}[0]{VIRTUALMACHINES}},
{
NAME => [$name],
PARALLELSUUID => [$uuid],
GUESTUUID => [$currentUUID],
};
}
open (MYFILE, "> $xmlfile");
print MYFILE $parallels->XMLout($vm);
close (MYFILE);
}
$common->addVirtualMachine ({
NAME => $name,
VCPU => $cpus,
MEMORY => $mem,
STATUS => $status,
SUBSYSTEM => $subsys,
VMTYPE => "Parallels",
UUID => $hwUUID,
});
}
}
}
1;
|