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 2009/06/01 19:51:52 UTC
svn commit: r780755 - in
/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS: Windows_mod.pm
Windows_mod/Version_5.pm Windows_mod/Version_5/XP_mod.pm
Windows_mod/Version_6.pm Windows_mod/Version_6/
Windows_mod/Version_6/Vista_mod.pm
Author: arkurth
Date: Mon Jun 1 17:51:52 2009
New Revision: 780755
URL: http://svn.apache.org/viewvc?rev=780755&view=rev
Log:
VCL-23
Made several minor improvements to Windows modules during testing.
Windows_mod.pm:
-Added check for 'end_state' argument in pre_capture() so child classes don't have to check for it
-Set pre_capture() to disable RDP before capture instead of enabling it for 10.x.x.x addresses in case these addresses are used for public access. Also set post_load to enable RDP on the private interface.
-Added call to post_load() to set the computer name. The script that runs during Sysprep does not always work correctly.
-Commented out disable_netbios() and disable_dynamic_dns() calls from post_load() to speed things up. These can be controlled by OS config variables some day.
-Moved grant_access() and revoke_access() within the file so they appear under the pod section for interface functions.
-Added max_depth argument and default setting to delete_files_by_pattern(). This was running very slow on Vista when searching directories with many files.
-Changed enable_pagefile() and disable_pagefile() to call reg.exe instead of importing a .reg file. The pagefile key should be a REG_MULTI_SZ. This type is difficult to configure using a .reg file.
-Changed enable_pagefile() to set the registry key to C:\pagefile.sys instead of ?:\pagefile.sys. The question mark string worked but the interface to control the pagefile did not reflect the actual setting properly.
-Changed import_registry_string() to name the temporary .reg file after the sub and line number which called it so it's easy to determine where the .reg file came from.
-Added shutdown() subroutine. This is called after newsid.exe runs.
-Changed run_newsid() to not rename the computer. This is done elsewhere.
-Added commands to disable_dynamic_dns() to disable DNS updating for each adapter.
-Added firewall_enable_rdp_private() sub which will allow RDP only on the private interface.
-Added get_node_configuration_directory() so child classes can use the variable stored in Windows_mod.pm. It is the location on the node where VCL files are stored.
-Added set_computer_name() which sets registry entries to rename the computer.
Version_5.pm:
-Added argument to SUPER::pre_capture() call to pass the args which were passed to it.
XP_mod.pm:
-Removed end_state argument check. This was moved up to Windows_mod.pm so other classes don't duplicate the code. This is only possible by passing the arguments up to the parent's subroutine.
Added Version_6.pm, Version_6 directory, and Vista_mod.pm.
Added:
incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_6/
incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_6.pm
incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_6/Vista_mod.pm
Modified:
incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod.pm
incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_5.pm
incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_5/XP_mod.pm
Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod.pm?rev=780755&r1=780754&r2=780755&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod.pm Mon Jun 1 17:51:52 2009
@@ -117,11 +117,19 @@
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
return;
}
+
+ # Check if end_state argument was passed
+ if (defined $args->{end_state}) {
+ $self->{end_state} = $args->{end_state};
+ }
+ else {
+ $self->{end_state} = 'off';
+ }
my $computer_node_name = $self->data->get_computer_node_name();
- notify($ERRORS{'OK'}, 0, "beginning Windows image capture preparation tasks on $computer_node_name, end state: $self->{end_state}");
-
+ notify($ERRORS{'OK'}, 0, "beginning Windows image capture preparation tasks on $computer_node_name");
+
=item 1
Log off all currently logged in users
@@ -197,7 +205,6 @@
notify($ERRORS{'WARNING'}, 0, "unable to disable dynamic dns");
}
-
=item *
Disable Internet Explorer configuration page
@@ -262,7 +269,7 @@
=item *
-Allow users to connect remoteley
+Allow users to connect remotely
=cut
@@ -272,12 +279,12 @@
=item *
-Enable RDP access from private IP addresses by adding a firewall exception
+Disable RDP access from any address by adding a firewall exception
=cut
- if (!$self->firewall_enable_rdp('10.0.0.0/8')) {
- notify($ERRORS{'WARNING'}, 0, "unable to enable RDP from private IP addresses");
+ if (!$self->firewall_disable_rdp()) {
+ notify($ERRORS{'WARNING'}, 0, "unable to disable RDP from all addresses");
return 0;
}
@@ -371,7 +378,7 @@
notify($ERRORS{'OK'}, 0, "beginning Windows post-load tasks");
-=item *
+=item 1
Log off all currently logged in users
@@ -380,15 +387,25 @@
if (!$self->logoff_users()) {
notify($ERRORS{'WARNING'}, 0, "failed to log off all currently logged in users");
}
+
+=item *
+
+Set the computer name
+
+=cut
+
+ if (!$self->set_computer_name()) {
+ notify($ERRORS{'WARNING'}, 0, "failed to set the computer name");
+ }
=item *
-Enable RDP access from private IP addresses by adding a firewall exception
+Enable RDP access only from private network by adding a firewall exception
=cut
- if (!$self->firewall_enable_rdp('10.0.0.0/8')) {
- notify($ERRORS{'WARNING'}, 0, "unable to enable RDP from private IP addresses");
+ if (!$self->firewall_enable_rdp_private()) {
+ notify($ERRORS{'WARNING'}, 0, "unable to enable RDP on private network");
return 0;
}
@@ -422,25 +439,25 @@
notify($ERRORS{'WARNING'}, 0, "failed to rename My Computer");
}
-=item *
-
-Disable NetBIOS
-
-=cut
-
- if (!$self->disable_netbios()) {
- notify($ERRORS{'WARNING'}, 0, "failed to disable NetBIOS");
- }
-
-=item *
-
-Disable dynamic DNS
-
-=cut
+#=item *
+#
+#Disable NetBIOS
+#
+#=cut
+#
+# if (!$self->disable_netbios()) {
+# notify($ERRORS{'WARNING'}, 0, "failed to disable NetBIOS");
+# }
- if (!$self->disable_dynamic_dns()) {
- notify($ERRORS{'WARNING'}, 0, "failed to disable dynamic DNS");
- }
+#=item *
+#
+#Disable dynamic DNS
+#
+#=cut
+#
+# if (!$self->disable_dynamic_dns()) {
+# notify($ERRORS{'WARNING'}, 0, "failed to disable dynamic DNS");
+# }
=item *
@@ -463,16 +480,6 @@
if (!$self->set_password('Administrator', $administrator_random_password)) {
notify($ERRORS{'WARNING'}, 0, "failed to set random Administrator password");
}
-
-#=item *
-#
-#Create scheduled task to run script at computer startup
-#
-#=cut
-#
-# if (!$self->create_startup_scheduled_task('System Startup Script', 'cmd.exe /c start "system_startup.cmd" /MIN cmd.exe /c "' . $NODE_CONFIGURATION_DIRECTORY . '/Scripts/system_startup.cmd >> ' . $NODE_CONFIGURATION_DIRECTORY . '/Logs/system_startup.log 2>&1"', 'root', $root_random_password)) {
-# notify($ERRORS{'WARNING'}, 0, "failed to create scheduled task to run system_startup.cmd at computer startup");
-# }
=item *
@@ -484,7 +491,7 @@
notify($ERRORS{'OK'}, 0, "imagemeta postoption reboot is set for image, rebooting computer");
if (!$self->reboot()) {
notify($ERRORS{'WARNING'}, 0, "failed to reboot the computer");
- return 0;
+ return;
}
}
@@ -578,6 +585,107 @@
return 1;
} ## end sub sanitize
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 grant_access
+
+ Parameters :
+ Returns :
+ Description :
+
+=cut
+
+sub grant_access {
+ 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 $remote_ip = $self->data->get_reservation_remote_ip();
+ my $multiple_users = $self->data->get_imagemeta_usergroupmembercount();
+ my $request_forimaging = $self->data->get_request_forimaging();
+
+ # Check to make sure remote IP is defined
+ my $remote_ip_range;
+ if (!$remote_ip) {
+ notify($ERRORS{'WARNING'}, 0, "reservation remote IP address is not set in the data structure, opening RDP to any address");
+ }
+ elsif ($multiple_users) {
+ notify($ERRORS{'OK'}, 0, "reservation has multiple users, opening RDP to any address");
+ }
+ elsif ($remote_ip !~ /^(\d{1,3}\.?){4}$/) {
+ notify($ERRORS{'WARNING'}, 0, "reservation remote IP address format is invalid: $remote_ip, opening RDP to any address");
+ }
+ else {
+ # Assemble the IP range string in CIDR notation
+ $remote_ip_range = "$remote_ip/16";
+ notify($ERRORS{'OK'}, 0, "RDP will be allowed from $remote_ip_range on $computer_node_name");
+ }
+
+ # Set the $remote_ip_range variable to the string 'all' if it isn't already set (for display purposes)
+ $remote_ip_range = 'all' if !$remote_ip_range;
+
+ # Allow RDP connections
+ if ($self->firewall_enable_rdp($remote_ip_range)) {
+ notify($ERRORS{'OK'}, 0, "firewall was configured to allow RDP access from $remote_ip_range on $computer_node_name");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "firewall could not be configured to grant RDP access from $remote_ip_range on $computer_node_name");
+ return 0;
+ }
+
+ # If this is an imaging request, make sure the Administrator account is enabled
+ if ($request_forimaging) {
+ notify($ERRORS{'DEBUG'}, 0, "imaging request, making sure Administrator account is enabled");
+ if ($self->enable_user('Administrator')) {
+ notify($ERRORS{'OK'}, 0, "Administrator account is enabled for imaging request");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to enable Administrator account for imaging request");
+ return 0;
+ }
+ } ## end if ($request_forimaging)
+
+ notify($ERRORS{'OK'}, 0, "access has been granted for reservation on $computer_node_name");
+ return 1;
+} ## end sub grant_access
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 revoke_access
+
+ Parameters :
+ Returns :
+ Description :
+
+=cut
+
+sub revoke_access {
+ 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();
+
+ # Disallow RDP connections
+ if ($self->firewall_disable_rdp()) {
+ notify($ERRORS{'OK'}, 0, "firewall was configured to deny RDP access on $computer_node_name");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "firewall could not be configured to deny RDP access on $computer_node_name");
+ return 0;
+ }
+
+ notify($ERRORS{'OK'}, 0, "access has been revoked to $computer_node_name");
+ return 1;
+} ## end sub revoke_access
+
##############################################################################
=head1 AUXILIARY OBJECT METHODS
@@ -855,6 +963,7 @@
my $base_directory = shift;
my $pattern = shift;
+ my $max_depth = shift || '5';
# Make sure base directory and pattern were specified
if (!($base_directory && $pattern)) {
@@ -865,12 +974,12 @@
# Make sure base directory has trailing / or else find will fail
$base_directory =~ s/[\/\\]*$/\//;
- notify($ERRORS{'DEBUG'}, 0, "attempting to delete files under $base_directory matching pattern $pattern");
+ notify($ERRORS{'DEBUG'}, 0, "attempting to delete files under $base_directory matching pattern $pattern, max depth: $max_depth");
# Assemble command
# Use find to locate all the files under the base directory matching the pattern specified
# chmod 777 each file then call rm
- my $command = "/bin/find.exe \"$base_directory\" -mindepth 1 -iregex \"$pattern\" -exec chmod 777 {} \\; -exec rm -rvf {} \\;";
+ my $command = "/bin/find.exe \"$base_directory\" -mindepth 1 -maxdepth $max_depth -iregex \"$pattern\" -exec chmod 777 {} \\; -exec rm -rvf {} \\;";
my ($exit_status, $output) = run_ssh_command($computer_node_name, $management_node_keys, $command, '', '', 1);
if (defined($exit_status)) {
my @deleted = grep(/removed /, @$output);
@@ -1380,14 +1489,13 @@
Description :
=cut
-
sub set_password {
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();
@@ -1431,7 +1539,7 @@
# Attempt to change scheduled task passwords
notify($ERRORS{'DEBUG'}, 0, "changing passwords for scheduled tasks");
- my ($schtasks_query_exit_status, $schtasks_query_output) = run_ssh_command($computer_node_name, $management_node_keys, "schtasks.exe /Query /V /FO LIST");
+ my ($schtasks_query_exit_status, $schtasks_query_output) = run_ssh_command($computer_node_name, $management_node_keys, "schtasks.exe /Query /V /FO LIST", '', '', 1);
if (defined($schtasks_query_exit_status) && $schtasks_query_exit_status == 0) {
notify($ERRORS{'DEBUG'}, 0, "queried scheduled tasks on $computer_node_name");
}
@@ -1446,7 +1554,6 @@
for my $schtasks_output_line (@{$schtasks_query_output}) {
if ($schtasks_output_line =~ /TaskName:\s+([ \S]+)/i) {
$task_name = $1;
- notify($ERRORS{'DEBUG'}, 0, "found task: " . string_to_ascii($task_name));
}
if ($schtasks_output_line =~ /Run As User.*\\$username/i) {
notify($ERRORS{'DEBUG'}, 0, "password needs to be updated for scheduled task: $task_name\n$schtasks_output_line");
@@ -1541,21 +1648,21 @@
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
-
-[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management]
-"PagingFiles"=""
-EOF
-
- # Import the string into the registry
- if ($self->import_registry_string($registry_string)) {
- notify($ERRORS{'OK'}, 0, "set the registry key to disable the pagefile");
+ # Set the registry key to blank
+ my $memory_management_key = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management';
+ my $reg_add_command = '$SYSTEMROOT/System32/reg.exe add "' . $memory_management_key . '" /v PagingFiles /d "" /t REG_MULTI_SZ /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, "set registry key to disable pagefile");
}
- else {
- notify($ERRORS{'WARNING'}, 0, "failed to set the registry key to disable the pagefile");
+ elsif (defined($reg_add_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to set registry key to disable pagefile, exit status: $reg_add_exit_status, output:\n@{$reg_add_output}");
return 0;
}
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to set registry key to disable pagefile");
+ return;
+ }
# Attempt to reboot the computer in order to delete the pagefile
if ($self->reboot()) {
@@ -1594,22 +1701,22 @@
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
-
-[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management]
-"PagingFiles"="?:\\\\pagefile.sys"
-EOF
-
- # Import the string into the registry
- if ($self->import_registry_string($registry_string)) {
- notify($ERRORS{'OK'}, 0, "set registry key to enable the pagefile");
+
+ my $memory_management_key = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management';
+
+ my $reg_add_command = '$SYSTEMROOT/System32/reg.exe add "' . $memory_management_key . '" /v PagingFiles /d "$SYSTEMDRIVE\\pagefile.sys 0 0" /t REG_MULTI_SZ /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, "set registry key to enable pagefile");
}
- else {
- notify($ERRORS{'WARNING'}, 0, "failed to set registry key to enable the pagefile");
+ elsif (defined($reg_add_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to set registry key to enable pagefile, exit status: $reg_add_exit_status, output:\n@{$reg_add_output}");
return 0;
}
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to set registry key to enable pagefile");
+ return;
+ }
return 1;
} ## end sub enable_pagefile
@@ -1765,9 +1872,16 @@
# Replace regular newlines with Windows newlines
$registry_string =~ s/\r?\n/\r\n/gs;
+
+ # Remove spaces from end of file
+ $registry_string =~ s/\s+$//;
- # Specify where on the node the temporary registry file will reside
- my $temp_registry_file_path = 'C:/Cygwin/tmp/vcl_import.reg';
+ # Assemble a temporary registry file path
+ # Name the file after the sub which called this so you can tell where the .reg file was generated from
+ my @caller = caller(1);
+ my ($calling_sub) = $caller[3] =~ /([^:]+)$/;
+ my $calling_line = $caller[2];
+ my $temp_registry_file_path = "C:/Cygwin/tmp/$calling_sub\_$calling_line.reg";
# Echo the registry string to a file on the node
my $echo_registry_command = "rm -f $temp_registry_file_path; /usr/bin/echo.exe -E \"$registry_string\" > " . $temp_registry_file_path;
@@ -2346,6 +2460,63 @@
#/////////////////////////////////////////////////////////////////////////////
+=head2 shutdown
+
+ Parameters :
+ Returns :
+ Description :
+
+=cut
+
+sub shutdown {
+ 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();
+
+ notify($ERRORS{'DEBUG'}, 0, "$computer_node_name will be shut down");
+
+ # Initiate the shutdown.exe command to reboot the computer
+ my $shutdown_command = "C:/Windows/system32/shutdown.exe -s -t 0 -f";
+ my ($shutdown_exit_status, $shutdown_output) = run_ssh_command($computer_node_name, $management_node_keys, $shutdown_command);
+ if (defined($shutdown_exit_status) && $shutdown_exit_status == 0) {
+ notify($ERRORS{'DEBUG'}, 0, "executed shutdown command on $computer_node_name");
+
+ # Wait maximum of 3 minutes for the computer to become unresponsive
+ if ($self->wait_for_no_ping(3)) {
+ notify($ERRORS{'OK'}, 0, "computer has become unresponsive after shutdown command was issued");
+ return 1;
+ }
+ else {
+ # Computer never stopped responding to ping
+ notify($ERRORS{'WARNING'}, 0, "$computer_node_name never became unresponsive after shutdown command was issued, attempting power off");
+ }
+ }
+ elsif (defined($shutdown_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to execute shutdown command on $computer_node_name, exit status: $shutdown_exit_status, output:\n@{$shutdown_output}");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to execute ssh command to shutdown $computer_node_name");
+ }
+
+ # Call provisioning module's power_off() subroutine
+ if ($self->provisioner->power_off()) {
+ notify($ERRORS{'OK'}, 0, "powered off $computer_node_name");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to power off $computer_node_name");
+ return;
+ }
+
+ return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
=head2 wait_for_ping
Parameters : Maximum number of minutes to wait (optional)
@@ -2643,21 +2814,12 @@
my $computer_node_name = $self->data->get_computer_node_name();
my $computer_id = $self->data->get_computer_id();
- # Attempt to get the computer name from the arguments
- # If no argument was supplied, use the name specified in the DataStructure
- my $computer_name = shift;
- if (!(defined($computer_name))) {
- my $image_id = $self->data->get_image_id();
- my $computer_short_name = $self->data->get_computer_short_name();
- $computer_name = "$computer_short_name-$image_id";
- }
-
- my $registry_string .= <<"EOF";
+ my $registry_string .= <<'EOF';
Windows Registry Editor Version 5.00
; This registry file contains the entries to bypass the license agreement when newsid.exe is run
-[HKEY_CURRENT_USER\\Software\\Sysinternals\\NewSID]
+[HKEY_CURRENT_USER\Software\Sysinternals\NewSID]
"EulaAccepted"=dword:00000001
EOF
@@ -2669,22 +2831,22 @@
notify($ERRORS{'WARNING'}, 0, "failed to add newsid eulaaccepted registry string");
return 0;
}
-
+
# Attempt to run newsid.exe
# newsid.exe should automatically reboot the computer
# It isn't done when the process exits, newsid.exe starts working and immediately returns
# NewSid.exe [/a[[/n]|[/d <reboot delay (in seconds)>]]][<new computer name>]
# /a - run without prompts
# /n - Don't reboot after automatic run
- my $newsid_command = "\"$NODE_CONFIGURATION_DIRECTORY/Utilities/newsid.exe\" /a \"$computer_name\"";
+ my $newsid_command = "\"$NODE_CONFIGURATION_DIRECTORY/Utilities/NewSID/newsid.exe\" /a";
my $newsid_start_processing_time = time();
my ($newsid_exit_status, $newsid_output) = run_ssh_command($computer_node_name, $management_node_keys, $newsid_command);
if (defined($newsid_exit_status) && $newsid_exit_status == 0) {
- notify($ERRORS{'OK'}, 0, "newsid.exe has been started on $computer_node_name, new computer name: $computer_name");
+ notify($ERRORS{'OK'}, 0, "newsid.exe has been started on $computer_node_name");
}
elsif (defined($newsid_exit_status)) {
notify($ERRORS{'WARNING'}, 0, "failed to start newsid.exe on $computer_node_name, exit status: $newsid_exit_status, output:\n@{$newsid_output}");
- return 0;
+ return;
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to start newsid.exe on $computer_node_name");
@@ -2693,13 +2855,13 @@
my $newsid_end_processing_time = time();
my $newsid_processing_duration = ($newsid_end_processing_time - $newsid_start_processing_time);
- notify($ERRORS{'OK'}, 0, "newsid.exe complete, newsid.exe took $newsid_processing_duration seconds");
- insertloadlog($reservation_id, $computer_id, "info", "newsid.exe processing took $newsid_processing_duration seconds");
+ notify($ERRORS{'OK'}, 0, "newsid.exe execution took $newsid_processing_duration seconds");
+ insertloadlog($reservation_id, $computer_id, "info", "newsid.exe execution took $newsid_processing_duration seconds");
# After launching newsid.exe, wait for machine to become unresponsive
if (!$self->wait_for_no_ping(10)) {
notify($ERRORS{'WARNING'}, 0, "failed to run newsid.exe, $computer_node_name never rebooted after waiting 10 minutes");
- return 0;
+ return;
}
my $newsid_shutdown_time = time();
@@ -2906,8 +3068,8 @@
# Attempt to delete the user account
my $schtasks_command = '$SYSTEMROOT/System32/schtasks.exe /Change /DISABLE /TN "' . $task_name . '"';
- my ($schtasks_exit_status, $schtasks_output) = run_ssh_command($computer_node_name, $management_node_keys, $schtasks_command);
- if (defined($schtasks_exit_status) && $schtasks_exit_status == 0) {
+ my ($schtasks_exit_status, $schtasks_output) = run_ssh_command($computer_node_name, $management_node_keys, $schtasks_command, '', '', 1);
+ if (defined($schtasks_output) && grep(/have been changed/, @$schtasks_output)) {
notify($ERRORS{'OK'}, 0, "$task_name scheduled task disabled on $computer_node_name");
}
elsif (defined($schtasks_exit_status)) {
@@ -3072,14 +3234,46 @@
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to disable dynamic dns");
- return 0;
+ return;
}
# Get the network configuration
my $network_configuration = $self->get_network_configuration();
if (!$network_configuration) {
notify($ERRORS{'WARNING'}, 0, "unable to retrieve network configuration");
- return 0;
+ return;
+ }
+
+ # Get the public and private interface names
+ my $public_interface_name = $self->get_public_interface_name();
+ my $private_interface_name = $self->get_private_interface_name();
+
+ # Assemble netsh.exe commands to disable DNS registration
+ my $netsh_command;
+ $netsh_command .= "netsh.exe interface ip set dns";
+ $netsh_command .= " name = \"$public_interface_name\"";
+ $netsh_command .= " source = dhcp";
+ $netsh_command .= " register = none";
+ $netsh_command .= " ;";
+
+ $netsh_command .= "netsh.exe interface ip set dns";
+ $netsh_command .= " name = \"$private_interface_name\"";
+ $netsh_command .= " source = dhcp";
+ $netsh_command .= " register = none";
+ $netsh_command .= " ;";
+
+ # Execute the netsh.exe command
+ my ($netsh_exit_status, $netsh_output) = run_ssh_command($computer_node_name, $management_node_keys, $netsh_command);
+ if (defined($netsh_exit_status) && $netsh_exit_status == 0) {
+ notify($ERRORS{'OK'}, 0, "disabled dynamic DNS registration on public and private adapters");
+ }
+ elsif (defined($netsh_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to disable dynamic DNS registration on public and private adapters, exit status: $netsh_exit_status, output:\n@{$netsh_output}");
+ return;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to disable dynamic DNS registration on public and private adapters");
+ return;
}
return 1;
@@ -3255,109 +3449,7 @@
#/////////////////////////////////////////////////////////////////////////////
-=head2 grant_access
-
- Parameters :
- Returns :
- Description :
-
-=cut
-
-sub grant_access {
- 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 $remote_ip = $self->data->get_reservation_remote_ip();
- my $multiple_users = $self->data->get_imagemeta_usergroupmembercount();
- my $request_forimaging = $self->data->get_request_forimaging();
-
- # Check to make sure remote IP is defined
- my $remote_ip_range;
- if (!$remote_ip) {
- notify($ERRORS{'WARNING'}, 0, "reservation remote IP address is not set in the data structure, opening RDP to any address");
- $remote_ip_range = '0.0.0.0/32';
- }
- elsif ($multiple_users) {
- notify($ERRORS{'OK'}, 0, "reservation has multiple users, opening RDP to any address");
- $remote_ip_range = '0.0.0.0/32';
- }
- elsif ($remote_ip !~ /^(\d{1,3}\.?){4}$/) {
- notify($ERRORS{'WARNING'}, 0, "reservation remote IP address format is invalid: $remote_ip, opening RDP to any address");
- $remote_ip_range = '0.0.0.0/32';
- }
- else {
- # Assemble the IP range string in CIDR notation
- $remote_ip_range = "$remote_ip/16";
- notify($ERRORS{'OK'}, 0, "RDP will be allowed from $remote_ip_range on $computer_node_name");
- }
-
-
- # Allow RDP connections
- if ($self->firewall_enable_rdp($remote_ip_range)) {
- notify($ERRORS{'OK'}, 0, "firewall was configured to allow RDP access from $remote_ip_range on $computer_node_name");
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "firewall could not be configured to grant RDP access from $remote_ip_range on $computer_node_name");
- return 0;
- }
-
- # If this is an imaging request, make sure the Administrator account is enabled
- if ($request_forimaging) {
- notify($ERRORS{'DEBUG'}, 0, "imaging request, making sure Administrator account is enabled");
- if ($self->enable_user('Administrator')) {
- notify($ERRORS{'OK'}, 0, "Administrator account is enabled for imaging request");
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "failed to enable Administrator account for imaging request");
- return 0;
- }
- } ## end if ($request_forimaging)
-
- notify($ERRORS{'OK'}, 0, "access has been granted for reservation on $computer_node_name");
- return 1;
-} ## end sub grant_access
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 revoke_access
-
- Parameters :
- Returns :
- Description :
-
-=cut
-
-sub revoke_access {
- 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();
-
- # Disallow RDP connections
- if ($self->firewall_disable_rdp()) {
- notify($ERRORS{'OK'}, 0, "firewall was configured to deny RDP access on $computer_node_name");
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "firewall could not be configured to deny RDP access on $computer_node_name");
- return 0;
- }
-
- notify($ERRORS{'OK'}, 0, "access has been revoked to $computer_node_name");
- return 1;
-} ## end sub revoke_access
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 get_currentimage_txt_contents
+=head2 get_currentimage_txt_contents
Parameters :
Returns : array containing lines in currentimage.txt
@@ -3951,6 +4043,91 @@
#/////////////////////////////////////////////////////////////////////////////
+=head2 firewall_enable_rdp_private
+
+ Parameters :
+ Returns : 1 if succeeded, 0 otherwise
+ Description :
+
+=cut
+
+sub firewall_enable_rdp_private {
+ 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 $netsh_command;
+
+ # Get the public interface name
+ # Add command to disable RDP on public interface if its name is found
+ my $public_interface_name = $self->get_public_interface_name();
+ if ($public_interface_name) {
+ notify($ERRORS{'DEBUG'}, 0, "RDP will be disabled on public interface: $public_interface_name");
+
+ $netsh_command .= "netsh.exe firewall delete portopening";
+ $netsh_command .= " protocol = TCP";
+ $netsh_command .= " port = 3389";
+ $netsh_command .= " interface = \"$public_interface_name\"";
+ $netsh_command .= ' ;';
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "RDP will not be disabled on public interface because public interface name could not be determined");
+ }
+
+ # Get the private interface name
+ # Add command to ensable RDP on private interface if its name is found
+ my $private_interface_name = $self->get_private_interface_name();
+ if ($private_interface_name) {
+ notify($ERRORS{'DEBUG'}, 0, "RDP will be enabled on private interface: $private_interface_name");
+
+ $netsh_command .= "netsh.exe firewall delete portopening";
+ $netsh_command .= " protocol = TCP";
+ $netsh_command .= " port = 3389";
+ $netsh_command .= " profile = ALL";
+ $netsh_command .= ' ;';
+
+ $netsh_command .= "netsh.exe firewall set portopening";
+ $netsh_command .= " name = \"Remote Desktop\"";
+ $netsh_command .= " protocol = TCP";
+ $netsh_command .= " port = 3389";
+ $netsh_command .= " mode = ENABLE";
+ $netsh_command .= " interface = \"$private_interface_name\"";
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "private interface name could not be determined, RDP will be enabled for all profiles");
+
+ $netsh_command .= "netsh.exe firewall set portopening";
+ $netsh_command .= " name = \"Remote Desktop\"";
+ $netsh_command .= " protocol = TCP";
+ $netsh_command .= " port = 3389";
+ $netsh_command .= " profile = ALL";
+ }
+
+ # Execute the netsh.exe command
+ my ($netsh_exit_status, $netsh_output) = run_ssh_command($computer_node_name, $management_node_keys, $netsh_command);
+
+ if (defined($netsh_output) && @$netsh_output[-1] =~ /Ok\./i) {
+ notify($ERRORS{'OK'}, 0, "configured firewall to allow RDP on private interface");
+ }
+ elsif (defined($netsh_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to configure firewall to allow RDP on private interface, exit status: $netsh_exit_status, output:\n@{$netsh_output}");
+ return;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to configure firewall to allow RDP on private interface");
+ return;
+ }
+
+ return 1;
+} ## end sub firewall_enable_ssh_private
+
+#/////////////////////////////////////////////////////////////////////////////
+
=head2 firewall_disable_rdp
Parameters :
@@ -4457,6 +4634,12 @@
# Remove old scripts and utilities
$self->delete_files_by_pattern('C:/Cygwin/home/root', '.*\(vbs\|exe\|cmd\|bat\|log\)');
+ # Remove old C:\VCL directory if it exists
+ $self->delete_file('C:/VCL');
+
+ # Delete VCL scheduled task if it exists
+ $self->delete_scheduled_task('VCL Startup Configuration');
+
## Remove VCLprepare.cmd and VCLcleanup.cmd lines from scripts.ini file
$self->remove_group_policy_script('logon', 'VCLprepare.cmd');
$self->remove_group_policy_script('logoff', 'VCLcleanup.cmd');
@@ -5298,7 +5481,7 @@
notify($ERRORS{'WARNING'}, 0, "unable to run ssh command to clear out setupapi.log");
return 0;
}
-
+
# Run Sysprep.exe, use cygstart to lauch the .exe and return immediately
my $sysprep_command = '/bin/cygstart.exe cmd.exe /c "C:/Sysprep/sysprep.exe /forceshutdown /quiet /reseal /mini"';
my ($sysprep_status, $sysprep_output) = run_ssh_command($computer_node_name, $management_node_keys, $sysprep_command);
@@ -5461,6 +5644,7 @@
'$SYSTEMDRIVE/RECYCLER,.*',
'$TEMP,.*',
'$TMP,.*',
+ '$SYSTEMDRIVE/cygwin/tmp,.*',
'$SYSTEMDRIVE/Temp,.*',
'$SYSTEMROOT/Temp,.*',
'$SYSTEMROOT/ie7updates,.*',
@@ -5468,21 +5652,21 @@
'$SYSTEMROOT/SoftwareDistribution/Download,.*',
'$SYSTEMROOT/Minidump,.*',
'$ALLUSERSPROFILE/Application Data/Microsoft/Dr Watson,.*',
- '$SYSTEMROOT,.*\\.tmp',
- '$SYSTEMROOT,.*\\$hf_mig\\$.*',
- '$SYSTEMROOT,.*\\$NtUninstall.*',
- '$SYSTEMROOT,.*\\$NtServicePackUninstall.*',
- '$SYSTEMROOT,.*\\$MSI.*Uninstall.*',
+ '$SYSTEMROOT,.*\\.tmp,1',
+ '$SYSTEMROOT,.*\\$hf_mig\\$.*,1',
+ '$SYSTEMROOT,.*\\$NtUninstall.*,1',
+ '$SYSTEMROOT,.*\\$NtServicePackUninstall.*,1',
+ '$SYSTEMROOT,.*\\$MSI.*Uninstall.*,1',
'$SYSTEMROOT/inf,.*INFCACHE\\.1',
'$SYSTEMROOT/inf,.*[\\\\\\/]oem.*\\..*',
- '$SYSTEMROOT,.*AFSCache',
- '$SYSTEMROOT,.*afsd_init\\.log',
- '$SYSTEMDRIVE/Documents and Settings,.*\\.log',
- '$SYSTEMDRIVE/Documents and Settings,.*Recent\\/.*',
- '$SYSTEMDRIVE/Documents and Settings,.*Cookies\\/.*',
- '$SYSTEMDRIVE/Documents and Settings,.*Temp\\/.*',
- '$SYSTEMDRIVE/Documents and Settings,.*Temporary Internet Files\\/Content.*\\/.*',
- '$SYSTEMDRIVE,.*pagefile\\.sys',
+ '$SYSTEMROOT,.*AFSCache,1',
+ '$SYSTEMROOT,.*afsd_init\\.log,1',
+ '$SYSTEMDRIVE/Documents and Settings,.*\\.log,10',
+ '$SYSTEMDRIVE/Documents and Settings,.*Recent\\/.*,10',
+ '$SYSTEMDRIVE/Documents and Settings,.*Cookies\\/.*,10',
+ '$SYSTEMDRIVE/Documents and Settings,.*Temp\\/.*,10',
+ '$SYSTEMDRIVE/Documents and Settings,.*Temporary Internet Files\\/Content.*\\/.*,10',
+ '$SYSTEMDRIVE,.*pagefile\\.sys,1',
);
# Attempt to stop the AFS service, needed to delete AFS files
@@ -5491,9 +5675,9 @@
# Loop through the directories to empty
# Don't care if they aren't emptied
for my $base_pattern (@patterns_to_delete) {
- my ($base_directory, $pattern) = split(',', $base_pattern);
+ my ($base_directory, $pattern, $max_depth) = split(',', $base_pattern);
notify($ERRORS{'DEBUG'}, 0, "attempting to delete files under $base_directory matching pattern $pattern");
- $self->delete_files_by_pattern($base_directory, $pattern);
+ $self->delete_files_by_pattern($base_directory, $pattern, $max_depth);
}
# Add the cleanmgr.exe settings to the registry
@@ -5680,8 +5864,8 @@
notify($ERRORS{'OK'}, 0, "service is not started: $service_name");
}
elsif (defined($output) && grep(/does not exist/i, @{$output})) {
- notify($ERRORS{'WARNING'}, 0, "service does not exist: $service_name, exit status: $status, output:\n@{$output}");
- return 0;
+ notify($ERRORS{'OK'}, 0, "service was not stopped because it does not exist: $service_name");
+ return;
}
elsif (defined($status)) {
notify($ERRORS{'WARNING'}, 0, "unable to stop service: $service_name, exit status: $status, output:\n@{$output}");
@@ -6059,7 +6243,7 @@
$inf_target_path =~ s/\//\\\\/g;
my $secedit_command = "$secedit_exe /configure /cfg \"$inf_target_path\" /db $secedit_db /log $secedit_log /verbose";
- my ($secedit_exit_status, $secedit_output) = run_ssh_command($computer_node_name, $management_node_keys, $secedit_command, '', '', 1);
+ my ($secedit_exit_status, $secedit_output) = run_ssh_command($computer_node_name, $management_node_keys, $secedit_command, '', '', 0);
if (defined($secedit_exit_status) && $secedit_exit_status == 0) {
notify($ERRORS{'OK'}, 0, "ran secedit.exe to apply $inf_file_name");
}
@@ -6195,100 +6379,80 @@
#/////////////////////////////////////////////////////////////////////////////
-=head2 run_newsid_new
+=head2 get_node_configuration_directory
- Parameters :
- Returns : 1 success 0 failure
- Description :
+ Parameters : None
+ Returns : String containing filesystem path
+ Description : Retrieves the $NODE_CONFIGURATION_DIRECTORY variable value the
+ OS. This is the path on the computer's hard drive where image
+ configuration files and scripts are copied.
+
+=cut
+
+sub get_node_configuration_directory {
+ return $NODE_CONFIGURATION_DIRECTORY;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 set_computer_name
+
+ Parameters : $computer_name
+ Returns : If successful: true
+ If failed: false
+ Description : Sets the registry keys to set the computer name. This subroutine
+ does not attempt to reboot the computer.
+ The computer name argument is optional. If not supplied, the
+ computer's short name stored in the database will be used,
+ followed by a hyphen and the image ID that is loaded.
=cut
-sub run_newsid_new {
+sub set_computer_name {
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 $reservation_id = $self->data->get_reservation_id();
- my $management_node_keys = $self->data->get_management_node_keys();
- my $computer_node_name = $self->data->get_computer_node_name();
- my $computer_id = $self->data->get_computer_id();
-
- my $registry_string .= <<'EOF';
+ # Get the computer name
+ my $computer_name = shift;
+ if (!$computer_name) {
+ $computer_name = $self->data->get_computer_short_name();
+ if (!$computer_name) {
+ notify($ERRORS{'WARNING'}, 0, "computer name argument was not supplied and could not be retrieved from the reservation data");
+ return;
+ }
+
+ # Append the image ID to the computer name
+ my $image_id = $self->data->get_image_id();
+ $computer_name .= "-$image_id" if $image_id;
+ }
+
+ 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
-; This registry file contains the entries to bypass the license agreement when newsid.exe is run
+[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName]
+"ComputerName"="$computer_name"
-[HKEY_CURRENT_USER\\Software\\Sysinternals\\NewSID]
-"EulaAccepted"=dword:00000001
+[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters]
+"NV Hostname"="$computer_name"
EOF
-
+
# Import the string into the registry
if ($self->import_registry_string($registry_string)) {
- notify($ERRORS{'DEBUG'}, 0, "added newsid eulaaccepted registry string");
+ notify($ERRORS{'OK'}, 0, "set registry keys to change the computer name to $computer_name");
}
else {
- notify($ERRORS{'WARNING'}, 0, "failed to add newsid eulaaccepted registry string");
- }
-
- # Attempt to run newsid.exe
- # newsid.exe should automatically reboot the computer
- # It isn't done when the process exits, newsid.exe starts working and immediately returns
- # NewSid.exe [/a[[/n]|[/d <reboot delay (in seconds)>]]][<new computer name>]
- # /a - run without prompts
- # /n - Don't reboot after automatic run
- my $newsid_command = "\"$NODE_CONFIGURATION_DIRECTORY/Utilities/newsid.exe\" /a \"$computer_node_name\"";
-
- my $newsid_start_processing_time = time();
- my ($newsid_exit_status, $newsid_output) = run_ssh_command($computer_node_name, $management_node_keys, $newsid_command);
- my $newsid_end_processing_time = time();
-
- if (defined($newsid_exit_status) && $newsid_exit_status == 0) {
- notify($ERRORS{'DEBUG'}, 0, "ran newsid.exe on $computer_node_name");
- }
- elsif (defined($newsid_exit_status)) {
- notify($ERRORS{'WARNING'}, 0, "failed to run newsid.exe on $computer_node_name, exit status: $newsid_exit_status, output:\n@{$newsid_output}");
+ notify($ERRORS{'WARNING'}, 0, "failed to set registry keys to change the computer name to $computer_name");
return;
}
- else {
- notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to run newsid.exe on $computer_node_name");
- return;
- }
- my $newsid_processing_duration = ($newsid_end_processing_time - $newsid_start_processing_time);
- notify($ERRORS{'DEBUG'}, 0, "newsid.exe finished processing, newsid.exe took $newsid_processing_duration seconds");
- insertloadlog($reservation_id, $computer_id, "info", "newsid.exe processing took $newsid_processing_duration seconds");
-
- # After launching newsid.exe, wait for machine to become unresponsive
- if (!$self->wait_for_no_ping(10)) {
- notify($ERRORS{'WARNING'}, 0, "failed to run newsid.exe, $computer_node_name never became unresponsive after waiting 10 minutes");
- return;
- }
- my $newsid_shutdown_time = time();
- notify($ERRORS{'DEBUG'}, 0, "newsid.exe initiated reboot, $computer_node_name is unresponsive, reboot initialization took " . ($newsid_shutdown_time - $newsid_end_processing_time) . " seconds");
-
- # Wait maximum of 6 minutes for the computer to come back up
- if (!$self->wait_for_ping(6)) {
- notify($ERRORS{'WARNING'}, 0, "$computer_node_name never responded to ping, it never came back up");
- return;
- }
-
- my $newsid_ping_respond_time = time();
- notify($ERRORS{'DEBUG'}, 0, "reboot nearly complete on $computer_node_name after running newsid.exe, ping response took " . ($newsid_ping_respond_time - $newsid_shutdown_time) . " seconds");
-
- # Ping successful, try ssh
- notify($ERRORS{'OK'}, 0, "waiting for ssh to respond on $computer_node_name");
- if (!$self->wait_for_ssh(3)) {
- notify($ERRORS{'WARNING'}, 0, "newsid.exe failed, $computer_node_name rebooted but ssh never became available");
- return;
- }
- my $newsid_ssh_respond_time = time();
- my $newsid_entire_duration = ($newsid_ssh_respond_time - $newsid_start_processing_time);
- notify($ERRORS{'OK'}, 0, "newsid.exe succeeded on $computer_node_name, entire process took $newsid_entire_duration seconds");
- insertloadlog($reservation_id, $computer_id, "info", "entire newsid.exe process took $newsid_entire_duration seconds");
-
+
return 1;
-}
+} ## end sub disable_ipv6
#/////////////////////////////////////////////////////////////////////////////
Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_5.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_5.pm?rev=780755&r1=780754&r2=780755&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_5.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_5.pm Mon Jun 1 17:51:52 2009
@@ -80,11 +80,11 @@
return;
}
- notify($ERRORS{'OK'}, 0, "beginning Windows version 5 image capture preparation tasks, end state: $self->{end_state}");
+ notify($ERRORS{'OK'}, 0, "beginning Windows version 5 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()) {
+ if ($self->SUPER::pre_capture($args)) {
notify($ERRORS{'OK'}, 0, "successfully executed parent class pre_capture() subroutine");
}
else {
Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_5/XP_mod.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_5/XP_mod.pm?rev=780755&r1=780754&r2=780755&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_5/XP_mod.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_5/XP_mod.pm Mon Jun 1 17:51:52 2009
@@ -96,35 +96,23 @@
return;
}
- my $imagemeta_sysprep = $self->data->get_imagemeta_sysprep();
-
- # Check if end_state argument was passed
- if (defined $args->{end_state}) {
- $self->{end_state} = $args->{end_state};
- }
- else {
- $self->{end_state} = 'off';
- }
-
- notify($ERRORS{'OK'}, 0, "beginning Windows XP image capture preparation tasks, end state: $self->{end_state}");
+ notify($ERRORS{'OK'}, 0, "beginning Windows XP 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()) {
+ 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;
+ return;
}
# Check if Sysprep should be used
- if ($imagemeta_sysprep) {
- # Copy the Sysprep files to C:\Sysprep
- # Call this *AFTER* calling copy_capture_configuration_files
+ if ($self->data->get_imagemeta_sysprep()) {
if (!$self->run_sysprep()) {
notify($ERRORS{'WARNING'}, 0, "capture preparation failed, failed to run Sysprep");
- return 0;
+ return;
}
}
Added: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_6.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_6.pm?rev=780755&view=auto
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_6.pm (added)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_6.pm Mon Jun 1 17:51:52 2009
@@ -0,0 +1,1019 @@
+#!/usr/bin/perl -w
+###############################################################################
+# $Id: Version_5.pm 774457 2009-05-13 18:12:08Z arkurth $
+###############################################################################
+# 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_mod::Version_6.pm - VCL module to support Windows 6.x operating systems
+
+=head1 SYNOPSIS
+
+ Needs to be written
+
+=head1 DESCRIPTION
+
+ This module provides VCL support for Windows version 6.x operating systems.
+ Version 6.x Windows OS's include Windows Vista and Windows Server 2008.
+
+=cut
+
+##############################################################################
+package VCL::Module::OS::Windows_mod::Version_6;
+
+# Specify the lib path using FindBin
+use FindBin;
+use lib "$FindBin::Bin/../../../..";
+
+# Configure inheritance
+use base qw(VCL::Module::OS::Windows_mod);
+
+# 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 INTERFACE OBJECT METHODS
+
+=cut
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 pre_capture
+
+ Parameters : None
+ Returns : If successful: true
+ If failed: false
+ Description : Performs steps before an image is captured which are specific to
+ Windows version 6.x.
+
+=over 3
+
+=cut
+
+sub pre_capture {
+ my $self = shift;
+ my $args = shift;
+
+ # Check if subroutine was called as an object method
+ unless (ref($self) && $self->isa('VCL::Module')) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as a VCL::Module object method");
+ return;
+ }
+
+ notify($ERRORS{'OK'}, 0, "beginning Windows version 6 image pre-capture tasks");
+
+=item 1
+
+Disable defrag scheduled task
+
+=cut
+
+ $self->disable_scheduled_task('\Microsoft\Windows\Defrag\ScheduledDefrag');
+
+=item *
+
+Disable system restore scheduled task
+
+=cut
+
+ $self->disable_scheduled_task('\Microsoft\Windows\SystemRestore\SR');
+
+=item *
+
+Disable customer improvement program consolidator scheduled task
+
+=cut
+
+ $self->disable_scheduled_task('\Microsoft\Windows\Customer Experience Improvement Program\Consolidator');
+
+=item *
+
+Disable customer improvement program opt-in notification scheduled task
+
+=cut
+
+ $self->disable_scheduled_task('\Microsoft\Windows\Customer Experience Improvement Program\OptinNotification');
+
+=item *
+
+Call parent class's pre_capture() subroutine
+
+=cut
+
+ 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;
+ }
+
+=back
+
+=cut
+
+ notify($ERRORS{'OK'}, 0, "returning 1");
+ return 1;
+} ## end sub pre_capture
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 post_load
+
+ Parameters : None
+ Returns : If successful: true
+ If failed: false
+ Description : Performs steps after an image is loaded which are specific to
+ Windows version 6.x.
+
+=over 3
+
+=cut
+
+sub post_load {
+ my $self = shift;
+
+ # Check if subroutine was called as an object method
+ unless (ref($self) && $self->isa('VCL::Module')) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as a VCL::Module object method");
+ return;
+ }
+
+ notify($ERRORS{'DEBUG'}, 0, "beginning Windows version 6 (Vista, Server 2008) post-load tasks");
+
+=item 1
+
+Activate Windows license
+
+=cut
+
+ $self->activate_license();
+
+=item *
+
+Call parent class's post_load() subroutine
+
+=cut
+
+ notify($ERRORS{'DEBUG'}, 0, "calling parent class post_load() subroutine");
+ if ($self->SUPER::post_load()) {
+ notify($ERRORS{'OK'}, 0, "successfully executed parent class post_load() subroutine");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to execute parent class post_load() subroutine");
+ return;
+ }
+
+=back
+
+=cut
+
+ notify($ERRORS{'DEBUG'}, 0, "Windows version 6 (Vista, Server 2008) post-load tasks complete");
+ return 1;
+}
+
+##############################################################################
+
+=head1 AUXILIARY OBJECT METHODS
+
+=cut
+
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 activate_license
+
+ Parameters : None
+ Returns : If successful: true
+ If failed: false
+ Description : Runs cscript.exe slmgr.vbs -skms to set the KMS server address
+ stored on the computer.
+ Runs cscript.exe slmgr.vbs -ato to activate licensing on the
+ computer.
+
+=cut
+
+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");
+ return;
+ }
+
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+
+ # Get the image affiliation name
+ my $image_affiliation_name = $self->data->get_image_affiliation_name();
+ if ($image_affiliation_name) {
+ notify($ERRORS{'DEBUG'}, 0, "image affiliation name: $image_affiliation_name");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "image affiliation name could not be retrieved, using default licensing configuration");
+ $image_affiliation_name = 'default';
+ }
+
+ # Get the Windows activation data from the windows-activation variable
+ my $activation_data = $self->data->get_variable('windows-activation');
+ if ($activation_data) {
+ notify($ERRORS{'DEBUG'}, 0, "activation data:\n" . format_data($activation_data));
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "activation data could not be retrieved");
+ return;
+ }
+
+ # Get the activation data specific to the image affiliation
+ my $affiliation_config = $activation_data->{$image_affiliation_name};
+ if ($affiliation_config) {
+ notify($ERRORS{'DEBUG'}, 0, "$image_affiliation_name affiliation activation configuration:\n" . format_data($affiliation_config));
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "activation configuration does not exist for affiliation: $image_affiliation_name, attempting to retrieve default configuration");
+
+ $affiliation_config = $activation_data->{'default'};
+ if ($affiliation_config) {
+ notify($ERRORS{'DEBUG'}, 0, "default activation configuration:\n" . format_data($affiliation_config));
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "default activation configuration does not exist");
+ return;
+ }
+ }
+
+
+ # Loop through the activation methods for the affiliation
+ for my $activation_config (@$affiliation_config) {
+ my $activation_method = $activation_config->{method};
+
+ if ($activation_method =~ /kms/i) {
+ my $kms_address = $activation_config->{address};
+ 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");
+ }
+ 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:\n@{$kms_output}");
+ next;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to execute ssh command to set kms server to $kms_address:$kms_port");
+ next;
+ }
+
+ # 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;
+ }
+ elsif (defined($activate_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to activate license using kms server: $kms_address, exit status: $activate_exit_status, output:\n@{$activate_output}");
+ next;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to activate license using kms server: $kms_address");
+ next;
+ }
+ }
+
+ elsif ($activation_method =~ /mak/i) {
+ notify($ERRORS{'WARNING'}, 0, "MAK activation method is not supported yet");
+ next;
+ }
+
+ else {
+ notify($ERRORS{'WARNING'}, 0, "unsupported activation method: $activation_method");
+ next;
+ }
+ }
+
+ notify($ERRORS{'WARNING'}, 0, "failed to activate license on $computer_node_name using any configured kms servers");
+ return;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 deactivate_license
+
+ 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.
+ Runs cscript.exe slmgr.vbs -rearm to rearm licensing on the
+ computer.
+
+=cut
+
+sub deactivate_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");
+ return;
+ }
+
+ 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");
+ }
+ elsif (defined($ckms_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to clear kms address, exit status: $ckms_exit_status, output:\n@{$ckms_output}");
+ return;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to execute ssh command to clear kms address");
+ return;
+ }
+
+ # Run slmgr.vbs -rearm
+ my $rearm_command = '$SYSTEMROOT/System32/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");
+ }
+ elsif (defined($rearm_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to rearm licensing, exit status: $rearm_exit_status, output:\n@{$rearm_output}");
+ return;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to execute ssh command to rearm licensing");
+ return;
+ }
+
+ return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 set_network_location
+
+ Parameters :
+ Returns :
+ Description :
+
+=cut
+
+sub set_network_location {
+ 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();
+
+ #Category key: Home/Work=00000000, Public=00000001
+
+ my $registry_string .= <<"EOF";
+Windows Registry Editor Version 5.00
+
+[HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\Windows NT\\CurrentVersion\\NetworkList\\Signatures\\FirstNetwork]
+"Category"=dword:00000001
+EOF
+
+ # Import the string into the registry
+ if ($self->import_registry_string($registry_string)) {
+ notify($ERRORS{'DEBUG'}, 0, "set network location");
+ return 1;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to set network location");
+ return 0;
+ }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 firewall_enable_ping
+
+ Parameters :
+ Returns : 1 if succeeded, 0 otherwise
+ Description :
+
+=cut
+
+sub firewall_enable_ping {
+ 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();
+
+ # First delete any rules which allow ping and then add a new rule
+ my $add_rule_command;
+ $add_rule_command .= 'netsh.exe advfirewall firewall delete rule';
+ $add_rule_command .= ' name=all';
+ $add_rule_command .= ' dir=in';
+ $add_rule_command .= ' protocol=icmpv4:8,any';
+ $add_rule_command .= ' ;';
+
+ $add_rule_command .= ' netsh.exe advfirewall firewall add rule';
+ $add_rule_command .= ' name="VCL: allow ping from any address"';
+ $add_rule_command .= ' description="Allows incoming ping (ICMP type 8) messages from any address"';
+ $add_rule_command .= ' protocol=icmpv4:8,any';
+ $add_rule_command .= ' action=allow';
+ $add_rule_command .= ' enable=yes';
+ $add_rule_command .= ' dir=in';
+ $add_rule_command .= ' localip=any';
+ $add_rule_command .= ' remoteip=any';
+
+ # Add the firewall rule
+ my ($add_rule_exit_status, $add_rule_output) = run_ssh_command($computer_node_name, $management_node_keys, $add_rule_command);
+
+ if (defined($add_rule_output) && @$add_rule_output[-1] =~ /Ok\./i) {
+ notify($ERRORS{'OK'}, 0, "added firewall rule to enable ping from any address");
+ }
+ elsif (defined($add_rule_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to add firewall rule to enable ping from any address, exit status: $add_rule_exit_status, output:\n@{$add_rule_output}");
+ return;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to add firewall rule to enable ping from any address");
+ return;
+ }
+
+ return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 firewall_enable_ping_private
+
+ Parameters :
+ Returns : 1 if succeeded, 0 otherwise
+ Description :
+
+=cut
+
+sub firewall_enable_ping_private {
+ 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 computer's private IP address
+ my @private_ip_addresses = keys(%{$self->get_private_ip_addresses()});
+ if (!@private_ip_addresses) {
+ notify($ERRORS{'WARNING'}, 0, "unable to retrieve private IP addresses");
+ return;
+ }
+
+ # Join together the IP addresses in case multiple addresses are bound
+ my $private_ip_address_string = join("," , @private_ip_addresses);
+
+ # First delete any rules which allow ping and then add a new rule
+ my $add_rule_command;
+ $add_rule_command .= 'netsh.exe advfirewall firewall delete rule';
+ $add_rule_command .= ' name=all';
+ $add_rule_command .= ' dir=in';
+ $add_rule_command .= ' protocol=icmpv4:8,any';
+ $add_rule_command .= ' ;';
+
+ $add_rule_command .= ' netsh.exe advfirewall firewall add rule';
+ $add_rule_command .= ' name="VCL: allow incoming ping to: ' . $private_ip_address_string . '"';
+ $add_rule_command .= ' description="Allows incoming ping (ICMP type 8) messages to: ' . $private_ip_address_string . '"';
+ $add_rule_command .= ' protocol=icmpv4:8,any';
+ $add_rule_command .= ' action=allow';
+ $add_rule_command .= ' enable=yes';
+ $add_rule_command .= ' dir=in';
+ $add_rule_command .= ' localip=' . $private_ip_address_string;
+
+ # Add the firewall rule
+ my ($add_rule_exit_status, $add_rule_output) = run_ssh_command($computer_node_name, $management_node_keys, $add_rule_command);
+
+ if (defined($add_rule_output) && @$add_rule_output[-1] =~ /Ok\./i) {
+ notify($ERRORS{'OK'}, 0, "added firewall rule to allow incoming ping to: $private_ip_address_string");
+ }
+ elsif (defined($add_rule_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to add firewall rule to allow incoming ping to: $private_ip_address_string, exit status: $add_rule_exit_status, output:\n@{$add_rule_output}");
+ return;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to add firewall rule to allow incoming ping to: $private_ip_address_string");
+ return;
+ }
+
+ return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 firewall_disable_ping
+
+ Parameters :
+ Returns : 1 if succeeded, 0 otherwise
+ Description :
+
+=cut
+
+sub firewall_disable_ping {
+ 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();
+
+ # First delete any rules which allow ping and then add a new rule
+ my $netsh_command;
+ $netsh_command .= 'netsh.exe advfirewall firewall delete rule';
+ $netsh_command .= ' name=all';
+ $netsh_command .= ' dir=in';
+ $netsh_command .= ' protocol=icmpv4:8,any';
+
+ # Execute the netsh.exe command
+ my ($netsh_exit_status, $netsh_output) = run_ssh_command($computer_node_name, $management_node_keys, $netsh_command);
+
+ if (defined($netsh_output) && @$netsh_output[-1] =~ /Ok\./i) {
+ notify($ERRORS{'OK'}, 0, "configured firewall to disallow ping");
+ }
+ elsif (defined($netsh_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to configure firewall to disallow ping, exit status: $netsh_exit_status, output:\n@{$netsh_output}");
+ return;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to configure firewall to disallow ping");
+ return;
+ }
+
+ return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 firewall_enable_rdp
+
+ Parameters :
+ Returns : 1 if succeeded, 0 otherwise
+ Description :
+
+=cut
+
+sub firewall_enable_rdp {
+ 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;
+ }
+
+ # Check if the remote IP was passed as an argument
+ my $remote_ip = shift;
+ if (!defined($remote_ip)) {
+ $remote_ip = 'any';
+ }
+ elsif ($remote_ip !~ /[\d\.\/]/) {
+ notify($ERRORS{'WARNING'}, 0, "remote IP address argument is not a valid IP address: $remote_ip");
+ $remote_ip = 'any';
+ }
+
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+
+ # First delete any rules which allow ping and then add a new rule
+ my $add_rule_command;
+ $add_rule_command .= 'netsh.exe advfirewall firewall delete rule';
+ $add_rule_command .= ' name=all';
+ $add_rule_command .= ' dir=in';
+ $add_rule_command .= ' protocol=TCP';
+ $add_rule_command .= ' localport=3389';
+ $add_rule_command .= ' ;';
+
+ $add_rule_command .= ' netsh.exe advfirewall firewall add rule';
+ $add_rule_command .= ' name="VCL: allow RDP from address: ' . $remote_ip . '"';
+ $add_rule_command .= ' description="Allows incoming TCP port 3389 traffic from address: ' . $remote_ip . '"';
+ $add_rule_command .= ' protocol=TCP';
+ $add_rule_command .= ' action=allow';
+ $add_rule_command .= ' enable=yes';
+ $add_rule_command .= ' dir=in';
+ $add_rule_command .= ' localip=any';
+ $add_rule_command .= ' localport=3389';
+ $add_rule_command .= ' remoteip=' . $remote_ip;
+
+ # Add the firewall rule
+ my ($add_rule_exit_status, $add_rule_output) = run_ssh_command($computer_node_name, $management_node_keys, $add_rule_command);
+
+ if (defined($add_rule_output) && @$add_rule_output[-1] =~ /Ok\./i) {
+ notify($ERRORS{'OK'}, 0, "added firewall rule to enable RDP from $remote_ip");
+ }
+ elsif (defined($add_rule_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to add firewall rule to enable RDP from $remote_ip, exit status: $add_rule_exit_status, output:\n@{$add_rule_output}");
+ return;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to add firewall rule to enable RDP from $remote_ip");
+ return;
+ }
+
+ return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 firewall_enable_rdp_private
+
+ Parameters :
+ Returns : 1 if succeeded, 0 otherwise
+ Description :
+
+=cut
+
+sub firewall_enable_rdp_private {
+ 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 computer's private IP address
+ my @private_ip_addresses = keys(%{$self->get_private_ip_addresses()});
+ if (!@private_ip_addresses) {
+ notify($ERRORS{'WARNING'}, 0, "unable to retrieve private IP addresses");
+ return;
+ }
+
+ # Join together the IP addresses in case multiple addresses are bound
+ my $private_ip_address_string = join("," , @private_ip_addresses);
+
+ # First delete any rules which allow RDP and then add a new rule
+ my $add_rule_command;
+ $add_rule_command .= 'netsh.exe advfirewall firewall delete rule';
+ $add_rule_command .= ' name=all';
+ $add_rule_command .= ' dir=in';
+ $add_rule_command .= ' protocol=TCP';
+ $add_rule_command .= ' localport=3389';
+ $add_rule_command .= ' ;';
+
+ $add_rule_command .= ' netsh.exe advfirewall firewall add rule';
+ $add_rule_command .= ' name="VCL: allow RDP port 3389 to: ' . $private_ip_address_string . '"';
+ $add_rule_command .= ' description="Allows incoming RDP (TCP port 3389) traffic to: ' . $private_ip_address_string . '"';
+ $add_rule_command .= ' protocol=TCP';
+ $add_rule_command .= ' localport=3389';
+ $add_rule_command .= ' action=allow';
+ $add_rule_command .= ' enable=yes';
+ $add_rule_command .= ' dir=in';
+ $add_rule_command .= ' localip=' . $private_ip_address_string;
+
+ # Add the firewall rule
+ my ($add_rule_exit_status, $add_rule_output) = run_ssh_command($computer_node_name, $management_node_keys, $add_rule_command);
+
+ if (defined($add_rule_output) && @$add_rule_output[-1] =~ /Ok\./i) {
+ notify($ERRORS{'OK'}, 0, "added firewall rule to enable RDP to: $private_ip_address_string");
+ }
+ elsif (defined($add_rule_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to add firewall rule to enable RDP to: $private_ip_address_string, exit status: $add_rule_exit_status, output:\n@{$add_rule_output}");
+ return;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to add firewall rule to enable RDP to: $private_ip_address_string");
+ return;
+ }
+
+ return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 firewall_disable_rdp
+
+ Parameters :
+ Returns : 1 if succeeded, 0 otherwise
+ Description :
+
+=cut
+
+sub firewall_disable_rdp {
+ 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();
+
+ # First delete any rules which allow ping and then add a new rule
+ my $netsh_command;
+ $netsh_command .= 'netsh.exe advfirewall firewall delete rule';
+ $netsh_command .= ' name=all';
+ $netsh_command .= ' dir=in';
+ $netsh_command .= ' protocol=TCP';
+ $netsh_command .= ' localport=3389';
+
+ # Delete the firewall rule
+ my ($netsh_exit_status, $netsh_output) = run_ssh_command($computer_node_name, $management_node_keys, $netsh_command);
+
+ if (defined($netsh_output) && @$netsh_output[-1] =~ /Ok\./i) {
+ notify($ERRORS{'OK'}, 0, "deleted firewall rules which enable RDP");
+ }
+ elsif (defined($netsh_output) && @$netsh_output[-1] =~ /No rules match/i) {
+ notify($ERRORS{'OK'}, 0, "no firewall rules exist which enable RDP");
+ }
+ elsif (defined($netsh_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to delete firewall rules which enable RDP, exit status: $netsh_exit_status, output:\n@{$netsh_output}");
+ return;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to run command to delete firewall rules which enable RDP");
+ return;
+ }
+
+ return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 firewall_enable_ssh
+
+ Parameters :
+ Returns : 1 if succeeded, 0 otherwise
+ Description :
+
+=cut
+
+sub firewall_enable_ssh {
+ 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();
+
+ # First delete any rules which allow ping and then add a new rule
+ my $add_rule_command;
+ $add_rule_command .= 'netsh.exe advfirewall firewall delete rule';
+ $add_rule_command .= ' name=all';
+ $add_rule_command .= ' dir=in';
+ $add_rule_command .= ' protocol=TCP';
+ $add_rule_command .= ' localport=22';
+ $add_rule_command .= ' ;';
+
+ $add_rule_command .= ' netsh.exe advfirewall firewall add rule';
+ $add_rule_command .= ' name="VCL: allow SSH port 22 from any address"';
+ $add_rule_command .= ' description="Allows incoming SSH (TCP port 22) traffic from any address"';
+ $add_rule_command .= ' protocol=TCP';
+ $add_rule_command .= ' localport=22';
+ $add_rule_command .= ' action=allow';
+ $add_rule_command .= ' enable=yes';
+ $add_rule_command .= ' dir=in';
+ $add_rule_command .= ' localip=any';
+ $add_rule_command .= ' remoteip=any';
+
+ # Add the firewall rule
+ my ($add_rule_exit_status, $add_rule_output) = run_ssh_command($computer_node_name, $management_node_keys, $add_rule_command);
+
+ if (defined($add_rule_output) && @$add_rule_output[-1] =~ /Ok\./i) {
+ notify($ERRORS{'OK'}, 0, "added firewall rule to enable SSH from any address");
+ }
+ elsif (defined($add_rule_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to add firewall rule to enable SSH from any address, exit status: $add_rule_exit_status, output:\n@{$add_rule_output}");
+ return;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to add firewall rule to enable SSH from any address");
+ return;
+ }
+
+ return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 firewall_enable_ssh_private
+
+ Parameters :
+ Returns : 1 if succeeded, 0 otherwise
+ Description :
+
+=cut
+
+sub firewall_enable_ssh_private {
+ 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 computer's private IP address
+ my @private_ip_addresses = keys(%{$self->get_private_ip_addresses()});
+ if (!@private_ip_addresses) {
+ notify($ERRORS{'WARNING'}, 0, "unable to retrieve private IP addresses");
+ return;
+ }
+
+ # Join together the IP addresses in case multiple addresses are bound
+ my $private_ip_address_string = join("," , @private_ip_addresses);
+
+ # First delete any rules which allow ping and then add a new rule
+ my $add_rule_command;
+ $add_rule_command .= 'netsh.exe advfirewall firewall delete rule';
+ $add_rule_command .= ' name=all';
+ $add_rule_command .= ' dir=in';
+ $add_rule_command .= ' protocol=TCP';
+ $add_rule_command .= ' localport=22';
+ $add_rule_command .= ' ;';
+
+ $add_rule_command .= ' netsh.exe advfirewall firewall add rule';
+ $add_rule_command .= ' name="VCL: allow SSH port 22 to: ' . $private_ip_address_string . '"';
+ $add_rule_command .= ' description="Allows incoming SSH (TCP port 22) traffic to: ' . $private_ip_address_string . '"';
+ $add_rule_command .= ' protocol=TCP';
+ $add_rule_command .= ' localport=22';
+ $add_rule_command .= ' action=allow';
+ $add_rule_command .= ' enable=yes';
+ $add_rule_command .= ' dir=in';
+ $add_rule_command .= ' localip=' . $private_ip_address_string;
+
+ # Add the firewall rule
+ my ($add_rule_exit_status, $add_rule_output) = run_ssh_command($computer_node_name, $management_node_keys, $add_rule_command);
+
+ if (defined($add_rule_output) && @$add_rule_output[-1] =~ /Ok\./i) {
+ notify($ERRORS{'OK'}, 0, "added firewall rule to enable SSH to: $private_ip_address_string");
+ }
+ elsif (defined($add_rule_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to add firewall rule to enable SSH to: $private_ip_address_string, exit status: $add_rule_exit_status, output:\n@{$add_rule_output}");
+ return;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to add firewall rule to enable SSH to: $private_ip_address_string");
+ return;
+ }
+
+ return 1;
+}
+
+##############################################################################
+
+=head1 UTILITY FUNCTIONS
+
+=cut
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 add_kms_server
+
+ Parameters : $affiliation_name, $kms_address, $kms_port
+ Returns : If successful: true
+ If failed: false
+ Description : Adds a kms server to the windows-activation variable for the
+ specified affiliation name.
+ If a KMS server with the same address is already saved in the
+ windows-activation variable, it is deleted and the KMS server
+ specified in the subroutine arguments is added to the end of the
+ configuration list.
+
+=cut
+
+sub add_kms_server {
+ my ($affiliation_name, $kms_address, $kms_port) = @_;
+
+ # Check the arguments
+ unless ($affiliation_name && $kms_address) {
+ notify($ERRORS{'WARNING'}, 0, "affiliation name and kms server address must be specified as arguments");
+ return;
+ }
+
+ # Set the default KMS port to 1688 if the argument was not specified
+ $kms_port = 1688 unless $kms_port;
+
+ # Get a new DataStructure object
+ my $data = VCL::DataStructure->new();
+ if ($data) {
+ notify($ERRORS{'DEBUG'}, 0, "created new DataStructure object");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "unable to create new DataStructure object");
+ return;
+ }
+
+ # Get the Windows activation data from the windows-activation variable
+ my $activation_data = $data->get_variable('windows-activation');
+ if ($activation_data) {
+ notify($ERRORS{'DEBUG'}, 0, "existing activation data:\n" . format_data($activation_data));
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "activation data could not be retrieved, hopefully this is the first entry being added");
+ }
+
+ # Loop through the existing configurations for the affiliation
+ for (my $i=0; $i<(@{$activation_data->{$affiliation_name}}); $i++) {
+ my $affiliation_configuration = @{$activation_data->{$affiliation_name}}[$i];
+
+ # Remove the configuration if it's not defined
+ if (!defined $affiliation_configuration) {
+ splice @{$activation_data->{$affiliation_name}}, $i--, 1;
+ next;
+ }
+
+ # Check if an identical existing address already exists, if so, delete it
+ my $existing_affiliation_kms_address = $affiliation_configuration->{address};
+ if ($existing_affiliation_kms_address eq $kms_address) {
+ splice @{$activation_data->{$affiliation_name}}, $i--, 1;
+ notify($ERRORS{'DEBUG'}, 0, "deleted identical existing address for $affiliation_name: $existing_affiliation_kms_address");
+ }
+ else {
+ notify($ERRORS{'DEBUG'}, 0, "found existing address for $affiliation_name: $existing_affiliation_kms_address");
+ }
+ }
+
+ # Add the KMS configuration to the activation data
+ push @{$activation_data->{$affiliation_name}}, {
+ method => 'kms',
+ address => $kms_address,
+ port => $kms_port,
+ };
+
+ # Set the variable with the updated data
+ $data->set_variable('windows-activation', $activation_data);
+
+ # Retrieve the updated configuration data
+ $activation_data = $data->get_variable('windows-activation');
+ if ($activation_data) {
+ notify($ERRORS{'DEBUG'}, 0, "updated activation data:\n" . format_data($activation_data));
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "updated activation data could not be retrieved");
+ return;
+ }
+
+ return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+1;
+__END__
+
+=head1 AUTHOR
+
+ Aaron Peeler <aa...@ncsu.edu>
+ Andy Kurth <an...@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
Added: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_6/Vista_mod.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_6/Vista_mod.pm?rev=780755&view=auto
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_6/Vista_mod.pm (added)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod/Version_6/Vista_mod.pm Mon Jun 1 17:51:52 2009
@@ -0,0 +1,159 @@
+#!/usr/bin/perl -w
+###############################################################################
+# $Id: XP_mod.pm 774457 2009-05-13 18:12:08Z arkurth $
+###############################################################################
+# 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_mod::Version_6::Vista_mod.pm - VCL module to support Windows Vista operating system
+
+=head1 SYNOPSIS
+
+ Needs to be written
+
+=head1 DESCRIPTION
+
+ This module provides VCL support for Windows Vista.
+
+=cut
+
+##############################################################################
+package VCL::Module::OS::Windows_mod::Version_6::Vista_mod;
+
+# Specify the lib path using FindBin
+use FindBin;
+use lib "$FindBin::Bin/../../../../..";
+
+# Configure inheritance
+use base qw(VCL::Module::OS::Windows_mod::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_Vista";
+
+##############################################################################
+
+=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 the node configuration directory
+ my $node_configuration_directory = $self->get_node_configuration_directory();
+ unless ($node_configuration_directory) {
+ notify($ERRORS{'WARNING'}, 0, "node configuration directory could not be determined");
+ return;
+ }
+
+ notify($ERRORS{'OK'}, 0, "beginning Windows Vista 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;
+ }
+
+ # Add HKLM run key to call run_newsid.cmd after the image comes up
+ if (!$self->add_hklm_run_registry_key('run_newsid.cmd', $node_configuration_directory . '/Scripts/run_newsid.cmd >> ' . $node_configuration_directory . '/Logs/run_newsid.log')) {
+ notify($ERRORS{'WARNING'}, 0, "unable to create run key to call run_newsid.cmd");
+ return;
+ }
+
+ #Shut down computer unless end_state argument was passed with a value other than 'off'
+ my $end_state = $self->{end_state} || 'off';
+ if ($end_state eq 'off') {
+ unless ($self->shutdown()) {
+ notify($ERRORS{'WARNING'}, 0, "failed to shut down computer");
+ return;
+ }
+ }
+exit;
+ notify($ERRORS{'OK'}, 0, "returning 1");
+ return 1;
+} ## end sub pre_capture
+
+#/////////////////////////////////////////////////////////////////////////////
+
+1;
+__END__
+
+=head1 AUTHOR
+
+ Aaron Peeler <aa...@ncsu.edu>
+ Andy Kurth <an...@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