688 lines
22 KiB
Perl
688 lines
22 KiB
Perl
# IBM(c) 2008 EPL license http://www.eclipse.org/legal/epl-v10.html
|
|
# Ver. 2.1 (4) - sf@mauricebrinkmann.de
|
|
# Ver. 3.0 - Herbert Mehlhose, IBM - add support of VirtualBox V4
|
|
#
|
|
#-------------------------------------------------------
|
|
|
|
=head1
|
|
xCAT plugin package to handle VirtualBox machines
|
|
|
|
Supported command:
|
|
rpower
|
|
|
|
=cut
|
|
|
|
#-------------------------------------------------------
|
|
package xCAT_plugin::vbox;
|
|
require Sys::Hostname;
|
|
require xCAT::Table;
|
|
|
|
require xCAT::Utils;
|
|
require xCAT::TableUtils;
|
|
require xCAT::ServiceNodeUtils;
|
|
require xCAT::MsgUtils;
|
|
use Getopt::Long;
|
|
1;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
#-------------------------------------------------------
|
|
|
|
=head3 handled_commands
|
|
|
|
Return list of commands handled by this plugin
|
|
|
|
=cut
|
|
|
|
#-------------------------------------------------------
|
|
|
|
sub handled_commands
|
|
{
|
|
return {rpower => 'nodehm:power,mgt'};
|
|
}
|
|
|
|
#-------------------------------------------------------
|
|
|
|
=head3 preprocess_request
|
|
|
|
Check and setup for hierarchy
|
|
|
|
=cut
|
|
|
|
#-------------------------------------------------------
|
|
sub preprocess_request
|
|
{
|
|
my $req = shift;
|
|
my $cb = shift;
|
|
if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; }
|
|
#exit if preprocessed
|
|
my $nodes = $req->{node};
|
|
my $service = "xcat";
|
|
|
|
# find service nodes for requested nodes
|
|
# build an individual request for each service node
|
|
my $sn = xCAT::ServiceNodeUtils->get_ServiceNode($nodes, $service, "MN");
|
|
|
|
my @requests = ();
|
|
|
|
# build each request for each service node
|
|
foreach my $snkey (keys %$sn) {
|
|
my $n=$sn->{$snkey};
|
|
print "snkey=$snkey, nodes=@$n\n";
|
|
my $reqcopy = {%$req};
|
|
$reqcopy->{node} = $sn->{$snkey};
|
|
$reqcopy->{'_xcatdest'} = $snkey;
|
|
$reqcopy->{_xcatpreprocessed}->[0] = 1;
|
|
push @requests, $reqcopy;
|
|
|
|
}
|
|
return \@requests;
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------
|
|
|
|
=head3 process_request
|
|
|
|
Process the command
|
|
|
|
=cut
|
|
|
|
#-------------------------------------------------------
|
|
sub process_request
|
|
{
|
|
|
|
my $request = shift;
|
|
our $callback = shift;
|
|
my $nodes = $request->{node};
|
|
my $command = $request->{command}->[0];
|
|
my $args = $request->{arg};
|
|
my $envs = $request->{env};
|
|
our $rsp;
|
|
my $node;
|
|
|
|
my $soapsupport = eval { require SOAP::Lite; };
|
|
unless ($soapsupport) { #Still no SOAP::Lite module
|
|
$callback->({error=>"SOAP::Lite perl module missing, unable to fulfill Virtual Box plugin requirements",errorcode=>[42]});
|
|
return [];
|
|
}
|
|
require xCAT::vboxService;
|
|
|
|
my @nodes=@$nodes;
|
|
|
|
PROCESSNODES: foreach $node (@nodes) ######################################
|
|
{
|
|
# Load node information from xCAT tables
|
|
my ($error, $url, $username, $password, $vmname, $vncport) = getInfo($node);
|
|
next PROCESSNODES if ($error == 1);
|
|
last PROCESSNODES if ($error == 2);
|
|
|
|
# Create connection to VirtualBox web service
|
|
my $api; # we assume V4 as default API
|
|
my $vbox = getWebService($url, $username, $password, $node);
|
|
next PROCESSNODES if (!$vbox);
|
|
|
|
# get version
|
|
my $vboxvers = xCAT::vboxService->IVirtualBox_getVersion($url, $vbox);
|
|
#$callback->({info=>"$node: Vbox version: '$vboxvers', requested vncport via xCAT 'vm' table: '$vncport'"});
|
|
if ($vboxvers =~ "^3.0" and $vncport =~ ",")
|
|
{
|
|
addError("$node: VirtualBox version 3.0 does only support a single RDP port, please correct entry vncport='$vncport' in table 'vm' for this node.");
|
|
next PROCESSNODES;
|
|
}
|
|
if($vboxvers =~ "^3.") {
|
|
$api="3"; # There is no getAPIVersion in Version 3, set to 3
|
|
} elsif($vboxvers =~ "^4.0") {
|
|
$api="4_0"; # There is no getAPIVersion in Version 4.0 set to 4_0
|
|
} else {
|
|
$api = xCAT::vboxService->IVirtualBox_getAPIVersion($url, $vbox);
|
|
}
|
|
# Get the machine
|
|
my $machine = getMachine($api, $url, $vbox, $vmname, $node);
|
|
if ($machine) {
|
|
|
|
# Command differentiation #------------------------------------
|
|
|
|
if ($command eq "rpower" and @$args > 0) {
|
|
powerCtrl($vboxvers, $api, $url, $vbox, $machine, $vmname, $node, $vncport, $args);
|
|
}
|
|
|
|
#else # unrecognized command
|
|
#{
|
|
# addError("$node: $command unsupported on vm");
|
|
#}
|
|
|
|
# End Command differentiation #--------------------------------
|
|
|
|
} # /existing $machine reference
|
|
|
|
xCAT::vboxService->IWebsessionManager_logoff($url, $vbox);
|
|
|
|
} # /for each $node in @nodes
|
|
continue
|
|
{
|
|
# print out status before waiting for others and others and ..
|
|
printMessages();
|
|
|
|
# yield???
|
|
}
|
|
|
|
# last chance to print remaining messages
|
|
printMessages();
|
|
|
|
return;
|
|
|
|
|
|
sub addMessage ############################################################
|
|
{
|
|
push @{$rsp->{data}}, shift;
|
|
|
|
} # /addMessage
|
|
|
|
sub addError ##############################################################
|
|
{
|
|
push @{$rsp->{error}}, shift;
|
|
|
|
} # /addError
|
|
|
|
|
|
sub printMessages #########################################################
|
|
{
|
|
if (defined($rsp->{data}) or defined($rsp->{error})) {
|
|
if (defined($rsp->{error})) {
|
|
push @{$rsp->{errorcode}}, 1;
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 0);
|
|
} else {
|
|
xCAT::MsgUtils->message("I", $rsp, $callback, 0);
|
|
}
|
|
}
|
|
|
|
} # /printMessages
|
|
|
|
|
|
sub powerCtrl #############################################################
|
|
{
|
|
my ($vboxvers, $api, $url, $vbox, $machine, $vmname, $node, $vncport, $args) =
|
|
(shift, shift, shift, shift, shift, shift, shift, shift, shift);
|
|
|
|
# Get state of the machine first
|
|
my $cmd = "IMachine_getState";
|
|
if($api eq "3") {
|
|
$cmd=$cmd . "_V3";
|
|
}
|
|
my $vmstate = xCAT::vboxService->$cmd($url, $machine);
|
|
|
|
# Check if there is anything to do
|
|
if (!$vmstate) {
|
|
addError("$node: Can not determine vm's state!");
|
|
return;
|
|
} elsif ($vmstate =~ m/^PoweredOff|^Aborted|^Saved/) {
|
|
if ($args->[0] eq "off") {
|
|
addMessage("$node: off");
|
|
return;
|
|
} elsif ($args->[0] =~ m/^reset|^boot/) {
|
|
# if machine is off: turn on when reset was choosen
|
|
$args->[0] = "on reset";
|
|
} elsif ($args->[0] =~ m/^stat/) {
|
|
# addMessage("$node: off ($vmstate)");
|
|
addMessage("$node: off");
|
|
return;
|
|
}
|
|
} else {
|
|
if ($args->[0] eq "on") {
|
|
addMessage("$node: on");
|
|
return;
|
|
} elsif ($args->[0] =~ m/^stat/) {
|
|
# addMessage("$node: on ($vmstate)");
|
|
addMessage("$node: on");
|
|
return;
|
|
}
|
|
}
|
|
|
|
# Determine machine's UUID - Should work since we got the state
|
|
$cmd = "IMachine_getId";
|
|
if($api eq "3") {$cmd=$cmd . "_V3";}
|
|
my $uuid = xCAT::vboxService->$cmd($url, $machine);
|
|
|
|
# Open Session
|
|
my $session = getSession($api, $url, $vbox, $node, $vmname);
|
|
if ($session) {
|
|
# Decide what to do
|
|
if ($args->[0] =~ m/^on/) {
|
|
if($api eq "3") {
|
|
powerOn_V3($vboxvers, $url, $vbox, $machine, $session, $uuid, $node, $vncport, $args);
|
|
} else {
|
|
powerOn($url, $vbox, $machine, $session, $uuid, $node, $vncport, $args);
|
|
}
|
|
} else {
|
|
if($api eq "3") {
|
|
powerOff_V3($url, $vbox, $session, $machine, $uuid, $node, $args);
|
|
} else {
|
|
powerOff($url, $vbox, $session, $machine, $uuid, $node, $args);
|
|
}
|
|
}
|
|
|
|
xCAT::vboxService->ISession_unlockMachine($url,$session);
|
|
} # /existing $session
|
|
|
|
return;
|
|
|
|
|
|
sub powerOn #**********************************************************
|
|
{
|
|
my ($url, $vbox, $machine, $session, $uuid, $node, $vncport, $args) =
|
|
(shift, shift, shift, shift, shift, shift, shift, shift);
|
|
|
|
my $locktype="Write";
|
|
xCAT::vboxService->IMachine_lockMachine($url,$machine,$session,$locktype);
|
|
|
|
my $directmachine = xCAT::vboxService->ISession_getMachine($url, $session);
|
|
if (!$directmachine) {
|
|
addError("$node: Could not access mutable machine");
|
|
} else {
|
|
my $vrde = xCAT::vboxService->IMachine_getVRDEServer($url, $directmachine);
|
|
|
|
# 'Oracle VM VirtualBox Extension Pack' needs to be installed on vbox server
|
|
# to be able to use RDP
|
|
my $extpack;
|
|
my @VRDEextpack = xCAT::vboxService->IVRDEServer_getVRDEExtPack($url, $vrde);
|
|
foreach(@VRDEextpack) {
|
|
if($_ eq "Oracle VM VirtualBox Extension Pack") {
|
|
$extpack=1;
|
|
}
|
|
}
|
|
|
|
if($extpack) {
|
|
my $hasVRDE = xCAT::vboxService->IVRDEServer_getEnabled($url, $vrde);
|
|
|
|
my $prop="TCP/Ports";
|
|
my $portno = xCAT::vboxService->IVRDEServer_getVRDEProperty($url, $vrde, $prop);
|
|
|
|
if ($vncport) { # vncport determines, if rdp will be enabled
|
|
my $change;
|
|
# If port is specified but different: Update machine settings
|
|
if($hasVRDE eq "false") {
|
|
$hasVRDE="true";
|
|
xCAT::vboxService->IVRDEServer_setEnabled($url, $vrde, $hasVRDE);
|
|
$change=1;
|
|
}
|
|
if($vncport ne $portno) {
|
|
xCAT::vboxService->IVRDEServer_setVRDEProperty($url, $vrde, $prop, $vncport);
|
|
$change=1;
|
|
}
|
|
if($change) {
|
|
xCAT::vboxService->IMachine_saveSettings($url, $directmachine);
|
|
}
|
|
} elsif (!$vncport and $hasVRDE eq "true") {
|
|
# If not specified: disable RDP for the guest
|
|
$hasVRDE="false";
|
|
xCAT::vboxService->IVRDEServer_setEnabled($url, $vrde, $hasVRDE);
|
|
xCAT::vboxService->IMachine_saveSettings($url, $directmachine);
|
|
}
|
|
#xCAT::vboxService->IMachine_saveSettings($url, $directmachine);
|
|
xCAT::vboxService->IManagedObjectRef_release($url, $directmachine);
|
|
} else {
|
|
if($vncport) {
|
|
addMessage("Warning: for VirtualBox Version 4 and above, RDP needs the VRDE Extension Pack to be installed on the VirtualBox host system. Either install this package to use RDP with the guest machine or remove the 'vncport' from xCAT vm table for '$node' to avoid this warning message to appear. Starting without RDP for now.");
|
|
}
|
|
}
|
|
}
|
|
|
|
xCAT::vboxService->ISession_unlockMachine($url,$session);
|
|
|
|
my $progress = xCAT::vboxService->IMachine_launchVMProcess($url, $machine, $session, "headless", ""); #gui
|
|
|
|
if (!$progress) {
|
|
addError("$node: Can not open remote session");
|
|
} else { # existing $progress
|
|
xCAT::vboxService->IProgress_waitForCompletion($url, $progress, -1);
|
|
|
|
if (xCAT::vboxService->IProgress_getCompleted($url, $progress)) {
|
|
addMessage("$node: $args->[0]");
|
|
} else { # not successfully completed
|
|
addError("$node: Power on failed");
|
|
}
|
|
|
|
} # /existing $progress
|
|
|
|
return;
|
|
|
|
} # /powerOn
|
|
|
|
|
|
sub powerOn_V3 #**********************************************************
|
|
{
|
|
my ($vboxvers, $url, $vbox, $machine, $session, $uuid, $node, $vncport, $args) =
|
|
(shift, shift, shift, shift, shift, shift, shift, shift, shift);
|
|
|
|
xCAT::vboxService->IVirtualBox_openSession_V3($url, $vbox, $session, $uuid);
|
|
|
|
my $directmachine = xCAT::vboxService->ISession_getMachine_V3($url, $session);
|
|
my $hasVRDP;
|
|
if (!$directmachine) {
|
|
addError("$node: Could not access mutable machine");
|
|
} else {
|
|
my $vrdp = xCAT::vboxService->IMachine_getVRDPServer_V3($url, $directmachine);
|
|
$hasVRDP = xCAT::vboxService->IVRDPServer_getEnabled_V3($url, $vrdp);
|
|
my $portno;
|
|
my $vncportmismatch; # current rdp port differs from vm table vncport definition
|
|
if($vboxvers =~ "^3.0") { # returns single port as unsigned long
|
|
$portno = xCAT::vboxService->IVRDPServer_getPort_V30($url, $vrdp);
|
|
if ($vncport and ($vncport != $portno)) {
|
|
$vncportmismatch=1;
|
|
}
|
|
} else { # returns one or more ports as string
|
|
$portno = xCAT::vboxService->IVRDPServer_getPorts_V3($url, $vrdp);
|
|
if ($vncport and ($vncport ne $portno)) {
|
|
$vncportmismatch=1;
|
|
}
|
|
}
|
|
my $change;
|
|
if($vncport and ($hasVRDP eq "false")) {
|
|
$hasVRDP="true";
|
|
xCAT::vboxService->IVRDPServer_setEnabled_V3($url, $vrdp, $hasVRDP);
|
|
$change=1;
|
|
}
|
|
if ($vncportmismatch) {
|
|
if($vboxvers =~ "^3.0") { # returns single port as unsigned long
|
|
xCAT::vboxService->IVRDPServer_setPort_V30($url, $vrdp, $vncport);
|
|
} else {
|
|
xCAT::vboxService->IVRDPServer_setPorts_V3($url, $vrdp, $vncport);
|
|
}
|
|
$change=1;
|
|
}
|
|
if (!$vncport and $hasVRDP eq "true") {
|
|
$hasVRDP="false";
|
|
xCAT::vboxService->IVRDPServer_setEnabled_V3($url, $vrdp, $hasVRDP);
|
|
$change=1;
|
|
}
|
|
if ($change) {
|
|
xCAT::vboxService->IMachine_saveSettings_V3($url, $directmachine);
|
|
}
|
|
xCAT::vboxService->IManagedObjectRef_release_V3($url, $vrdp);
|
|
xCAT::vboxService->IManagedObjectRef_release_V3($url, $directmachine);
|
|
}
|
|
|
|
xCAT::vboxService->ISession_close_V3($url, $session);
|
|
my $v3session;
|
|
if ($hasVRDP eq "true") {
|
|
$v3session="vrdp"; #vrdp
|
|
} else {
|
|
# found "headles" to be undocumented in SDK ref, but this allows to open a headless session w/o VRDP
|
|
# and thus we can disable rdp without being forced to launch the gui. This allows to follow
|
|
# the logic, that an empty vncport in the vm table will disable rdp, and having a value in
|
|
# table vm will define the port and enable rdp.
|
|
$v3session="headless"; # gui
|
|
}
|
|
#my $progress = xCAT::vboxService->IVirtualBox_openRemoteSession_V3($url, $vbox, $session, $uuid, "vrdp", "");
|
|
my $progress = xCAT::vboxService->IVirtualBox_openRemoteSession_V3($url, $vbox, $session, $uuid, $v3session, "");
|
|
|
|
if (!$progress) {
|
|
addError("$node: Can not open remote session");
|
|
} else { # existing $progress
|
|
xCAT::vboxService->IProgress_waitForCompletion_V3($url, $progress, -1);
|
|
|
|
if (xCAT::vboxService->IProgress_getCompleted_V3($url, $progress)) {
|
|
addMessage("$node: $args->[0]");
|
|
} else { # not successfully completed
|
|
addError("$node: Power on failed");
|
|
}
|
|
|
|
} # /existing $progress
|
|
|
|
return;
|
|
} # /powerOn_V3
|
|
|
|
sub powerOff #*********************************************************
|
|
{
|
|
my ($url, $vbox, $session, $machine, $uuid, $node, $args) =
|
|
(shift, shift, shift, shift, shift, shift, shift);
|
|
|
|
# Lock session with machine
|
|
my $vmsessionstate = xCAT::vboxService->IMachine_getSessionState($url, $machine);
|
|
my $vmsessiontype = xCAT::vboxService->IMachine_getSessionType($url, $machine);
|
|
|
|
if ($vmsessionstate eq "Locked") {
|
|
my $locktype="Shared";
|
|
xCAT::vboxService->IMachine_lockMachine($url,$machine,$session,$locktype);
|
|
} elsif ($vmsessionstate eq "Unlocked") {
|
|
my $locktype="Write";
|
|
xCAT::vboxService->IMachine_lockMachine($url,$machine,$session,$locktype);
|
|
} else { # !$vmsessionstate
|
|
addError("$node: No direct session to machine");
|
|
}
|
|
|
|
# just test: check sessiontype - it turns out, that this needs a lock from traces
|
|
#my $teste = xCAT::vboxService->ISession_getType($url, $session);
|
|
#addError("$node: sessiontype =$teste");
|
|
|
|
# The session is now locked with the machine, now its direct session or console can be optained and manipulated
|
|
# Now get the console for the mutable machine
|
|
my $console = xCAT::vboxService->ISession_getConsole($url, $session);
|
|
if (!$console) {
|
|
addError("$node: No console for mutable machine");
|
|
} else { # existing $console
|
|
if ($args->[0] =~ m/^reset|^boot/) {
|
|
xCAT::vboxService->IConsole_reset($url, $console);
|
|
xCAT::vboxService->IManagedObjectRef_release($url, $console);
|
|
addMessage("$node: on reset");
|
|
#xCAT::vboxService->IManagedObjectRef_release($url, $console);
|
|
return;
|
|
} else {
|
|
xCAT::vboxService->IConsole_powerButton($url, $console);
|
|
unless (xCAT::vboxService->IConsole_getPowerButtonHandled($url, $console) eq "true") {
|
|
# In case of no reaction: force to power down machine
|
|
xCAT::vboxService->IConsole_powerDown($url, $console);
|
|
} addMessage("$node: off");
|
|
}
|
|
|
|
xCAT::vboxService->IManagedObjectRef_release($url, $console);
|
|
|
|
} # /existing $console
|
|
|
|
return;
|
|
|
|
} # /powerOff
|
|
|
|
sub powerOff_V3 #*********************************************************
|
|
{
|
|
my ($url, $vbox, $session, $machine, $uuid, $node, $args) =
|
|
(shift, shift, shift, shift, shift, shift, shift);
|
|
|
|
# Lock session with machine
|
|
my $vmsessionstate = xCAT::vboxService->IMachine_getSessionState_V3($url, $machine);
|
|
|
|
if ($vmsessionstate eq "Open") {
|
|
xCAT::vboxService->IVirtualBox_openExistingSession_V3($url, $vbox, $session, $uuid);
|
|
} elsif ($vmsessionstate eq "Closed") {
|
|
xCAT::vboxService->IVirtualBox_openSession_V3($url, $vbox, $session, $uuid);
|
|
} else {
|
|
addError("$node: No direct session to machine");
|
|
}
|
|
|
|
# Now get the console for the mutable machine
|
|
my $console = xCAT::vboxService->ISession_getConsole_V3($url, $session);
|
|
if (!$console) {
|
|
addError("$node: No console for mutable machine");
|
|
} else { # existing $console
|
|
if ($args->[0] =~ m/^reset|^boot/) {
|
|
xCAT::vboxService->IConsole_reset_V3($url, $console);
|
|
xCAT::vboxService->IManagedObjectRef_release_V3($url, $console);
|
|
addMessage("$node: on reset");
|
|
#xCAT::vboxService->IManagedObjectRef_release_V3($url, $console);
|
|
return;
|
|
} else {
|
|
xCAT::vboxService->IConsole_powerButton_V3($url, $console);
|
|
unless (xCAT::vboxService->IConsole_getPowerButtonHandled_V3($url, $console) eq "true") {
|
|
# In case of no reaction: force to power down machine
|
|
xCAT::vboxService->IConsole_powerDown_V3($url, $console);
|
|
} addMessage("$node: off");
|
|
}
|
|
|
|
xCAT::vboxService->IManagedObjectRef_release_V3($url, $console);
|
|
|
|
} # /existing $console
|
|
|
|
return;
|
|
} # /powerOff_V3
|
|
|
|
} # /powerCtrl
|
|
|
|
|
|
sub getSession ############################################################
|
|
{
|
|
my $sess;
|
|
my ($api, $url, $vbox, $node, $vmname) = (shift, shift, shift, shift, shift);
|
|
|
|
my $cmd = "IWebsessionManager_getSessionObject";
|
|
if($api eq "3") {$cmd=$cmd . "_V3";}
|
|
|
|
eval {
|
|
$sess = xCAT::vboxService->$cmd($url, $vbox);
|
|
};
|
|
|
|
return $sess if ($sess and not $@);
|
|
|
|
addError("$node: No session for $vmname on web service @ $url.");
|
|
return undef;
|
|
} # /getSession
|
|
|
|
|
|
sub getMachine ############################################################
|
|
{
|
|
my $machine;
|
|
my ($api, $url, $vbox, $vmname, $node) = (shift, shift, shift, shift, shift);
|
|
|
|
my $cmd = "IVirtualBox_findMachine";
|
|
if($api eq "3") {$cmd=$cmd . "_V3";}
|
|
|
|
eval {
|
|
$machine = xCAT::vboxService->$cmd($url, $vbox, $vmname);
|
|
};
|
|
return $machine if ($machine and not $@);
|
|
|
|
addError("$node: VM $vmname not known by the web service @ $url.");
|
|
return undef;
|
|
} # /getMachine
|
|
|
|
|
|
sub getWebService #########################################################
|
|
{
|
|
my $ws;
|
|
my ($url, $user, $passwd, $node) = (shift, shift, shift, shift);
|
|
|
|
my $cmd = "IWebsessionManager_logon";
|
|
eval {
|
|
$ws = xCAT::vboxService->$cmd($url, $user, $passwd);
|
|
};
|
|
|
|
return $ws if ($ws and not $@);
|
|
|
|
addError("$node: No connection to the web service @ $url.");
|
|
return undef;
|
|
} # /getWebService
|
|
|
|
|
|
sub getInfo ###############################################################
|
|
{
|
|
my $node = shift;
|
|
|
|
# Open tables first, return in case of a critical error = 2
|
|
my $hostsTab = openTable('hosts');
|
|
return (2, undef, undef, undef, undef) if (!$hostsTab);
|
|
|
|
my $vmTab = openTable('vm');
|
|
return (2, undef, undef, undef, undef) if (!$vmTab);
|
|
|
|
my $websrvTab = openTable('websrv');
|
|
return (2, undef, undef, undef, undef) if (!$websrvTab);
|
|
|
|
# Load attributes, return in case of missing information error = 1
|
|
my $values;
|
|
|
|
my @attributes = ('host','vncport','comments');
|
|
$values = loadValues($vmTab, $node, \@attributes);
|
|
return (1, undef, undef, undef, undef) if (!defined($values));
|
|
|
|
my $hostname = $values->{host};
|
|
my $vncport = $values->{vncport};
|
|
my $comments = $values->{comments};
|
|
my $vmname = undef;
|
|
if ($comments =~ m/vmname:(.+)!/) {
|
|
$vmname = $1;
|
|
} else {
|
|
$vmname = $node;
|
|
}
|
|
|
|
@attributes = ('port','username', 'password');
|
|
$values = loadValues($websrvTab, $hostname, \@attributes);
|
|
return (1, undef, undef, undef, undef) if (!defined($values));
|
|
|
|
my $port = $values->{port};
|
|
my $username = $values->{username};
|
|
my $password = $values->{password};
|
|
|
|
@attributes = ('ip');
|
|
$values = loadValues($hostsTab, $hostname, \@attributes);
|
|
return (1, undef, undef, undef, undef) if (!defined($values));
|
|
|
|
my $ipaddr = $values->{ip};
|
|
my $url = "http://$ipaddr:$port/";
|
|
|
|
return (0, $url, $username, $password, $vmname, $vncport);
|
|
|
|
|
|
sub loadValues #*******************************************************
|
|
{
|
|
my ($table, $node, $attributes) = (shift, shift, shift);
|
|
my ($values) = $table->getAttribs({'node'=>$node}, @$attributes);
|
|
$table->close;
|
|
|
|
addError("$node: Missing information: @$attributes")
|
|
if (!defined($values));
|
|
|
|
return $values;
|
|
|
|
} # /loadValues
|
|
|
|
|
|
sub openTable #********************************************************
|
|
{
|
|
my $tabname = shift;
|
|
my $table = xCAT::Table->new($tabname);
|
|
|
|
# try to create vbox tables if they don't exist yet
|
|
if (!$table and $tabname =~ m/websrv/)
|
|
{
|
|
$table = xCAT::Table->new( $tabname, -create=>1, -autocommit=>1 );
|
|
$table->close;
|
|
addMessage("[xCAT] Info: The table $tabname has been created.");
|
|
$table = xCAT::Table->new($tabname);
|
|
}
|
|
|
|
addError("[xCAT] Can not open table: $tabname. Command aborted.")
|
|
if (!$table);
|
|
|
|
return $table;
|
|
|
|
} # /openTable
|
|
|
|
} # /getInfo
|
|
}
|
|
|
|
# see Lite.pm for other serializer code, e.g. as_string
|
|
sub SOAP::Serializer::as_LockType
|
|
{
|
|
my ($self, $value, $name, $type, $attr) = @_;
|
|
die "String value expected instead of @{[ref $value]} reference\n"
|
|
if ref $value;
|
|
return [
|
|
$name,
|
|
{'xsi:type' => 'vbox:LockType', %$attr},
|
|
SOAP::Utils::encode_data($value)
|
|
];
|
|
}
|
|
|
|
1;
|