Author: arkurth
Date: Tue Aug 18 16:17:15 2009
New Revision: 805478

URL: http://svn.apache.org/viewvc?rev=805478&view=rev
Log:
VCL-195
Added Windows/Version_6/2008.pm file. Improved activation subroutines in 
Version_6.pm to allow for MAK activation. Added Version_6.pm::run_sysprep() 
subroutine.

VCL-196
Added is_64_bit(), get_system32_path() and get_product_name() subroutines to 
Windows.pm. Updated calls which specify system32 to use the get_system32_path() 
subroutine. This is done to overcome a problem with 64-bit Windows OS's, where 
there are separate system32 directories for 32-bit and 64-bit.

VCL-23
Added format_path_unix() and format_path_dos() subroutines to Windows.pm. 
Updated delete_File::Basename() to use these subroutines. It contains a mix of 
Unix/Linux and DOS commands and the path has to be formatted properly for each.

Added:
    
incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6/2008.pm
Modified:
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
URL: 
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm?rev=805478&r1=805477&r2=805478&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Tue Aug 18 
16:17:15 2009
@@ -857,8 +857,8 @@
                return;
        }
        
-       # Replace backslashes with forward slashes
-       $path =~ s/\\+/\//gs;
+       my $path_unix = $self->format_path_unix($path);
+       my $path_dos = $self->format_path_dos($path);
        
        if (!$self->filesystem_entry_exists($path)) {
                notify($ERRORS{'DEBUG'}, 0, "file not deleted because it does 
not exist: $path");
@@ -868,37 +868,37 @@
        notify($ERRORS{'DEBUG'}, 0, "attempting to delete file: $path");
        
        # Run chmod
-       my $chmod_command = "chmod -Rv 777 \"$path\"";
+       my $chmod_command = "chmod -Rv 777 $path_unix";
        my ($chmod_exit_status, $chmod_output) = 
run_ssh_command($computer_node_name, $management_node_keys, $chmod_command, '', 
'', 1);
        if (defined($chmod_exit_status) && $chmod_exit_status == 0) {
-               notify($ERRORS{'DEBUG'}, 0, "set permissions to 777 on $path");
+               notify($ERRORS{'DEBUG'}, 0, "set permissions to 777 on 
$path_unix");
        }
        elsif ($chmod_exit_status) {
-               notify($ERRORS{'WARNING'}, 0, "failed to set permissions to 777 
on $path, exit status: $chmod_exit_status, output:\...@{$chmod_output}");
+               notify($ERRORS{'WARNING'}, 0, "failed to set permissions to 777 
on $path_unix, exit status: $chmod_exit_status, output:\...@{$chmod_output}");
        }
        else {
-               notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to set 
permissions to 777 on $path");
+               notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to set 
permissions to 777 on $path_unix");
        }
 
        # Assemble the Windows shell del command and execute it
-       my $rm_command = "rm -rfv \"$path\"";
+       my $rm_command = "rm -rfv $path_unix";
        my ($rm_exit_status, $rm_output) = run_ssh_command($computer_node_name, 
$management_node_keys, $rm_command, '', '', 1);
        if ($rm_output && grep(/removed/i, @{$rm_output})) {
                my $files_deleted = grep(/removed \W/i, @{$rm_output});
                my $directories_deleted = grep(/removed directory/i, 
@{$rm_output});
-               notify($ERRORS{'OK'}, 0, "deleted $path using rm, files 
deleted: $files_deleted, directories deleted: $directories_deleted");
+               notify($ERRORS{'OK'}, 0, "deleted $path_unix using rm, files 
deleted: $files_deleted, directories deleted: $directories_deleted");
        }
        elsif (defined($rm_exit_status) && $rm_exit_status == 0) {
-               notify($ERRORS{'OK'}, 0, "file either deleted or does not exist 
on $computer_node_name: $path, output:\...@{$rm_output}");
+               notify($ERRORS{'OK'}, 0, "file either deleted or does not exist 
on $computer_node_name: $path_unix, output:\...@{$rm_output}");
        }
        elsif (defined($rm_output) && grep(/Circular directory structure/i, 
@{$rm_output})) {
                notify($ERRORS{'DEBUG'}, 0, "circular directory structure 
found, rm can't handle this, attempting next deletion method");
        }
        elsif ($rm_exit_status) {
-               notify($ERRORS{'WARNING'}, 0, "failed to delete file on 
$computer_node_name: $path, exit status: $rm_exit_status, 
output:\...@{$rm_output}");
+               notify($ERRORS{'WARNING'}, 0, "failed to delete file on 
$computer_node_name: $path_unix, exit status: $rm_exit_status, 
output:\...@{$rm_output}");
        }
        else {
-               notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to 
delete file on $computer_node_name: $path");
+               notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to 
delete file on $computer_node_name: $path_unix");
        }
 
        # Check if file was deleted
@@ -912,22 +912,22 @@
        
        # rm didn't get rid of the file, try del
        # Assemble the Windows shell del command and execute it
-       my $del_command = '$SYSTEMROOT/System32/cmd.exe /c "del /s /q /f /a 
\\"' . $path . '\\""';
+       my $del_command = '$SYSTEMROOT/System32/cmd.exe /c "del /s /q /f /a 
\\"' . $path_dos . '\\""';
        my ($del_exit_status, $del_output) = 
run_ssh_command($computer_node_name, $management_node_keys, $del_command, '', 
'', 1);
        if ($del_output && (my $deleted_count = grep(/deleted file/i, 
@{$del_output}))) {
-               notify($ERRORS{'OK'}, 0, "deleted $path using del, files 
deleted: $deleted_count");
+               notify($ERRORS{'OK'}, 0, "deleted $path_dos using del, files 
deleted: $deleted_count");
        }
        elsif (defined($del_exit_status) && $del_exit_status == 0) {
-               notify($ERRORS{'DEBUG'}, 0, "file does not exist on 
$computer_node_name: $path, output:\...@{$del_output}");
+               notify($ERRORS{'DEBUG'}, 0, "file does not exist on 
$computer_node_name: $path_dos, output:\...@{$del_output}");
        }
        elsif ($del_output && grep(/cannot find/, @{$del_output})) {
-               notify($ERRORS{'DEBUG'}, 0, "file not found on 
$computer_node_name: $path, exit status: $del_exit_status, 
output:\...@{$del_output}");
+               notify($ERRORS{'DEBUG'}, 0, "file not found on 
$computer_node_name: $path_dos, exit status: $del_exit_status, 
output:\...@{$del_output}");
        }
        elsif ($del_exit_status) {
-               notify($ERRORS{'WARNING'}, 0, "failed to delete file on 
$computer_node_name: $path, exit status: $del_exit_status, 
output:\...@{$del_output}");
+               notify($ERRORS{'WARNING'}, 0, "failed to delete file on 
$computer_node_name: $path_dos, exit status: $del_exit_status, 
output:\...@{$del_output}");
        }
        else {
-               notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to 
delete file on $computer_node_name: $path");
+               notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to 
delete file on $computer_node_name: $path_dos");
        }
        
        # Check if file was deleted
@@ -940,20 +940,20 @@
        notify($ERRORS{'DEBUG'}, 0, "file still exists: $path, attempting to 
delete it using cmd.exe /c rmdir");
 
        # Assemble the Windows shell rmdir command and execute it
-       my $rmdir_command = '$SYSTEMROOT/System32/cmd.exe /c "rmdir /s /q \\"' 
. $path . '\\""';
+       my $rmdir_command = '$SYSTEMROOT/System32/cmd.exe /c "rmdir /s /q \\"' 
. $path_dos . '\\""';
        my ($rmdir_exit_status, $rmdir_output) = 
run_ssh_command($computer_node_name, $management_node_keys, $rmdir_command, '', 
'', 1);
        if (defined($rmdir_exit_status) && $rmdir_exit_status == 0) {
-               notify($ERRORS{'DEBUG'}, 0, "directory deleted using rmdir on 
$computer_node_name: $path, output:\...@{$rmdir_output}");
+               notify($ERRORS{'DEBUG'}, 0, "directory deleted using rmdir on 
$computer_node_name: $path_dos, output:\...@{$rmdir_output}");
        }
        elsif (defined($rmdir_output) && grep(/cannot find the/, 
@{$rmdir_output})) {
                # Exit status 2 should mean the directory was not found
-               notify($ERRORS{'DEBUG'}, 0, "directory to be deleted was not 
found on $computer_node_name: $path, exit status: $rmdir_exit_status, 
output:\...@{$rmdir_output}");
+               notify($ERRORS{'DEBUG'}, 0, "directory to be deleted was not 
found on $computer_node_name: $path_dos, exit status: $rmdir_exit_status, 
output:\...@{$rmdir_output}");
        }
        elsif ($rmdir_exit_status) {
-               notify($ERRORS{'WARNING'}, 0, "failed to delete directory on 
$computer_node_name: $path, exit status: $rmdir_exit_status, 
output:\...@{$rmdir_output}");
+               notify($ERRORS{'WARNING'}, 0, "failed to delete directory on 
$computer_node_name: $path_dos, exit status: $rmdir_exit_status, 
output:\...@{$rmdir_output}");
        }
        else {
-               notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to 
delete directory on $computer_node_name: $path");
+               notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to 
delete directory on $computer_node_name: $path_dos");
        }
        
        # Check if file was deleted
@@ -1106,7 +1106,7 @@
        }
        
        # Replace any backslashes or forward slashes with \\
-       $path =~ s/[\\\/]+/\\\\/g;
+       $path =~ s/[\\\/]/\\\\/g;
 
        # Assemble the dir command and execute it
        my $dir_command = "cmd.exe /c dir /a /b \"$path\"";
@@ -2014,6 +2014,122 @@
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 reg_query
+
+ Parameters  : registry key, registry value
+ Returns     :
+ Description :
+
+=cut
+
+sub reg_query {
+       my $self = shift;
+       if (ref($self) !~ /windows/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+
+       my $management_node_keys = $self->data->get_management_node_keys();
+       my $computer_node_name   = $self->data->get_computer_node_name();
+       
+       # Get the arguments
+       my $registry_key = shift;
+       if (!defined($registry_key) || !$registry_key) {
+               notify($ERRORS{'WARNING'}, 0, "registry key was not passed 
correctly as an argument");
+               return;
+       }
+       
+       my $registry_value = shift;
+       if (!defined($registry_value) || !$registry_value) {
+               notify($ERRORS{'WARNING'}, 0, "registry value was not passed 
correctly as an argument");
+               return;
+       }
+       
+       # Replace forward slashes with backslashes in registry key
+       $registry_key =~ s/\//\\\\/g;
+       
+       # Run reg.exe QUERY
+       my $query_registry_command .= $self->get_system32_path() . "/reg.exe 
QUERY \"$registry_key\" /v \"$registry_value\"";
+       my ($query_registry_exit_status, $query_registry_output) = 
run_ssh_command($computer_node_name, $management_node_keys, 
$query_registry_command, '', '', 1);
+       if (defined($query_registry_exit_status) && $query_registry_exit_status 
== 0) {
+               notify($ERRORS{'DEBUG'}, 0, "queried registry key: 
$registry_key, value: $registry_value, output:\n" . join("\n", 
@$query_registry_output));
+       }
+       elsif ($query_registry_exit_status) {
+               notify($ERRORS{'WARNING'}, 0, "failed to query registry key: 
$registry_key, value: $registry_value, exit status: 
$query_registry_exit_status, output:\...@{$query_registry_output}");
+               return;
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to 
query registry key: $registry_key, value: $registry_value");
+               return;
+       }
+       
+       my ($output_line) = grep(/^\s*$registry_value/i, 
@$query_registry_output);
+       #notify($ERRORS{'DEBUG'}, 0, "output line: $output_line");
+       
+       my ($output_value, $output_type, $output_data) = $output_line =~ 
/\s*($registry_value)\s+([\w_]+)\s+(.*)/;
+       notify($ERRORS{'DEBUG'}, 0, "output:\nvalue: '$output_value'\ntype: 
'$output_type'\ndata: '$output_data'");
+       
+       return $output_data;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 reg_delete
+
+ Parameters  : registry key, registry value
+ Returns     :
+ Description :
+
+=cut
+
+sub reg_delete {
+       my $self = shift;
+       if (ref($self) !~ /windows/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+
+       my $management_node_keys = $self->data->get_management_node_keys();
+       my $computer_node_name   = $self->data->get_computer_node_name();
+       
+       # Get the arguments
+       my $registry_key = shift;
+       if (!defined($registry_key) || !$registry_key) {
+               notify($ERRORS{'WARNING'}, 0, "registry key was not passed 
correctly as an argument");
+               return;
+       }
+       my $registry_value = shift;
+       
+       # Replace forward slashes with backslashes in registry key
+       $registry_key =~ s/\//\\\\/g;
+       
+       # Run reg.exe DELETE
+       my $delete_registry_command;
+       if ($registry_value) {
+               $delete_registry_command = $self->get_system32_path() . 
"/reg.exe DELETE \"$registry_key\" /v \"$registry_value\" /f";
+       }
+       else {
+               $delete_registry_command = $self->get_system32_path() . 
"/reg.exe DELETE \"$registry_key\" /f";
+               $registry_value = '*';
+       }
+       my ($delete_registry_exit_status, $delete_registry_output) = 
run_ssh_command($computer_node_name, $management_node_keys, 
$delete_registry_command, '', '', 1);
+       if (defined($delete_registry_exit_status) && 
$delete_registry_exit_status == 0) {
+               notify($ERRORS{'DEBUG'}, 0, "deleted registry key: 
$registry_key, value: $registry_value, output:\n" . join("\n", 
@$delete_registry_output));
+       }
+       elsif ($delete_registry_exit_status) {
+               notify($ERRORS{'WARNING'}, 0, "failed to delete registry key: 
$registry_key, value: $registry_value, exit status: 
$delete_registry_exit_status, output:\...@{$delete_registry_output}");
+               return;
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to 
delete registry key: $registry_key, value: $registry_value");
+               return;
+       }
+       
+       return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 reg_import
 
  Parameters  :
@@ -2040,7 +2156,7 @@
        }
        
        # Run reg.exe IMPORT
-       my $import_registry_command .= 
'"//$COMPUTERNAME/c$/WINDOWS/system32/reg.exe" IMPORT ' . $registry_file_path;
+       my $import_registry_command .= $self->get_system32_path() . "/reg.exe 
IMPORT $registry_file_path";
        my ($import_registry_exit_status, $import_registry_output) = 
run_ssh_command($computer_node_name, $management_node_keys, 
$import_registry_command, '', '', 1);
        if (defined($import_registry_exit_status) && 
$import_registry_exit_status == 0) {
                notify($ERRORS{'DEBUG'}, 0, "imported registry file: 
$registry_file_path");
@@ -2120,7 +2236,7 @@
        }
        
        # Attempt to query the registry key to make sure it was added
-       my $reg_query_command = '$SYSTEMROOT/System32/reg.exe query 
"HKLM\\SOFTWARE\\Microsoft\Windows\\\CurrentVersion\\Run"';
+       my $reg_query_command = $self->get_system32_path() . '/reg.exe query 
"HKLM\\SOFTWARE\\Microsoft\Windows\\\CurrentVersion\\Run"';
        my ($reg_query_exit_status, $reg_query_output) = 
run_ssh_command($computer_node_name, $management_node_keys, $reg_query_command, 
'', '', 1);
        if (defined($reg_query_exit_status) && $reg_query_exit_status == 0) {
                notify($ERRORS{'DEBUG'}, 0, "queried '$command_name' registry 
key:\n" . join("\n", @{$reg_query_output}));
@@ -2166,7 +2282,7 @@
        }
        
        # Attempt to query the registry key to make sure it was added
-       my $reg_delete_command = '$SYSTEMROOT/System32/reg.exe delete 
"HKLM\\SOFTWARE\\Microsoft\Windows\\\CurrentVersion\\Run" /v "' . $key_name . 
'" /F';
+       my $reg_delete_command = $self->get_system32_path() . '/reg.exe delete 
"HKLM\\SOFTWARE\\Microsoft\Windows\\\CurrentVersion\\Run" /v "' . $key_name . 
'" /F';
        my ($reg_delete_exit_status, $reg_delete_output) = 
run_ssh_command($computer_node_name, $management_node_keys, 
$reg_delete_command, '', '', 1);
        if (defined($reg_delete_exit_status) && $reg_delete_exit_status == 0) {
                notify($ERRORS{'OK'}, 0, "deleted '$key_name' run registry 
key:\n" . join("\n", @{$reg_delete_output}));
@@ -3468,7 +3584,7 @@
        my $computer_node_name   = $self->data->get_computer_node_name();
 
        # Attempt to query the registry for the NetBT service parameters
-       my $reg_query_command = '$SYSTEMROOT/System32/reg.exe query 
"HKLM\SYSTEM\CurrentControlSet\Services\NetBT\Parameters\Interfaces" /s';
+       my $reg_query_command = $self->get_system32_path() . '/reg.exe query 
"HKLM\SYSTEM\CurrentControlSet\Services\NetBT\Parameters\Interfaces" /s';
        my ($reg_query_exit_status, $reg_query_output) = 
run_ssh_command($computer_node_name, $management_node_keys, $reg_query_command, 
'', '', 1);
        if (defined($reg_query_exit_status) && $reg_query_exit_status == 0) {
                notify($ERRORS{'DEBUG'}, 0, "queried NetBT parameters registry 
keys");
@@ -3493,7 +3609,7 @@
 
                if ($query_line =~ /NetbiosOptions/i) {
                        # Attempt to set the NetbiosOptions key
-                       my $reg_add_command = '$SYSTEMROOT/System32/reg.exe add 
"' . $interface_key . '" /v NetbiosOptions /d 2 /t REG_DWORD /f';
+                       my $reg_add_command = $self->get_system32_path() . 
'/reg.exe add "' . $interface_key . '" /v NetbiosOptions /d 2 /t REG_DWORD /f';
                        my ($reg_add_exit_status, $reg_add_output) = 
run_ssh_command($computer_node_name, $management_node_keys, $reg_add_command, 
'', '', 1);
                        if (defined($reg_add_exit_status) && 
$reg_add_exit_status == 0) {
                                notify($ERRORS{'OK'}, 0, "disabled NetBIOS 
under: $interface_key");
@@ -3598,7 +3714,7 @@
        my $value = shift;
        $value = $image_prettyname if !$value;
 
-       my $add_registry_command .= "\"\$SYSTEMROOT/System32/reg.exe\" add 
\"HKCR\\CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\" /v LocalizedString /t 
REG_EXPAND_SZ /d \"$value\" /f";
+       my $add_registry_command .= $self->get_system32_path() . "/reg.exe add 
\"HKCR\\CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\" /v LocalizedString /t 
REG_EXPAND_SZ /d \"$value\" /f";
        my ($add_registry_exit_status, $add_registry_output) = 
run_ssh_command($computer_node_name, $management_node_keys, 
$add_registry_command, '', '', 1);
        if (defined($add_registry_exit_status) && $add_registry_exit_status == 
0) {
                notify($ERRORS{'OK'}, 0, "my computer name changed to 
'$value'");
@@ -5876,7 +5992,7 @@
        }
        
        # Delete existing DevicePath key
-       my $reg_del_command = '$SYSTEMROOT/System32/reg.exe DELETE 
"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion" /v DevicePath /f';
+       my $reg_del_command = $self->get_system32_path() . '/reg.exe DELETE 
"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion" /v DevicePath /f';
        my ($reg_del_status, $reg_del_output) = 
run_ssh_command($computer_node_name, $management_node_keys, $reg_del_command);
        if (defined($reg_del_status) && $reg_del_status == 0) {
                notify($ERRORS{'DEBUG'}, 0, "deleted existing DevicePath key");
@@ -5906,7 +6022,7 @@
        }
        
        # Query the DevicePath registry value in order to save it in the log 
for troubleshooting
-       my $reg_query_command = '$SYSTEMROOT/System32/reg.exe QUERY 
"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion" /v DevicePath';
+       my $reg_query_command = $self->get_system32_path() . '/reg.exe QUERY 
"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion" /v DevicePath';
        my ($reg_query_status, $reg_query_output) = 
run_ssh_command($computer_node_name, $management_node_keys, $reg_query_command, 
'', '', 1);
        if (defined($reg_query_status) && $reg_query_status == 0) {
                notify($ERRORS{'DEBUG'}, 0, "queried DevicePath registry 
key:\n" . join("\n", @{$reg_query_output}));
@@ -6284,7 +6400,7 @@
        }
 
        # Attempt to query the registry for installed applications
-       my $reg_query_command = '$SYSTEMROOT/System32/reg.exe QUERY 
"HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall" /s';
+       my $reg_query_command = $self->get_system32_path() . '/reg.exe QUERY 
"HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall" /s';
        my ($reg_query_exit_status, $reg_query_output) = 
run_ssh_command($computer_node_name, $management_node_keys, $reg_query_command, 
'', '', 1);
        if (defined($reg_query_exit_status) && $reg_query_exit_status == 0) {
                notify($ERRORS{'DEBUG'}, 0, "queried Uninstall registry keys");
@@ -7025,7 +7141,7 @@
        }
        
        # Assemble the query command string
-       my $reg_query_command = "\$SYSTEMROOT/System32/reg.exe QUERY 
\"$key_name\"";
+       my $reg_query_command = $self->get_system32_path() . "/reg.exe QUERY 
\"$key_name\"";
        
        # Check if the value name argument was specified
        my $query_mode;
@@ -7419,6 +7535,220 @@
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 is_64_bit
+
+ Parameters  : None
+ Returns     : If 64-bit: true
+               If 32-bit: false
+ Description : Determines if Windows OS is 64 or 32-bit.
+
+=cut
+
+sub is_64_bit {
+       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; 
+       }
+       
+       # Check if architecture has previously been determined
+       if (defined($self->{OS_ARCHITECTURE}) && $self->{OS_ARCHITECTURE} eq 
'64') {
+               notify($ERRORS{'DEBUG'}, 0, '64-bit Windows OS previously 
detected');
+               return 1;
+       }
+       elsif (defined($self->{OS_ARCHITECTURE}) && $self->{OS_ARCHITECTURE} eq 
'32') {
+               notify($ERRORS{'DEBUG'}, 0, '32-bit Windows OS previously 
detected');
+               return 0;
+       }
+       
+       my $management_node_keys = $self->data->get_management_node_keys();
+       my $computer_node_name   = $self->data->get_computer_node_name();
+       
+       # Get the PROCESSOR_IDENTIFIER environment variable to determine if OS 
is 32 or 64-bit
+       my ($set_exit_status, $set_output) = 
run_ssh_command($computer_node_name, $management_node_keys, 'set', '', '', 1);
+       if (defined($set_exit_status) && $set_exit_status == 0) {
+               notify($ERRORS{'OK'}, 0, "executed set command to determine 
architecture on $computer_node_name");
+       }
+       elsif (defined($set_exit_status)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute set command to 
determine architecture on $computer_node_name, exit status: $set_exit_status, 
output:\...@{$set_output}");
+               return;
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute ssh command to 
set command to determine architecture on $computer_node_name");
+               return;
+       }
+       
+       # Get the line containing PROCESSOR_IDENTIFIER
+       my ($processor_identifier_line) = grep(/PROCESSOR_IDENTIFIER=/, 
@$set_output);
+       if (!$processor_identifier_line) {
+               notify($ERRORS{'WARNING'}, 0, "failed to locate 
PROCESSOR_IDENTIFIER in set output:\n" . join("\n", @$set_output));
+               return;
+       }
+       notify($ERRORS{'DEBUG'}, 0, "PROCESSOR_IDENTIFIER environment variable: 
$processor_identifier_line");
+       
+       # Check if the environment variable contains 64, otherwise assume 
32-bit OS is being used
+       if ($processor_identifier_line =~ /64/) {
+               $self->{OS_ARCHITECTURE} = 64;
+               notify($ERRORS{'DEBUG'}, 0, '64-bit Windows OS detected');
+               return 1;
+       }
+       else {
+               $self->{OS_ARCHITECTURE} = 32;
+               notify($ERRORS{'DEBUG'}, 0, '32-bit Windows OS detected');
+               return 0;
+       }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_system32
+
+ Parameters  : None
+ Returns     : If 64-bit: true
+               If 32-bit: false
+ Description : 
+
+=cut
+
+sub get_system32_path {
+       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; 
+       }
+       
+       # Check if architecture has previously been determined
+       # If not, check if OS is 32 or 64-bit
+       if ($self->{SYSTEM32_PATH}) {
+               notify($ERRORS{'DEBUG'}, 0, "System32 string previously 
detected: $self->{SYSTEM32_PATH}");
+       }
+       elsif ($self->is_64_bit()) {
+               $self->{SYSTEM32_PATH} = 'C:/Windows/Sysnative';
+               notify($ERRORS{'DEBUG'}, 0, "64-bit Windows OS, using 
$self->{SYSTEM32_PATH}");
+       }
+       else {
+               $self->{SYSTEM32_PATH} = 'C:/Windows/System32';
+               notify($ERRORS{'DEBUG'}, 0, "32-bit Windows OS, using 
$self->{SYSTEM32_PATH}");
+       }
+       
+       return $self->{SYSTEM32_PATH};
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_product_name
+
+ Parameters  : None
+ Returns     : If successful: string containing Windows product name
+               If failed: false
+ Description : Retrieves the Windows product name from the registry. This is
+               stored at:
+               HKLM\Software\Microsoft\Windows NT\CurrentVersion\ProductName
+
+=cut
+
+sub get_product_name {
+       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; 
+       }
+       
+       # Check if product name has previously been retrieved from registry
+       if ($self->{PRODUCT_NAME}) {
+               notify($ERRORS{'DEBUG'}, 0, "Windows product name previously 
retrieved: $self->{PRODUCT_NAME}");
+               return $self->{PRODUCT_NAME};
+       }
+       
+       my $management_node_keys = $self->data->get_management_node_keys();
+       my $computer_node_name   = $self->data->get_computer_node_name();
+       
+       # Get the Windows product name from the registry
+       my $product_name = $self->reg_query('HKLM/Software/Microsoft/Windows 
NT/CurrentVersion', 'ProductName');
+       if ($product_name) {
+               notify($ERRORS{'DEBUG'}, 0, "retrieved Windows product name: 
$product_name");
+               $self->{PRODUCT_NAME} = $product_name;
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "failed to retrieve Windows 
product name from registry");
+               return;
+       }
+       
+       return $self->{PRODUCT_NAME};
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 format_path_unix
+
+ Parameters  : path
+ Returns     : If successful: path formatted for Unix
+               If failed: false
+ Description : 
+
+=cut
+
+sub format_path_unix {
+       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; 
+       }
+       
+       # Get the path argument
+       my $path = shift;
+       if (!$path) {
+               notify($ERRORS{'WARNING'}, 0, "path argument was not 
specified");
+               return; 
+       }
+       
+       # Replace all backslashes with forward slashes
+       $path =~ s/\\+/\//g;
+       
+       # Replace multiple forward slashes with a single forward slash
+       $path =~ s/\/+/\//g;
+       
+       # Escape all spaces
+       $path =~ s/ /\\ /g;
+       
+       notify($ERRORS{'DEBUG'}, 0, "formatted path for Unix: $path");
+       return $path;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 format_path_dos
+
+ Parameters  : path
+ Returns     : If successful: path formatted for DOS
+               If failed: false
+ Description : 
+
+=cut
+
+sub format_path_dos {
+       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; 
+       }
+       
+       # Get the path argument
+       my $path = shift;
+       if (!$path) {
+               notify($ERRORS{'WARNING'}, 0, "path argument was not 
specified");
+               return; 
+       }
+       
+       # Replace all forward slashes with 2 backslashes
+       $path =~ s/\//\\\\/g;
+       
+       notify($ERRORS{'DEBUG'}, 0, "formatted path for DOS: $path");
+       return $path;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 1;
 __END__
 

Modified: 
incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm
URL: 
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm?rev=805478&r1=805477&r2=805478&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm 
(original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm 
Tue Aug 18 16:17:15 2009
@@ -158,7 +158,7 @@
 
 =cut
 
-       if (!$self->deactivate_license()) {
+       if (!$self->deactivate()) {
                notify($ERRORS{'WARNING'}, 0, "unable to deactivate Windows 
licensing activation");
                return 0;
        }
@@ -195,16 +195,8 @@
        }
        
        notify($ERRORS{'DEBUG'}, 0, "beginning Windows version 6 (Vista, Server 
2008) post-load tasks");
-       
-=item 1
-
-Activate Windows license
-
-=cut
-
-       $self->activate_license();
 
-=item *
+=item 1
 
 Call parent class's post_load() subroutine
 
@@ -219,6 +211,14 @@
                return;
        }
 
+=item *
+
+Activate Windows license
+
+=cut
+
+       $self->activate();
+
 =back
 
 =cut
@@ -236,7 +236,7 @@
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 activate_license
+=head2 activate
 
  Parameters  : None
  Returns     : If successful: true
@@ -248,7 +248,7 @@
 
 =cut
 
-sub activate_license {
+sub activate {
        my $self = shift;
        if (ref($self) !~ /windows/i) {
                notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
@@ -257,6 +257,7 @@
        
        my $management_node_keys     = $self->data->get_management_node_keys();
        my $computer_node_name       = $self->data->get_computer_node_name();
+       my $product_name             = $self->get_product_name();
        
        # Get the image affiliation name
        my $image_affiliation_name = $self->data->get_image_affiliation_name();
@@ -306,69 +307,228 @@
                        my $kms_port = $activation_config->{port} || 1688;
                        notify($ERRORS{'DEBUG'}, 0, "attempting to set kms 
server: $kms_address, port: $kms_port");
                        
-                       # Run slmgr.vbs -skms
-                       my $kms_command = '$SYSTEMROOT/System32/cscript.exe 
//NoLogo $SYSTEMROOT/System32/slmgr.vbs -skms ' . "$kms_address:$kms_port";
-                       my ($kms_exit_status, $kms_output) = 
run_ssh_command($computer_node_name, $management_node_keys, $kms_command);
-                       if (defined($kms_exit_status) && $kms_exit_status == 0 
&& grep(/successfully/i, @$kms_output)) {
-                               notify($ERRORS{'OK'}, 0, "set kms server to 
$kms_address:$kms_port");
+                       # Attempt to install the KMS client product key
+                       # This must be done or else the slmgr.vbs -skms option 
won't be available
+                       if ($self->install_kms_client_product_key()) {
+                               notify($ERRORS{'DEBUG'}, 0, "installed the KMS 
client product key");
                        }
-                       elsif (defined($kms_exit_status)) {
-                               notify($ERRORS{'WARNING'}, 0, "failed to set 
kms server to $kms_address:$kms_port, exit status: $kms_exit_status, 
output:\...@{$kms_output}");
+                       else {
+                               notify($ERRORS{'WARNING'}, 0, "failed to 
install the KMS client product key");
                                next;
                        }
+                       
+                       # Run slmgr.vbs -skms to configure the computer to use 
the KMS server
+                       if ($self->set_kms($kms_address, $kms_port)) {
+                               notify($ERRORS{'DEBUG'}, 0, "set KMS address");
+                       }
                        else {
-                               notify($ERRORS{'WARNING'}, 0, "failed to 
execute ssh command to set kms server to $kms_address:$kms_port");
+                               notify($ERRORS{'WARNING'}, 0, "failed to set 
KMS address");
                                next;
                        }
+               }
+               elsif ($activation_method =~ /mak/i) {
+                       my $mak_key = $activation_config->{key};
+                       my $mak_product = $activation_config->{product};
                        
-                       # KMS server successfully set, run slmgr.vbs -ato
-                       my $activate_command = 
'$SYSTEMROOT/System32/cscript.exe //NoLogo $SYSTEMROOT/System32/slmgr.vbs -ato';
-                       my ($activate_exit_status, $activate_output) = 
run_ssh_command($computer_node_name, $management_node_keys, $activate_command);
-                       if (defined($activate_exit_status)  && 
$activate_exit_status == 0 && grep(/successfully/i, @$activate_output)) {
-                               notify($ERRORS{'OK'}, 0, "license activated 
using kms server: $kms_address");
-                               return 1;
+                       if ($mak_product eq $product_name) {
+                               notify($ERRORS{'DEBUG'}, 0, "attempting to set 
install MAK key for $mak_product: $mak_key");
                        }
-                       elsif (defined($activate_exit_status)) {
-                               notify($ERRORS{'WARNING'}, 0, "failed to 
activate license using kms server: $kms_address, exit status: 
$activate_exit_status, output:\...@{$activate_output}");
+                       else {
+                               notify($ERRORS{'DEBUG'}, 0, "MAK key product 
($mak_product) does not match installed version of Windows ($product_name)");
                                next;
                        }
+                       
+                       # Attempt to install the MAK product key
+                       if ($self->install_product_key($mak_key)) {
+                               notify($ERRORS{'DEBUG'}, 0, "installed MAK 
product key: $mak_key");
+                       }
                        else {
-                               notify($ERRORS{'WARNING'}, 0, "failed to 
activate license using kms server: $kms_address");
+                               notify($ERRORS{'WARNING'}, 0, "failed to 
install MAK product key: $mak_key");
                                next;
                        }
                }
-               
-               elsif ($activation_method =~ /mak/i) {
-                       notify($ERRORS{'WARNING'}, 0, "MAK activation method is 
not supported yet");
+               else  {
+                       notify($ERRORS{'WARNING'}, 0, "unsupported activation 
method: $activation_method");
                        next;
                }
                
-               else  {
-                       notify($ERRORS{'WARNING'}, 0, "unsupported activation 
method: $activation_method");
+               # Attempt to activate the license
+               if ($self->activate_license()) {
+                       notify($ERRORS{'OK'}, 0, "activated license");
+                       return 1;
+               }
+               else {
+                       notify($ERRORS{'WARNING'}, 0, "failed to activate 
license");
                        next;
                }
        }
        
-       notify($ERRORS{'WARNING'}, 0, "failed to activate license on 
$computer_node_name using any configured kms servers");
+       notify($ERRORS{'WARNING'}, 0, "failed to activate license on 
$computer_node_name using any configured method");
        return;
 }
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 deactivate_license
+=head2 install_kms_client_product_key
 
  Parameters  : None
  Returns     : If successful: true
                If failed: false
- Description : Runs cscript.exe slmgr.vbs -ckms to clear the KMS server address
-               stored on the computer.
-               Deletes existing KMS servers keys from the registry.
-               Runs cscript.exe slmgr.vbs -rearm to rearm licensing on the
-               computer.
+ Description : 
+
+=cut
+
+sub install_kms_client_product_key {
+       my $self = shift;
+       if (ref($self) !~ /windows/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       # Create a hash of KMS setup product keys
+       # These are publically available from Microsoft's Volume Activation 2.0 
Deployment Guide
+       my %kms_product_keys = (
+               'Windows Vista (R) Business'                         => 
'YFKBB-PQJJV-G996G-VWGXY-2V3X8',
+               'Windows Vista (R) Business N'                       => 
'HMBQG-8H2RH-C77VX-27R82-VMQBT',
+               'Windows Vista (R) Enterprise'                       => 
'VKK3X-68KWM-X2YGT-QR4M6-4BWMV',
+               'Windows Vista (R) Enterprise N'                     => 
'VTC42-BM838-43QHV-84HX6-XJXKV',
+               'Windows Server (R) 2008 Datacenter'                 => 
'7M67G-PC374-GR742-YH8V4-TCBY3',
+               'Windows Server (R) 2008 Datacenter without Hyper-V' => 
'22XQ2-VRXRG-P8D42-K34TD-G3QQC',
+               'Windows Server (R) 2008 for Itanium-Based Systems'  => 
'4DWFP-JF3DJ-B7DTH-78FJB-PDRHK',
+               'Windows Server (R) 2008 Enterprise'                 => 
'YQGMW-MPWTJ-34KDK-48M3W-X4Q6V',
+               'Windows Server (R) 2008 Enterprise without Hyper-V' => 
'39BXF-X8Q23-P2WWT-38T2F-G3FPG',
+               'Windows Server (R) 2008 Standard'                   => 
'TM24T-X9RMF-VWXK6-X8JC9-BFGM2',
+               'Windows Server (R) 2008 Standard without Hyper-V'   => 
'W7VD6-7JFBR-RX26B-YKQ3Y-6FFFJ',
+               'Windows Web Server (R) 2008'                        => 
'WYR28-R7TFJ-3X2YQ-YCY4H-M249D',
+       );
+       
+       # Get the KMS setup product key from the hash
+       my $product_name = $self->get_product_name();
+       my $product_key = $kms_product_keys{$product_name};
+       if (!$product_key) {
+               notify($ERRORS{'WARNING'}, 0, "failed to retrieve KMS setup key 
for Windows product: $product_name");
+               return;
+       }
+       notify($ERRORS{'DEBUG'}, 0, "KMS client setup key for $product_name: 
$product_key");
+       
+       # Install the KMS client product key
+       if ($self->install_product_key($product_key)) {
+               notify($ERRORS{'OK'}, 0, "installed KMS client product key");
+               return 1;
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "failed to install KMS client 
product key");
+               return;
+       }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 install_product_key
+
+ Parameters  : None
+ Returns     : If successful: true
+               If failed: false
+ Description : 
+
+=cut
+
+sub install_product_key {
+       my $self = shift;
+       if (ref($self) !~ /windows/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       my $management_node_keys     = $self->data->get_management_node_keys();
+       my $computer_node_name       = $self->data->get_computer_node_name();
+       
+       # Get the arguments
+       my $product_key = shift;
+       if (!defined($product_key) || !$product_key) {
+               notify($ERRORS{'WARNING'}, 0, "product key was not passed 
correctly as an argument");
+               return;
+       }
+       
+       # Run cscript.exe slmgr.vbs -ipk to install the product key
+       my $ipk_command = 'cscript.exe //NoLogo $SYSTEMROOT/System32/slmgr.vbs 
-ipk ' . $product_key;
+       my ($ipk_exit_status, $ipk_output) = 
run_ssh_command($computer_node_name, $management_node_keys, $ipk_command);
+       if (defined($ipk_exit_status) && $ipk_exit_status == 0 && 
grep(/successfully/i, @$ipk_output)) {
+               notify($ERRORS{'OK'}, 0, "installed product key: $product_key");
+       }
+       elsif (defined($ipk_exit_status)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to install product key: 
$product_key, exit status: $ipk_exit_status, output:\...@{$ipk_output}");
+               next;
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute ssh command to 
install product key: $product_key");
+               next;
+       }
+       
+       return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 set_kms
+
+ Parameters  : None
+ Returns     : If successful: true
+               If failed: false
+ Description : 
+
+=cut
+
+sub set_kms {
+       my $self = shift;
+       if (ref($self) !~ /windows/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       my $management_node_keys     = $self->data->get_management_node_keys();
+       my $computer_node_name       = $self->data->get_computer_node_name();
+       
+       # Get the KMS address argument
+       my $kms_address = shift;
+       if (!$kms_address) {
+               notify($ERRORS{'WARNING'}, 0, "KMS address was not passed 
correctly as an argument");
+               return;
+       }
+       
+       # Get the KMS port argument or use the default port
+       my $kms_port = shift || 1688;
+       
+       # Run slmgr.vbs -skms to configure the computer to use the KMS server
+       my $skms_command = 'cscript.exe //NoLogo $SYSTEMROOT/System32/slmgr.vbs 
-skms ' . "$kms_address:$kms_port";
+       my ($skms_exit_status, $skms_output) = 
run_ssh_command($computer_node_name, $management_node_keys, $skms_command);
+       if (defined($skms_exit_status) && $skms_exit_status == 0 && 
grep(/successfully/i, @$skms_output)) {
+               notify($ERRORS{'OK'}, 0, "set kms server to 
$kms_address:$kms_port");
+       }
+       elsif (defined($skms_exit_status)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to set kms server to 
$kms_address:$kms_port, exit status: $skms_exit_status, 
output:\...@{$skms_output}");
+               return;
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute ssh command to 
set kms server to $kms_address:$kms_port");
+               return;
+       }
+       
+       return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 activate_license
+
+ Parameters  : None
+ Returns     : If successful: true
+               If failed: false
+ Description : 
 
 =cut
 
-sub deactivate_license {
+sub activate_license {
        my $self = shift;
        if (ref($self) !~ /windows/i) {
                notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
@@ -378,21 +538,47 @@
        my $management_node_keys     = $self->data->get_management_node_keys();
        my $computer_node_name       = $self->data->get_computer_node_name();
        
-       # Run slmgr.vbs -ckms
-       my $ckms_command = '$SYSTEMROOT/System32/cscript.exe //NoLogo 
$SYSTEMROOT/System32/slmgr.vbs -ckms';
-       my ($ckms_exit_status, $ckms_output) = 
run_ssh_command($computer_node_name, $management_node_keys, $ckms_command);
-       if (defined($ckms_exit_status) && $ckms_exit_status == 0 && 
grep(/successfully/i, @$ckms_output)) {
-               notify($ERRORS{'OK'}, 0, "cleared kms address");
+       # Run cscript.exe slmgr.vbs -ato to install the product key
+       my $ato_command = 'cscript.exe //NoLogo $SYSTEMROOT/System32/slmgr.vbs 
-ato';
+       my ($ato_exit_status, $ato_output) = 
run_ssh_command($computer_node_name, $management_node_keys, $ato_command);
+       if (defined($ato_exit_status) && $ato_exit_status == 0 && 
grep(/successfully/i, @$ato_output)) {
+               notify($ERRORS{'OK'}, 0, "activated license");
        }
-       elsif (defined($ckms_exit_status)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to clear kms address, 
exit status: $ckms_exit_status, output:\...@{$ckms_output}");
+       elsif (defined($ato_exit_status)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to activate license, exit 
status: $ato_exit_status, output:\...@{$ato_output}");
                return;
        }
        else {
-               notify($ERRORS{'WARNING'}, 0, "failed to execute ssh command to 
clear kms address");
+               notify($ERRORS{'WARNING'}, 0, "failed to execute ssh command to 
activate license");
+               return;
+       }
+       
+       return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 deactivate
+
+ Parameters  : None
+ Returns     : If successful: true
+               If failed: false
+ Description : Deletes existing KMS servers keys from the registry.
+               Runs cscript.exe slmgr.vbs -rearm to rearm licensing on the
+               computer.
+
+=cut
+
+sub deactivate {
+       my $self = shift;
+       if (ref($self) !~ /windows/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
                return;
        }
        
+       my $management_node_keys     = $self->data->get_management_node_keys();
+       my $computer_node_name       = $self->data->get_computer_node_name();
+       
        my $registry_string .= <<'EOF';
 Windows Registry Editor Version 5.00
 
@@ -412,7 +598,7 @@
        }
        
        # Run slmgr.vbs -rearm
-       my $rearm_command = '$SYSTEMROOT/System32/cscript.exe //NoLogo 
$SYSTEMROOT/System32/slmgr.vbs -rearm';
+       my $rearm_command = 'cscript.exe //NoLogo 
$SYSTEMROOT/System32/slmgr.vbs -rearm';
        my ($rearm_exit_status, $rearm_output) = 
run_ssh_command($computer_node_name, $management_node_keys, $rearm_command);
        if (defined($rearm_exit_status) && $rearm_exit_status == 0 && 
grep(/successfully/i, @$rearm_output)) {
                notify($ERRORS{'OK'}, 0, "rearmed licensing");
@@ -1048,6 +1234,103 @@
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 run_sysprep
+
+ Parameters  : None
+ Returns     : 1 if successful, 0 otherwise
+ Description :
+
+=cut
+
+sub run_sysprep {
+       my $self = shift;
+       if (ref($self) !~ /windows/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+
+       my $management_node_keys = $self->data->get_management_node_keys();
+       my $computer_node_name   = $self->data->get_computer_node_name();
+       my $system32_path = $self->get_system32_path();
+       my $system32_path_dos = $system32_path;
+       $system32_path_dos =~ s/\//\\/g;
+       
+       # Delete existing setupapi files (log files generated by Sysprep)
+       if (!$self->delete_file('C:/Windows/inf/setupapi*')) {
+               notify($ERRORS{'WARNING'}, 0, "unable to delete setupapi log 
files, Sysprep will proceed");
+       }
+
+       # Delete existing Sysprep_succeeded.tag file
+       if (!$self->delete_file("$system32_path/sysprep/Sysprep*.tag")) {
+               notify($ERRORS{'WARNING'}, 0, "unable to delete 
Sysprep_succeeded.tag log file, Sysprep will proceed");
+       }
+
+       # Delete existing Panther directory, contains Sysprep log files
+       if (!$self->delete_file("$system32_path/sysprep/Panther")) {
+               notify($ERRORS{'WARNING'}, 0, "unable to delete Sysprep Panther 
directory, Sysprep will proceed");
+       }
+
+       # Delete existing Panther directory, contains Sysprep log files
+       if (!$self->delete_file("$system32_path/sysprep/Unattend.xml")) {
+               notify($ERRORS{'WARNING'}, 0, "unable to delete Sysprep 
Unattend.xml file, Sysprep will NOT proceed");
+               return;
+       }
+
+       # Copy Unattend.xml file to sysprep directory
+       my $node_configuration_directory = 
$self->get_node_configuration_directory();
+       my $cp_command = "cp -f 
$node_configuration_directory/Utilities/Sysprep/Unattend.xml 
$system32_path/sysprep/Unattend.xml";
+       my ($cp_status, $cp_output) = run_ssh_command($computer_node_name, 
$management_node_keys, $cp_command);
+       if (defined($cp_status) && $cp_status == 0) {
+               notify($ERRORS{'DEBUG'}, 0, "copied Unattend.xml to 
$system32_path/sysprep");
+       }
+       elsif (defined($cp_status)) {
+               notify($ERRORS{'OK'}, 0, "failed to copy copy Unattend.xml to 
$system32_path/sysprep, exit status: $cp_status, output:\...@{$cp_output}");
+               return;
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "unable to run ssh command to 
copy Unattend.xml to $system32_path/sysprep");
+               return;
+       }
+
+       # Run Sysprep.exe, use cygstart to lauch the .exe and return immediately
+       my $sysprep_command = '/bin/cygstart.exe cmd.exe /c "' . 
$system32_path_dos . '\\sysprep\\sysprep.exe /generalize /oobe /shutdown 
/quiet"';
+       my ($sysprep_status, $sysprep_output) = 
run_ssh_command($computer_node_name, $management_node_keys, $sysprep_command);
+       if (defined($sysprep_status) && $sysprep_status == 0) {
+               notify($ERRORS{'OK'}, 0, "initiated Sysprep.exe, waiting for 
$computer_node_name to become unresponsive");
+       }
+       elsif (defined($sysprep_status)) {
+               notify($ERRORS{'OK'}, 0, "failed to initiate Sysprep.exe, exit 
status: $sysprep_status, output:\...@{$sysprep_output}");
+               return 0;
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "unable to run ssh command to 
initiate Sysprep.exe");
+               return 0;
+       }
+       
+       # Wait maximum of 5 minutes for the computer to become unresponsive
+       if (!$self->wait_for_no_ping(5)) {
+               # Computer never stopped responding to ping
+               notify($ERRORS{'WARNING'}, 0, "$computer_node_name never became 
unresponsive to ping");
+               return 0;
+       }
+       
+       # Wait for 3 minutes then call provisioning module's power_off() 
subroutine
+       # Sysprep does not always shut down the computer when it is done
+       notify($ERRORS{'OK'}, 0, "sleeping for 3 minutes to allow Sysprep.exe 
to finish");
+       sleep 180;
+
+       # Call power_off() to make sure computer is shut down
+       if (!$self->provisioner->power_off()) {
+               # Computer could not be shut off
+               notify($ERRORS{'WARNING'}, 0, "unable to power off 
$computer_node_name");
+               return 0;
+       }
+
+       return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 1;
 __END__
 

Added: 
incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6/2008.pm
URL: 
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6/2008.pm?rev=805478&view=auto
==============================================================================
--- 
incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6/2008.pm 
(added)
+++ 
incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6/2008.pm 
Tue Aug 18 16:17:15 2009
@@ -0,0 +1,156 @@
+#!/usr/bin/perl -w
+###############################################################################
+# $Id: $
+###############################################################################
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+###############################################################################
+
+=head1 NAME
+
+VCL::Module::OS::Windows::Version_6::2008.pm - VCL module to support Windows 
Server 2008 operating system
+
+=head1 SYNOPSIS
+
+ Needs to be written
+
+=head1 DESCRIPTION
+
+ This module provides VCL support for Windows Server 2008.
+
+=cut
+
+##############################################################################
+package VCL::Module::OS::Windows::Version_6::2008;
+
+# Specify the lib path using FindBin
+use FindBin;
+use lib "$FindBin::Bin/../../../../..";
+
+# Configure inheritance
+use base qw(VCL::Module::OS::Windows::Version_6);
+
+# Specify the version of this module
+our $VERSION = '2.00';
+
+# Specify the version of Perl to use
+use 5.008000;
+
+use strict;
+use warnings;
+use diagnostics;
+
+use VCL::utils;
+use File::Basename;
+
+##############################################################################
+
+=head1 CLASS VARIABLES
+
+=cut
+
+=head2 $SOURCE_CONFIGURATION_DIRECTORY
+
+ Data type   : Scalar
+ Description : Location on management node of script/utilty/configuration
+               files needed to configure the OS. This is normally the
+                                       directory under the 'tools' directory 
specific to this OS.
+
+=cut
+
+our $SOURCE_CONFIGURATION_DIRECTORY = "$TOOLS/Windows_Server_2008";
+
+##############################################################################
+
+=head1 OBJECT METHODS
+
+=cut
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 pre_capture
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub pre_capture {
+       my $self = shift;
+       my $args = shift;
+       if (ref($self) !~ /windows/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       # Get required data
+       my $imagemeta_sysprep = $self->data->get_imagemeta_sysprep();
+       
+       notify($ERRORS{'OK'}, 0, "beginning Windows Server 2008 image capture 
preparation tasks");
+       
+       # Call parent class's pre_capture() subroutine
+       notify($ERRORS{'OK'}, 0, "calling parent class pre_capture() 
subroutine");
+       if ($self->SUPER::pre_capture($args)) {
+               notify($ERRORS{'OK'}, 0, "successfully executed parent class 
pre_capture() subroutine");
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute parent class 
pre_capture() subroutine");
+               return 0;
+       }
+       
+       # Check if Sysprep is to be used
+       if ($imagemeta_sysprep) {
+               # Run sysprep.exe and shut down the computer
+               if (!$self->run_sysprep()) {
+                       notify($ERRORS{'WARNING'}, 0, "failed to Sysprep the 
computer");
+                       return 0;
+               }
+       }
+       else {
+               # Prepare the computer for newsid.exe to be run and shut down 
the computer
+               if (!$self->prepare_newsid()) {
+                       notify($ERRORS{'WARNING'}, 0, "failed to prepare the 
computer for newsid.exe to be run");
+                       return 0;
+               }
+       }
+       
+       notify($ERRORS{'OK'}, 0, "returning 1");
+       return 1;
+} ## end sub pre_capture
+
+#/////////////////////////////////////////////////////////////////////////////
+
+1;
+__END__
+
+=head1 AUTHOR
+
+ Aaron Peeler <aaron_pee...@ncsu.edu>
+ Andy Kurth <andy_ku...@ncsu.edu>
+
+=head1 COPYRIGHT
+
+ Apache VCL incubator project
+ Copyright 2009 The Apache Software Foundation
+ 
+ This product includes software developed at
+ The Apache Software Foundation (http://www.apache.org/).
+
+=head1 SEE ALSO
+
+L<http://cwiki.apache.org/VCL/>
+
+=cut


Reply via email to