Author: dimach
Date: Fri Oct 18 19:50:57 2013
New Revision: 1533611
URL: http://svn.apache.org/r1533611
Log:
VCL-722: added support for ONE templates - allows to use ONE templates to
build custom VMs. Template name should match image name. Templates are
optional, one.pm will create VM based on disk image using default values.
Modified:
vcl/trunk/managementnode/lib/VCL/Module/Provisioning/one.pm
Modified: vcl/trunk/managementnode/lib/VCL/Module/Provisioning/one.pm
URL:
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/one.pm?rev=1533611&r1=1533610&r2=1533611&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Provisioning/one.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Provisioning/one.pm Fri Oct 18
19:50:57 2013
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl -w -d
###############################################################################
# $Id: $
###############################################################################
@@ -62,17 +62,6 @@ use Data::Dumper;
my %one;
my $xml;
-##############################################################################
-
-
-##############################################################################
-
-=head1 OBJECT METHODS
-
-=cut
-
-#/////////////////////////////////////////////////////////////////////////////
-
=head2 initialize
Parameters :
@@ -128,6 +117,7 @@ sub load {
return 0;
}
+
my $reservation_id = $self->data->get_reservation_id();
my $computer_id = $self->data->get_computer_id();
my $image_name = $self->data->get_image_name();
@@ -143,76 +133,110 @@ sub load {
my $computer_name = $self->data->get_computer_hostname();
if ($memory < 512) {
$memory = 512;
- $memory = $cpu_count * 2048;
+ #$memory = $cpu_count * 2048;
}
my $one_vm_name = "$computer_name ($image_name)";
-
#delete running VM, if present
- my $one_computer_id =
$self->one_get_object_id("computer",$computer_name);
+ notify($ERRORS{'OK'}, 0, "Checking if computer $computer_name already
loaded on ONE...");
+ my $one_computer_id =
$self->_one_get_object_id("computer",$computer_name);
if ($one_computer_id) {
- $self->one_delete_vm($one_computer_id);
+ $self->_one_delete_vm($one_computer_id);
+ notify($ERRORS{'OK'}, 0, "Computer $computer_name already
loaded on ONE ... deleted.");
}
- my $one_network_0_id =
$self->one_get_object_id("network",$one_network_0);
- my $one_network_1_id =
$self->one_get_object_id("network",$one_network_1);
- my $one_image_id = $self->one_get_object_id("image",$image_name);
- my $one_virtio = '';
- $one_virtio = $self->one_get_virtio($one_image_id);
-
- my $one_network =
'NIC=[NETWORK_ID="'.$one_network_0_id.'",IP="'.$eth0_ip.'"'.$one_virtio.']';
-
- if ($self->data->can("get_vNetwork")) {
- my @vNetwork = $self->data->get_vNetwork();
- if (@vNetwork) {
- # yes, add custom network(s);
- notify($ERRORS{'OK'}, 0, "Reservation will be loaded
with addition Networks:");
- foreach (@vNetwork) {
- my $one_net_id =
$self->one_get_object_id("network",'VLAN_ID='.$_);
- $one_network =
$one_network.'NIC=[NETWORK_ID="'.$one_net_id.'"'.$one_virtio.']';
- }
- } else {
- # no custom networks, add eth1 as default public;
- $one_network =
$one_network.'NIC=[NETWORK_ID="'.$one_network_1_id.'"'.$one_virtio.']';
- }
- } else {
- # custom networking is not implemented, add eth1 as default
public;
- $one_network =
$one_network.'NIC=[NETWORK_ID="'.$one_network_1_id.'"'.$one_virtio.']';
- }
+ # check if there is ONE template already exsist for the image
+ # and create VM based on the template. If no template create 'manually'
- # Check if SWAP disk needed, format:
DISK=[DEV_PREFIX="vd",TYPE="swap",SIZE="4096"]
- my $swap_disk = '';
- my $swap_size = $self->one_get_image_tag_value("SWAP");
- if (defined($swap_size)) {
- if ($self->one_get_image_tag_value("DEV_PREFIX") eq "vd") {
- $swap_disk =
'DISK=[DEV_PREFIX="vd",TYPE="swap",SIZE="'.$swap_size.'"]';
+ my $one_template_id = $self->_one_get_template_id($image_name);
+ if ($one_template_id) {
+ my @template_info =
$one{'server'}->call('one.template.info',$one{'auth'},$one_template_id);
+ if ($template_info[0][0]->value()) {
+ my $data = XMLin($template_info[0][1]);
+ my $template;
+ $template = $data->{TEMPLATE};
+ $template->{NAME} = $one_vm_name;
+ $template->{NIC}[0]{IP} = $eth0_ip;
+
+ my $one_new_vmid =
$self->_one_create_vm(XMLout($template,NoAttr => 1,RootName=>'TEMPLATE',));
+ if ($one_new_vmid) {
+ notify($ERRORS{'OK'}, 0, "New VM
$template->{NAME} deployed with ID $one_new_vmid using template ID
$one_template_id");
+ insertloadlog($reservation_id, $computer_id,
"vmsetupconfig", "defined $computer_name");
+ insertloadlog($reservation_id, $computer_id,
"startvm", "powered on $computer_name");
+ } else {
+ notify($ERRORS{'CRITICAL'}, 0, "Could't create
requested VM. Abort.");
+ return 0;
+ }
} else {
- $swap_disk = 'DISK=[TYPE="swap",SIZE="'.$swap_size.'"]';
+ notify($ERRORS{'CRITICAL'}, 0, "Error while making
one.template.info call: $template_info[0][1]");
}
- }
-
- my $VM_TEMPLATE = 'OS=[BOOT="hd",ARCH="'.$image_arch.'",ACPI="YES"]
- NAME="'.$one_vm_name.'"
- CPU="'.$cpu_count.'"
- VCPU="'.$cpu_count.'"
- INPUT=[BUS="usb",TYPE="tablet"]
- MEMORY="'.$memory.'"
- GRAPHICS=[TYPE="VNC",LISTEN="0.0.0.0"]
- DISK=[IMAGE_ID="'.$one_image_id.'"]'.$swap_disk.$one_network;
-
- # create VM
- my @reply =
$one{'server'}->call('one.vm.allocate',$one{'auth'},$VM_TEMPLATE,$one{'false'});
-
- if ( $reply[0][0]->value() ) {
- notify($ERRORS{'OK'}, 0, "New VM ".$vm_name." deployed with ID:
$reply[0][1] using template: $VM_TEMPLATE");
- insertloadlog($reservation_id, $computer_id, "vmsetupconfig",
"defined $computer_name");
- insertloadlog($reservation_id, $computer_id, "startvm",
"powered on $computer_name");
} else {
- notify($ERRORS{'CRITICAL'}, 0,
"\n".$VM_TEMPLATE."\n".$reply[0][1]);
- return 0;
+
+ # No template, create VM manually:
+ my $template = {};
+ my $one_network_0_id =
$self->_one_get_object_id("network",$one_network_0);
+ my $one_network_1_id =
$self->_one_get_object_id("network",$one_network_1);
+ my $one_image_id =
$self->_one_get_object_id("image",$image_name);
+ my $one_virtio = $self->_one_get_virtio($one_image_id);
+ my $virtio = 0;
+ if ($self->_one_get_image_tag_value($image_name,"DEV_PREFIX")
eq "vd") {
+ $virtio = 1;
+ }
+
+ $template->{NAME} = $one_vm_name;
+ $template->{CPU} = $cpu_count;
+ $template->{VCPU} = $cpu_count;
+ $template->{MEMORY} = $memory;
+ $template->{OS}{ARCH} = $image_arch;
+ $template->{INPUT}{BUS} = "usb";
+ $template->{INPUT}{TYPE} = "tablet";
+ $template->{GRAPHICS}{TYPE} = "VNC";
+ $template->{GRAPHICS}{LISTEN} = "0.0.0.0";
+ $template->{REQUIREMENTS} = "CLUSTER_ID=\"100\"";
+ $template->{DISK}[0]{IMAGE_ID} = $one_image_id;
+ $template->{NIC}[0]{NETWORK_ID} = $one_network_0_id;
+ $template->{NIC}[0]{IP} = $eth0_ip;
+ $template->{NIC}[0]{MODEL} = "virtio" if ($virtio);
+
+ if ($self->data->can("get_vNetwork")) {
+ my @vNetwork = $self->data->get_vNetwork();
+ if (@vNetwork) {
+ # yes, add custom network(s);
+ notify($ERRORS{'OK'}, 0, "Reservation will be
loaded with addition Network(s):");
+ foreach (@vNetwork) {
+ my $one_net_id =
$self->_one_get_object_id("network",'VLAN_ID='.$_);
+ $template->{NIC}[1]{NETWORK_ID} =
$one_net_id;
+ }
+ } else {
+ # no custom networks, add eth1 as default
public;
+ $template->{NIC}[1]{NETWORK_ID} =
$one_network_1_id;
+ }
+ } else {
+ # custom networking is not implemented, add eth1 as
default public;
+ $template->{NIC}[1]{NETWORK_ID} = $one_network_1_id;
+ }
+
+ $template->{NIC}[1]{MODEL} = "virtio" if ($virtio);
+
+ # Check if SWAP disk needed. Does image have SWAP=<size_MB>
attribute?
+ my $swap_disk = '';
+ my $swap_size =
$self->_one_get_image_tag_value($image_name,"SWAP");
+ if ($swap_size) {
+ $template->{DISK}[1]{TYPE} = "swap";
+ $template->{DISK}[1]{SIZE} = $swap_size;
+ $template->{DISK}[1]{DEV_PREFIX} = "vd" if ($virtio);
+ }
+
+ # create VM
+
+ my $one_new_vmid =
$self->_one_create_vm(XMLout($template,NoAttr => 1,RootName=>'TEMPLATE',));
+ if ($one_new_vmid) {
+ notify($ERRORS{'OK'}, 0, "New VM $template->{NAME}
deployed with ID $one_new_vmid");
+ insertloadlog($reservation_id, $computer_id,
"vmsetupconfig", "defined $computer_name");
+ insertloadlog($reservation_id, $computer_id, "startvm",
"powered on $computer_name");
+ }
}
-
-
+ # VM is created and loading, execute "post_load"
if ($self->os->can("post_load")) {
if ($self->os->post_load()) {
insertloadlog($reservation_id, $computer_id,
"loadimagecomplete", "performed OS post-load tasks for $computer_name");
@@ -229,38 +253,7 @@ sub load {
return 1;
}
-#/////////////////////////////////////////////////////////////////////////////
-=head2 one_get_virtio
-
- Parameters : imagename
- Returns : '' or MODEL="virtio"
- Description :
-
-=cut
-sub one_get_virtio {
- my $self = shift;
- unless (ref($self) && $self->isa('VCL::Module')) {
- notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called
as a VCL::Module module object method");
- return;
- }
-
- my $one_image_id = shift;
-
- my @reply =
$one{'server'}->call('one.image.info',$one{'auth'},$one_image_id);
-
- if ( $reply[0][0]->value() ) {
- my $data = $xml->XMLin($reply[0][1]);
- if ($data->{TEMPLATE}{DEV_PREFIX} eq 'vd' ) {
- return ',MODEL="virtio"';
- }
- } else {
- notify($ERRORS{'WARNING'}, 0, "couldn't get image configuration
for image_id $one_image_id, won't use VIRTIO driver.");
- return '';
- }
-
- return '';
-}
#/////////////////////////////////////////////////////////////////////////////
=head2 does_image_exist
@@ -287,7 +280,7 @@ sub does_image_exist {
return;
}
- my $one_image_id = $self->one_get_object_id("image",$image_name);
+ my $one_image_id = $self->_one_get_object_id("image",$image_name);
if ($one_image_id) {
notify($ERRORS{'DEBUG'}, 0, "Found image $image_name with id
$one_image_id");
return $one_image_id;
@@ -299,118 +292,6 @@ sub does_image_exist {
#/////////////////////////////////////////////////////////////////////////////
-=head2 one_get_object_id
-
- Parameters : $o_type, $o_name
- Returns : ONE Object ID (INT)
- Description :
-
-=cut
-
-sub one_get_object_id {
- my $self = shift;
- unless (ref($self) && $self->isa('VCL::Module')) {
- notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
- return 0;
- }
-
- my $o_type = shift;
- my $o_name = shift;
-
- if ($o_type eq "computer") {
- my @reply =
$one{server}->call('one.vmpool.info',$one{'auth'},-3,-1,-1,-1);
- if ( $reply[0][0]->value() ) {
-
- my $data = $xml->XMLin($reply[0][1]);
- if ( (ref($data->{VM})) eq "ARRAY" ){
- foreach (@{$data->{VM}}) {
- if ($_->{NAME} =~ /$o_name/i) {
- return $_->{ID};
- }
- }
- } else { #HASH, found only one entry
- if ($data->{VM}{NAME} =~ /$o_name/i) {
- return $data->{VM}{ID};
- }
- }
- } else {
- notify($ERRORS{'CRITICAL'}, 0, $reply[0][1]);
- return 0;
- }
- } elsif ($o_type eq "image") {
- my @reply = $one{'server'}->call('one.imagepool.info',
$one{'auth'},-3,-1,-1);
- if ( $reply[0][0]->value() ) {
-
- my $rs_data = $xml->XMLin($reply[0][1]);
- if ( (ref($rs_data->{IMAGE})) eq "ARRAY" ) {
- foreach (@{$rs_data->{IMAGE}}) {
- if ($_->{NAME} eq $o_name) {
- return $_->{ID};
- }
- }
- } else { #HASH, only one entry
- if ($rs_data->{IMAGE}{NAME} eq
$o_name) {
- return
$rs_data->{IMAGE}{ID};
- }
- }
- } else {
- notify($ERRORS{'CRITICAL'}, 0, $reply[0][1]);
- return 0;
- }
- } elsif ($o_type eq "network") {
- my @reply =
$one{'server'}->call('one.vnpool.info',$one{'auth'},-1,-1,-1);
- if ($reply[0][0]->value()) {
- my $rs_data = $xml->XMLin($reply[0][1]);
- # don't check if ARRAY or HASH since we always have
more then 1 network
- foreach (@{$rs_data->{VNET}}) {
- # if $o_name is in VLAN_ID= then lookup by
VLAN_ID, not NAME
-
- if ($o_name =~ /^VLAN_ID=/i) {
- my @vlan_id = split('=',$o_name);
- if ($_->{VLAN_ID} == $vlan_id[1]) {
- return $_->{ID};
- }
- } else {
- if ($_->{NAME} eq $o_name) {
- return $_->{ID};
- }
- }
- }
- } else {
- notify($ERRORS{'CRITICAL'},0,$reply[0][1]);
- return 0;
- }
- } else {
- notify($ERRORS{'CRITICAL'}, 0, "$o_type is UNKNOWN type");
- return 0;
- }
-
- return 0;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 one_delete_vm
-
- Parameters : $vmid
- Returns :
- Description : one.vm.action
-
-=cut
-
-sub one_delete_vm {
- my $self = shift;
- my $vmid = shift;
- my @reply;
-
- @reply = $one{'server'}->call('one.vm.action',
$one{'auth'},'delete',$vmid);
- if ( $reply[0][0]->value() ) {
- notify($ERRORS{'OK'}, 0, "ONE VM $vmid deleted");
- } else {
- notify($ERRORS{'CRITICAL'}, 0, $reply[0][1]);
- }
-
-}
#/////////////////////////////////////////////////////////////////////////////
@@ -430,6 +311,7 @@ sub capture {
return;
}
+ my $old_image_name;
my $image_name = $self->data->get_image_name();
my $image_id = $self->data->get_image_id();
@@ -442,8 +324,12 @@ sub capture {
notify($ERRORS{'OK'}, 0, "ONE module starting image capture.");
- my $vmid = $self->one_get_object_id("computer",$computer_name);
+ my $vmid = $self->_one_get_object_id("computer",$computer_name);
if ($vmid) {
+ # get {TEMPLATE}{DISK}{IMAGE} of $vmid, the name of current
image
+
+ $old_image_name = $self->_one_get_vm_disk($vmid);
+
my @savedisk = $one{'server'}->call('one.vm.savedisk',
$one{'auth'},$vmid,0,$image_name,'OS',$one{'false'});
if ( $savedisk[0][0]->value() ) {
notify($ERRORS{'OK'}, 0, "VM $vmid will be captured as
$image_name");
@@ -485,15 +371,15 @@ sub capture {
my $lcm_state;
notify($ERRORS{'OK'}, 0, "Wait for the VM $vmid to enter
ACTIVE/EPILOG (3/11) state...");
- while (1) {
- $state = $self->one_get_vm_state($vmid);
+ EPILOG: while (1) {
+ $state = $self->_one_get_vm_state($vmid);
notify($ERRORS{'OK'}, 0, "VM $vmid is in $state state");
if ($state == 3) {
- $lcm_state = $self->one_get_vm_lcm_state($vmid);
+ $lcm_state =
$self->_one_get_vm_lcm_state($vmid);
notify($ERRORS{'OK'}, 0, "VM $vmid is in
$lcm_state lcm_state");
if ($lcm_state == 11) {
notify($ERRORS{'OK'}, 0, "VM $vmid is
in EPILOG state. OK");
- last;
+ last EPILOG;
} else {
notify($ERRORS{'OK'}, 0, "VM $vmid is
in $state / $lcm_state state...");
}
@@ -505,15 +391,15 @@ sub capture {
$wait_time = $wait_time - $sleep;
notify($ERRORS{'OK'}, 0, "Waiting for VM $vmid to enter
ACTIVE/EPILOG state, $wait_time sec left ...");
- if ($wait_time <= 0) {
+ if ($wait_time <= $sleep) {
notify($ERRORS{'DEBUG'}, 0, "VM $vmid never
reached EPILOG state. Wait for ACTIVE/RUNNING (3/3) and send 'shutdown-hard'");
my $sleep = 15;
my $wait_time = 20 * 60; #how long to wait for
ACTIVE/RUNNING (3/3)
while (1) {
- $state = $self->one_get_vm_state($vmid);
+ $state =
$self->_one_get_vm_state($vmid);
if ($state == 3) {
- $lcm_state =
$self->one_get_vm_lcm_state($vmid);
+ $lcm_state =
$self->_one_get_vm_lcm_state($vmid);
if ($lcm_state == 3) {
notify($ERRORS{'OK'},
0, "VM $vmid is in $state / $lcm_state state. Wait $sleep sec and send
'shutdown-hard'");
sleep $sleep;
@@ -521,34 +407,31 @@ sub capture {
notify($ERRORS{'CRITICAL'}, 0, "Couldn't shutdown $computer_name with
power_off('hard')");
return 0;
}
- last;
+ last EPILOG;
} else {
notify($ERRORS{'OK'},
0, "VM $vmid is in $state / $lcm_state state...");
}
} else {
notify($ERRORS{'OK'}, 0, "VM
$vmid is in $state state...");
}
- sleep $sleep;
+ sleep $sleep if ($wait_time > 0);
$wait_time = $wait_time - $sleep;
notify($ERRORS{'OK'}, 0, "Waiting for
VM $vmid to enter ACTIVE/RUNNING state, $wait_time sec left ...");
- if ($wait_time <= 0) {
+ if ($wait_time <= $sleep) {
notify($ERRORS{'CRITICAL'}, 0,
"VM $vmid is in $state / $lcm_state after $wait_time sec ... Fail!");
return 0;
}
}
-
}
}
}
- #
-
# Check that we have new_image_name created on ONE (it will be in
LOCKED state until disk_save is done).
# just procation, image stub should be created already.
my $sleep = 5;
my $wait_time = 20 * 60; # in min * 60 = seconds
while (1) {
- $one_new_image_id =
$self->one_get_object_id("image",$image_name);
+ $one_new_image_id =
$self->_one_get_object_id("image",$image_name);
last if ($one_new_image_id);
$wait_time = $wait_time - $sleep;
if ($wait_time <= 0) {
@@ -563,7 +446,7 @@ sub capture {
$wait_time = 30 * 60; # in min * 60 = seconds
while (1) {
notify($ERRORS{'OK'}, 0, "check status for new image id
$one_new_image_id, $wait_time sec left...");
- my $one_image_state =
$self->one_get_image_state($one_new_image_id);
+ my $one_image_state =
$self->_one_get_image_state($one_new_image_id);
if ($one_image_state == 4) {
notify($ERRORS{'OK'}, 0, "disk save in pregress, image
id $one_new_image_id is LOCKED");
}
@@ -573,6 +456,31 @@ sub capture {
}
if ($one_image_state == 1) {
notify($ERRORS{'OK'}, 0, "disk save OK, image id
$one_new_image_id is READY");
+ # check if template exists for the old image and create
template for the new image.
+ my $one_template_id =
$self->_one_get_template_id($old_image_name);
+ if ($one_template_id) {
+ notify($ERRORS{'OK'}, 0, "Found existing
template id $one_template_id for $old_image_name");
+ my @template_info =
$one{'server'}->call('one.template.info',$one{'auth'},$one_template_id);
+ if ($template_info[0][0]->value()) {
+ my $data = XMLin($template_info[0][1]);
+ my $template = $data->{TEMPLATE};
+ $template->{NAME} = $image_name;
+
+ if ( (ref($template->{DISK})) eq
"ARRAY" ) { # template has multiple disks, update [0]
+ $template->{DISK}[0]{IMAGE_ID}
= $one_new_image_id;
+ } else { #template has one disk
+ $template->{DISK}{IMAGE_ID} =
$one_new_image_id;
+ }
+
+ if
(!$self->_one_create_template(XMLout($template,NoAttr =>
1,RootName=>'TEMPLATE',))) {
+ notify($ERRORS{'CRITICAL'}, 0,
"Could't create $image_name template. Abort.");
+ }
+ } else {
+ notify($ERRORS{'CRITICAL'}, 0, "Error
while making one.template.info call: $template_info[0][1]");
+ }
+ } else {
+ notify($ERRORS{'OK'}, 0, "No template exists
for $old_image_name");
+ }
return 1;
}
if ( $wait_time <= 0 ) {
@@ -587,24 +495,7 @@ sub capture {
}
-sub one_get_image_state {
- my $self = shift;
- unless (ref($self) && $self->isa('VCL::Module')) {
- notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
- return;
- }
-
- my $image_id = shift;
-
- my @status =
$one{'server'}->call('one.image.info',$one{'auth'},$image_id);
- if ( $status[0][0]->value() ) {
- my $data = $xml->XMLin($status[0][1]);
- return $data->{STATE};
- } else {
- notify($ERRORS{'CRITICAL'}, 0, $status[0][1]);
- }
-
-}
+
=head2 power_off
@@ -624,7 +515,7 @@ sub power_off {
my $action = shift;
my $computer_name = $self->data->get_computer_hostname();
- my $vmid = $self->one_get_object_id("computer",$computer_name);
+ my $vmid = $self->_one_get_object_id("computer",$computer_name);
my @poweroff;
if (defined($action) and $action eq 'hard') {
@@ -654,7 +545,7 @@ sub power_reset() {
}
my $computer_name = $self->data->get_computer_hostname();
- my $vmid = $self->one_get_object_id("computer",$computer_name);
+ my $vmid = $self->_one_get_object_id("computer",$computer_name);
my @poweroff = $one{'server'}->call('one.vm.action',
$one{'auth'},'reboot',$vmid);
if ( $poweroff[0][0]->value() ) {
@@ -666,136 +557,46 @@ sub power_reset() {
}
}
-#/////////////////////////////////////////////////////////////////////////////
-=head2 one_wait_for_vm_status
- Parameters :
- Returns :
- Description :
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 power_status
+ Parameters : $domain_name (optional)
+ Returns : string
+ Description : Determines the power state of the domain. A string is returned
+ containing one of the following values:
+ * 'on'
+ * 'off'
+ * 'suspended'
=cut
-sub one_wait_for_vm_state {
+sub power_status {
my $self = shift;
unless (ref($self) && $self->isa('VCL::Module')) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
return;
}
- my $vmid = shift;
- my $state = shift;
- my $wait = shift;
- my $sleep = 15;
- my $num_state = 0;
-
- # 6 - POWEROFF
-
- $num_state = 6 if ($state eq "SHUTDOWN");
-
-
- if (!$num_state) {
- notify($ERRORS{'CRITICAL'}, 0, "Unknown vm_state $state
requested");
- return 0;
- }
+ my $computer_name = $self->data->get_computer_hostname();
+ my $vmid = $self->_one_get_object_id("computer",$computer_name);
- while (1) {
- notify($ERRORS{'OK'}, 0, "Check state of VM $vmid ...");
- my $ttime;
- my $one_vm_state = $self->one_get_vm_state($vmid);
- if ( $self->one_get_vm_state($vmid) == $num_state ) {
- notify($ERRORS{'OK'}, 0, "VM $vmid is in $state state");
- return 1;
- } else {
- notify($ERRORS{'OK'}, 0, "VM $vmid is NOT in $state
state. Waiting $sleep sec...");
- sleep $sleep;
- $ttime = $ttime + $sleep;
- if ($ttime >= $wait) {
- notify($ERRORS{'CRITICAL'}, 0, "VM $vmid is
still NOT in $state state after $wait sec, abort");
- last;
+ my @result = $one{'server'}->call('one.vm.info', $one{'auth'},$vmid);
+ if ( $result[0][0]->value() ) {
+ my $data = $xml->XMLin($result[0][1]);
+ if ($data->{STATE} == 3) {
+ if ($data->{LCM_STATE} == 3) {
+ notify($ERRORS{'OK'}, 0, "vm $vmid is RUNNING,
STATE=3 and LCM_STATE=3");
+ return 'on';
}
}
+ } else {
+ notify($ERRORS{'CRITICAL'}, 0, $result[0][1]);
+ return 0;
}
-
- return 0;
-
-} ## end sub one_wait_for_vm_status
-
-#
-sub one_get_vm_state {
- my $self = shift;
- my $vmid = shift;
-
- my @result = $one{'server'}->call('one.vm.info', $one{'auth'},$vmid);
- if ( $result[0][0]->value() ) {
- my $data = $xml->XMLin($result[0][1]);
- return $data->{STATE};
- } else {
- notify($ERRORS{'CRITICAL'}, 0, $result[0][1]);
- return 0;
- }
-}
-
-# gets LCM_STATE values, this sub-state is relevant only when STATE is ACTIVE
(3)
-sub one_get_vm_lcm_state {
- my $self = shift;
- my $vmid = shift;
-
- my @result = $one{'server'}->call('one.vm.info', $one{'auth'},$vmid);
- if ( $result[0][0]->value() ) {
- my $data = $xml->XMLin($result[0][1]);
- if ($data->{STATE} == 3) {
- return $data->{LCM_STATE};
- } else {
- notify($ERRORS{'DEBUG'}, 0, "Cannot return LCM_STATE of
VM $vmid, VM's STATE is not ACTIVE");
- return;
- }
- } else {
- notify($ERRORS{'CRITICAL'}, 0, $result[0][1]);
- return 0;
- }
-}
-
-
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 power_status
-
- Parameters : $domain_name (optional)
- Returns : string
- Description : Determines the power state of the domain. A string is returned
- containing one of the following values:
- * 'on'
- * 'off'
- * 'suspended'
-=cut
-
-sub power_status {
- my $self = shift;
- unless (ref($self) && $self->isa('VCL::Module')) {
- notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
- return;
- }
-
- my $computer_name = $self->data->get_computer_hostname();
- my $vmid = $self->one_get_object_id("computer",$computer_name);
-
- my @result = $one{'server'}->call('one.vm.info', $one{'auth'},$vmid);
- if ( $result[0][0]->value() ) {
- my $data = $xml->XMLin($result[0][1]);
- if ($data->{STATE} == 3) {
- if ($data->{LCM_STATE} == 3) {
- notify($ERRORS{'OK'}, 0, "vm $vmid is RUNNING,
STATE=3 and LCM_STATE=3");
- return 'on';
- }
- }
- } else {
- notify($ERRORS{'CRITICAL'}, 0, $result[0][1]);
- return 0;
- }
-
- return 'off';
+
+ return 'off';
} ## end sub power_status
@@ -813,7 +614,7 @@ sub power_on {
return;
}
my $computer_name = $self->data->get_computer_hostname();
- my $vmid = $self->one_get_object_id("computer",$computer_name);
+ my $vmid = $self->_one_get_object_id("computer",$computer_name);
#later
return 1;
@@ -835,27 +636,16 @@ sub get_image_size {
return;
}
- return $self->one_get_image_tag_value("SIZE");
-#
-# my $image_name = $self->data->get_image_name();
-#
-# my $imid = $self->one_get_object_id("image",$image_name);
-# my @result = $one{server}->call('one.image.info',$one{'auth'},$imid);
-# if ( $result[0][0]->value() ) {
-# my $data = $xml->XMLin($result[0][1]);
-# return $data->{SIZE};
-# } else {
-# notify($ERRORS{'CRITICAL'}, 0, $result[0][1]);
-# return 0;
-# }
+ return
$self->_one_get_image_tag_value($self->data->get_image_name(),"SIZE");
+
}
-sub one_get_image_tag_value {
+sub _one_get_image_tag_value {
my $self = shift;
+ my $image_name = shift;
my $tag = shift;
- my $image_name = $self->data->get_image_name();
- my $imid = $self->one_get_object_id("image",$image_name);
+ my $imid = $self->_one_get_object_id("image",$image_name);
my @result = $one{server}->call('one.image.info',$one{'auth'},$imid);
if ( $result[0][0]->value() ) {
my $data = $xml->XMLin($result[0][1]);
@@ -864,7 +654,7 @@ sub one_get_image_tag_value {
if (defined($data->{$tag})) {
return $data->{$tag};
} else {
- return;
+ return 0;
}
}
@@ -872,7 +662,7 @@ sub one_get_image_tag_value {
if (defined($data->{TEMPLATE}{$tag})) {
return $data->{TEMPLATE}{$tag};
} else {
- return;
+ return 0;
}
}
@@ -880,19 +670,326 @@ sub one_get_image_tag_value {
if (defined($data->{TEMPLATE}{$tag})) {
return $data->{TEMPLATE}{$tag};
} else {
- return;
+ return 0;
}
}
} else {
- notify($ERRORS{'CRITICAL'}, 0, $result[0][1]);
+ notify($ERRORS{'CRITICAL'}, 0, "Error while making
one.image.info call: $result[0][1]");
return 0;
}
notify($ERRORS{'CRITICAL'},0,"requested tag = $tag, don't know how to
get it...");
return 0;
}
+sub _one_get_template_id {
+ # in: $template_name
+ # out: $template_id or 0
+ my $self = shift;
+ my $template_name = shift;
+
+ my @templatepool_info =
$one{'server'}->call('one.templatepool.info',$one{'auth'},-1,-1,-1);
+ if ($templatepool_info[0][0]->value()) {
+ my $data = XMLin($templatepool_info[0][1]);
+ foreach (@{$data->{VMTEMPLATE}}) {
+ if ($template_name eq $_->{NAME}) {
+ return $_->{ID};
+ }
+ }
+ } else {
+ print "Error while making one.templatepool.info call:
$templatepool_info[0][1]";
+ }
+ return 0;
+}
+
+
+
+#/////////////////////////////////////////////////////////////////////////////
+=head2 _one_get_virtio
+
+ Parameters : imagename
+ Returns : '' or MODEL="virtio"
+ Description :
+
+=cut
+
+sub _one_get_virtio {
+ my $self = shift;
+ my $one_image_id = shift;
+
+ my @reply =
$one{'server'}->call('one.image.info',$one{'auth'},$one_image_id);
+
+ if ( $reply[0][0]->value() ) {
+ my $data = $xml->XMLin($reply[0][1]);
+ if ($data->{TEMPLATE}{DEV_PREFIX} eq 'vd' ) {
+ return ',MODEL="virtio"';
+ }
+ } else {
+ notify($ERRORS{'WARNING'}, 0, "couldn't get image configuration
for image_id $one_image_id, won't use VIRTIO driver.");
+ return '';
+ }
+
+ return '';
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 one_wait_for_vm_status
+
+ Parameters :
+ Returns :
+ Description :
+
+=cut
+
+sub _one_wait_for_vm_state {
+ my $self = shift;
+ my $vmid = shift;
+ my $state = shift;
+ my $wait = shift;
+ my $sleep = 15;
+ my $num_state = 0;
+
+ # 6 - POWEROFF
+
+ $num_state = 6 if ($state eq "SHUTDOWN");
+
+
+ if (!$num_state) {
+ notify($ERRORS{'CRITICAL'}, 0, "Unknown vm_state $state
requested");
+ return 0;
+ }
+
+ while (1) {
+ notify($ERRORS{'OK'}, 0, "Check state of VM $vmid ...");
+ my $ttime;
+ my $one_vm_state = $self->_one_get_vm_state($vmid);
+ if ( $self->_one_get_vm_state($vmid) == $num_state ) {
+ notify($ERRORS{'OK'}, 0, "VM $vmid is in $state state");
+ return 1;
+ } else {
+ notify($ERRORS{'OK'}, 0, "VM $vmid is NOT in $state
state. Waiting $sleep sec...");
+ sleep $sleep;
+ $ttime = $ttime + $sleep;
+ if ($ttime >= $wait) {
+ notify($ERRORS{'CRITICAL'}, 0, "VM $vmid is
still NOT in $state state after $wait sec, abort");
+ last;
+ }
+ }
+ }
+
+ return 0;
+
+} ## end sub one_wait_for_vm_status
+
+#
+sub _one_get_vm_state {
+ my $self = shift;
+ my $vmid = shift;
+
+ my @result = $one{'server'}->call('one.vm.info', $one{'auth'},$vmid);
+ if ( $result[0][0]->value() ) {
+ my $data = $xml->XMLin($result[0][1]);
+ return $data->{STATE};
+ } else {
+ notify($ERRORS{'CRITICAL'}, 0, $result[0][1]);
+ return 0;
+ }
+}
+
+# gets LCM_STATE values, this sub-state is relevant only when STATE is ACTIVE
(3)
+sub _one_get_vm_lcm_state {
+ my $self = shift;
+ my $vmid = shift;
+
+ my @result = $one{'server'}->call('one.vm.info', $one{'auth'},$vmid);
+ if ( $result[0][0]->value() ) {
+ my $data = $xml->XMLin($result[0][1]);
+ if ($data->{STATE} == 3) {
+ return $data->{LCM_STATE};
+ } else {
+ notify($ERRORS{'DEBUG'}, 0, "Cannot return LCM_STATE of
VM $vmid, VM's STATE is not ACTIVE");
+ return;
+ }
+ } else {
+ notify($ERRORS{'CRITICAL'}, 0, $result[0][1]);
+ return 0;
+ }
+}
+
+sub _one_get_image_state {
+ my $self = shift;
+ my $image_id = shift;
+
+ my @status =
$one{'server'}->call('one.image.info',$one{'auth'},$image_id);
+ if ( $status[0][0]->value() ) {
+ my $data = $xml->XMLin($status[0][1]);
+ return $data->{STATE};
+ } else {
+ notify($ERRORS{'CRITICAL'}, 0, $status[0][1]);
+ }
+
+}
+
+=head2 _one_get_object_id
+
+ Parameters : $o_type, $o_name
+ Returns : ONE Object ID (INT)
+ Description :
+
+=cut
+
+sub _one_get_object_id {
+ my $self = shift;
+ my $o_type = shift;
+ my $o_name = shift;
+
+ if ($o_type eq "computer") {
+ my @reply =
$one{'server'}->call('one.vmpool.info',$one{'auth'},-3,-1,-1,-1);
+ if ( $reply[0][0]->value() ) {
+
+ my $data = $xml->XMLin($reply[0][1]);
+
+ if ( (ref($data->{VM})) eq "ARRAY" ){
+ foreach (@{$data->{VM}}) {
+ if ($_->{NAME} =~ /$o_name/) {
+ return $_->{ID};
+ }
+ }
+ } else { #HASH, found only one entry
+ if ($data->{VM}{NAME} =~ /$o_name/) {
+ return $data->{VM}{ID};
+ }
+ }
+ } else {
+ notify($ERRORS{'CRITICAL'}, 0, $reply[0][1]);
+ return 0;
+ }
+ } elsif ($o_type eq "image") {
+ my @reply = $one{'server'}->call('one.imagepool.info',
$one{'auth'},-3,-1,-1);
+ if ( $reply[0][0]->value() ) {
+
+ my $rs_data = $xml->XMLin($reply[0][1]);
+ if ( (ref($rs_data->{IMAGE})) eq "ARRAY" ) {
+ foreach (@{$rs_data->{IMAGE}}) {
+ if ($_->{NAME} eq $o_name) {
+ return $_->{ID};
+ }
+ }
+ } else { #HASH, only one entry
+ if ($rs_data->{IMAGE}{NAME} eq
$o_name) {
+ return
$rs_data->{IMAGE}{ID};
+ }
+ }
+ } else {
+ notify($ERRORS{'CRITICAL'}, 0, $reply[0][1]);
+ return 0;
+ }
+ } elsif ($o_type eq "network") {
+ my @reply =
$one{'server'}->call('one.vnpool.info',$one{'auth'},-1,-1,-1);
+ if ($reply[0][0]->value()) {
+ my $rs_data = $xml->XMLin($reply[0][1]);
+ # don't check if ARRAY or HASH since we always have
more then 1 network
+ foreach (@{$rs_data->{VNET}}) {
+ # if $o_name is in VLAN_ID= then lookup by
VLAN_ID, not NAME
+
+ if ($o_name =~ /^VLAN_ID=/i) {
+ my @vlan_id = split('=',$o_name);
+ if ($_->{VLAN_ID} == $vlan_id[1]) {
+ return $_->{ID};
+ }
+ } else {
+ if ($_->{NAME} eq $o_name) {
+ return $_->{ID};
+ }
+ }
+ }
+ } else {
+ notify($ERRORS{'CRITICAL'},0,$reply[0][1]);
+ return 0;
+ }
+ } else {
+ notify($ERRORS{'CRITICAL'}, 0, "$o_type is UNKNOWN type");
+ return 0;
+ }
+
+ return 0;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 _one_delete_vm
+
+ Parameters : $vmid
+ Returns :
+ Description : one.vm.action
+
+=cut
+
+sub _one_delete_vm {
+ my $self = shift;
+ my $vmid = shift;
+ my @reply;
+
+ @reply = $one{'server'}->call('one.vm.action',
$one{'auth'},'delete',$vmid);
+ if ( $reply[0][0]->value() ) {
+ notify($ERRORS{'OK'}, 0, "ONE VM $vmid deleted");
+ } else {
+ notify($ERRORS{'CRITICAL'}, 0, $reply[0][1]);
+ }
+
+}
+
+sub _one_create_vm {
+ # in: $VM_TEMPLATE in XML
+ # out: new VM ID | 0
+ my $self = shift;
+ my $VM_TEMPLATE = shift;
+ my @vm_allocate =
$one{'server'}->call('one.vm.allocate',$one{'auth'},$VM_TEMPLATE,$one{'false'});
+ if ( $vm_allocate[0][0]->value() ) {
+ return $vm_allocate[0][1];
+ } else {
+ notify($ERRORS{'CRITICAL'}, 0, "Error while making
one.vm.allocate call : $vm_allocate[0][1]");
+ return 0;
+ }
+
+}
+
+sub _one_create_template {
+ # in: VM_TEMPLATE
+ # OUT: template_id | 0
+ # http://opennebula.org/documentation:rel4.2:api#onetemplateallocate
+ my $self = shift;
+ my $VM_TEMPLATE = shift;
+
+ my @template_allocate =
$one{'server'}->call('one.template.allocate',$one{'auth'},$VM_TEMPLATE);
+ if ($template_allocate[0][0]->value()) {
+ notify($ERRORS{'OK'}, 0, "New template created with id
$template_allocate[0][1]");
+ } else {
+ notify($ERRORS{'CRITICAL'}, 0, "Error while making
one.template.allocate call : $template_allocate[0][1]");
+ }
+}
+sub _one_get_vm_disk {
+ my $self = shift;
+ my $vmid = shift;
+
+ my @vm_info = $one{'server'}->call('one.vm.info', $one{'auth'},$vmid);
+ if ($vm_info[0][0]->value()) {
+ my $data = $xml->XMLin($vm_info[0][1]);
+
+ if ( (ref($data->{TEMPLATE}{DISK})) eq "ARRAY" ) { # template
has multiple disks, return [0]
+ return $data->{TEMPLATE}{DISK}[0]{IMAGE};
+ } else { #template has one disk
+ return $data->{TEMPLATE}{DISK}{IMAGE};
+ }
+
+
+
+ } else {
+ notify($ERRORS{'CRITICAL'}, 0, "Error while making one.vm.info
call : $vm_info[0][1]");
+ }
+}
1;
__END__