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__
 


Reply via email to