You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by ar...@apache.org on 2010/08/20 22:06:13 UTC
svn commit: r987623 [2/2] - in /incubator/vcl/trunk/managementnode/lib/VCL:
Module/OS/Windows.pm Module/Provisioning/VMware/VMware.pm
Module/Provisioning/VMware/vSphere_SDK.pm image.pm utils.pm
Modified: incubator/vcl/trunk/managementnode/lib/VCL/image.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/image.pm?rev=987623&r1=987622&r2=987623&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/image.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/image.pm Fri Aug 20 20:06:13 2010
@@ -65,6 +65,7 @@ use 5.008000;
use strict;
use warnings;
use diagnostics;
+use English '-no_match_vars';
use VCL::utils;
@@ -106,8 +107,9 @@ sub process {
my $managementnode_shortname = $self->data->get_management_node_short_name();
my $sysadmin_mail_address = $self->data->get_management_node_sysadmin_email();
- # Notify administrators that image creation is starting
- my $body = <<"END";
+ if ($sysadmin_mail_address) {
+ # Notify administrators that image creation is starting
+ my $body = <<"END";
VCL Image Creation Started
Request ID: $request_id
@@ -129,8 +131,9 @@ Computer name: $computer_shortname
Use Sysprep: $imagemeta_sysprep
END
- mail($sysadmin_mail_address, "VCL IMAGE Creation Started: $image_name", $body, $affiliation_helpaddress);
-
+ mail($sysadmin_mail_address, "VCL IMAGE Creation Started: $image_name", $body, $affiliation_helpaddress);
+ }
+
# Make sure image does not exist in the repository
my $image_already_exists = $self->provisioner->does_image_exist();
if ($image_already_exists) {
@@ -460,6 +463,321 @@ END
#/////////////////////////////////////////////////////////////////////////////
+=head2 setup
+
+ Parameters : none
+ Returns :
+ Description : This subroutine is used when vcld is run in setup mode. It
+ presents a menu for the image module.
+
+=cut
+
+sub setup {
+ 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;
+ }
+
+ push @{$ENV{setup_path}}, 'Image';
+
+ my @operation_choices = (
+ 'Capture Base Image',
+ );
+
+ my @setup_path = @{$ENV{setup_path}};
+ OPERATION: while (1) {
+ @{$ENV{setup_path}} = @setup_path;
+
+ print '-' x 76 . "\n";
+
+ print "Choose an operation:\n";
+ my $operation_choice_index = setup_get_array_choice(@operation_choices);
+ last if (!defined($operation_choice_index));
+ my $operation_name = $operation_choices[$operation_choice_index];
+ print "\n";
+
+ push @{$ENV{setup_path}}, $operation_name;
+
+ if ($operation_name =~ /capture/i) {
+ $self->setup_capture_base_image();
+ }
+ }
+
+ pop @{$ENV{setup_path}};
+ return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 setup_capture_base_image
+
+ Parameters : none
+ Returns :
+ Description : This subroutine is used when vcld is run in setup mode. It
+ inserts the database entries necessary to capture a base image.
+ Several questions are presented to the user via the command line.
+
+=cut
+
+sub setup_capture_base_image {
+ 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;
+ }
+
+ # Get the management node id, needed to insert a reservation row later on
+ my $management_node_id = $self->data->get_management_node_id();
+ if (!$management_node_id) {
+ print "ERROR: failed to determine the management node ID\n";
+ return;
+ }
+
+ # Get the user who the reservation and image will belong to
+ my $user_id;
+ my $username;
+ while (!$user_id) {
+ my $user_identifier = setup_get_input_string("Enter the VCL login name or ID of the user who will own the image:", 'admin');
+ return if (!defined($user_identifier));
+ my $user_info = get_user_info($user_identifier);
+ if (!$user_info) {
+ print "User was not found: $user_identifier\n";
+ }
+ else {
+ $user_id = (keys %$user_info)[0];
+ $username = $user_info->{$user_id}{unityid};
+ }
+ }
+ print "\nUser who will own the image: $username (ID: $user_id)\n\n";
+
+ # Determine the computer ID
+ my $computer_id;
+ my %computer_info;
+ while (!$computer_id) {
+ my $computer_identifier = setup_get_input_string("Enter the hostname or IP address of the computer to be captured:");
+ return if (!defined($computer_identifier));
+
+ # Search the computer table for a match
+ my @computer_ids = get_computer_ids($computer_identifier);
+ if (!@computer_ids) {
+ print "No VCL computers were found with the name or IP address: $computer_identifier\n";
+ next;
+ }
+
+ # Get information from the database for all of the computers found
+ for my $computer_id (@computer_ids) {
+ $computer_info{$computer_id} = get_computer_info($computer_id)->{computer};
+ if (!$computer_info{$computer_id}) {
+ print "ERROR: unable to retrieve information for computer ID: $computer_id\n";
+ return;
+ }
+ }
+
+ if (scalar(@computer_ids) > 1) {
+ print "Multiple VCL computers were found with the name or IP address: '$computer_identifier' (@computer_ids)\n\n";
+ print "Choose a computer:\n";
+ $computer_id = setup_get_hash_choice(\%computer_info, 'hostname');
+ return if (!defined($computer_id));
+ }
+ else {
+ $computer_id = (keys %computer_info)[0];
+ }
+ }
+
+ my $computer_hostname = $computer_info{$computer_id}{hostname};
+ my $computer_state_name = $computer_info{$computer_id}{state}{name};
+ my $computer_provisioning_module_name = $computer_info{$computer_id}{provisioning}{module}{name};
+
+ my $install_type;
+ if ($computer_provisioning_module_name =~ /vm/i) {
+ $install_type = 'vmware';
+ }
+ else {
+ $install_type = 'partimage';
+ }
+
+ print "\nComputer to be captured: $computer_hostname (ID: $computer_id)\n";
+ print "Provisioning module: $computer_provisioning_module_name\n";
+ print "Install type: $install_type\n";
+ print "\n";
+
+ # Make sure the computer state is valid
+ if ($computer_state_name =~ /(maintenance|deleted)/i) {
+ print "ERROR: state of $computer_hostname is $computer_state_name\n";
+ return;
+ }
+
+
+ # Get the OS table contents from the database
+ my $os_info = get_os_info();
+ if (!$os_info) {
+ print "ERROR: failed to retrieve OS info from the database\n";
+ return;
+ }
+
+ # Loop through the OS table info
+ for my $os_id (keys %$os_info) {
+ # Remove keys which don't match the selected computer type
+ # Remove keys where the name begins with esx - deprecated OS type
+ if ($os_info->{$os_id}{installtype} ne $install_type || $os_info->{$os_id}{name} =~ /^vmwareesx/i) {
+ delete $os_info->{$os_id};
+ }
+ }
+
+ print "Select the OS to be captured (install type: $install_type):\n";
+ my $os_id = setup_get_hash_choice($os_info, 'prettyname');
+ return if (!defined($os_id));
+ my $os_prettyname = $os_info->{$os_id}{prettyname};
+ my $os_module_perl_package = $os_info->{$os_id}{module}{perlpackage};
+ my $os_type = $os_info->{$os_id}{type};
+ print "\nSelected OS: $os_prettyname\n\n";
+
+ # If Windows, ask if Sysprep should be used
+ my $use_sysprep = 1;
+ if ($os_type =~ /windows/i) {
+ my @yes_no_choices = (
+ 'Yes',
+ 'No',
+ );
+
+ print "Use Sysprep:\n";
+ my $sysprep_choice_index = setup_get_array_choice(@yes_no_choices);
+ last if (!defined($sysprep_choice_index));
+ my $use_sysprep_choice = $yes_no_choices[$sysprep_choice_index];
+ print "\nUse Sysprep: $use_sysprep_choice\n\n";
+
+ if ($use_sysprep_choice =~ /no/i) {
+ $use_sysprep = 0;
+ }
+ }
+
+ my $image_prettyname;
+ while (!$image_prettyname) {
+ $image_prettyname = setup_get_input_string("Enter the name of the image to be captured:");
+ return if (!defined($image_prettyname));
+ #if ($image_prettyname =~ //) {
+ # print "Image name is not valid: $image_prettyname\n";
+ # $image_prettyname = 0;
+ #}
+ }
+
+ my $image_name = $image_prettyname;
+ $image_name =~ s/[\s\W]//g;
+ $image_name = $os_info->{$os_id}{name} . "-$image_name-v0";
+
+ my $insert_imagemeta_statement = <<EOF;
+INSERT INTO imagemeta
+(sysprep)
+VALUES
+('$use_sysprep')
+EOF
+
+ my $imagemeta_id = database_execute($insert_imagemeta_statement);
+ if (!defined($imagemeta_id)) {
+ print "ERROR: failed to insert into imagemeta table\n";
+ return;
+ }
+
+
+ my $insert_image_statement = <<EOF;
+INSERT INTO image (name, prettyname, ownerid, platformid, OSid, imagemetaid, deleted, lastupdate, size, architecture, basedoffrevisionid)
+VALUES ('$image_name', '$image_prettyname', '$user_id', '1', $os_id, $imagemeta_id, '1', NOW( ), '1450', 'x86', '4')
+EOF
+
+ my $image_id = database_execute($insert_image_statement);
+ if (!defined($image_id)) {
+ print "ERROR: failed to insert into image table\n";
+ return;
+ }
+
+ # Add the newly inserted image ID to the image name
+ $image_name =~ s/-v0$/$image_id-v0/;
+
+ # Upadate the name in the image table
+ my $update_image_statement = <<EOF;
+UPDATE image
+SET name = '$image_name'
+WHERE
+id = $image_id
+EOF
+ if (!database_execute($update_image_statement)) {
+ print "ERROR: failed to update the image table with the correct image name: $image_name\n";
+ return;
+ }
+
+
+ my $insert_imagerevision_statement = <<EOF;
+INSERT INTO imagerevision
+(imageid, revision, userid, datecreated, deleted, production, imagename)
+VALUES
+($image_id, '0', '$user_id', NOW( ), '1', '1', '$image_name')
+EOF
+
+ my $imagerevision_id = database_execute($insert_imagerevision_statement);
+ if (!defined($imagerevision_id)) {
+ print "ERROR: failed to insert into imagerevision table\n";
+ return;
+ }
+
+ my $insert_resource_statement = <<EOF;
+INSERT INTO resource
+(resourcetypeid, subid)
+VALUES ('13', '$image_id')
+EOF
+
+ my $resource_id = database_execute($insert_resource_statement);
+ if (!defined($resource_id)) {
+ print "ERROR: failed to insert into resource table\n";
+ return;
+ }
+
+ print "\nAdded new image to database: '$image_prettyname'\n";
+ print " image.name: $image_name\n";
+ print " image.id: $image_id\n";
+ print " imagerevision.id: $imagerevision_id\n";
+ print " imagemeta.id: $imagemeta_id\n";
+ print " resource.id: $resource_id\n\n";
+
+
+ my ($request_id, $reservation_id) = insert_request($management_node_id, 'image', 'image', 0, $username, $computer_id, $image_id, $imagerevision_id, 0, 60);
+ if (!defined($request_id) || !defined($reservation_id)) {
+ print "ERROR: failed to insert new imaging request\n";
+ return;
+ }
+
+ my $message = <<EOF;
+Inserted imaging request to the database:
+request ID: $request_id
+reservation ID: $reservation_id
+
+This process will now display the contents of the vcld.log file if the vcld
+daemon is running. If you do not see many lines of additional output, exit this
+process, start the vcld daemon, and monitor the image capture process by running
+the command:
+tail -f $LOGFILE | grep '$request_id:$reservation_id'
+
+EOF
+
+ print '-' x 76 . "\n";
+ print "$message";
+ print '-' x 76 . "\n";
+
+ # Pipe the command output to a file handle
+ # The open function returns the pid of the process
+ if (open(COMMAND, "tail -f $LOGFILE 2>&1 |")) {
+ # Capture the output of the command
+
+ while (my $output = <COMMAND>) {
+ print $output if ($output =~ /$reservation_id/);
+ }
+ }
+
+ exit;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
1;
__END__
Modified: incubator/vcl/trunk/managementnode/lib/VCL/utils.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=987623&r1=987622&r2=987623&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/utils.pm Fri Aug 20 20:06:13 2010
@@ -108,8 +108,10 @@ our @EXPORT = qw(
format_number
get_affiliation_info
get_block_request_image_info
+ get_caller_trace
get_computer_current_state_name
get_computer_grp_members
+ get_computer_ids
get_computer_info
get_computers_controlled_by_MN
get_current_file_name
@@ -127,12 +129,14 @@ our @EXPORT = qw(
get_management_predictive_info
get_module_info
get_next_image_default
+ get_os_info
get_production_imagerevision_info
get_request_by_computerid
get_request_end
get_request_info
get_resource_groups
get_managable_resource_groups
+ get_user_info
get_vmhost_info
get_user_info
getdynamicaddress
@@ -8243,6 +8247,50 @@ EOF
#/////////////////////////////////////////////////////////////////////////////
+=head2 get_computer_ids
+
+ Parameters : $computer_identifier
+ Returns : array
+ Description : Queries the computer table for computers matching the
+ $computer_identifier argument. The argument may contain either
+ the computer's hostname or IP address. An array containing the
+ computer IDs is returned.
+
+=cut
+
+sub get_computer_ids {
+ my ($computer_identifier) = @_;
+
+ if(!defined($computer_identifier)){
+ notify($ERRORS{'WARNING'}, $LOGFILE, "computer identifier argument was not supplied");
+ return;
+ }
+
+ my $select_statement = <<EOF;
+SELECT
+*
+FROM
+computer
+WHERE
+hostname LIKE '$computer_identifier'
+OR hostname LIKE '$computer_identifier.%'
+OR IPaddress = '$computer_identifier'
+OR privateIPaddress = '$computer_identifier'
+EOF
+
+ my @selected_rows = database_select($select_statement);
+ if (!@selected_rows) {
+ notify($ERRORS{'DEBUG'}, 0, "no computers were found matching identifier: $computer_identifier");
+ return ();
+ }
+
+ my @computer_ids = map { $_->{id} } @selected_rows;
+ notify($ERRORS{'DEBUG'}, 0, "found computers matching identifier: $computer_identifier, IDs: @computer_ids");
+ return sort @computer_ids;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
=head2 insert_request
Parameters : $managementnode_id, $request_state_name, $request_laststate_name, $end_minutes_in_future, $user_unityid, $computer_id, $image_id, $imagerevision_id
@@ -9549,6 +9597,64 @@ sub get_module_info {
#/////////////////////////////////////////////////////////////////////////////
+=head2 get_user_info
+
+ Parameters : $user_identifier
+ Returns : hash reference
+ Description : Retrieves information from the database for the user specified by
+ the $user_identifier argument. The $user_identifier argument can
+ either be a user ID or login name.
+
+=cut
+
+sub get_user_info {
+ my ($user_identifier) = @_;
+ if (!defined($user_identifier)) {
+ notify($ERRORS{'WARNING'}, 0, "user identifier argument was not specified");
+ return;
+ }
+
+ my $select_statement = <<EOF;
+SELECT
+*
+FROM
+user
+WHERE
+EOF
+
+ if ($user_identifier =~ /^\d+$/) {
+ $select_statement .= "id = $user_identifier";
+ }
+ else {
+ $select_statement .= "unityid = '$user_identifier'";
+ }
+
+ # Call the database select subroutine
+ my @selected_rows = database_select($select_statement);
+
+ # Check to make sure rows were returned
+ if (!@selected_rows) {
+ notify($ERRORS{'WARNING'}, 0, "unable to retrieve rows from user table");
+ return;
+ }
+
+ # Transform the array of database rows into a hash
+ my %info_hash;
+ for my $row (@selected_rows) {
+ my $user_id = $row->{id};
+
+ for my $key (keys %$row) {
+ my $value = $row->{$key};
+ $info_hash{$user_id}{$key} = $value;
+ }
+ }
+
+ notify($ERRORS{'DEBUG'}, 0, "retrieved user info:\n" . format_data(\%info_hash));
+ return \%info_hash;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
=head2 get_current_package_name
Parameters : None
@@ -10080,6 +10186,58 @@ sub setup_print_wrap {
#/////////////////////////////////////////////////////////////////////////////
+=head2 get_os_info
+
+ Parameters : none
+ Returns : hash reference
+ Description : Returns the contents of the OS table as a hash reference. The
+ hash keys are the OS IDs.
+
+=cut
+
+sub get_os_info {
+ # Create the select statement
+ my $select_statement = <<EOF;
+SELECT
+OS.*,
+module.name AS module_name,
+module.prettyname AS module_prettyname,
+module.perlpackage AS module_perlpackage
+FROM
+OS,
+module
+WHERE
+OS.moduleid = module.id
+EOF
+
+ # Call the database select subroutine
+ my @selected_rows = database_select($select_statement);
+
+ my %info;
+
+ for my $row (@selected_rows) {
+ my $os_id = $row->{id};
+
+ foreach my $key (keys %$row) {
+ my $value = $row->{$key};
+
+ (my $original_key = $key) =~ s/^.+_//;
+
+ if ($key =~ /module_/) {
+ $info{$os_id}{module}{$original_key} = $value;
+ }
+ else {
+ $info{$os_id}{$original_key} = $value;
+ }
+ }
+ }
+
+ notify($ERRORS{'DEBUG'}, 0, "retrieved OS info:\n" . format_data(\%info));
+ return \%info;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
1;
__END__