Author: arkurth Date: Wed May 16 18:10:59 2012 New Revision: 1339295 URL: http://svn.apache.org/viewvc?rev=1339295&view=rev Log: VCL-589 Updated Windows.pm::copy_capture_configuration_files to grant permissions to the SYSTEM account for the VCL directory in root's Cygwin profile. This allows scripts which run during Sysprep under the SYSTEM account to succeed.
Reworked Version_6.pm::run_sysprep. The Unattend.xml contents are now generated from the Perl code rather than copying a file from tools. This makes easier to troubleshoot. VCL-503 Made changes to OS.pm::execute_new. Commands with long timeouts were failing. Removed timeout argument when Net::SSH::Expect object is created and added command to set the timeout value in the object every time the subroutine is called. Added $identity_paths argument to call to execute_new in utils.pm::run_ssh_command. VCL-573 Removed the retrieval of user info for users specified in imagemeta.usergroupid from get_request_info and get_imagemeta_info. Removed entries from DataStructure.pm which return this information. VCL-545 Changed path where virtual disk files are located in the datastore. Instead of each residing in its own directory, files are stored at the root of the datastore. This was done because virt-manager assumes they reside in the root directory and cannot traverse subdirectories. Commented out code in KVM.pm::copy_virtual_disk which attempts to first convert the image to raw format. This was not working consistently. Other Updated Windows.pm::delete_file to detect if the path contains a wildcard. Added an additional command to delete files/directories beginning with a period. Added condition to utils.pm::is_request_deleted to check if the request state is makeproduction. This is effectively the same as deleted, but the user chose to update the production revision of the image when the request was ended. Also added a check to vcld where it checks if a request is deleted. Commented out line which returns cached user information in utils.pm::get_user_info. User preference changes were not being applied because the cached information was returned. Modified: incubator/vcl/trunk/managementnode/bin/vcld incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt/KVM.pm incubator/vcl/trunk/managementnode/lib/VCL/utils.pm Modified: incubator/vcl/trunk/managementnode/bin/vcld URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/bin/vcld?rev=1339295&r1=1339294&r2=1339295&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/bin/vcld (original) +++ incubator/vcl/trunk/managementnode/bin/vcld Wed May 16 18:10:59 2012 @@ -152,7 +152,7 @@ sub main () { #=========================================================================== while (1) { SLEEP: - + delete $ENV{request_id}; delete $ENV{reservation_id}; delete $ENV{state}; @@ -171,7 +171,7 @@ sub main () { else { notify($ERRORS{'CRITICAL'}, $LOGFILE, "could not update lastcheckin for management node $management_node_id"); } - + # Get all the requests assigned to this management node # get_management_node_requests() gets a subset of the information available if ($info{request} = {get_management_node_requests($management_node_id)}) { @@ -184,7 +184,7 @@ sub main () { # See if there's anything to do my $request_count = scalar keys %{$info{request}}; #notify($ERRORS{'DEBUG'}, $LOGFILE, "number of requests assigned to management node $management_node_id: $request_count"); - + #=========================================================================== # Loop through the requests assigned to this management node REQUEST: foreach my $request_id (keys %{$info{request}}) { @@ -271,7 +271,7 @@ sub main () { # Make sure reservation is not currently being processed my $being_processed = reservation_being_processed($reservation_id); - if ($being_processed && $request_state_name !~ /^(deleted|image|reinstall|rebootsoft|reboothard|servermodified)$/ ) { + if ($being_processed && $request_state_name !~ /^(deleted|makeproduction|image|reinstall|rebootsoft|reboothard|servermodified)$/ ) { notify($ERRORS{'WARNING'}, $LOGFILE, "reservation $reservation_id is already being processed"); next RESERVATION; } @@ -348,7 +348,6 @@ sub main () { # Make a new child process, passing it the request/reservation info make_new_child({request_info => \%request_info, data_structure => $data_structure}); - } ## end foreach my $reservation_id (keys %{$info{request... } ## end foreach my $request_id (keys %{$info{request}}) Modified: incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm?rev=1339295&r1=1339294&r2=1339295&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm Wed May 16 18:10:59 2012 @@ -370,10 +370,7 @@ $SUBROUTINE_MAPPINGS{imagemeta_id} = '$s $SUBROUTINE_MAPPINGS{imagemeta_postoption} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagemeta}{postoption}'; $SUBROUTINE_MAPPINGS{imagemeta_subimages} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagemeta}{subimages}'; $SUBROUTINE_MAPPINGS{imagemeta_sysprep} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagemeta}{sysprep}'; -$SUBROUTINE_MAPPINGS{imagemeta_usergroupid} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagemeta}{usergroupid}'; $SUBROUTINE_MAPPINGS{imagemeta_rootaccess} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagemeta}{rootaccess}'; -$SUBROUTINE_MAPPINGS{imagemeta_usergroupmembercount} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagemeta}{USERGROUPMEMBERCOUNT}'; -$SUBROUTINE_MAPPINGS{imagemeta_usergroupmembers} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagemeta}{USERGROUPMEMBERS}'; $SUBROUTINE_MAPPINGS{image_os_name} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{OS}{name}'; $SUBROUTINE_MAPPINGS{image_os_prettyname} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{OS}{prettyname}'; Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1339295&r1=1339294&r2=1339295&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm Wed May 16 18:10:59 2012 @@ -1967,7 +1967,7 @@ sub execute_new { raw_pty => 1, no_terminal => 1, ssh_option => $ssh_options, - timeout => 5, + #timeout => 5, ); if ($ssh) { @@ -2033,6 +2033,9 @@ sub execute_new { delete $ENV{net_ssh_expect}{$computer_name}; } + # Set the timeout + $ssh->timeout($timeout_seconds); + (my $command_formatted = $command) =~ s/\s+(;|&|&&)\s+/\n$1 /g; notify($ERRORS{'DEBUG'}, 0, $attempt_string . "executing command on $computer_name (timeout: $timeout_seconds seconds):\n$command_formatted") if ($display_output); $ssh->send($command . ' 2>&1 ; echo exitstatus:$?'); 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=1339295&r1=1339294&r2=1339295&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Wed May 16 18:10:59 2012 @@ -1198,6 +1198,9 @@ sub delete_file { # Try to take ownership, set the permissions, then delete the file using both Cygwin bash and Windows commands # This should allow files to be deleted with restrictive ownership, permissions, and attributes + my $path_unix_directory = parent_directory_path($path_unix); + my ($path_unix_pattern) = $path_unix =~ /\/([^\/]+)$/; + my $command; $command .= "echo ---"; $command .= " ; echo Calling chown.exe to change owner to root..."; @@ -1211,6 +1214,12 @@ sub delete_file { $command .= " ; echo Calling \\\"rm.exe -rfv $path_unix\\\" to to delete file..."; $command .= " ; /usr/bin/rm.exe -rfv $path_unix 2>&1"; + if ($path_unix_pattern =~ /\*/) { + $command .= " ; echo ---"; + $command .= " ; echo Calling \\\"rm.exe -rfv $path_unix_directory/.$path_unix_pattern\\\" to to delete file..."; + $command .= " ; /usr/bin/rm.exe -rfv $path_unix_directory/.$path_unix_pattern 2>&1"; + } + # Add call to rmdir if the path does not contain a wildcard # rmdir does not accept wildcards if ($path_dos !~ /\*/) { @@ -1418,17 +1427,57 @@ sub file_exists { my $path_dos = $self->format_path_dos($path); # Assemble the dir command and execute it - my $dir_command = "cmd.exe /c \"dir /a /b \\\"$path_dos\\\"\""; + my $dir_command = "cmd.exe /c \"dir /a \\\"$path_dos\\\"\""; my ($dir_exit_status, $dir_output) = run_ssh_command($computer_node_name, $management_node_keys, $dir_command, '', '', 0); if (!defined($dir_output)) { notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to determine if file exists on $computer_node_name: $path"); return; } + # Checking if directory exists, no wildcard: (directory exists) + # $ cmd.exe /c "dir /a C:\test" + # Volume in drive C has no label. + # Volume Serial Number is 4C9E-6C37 + # + # Directory of C:\test + # + #05/16/2012 01:19 PM <DIR> . + #05/16/2012 01:19 PM <DIR> .. + # 0 File(s) 0 bytes + # 2 Dir(s) 17,999,642,624 bytes free + + # Checking if file or directory exists with wildcard: (file exists) + # $ cmd.exe /c "dir /a C:\te*" + # Volume in drive C has no label. + # Volume Serial Number is 4C9E-6C37 + # + # Directory of C:\ + # + #05/16/2012 01:19 PM <DIR> test + # 0 File(s) 0 bytes + # 1 Dir(s) 17,999,642,624 bytes free + + # Checking if file exists with wildcard: (file does not exist) + # $ cmd.exe /c "dir /a C:\test\*" + # Volume in drive C has no label. + # Volume Serial Number is 4C9E-6C37 + # + # Directory of C:\test + # + #05/16/2012 01:19 PM <DIR> . + #05/16/2012 01:19 PM <DIR> .. + # 0 File(s) 0 bytes + # 2 Dir(s) 17,999,642,624 bytes free + if ($dir_exit_status == 1 || grep(/(file not found|cannot find)/i, @$dir_output)) { notify($ERRORS{'DEBUG'}, 0, "file does NOT exist on $computer_node_name: '$path'"); return 0; } + elsif ($path =~ /\*/ && grep(/\s0 File/, @$dir_output) && grep(/\s2 Dir/, @$dir_output)) { + #notify($ERRORS{'DEBUG'}, 0, "file does NOT exist on $computer_node_name: '$path', exit status: $dir_exit_status, command: '$dir_command', output:\n" . join("\n", @$dir_output)); + notify($ERRORS{'DEBUG'}, 0, "file does NOT exist on $computer_node_name: '$path'"); + return 0; + } else { notify($ERRORS{'DEBUG'}, 0, "file exists on $computer_node_name: '$path'"); return 1; @@ -5855,8 +5904,14 @@ sub delete_capture_configuration_files { my $system32_path = $self->get_system32_path() || return; # Remove old logon and logoff scripts - $self->delete_files_by_pattern($system32_path . '/GroupPolicy/User/Scripts', '.*\(Prepare\|prepare\|Cleanup\|cleanup\|post_load\).*'); - + if ($self->file_exists($system32_path . '/GroupPolicy/User/Scripts/*VCL*')) { + $self->delete_files_by_pattern($system32_path . '/GroupPolicy/User/Scripts', '.*\(Prepare\|prepare\|Cleanup\|cleanup\|post_load\).*'); + + # 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'); + } + # Remove old scripts and utilities $self->delete_files_by_pattern('C:/Cygwin/home/root', '.*\(vbs\|exe\|cmd\|bat\|log\)'); @@ -5866,10 +5921,6 @@ sub delete_capture_configuration_files { # 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'); - # Remove old root Application Data/VCL directory $self->delete_file('$SYSTEMDRIVE/Documents and Settings/root/Application Data/VCL'); @@ -6596,6 +6647,7 @@ sub copy_capture_configuration_files { 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() || return; # Get an array containing the configuration directory paths on the management node # This is made up of all the the $SOURCE_CONFIGURATION_DIRECTORY values for the OS class and it's parent classes @@ -6629,15 +6681,6 @@ sub copy_capture_configuration_files { notify($ERRORS{'OK'}, 0, "copying image capture configuration files from $source_configuration_directory to $computer_node_name"); if (run_scp_command("$source_configuration_directory/*", "$computer_node_name:$NODE_CONFIGURATION_DIRECTORY", $management_node_keys)) { notify($ERRORS{'OK'}, 0, "copied $source_configuration_directory directory to $computer_node_name:$NODE_CONFIGURATION_DIRECTORY"); - - notify($ERRORS{'DEBUG'}, 0, "attempting to set permissions on $computer_node_name:$NODE_CONFIGURATION_DIRECTORY"); - if (run_ssh_command($computer_node_name, $management_node_keys, "/usr/bin/chmod.exe -R 777 $NODE_CONFIGURATION_DIRECTORY")) { - notify($ERRORS{'OK'}, 0, "chmoded -R 777 $computer_node_name:$NODE_CONFIGURATION_DIRECTORY"); - } - else { - notify($ERRORS{'WARNING'}, 0, "could not chmod -R 777 $computer_node_name:$NODE_CONFIGURATION_DIRECTORY"); - return; - } } ## end if (run_scp_command("$source_configuration_directory/*"... else { notify($ERRORS{'WARNING'}, 0, "failed to copy $source_configuration_directory to $computer_node_name"); @@ -6645,6 +6688,12 @@ sub copy_capture_configuration_files { } } + $self->set_file_owner($NODE_CONFIGURATION_DIRECTORY, 'root:Administrators'); + $self->execute("/usr/bin/chmod.exe -Rv 777 $NODE_CONFIGURATION_DIRECTORY", 1); + + # Grant permissions to the SYSTEM user - this is needed or else Sysprep fails + $self->execute("cmd.exe /c \"$system32_path/icacls.exe $NODE_CONFIGURATION_DIRECTORY /grant SYSTEM:(OI)(CI)(F) /C\"", 1); + # Delete any Subversion files which may have been copied if (!$self->delete_files_by_pattern($NODE_CONFIGURATION_DIRECTORY, '.*\.svn.*')) { notify($ERRORS{'WARNING'}, 0, "unable to delete Subversion files under: $NODE_CONFIGURATION_DIRECTORY"); 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=1339295&r1=1339294&r2=1339295&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 Wed May 16 18:10:59 2012 @@ -1715,98 +1715,129 @@ sub run_sysprep { } 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() || return; - + my $computer_node_name = $self->data->get_computer_node_name(); + my $system32_path = $self->get_system32_path() || return; my $node_configuration_directory = $self->get_node_configuration_directory(); - #my $source_configuration_directory = eval '$' . ref($self) . '::SOURCE_CONFIGURATION_DIRECTORY'; - #run_scp_command("$source_configuration_directory/Utilities/Sysprep/Unattend.xml", "$computer_node_name:$node_configuration_directory/Utilities/sysprep/Unattend.xml"); + my $time_zone_name = $self->get_time_zone_name(); + if (!$time_zone_name) { + notify($ERRORS{'WARNING'}, 0, "time zone name could not be retrieved"); + return; + } - # Delete existing Panther directory, contains Sysprep log files - if (!$self->delete_file('C:/Windows/Panther')) { - notify($ERRORS{'WARNING'}, 0, "unable to delete Panther directory, Sysprep will proceed"); + my $product_key = $self->get_kms_client_product_key(); + if (!$product_key) { + notify($ERRORS{'WARNING'}, 0, "KMS client product key could not be retrieved"); + return; } - # Delete existing sysprep/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"); + my $unattend_xml_file_path = "$system32_path/sysprep/Unattend.xml"; + + my $unattend_xml_contents = <<EOF; +<?xml version="1.0" encoding="utf-8"?> +<unattend xmlns="urn:schemas-microsoft-com:unattend"> + <settings pass="generalize"> + <component name="Microsoft-Windows-PnpSysprep" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <PersistAllDeviceInstalls>true</PersistAllDeviceInstalls> + </component> + <component name="Microsoft-Windows-Security-SPP" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <SkipRearm>1</SkipRearm> + </component> + </settings> + <settings pass="specialize"> + <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <Display> + <ColorDepth>32</ColorDepth> + <DPI>120</DPI> + <HorizontalResolution>1024</HorizontalResolution> + <VerticalResolution>768</VerticalResolution> + <RefreshRate>72</RefreshRate> + </Display> + <ComputerName>*</ComputerName> + <TimeZone>$time_zone_name</TimeZone> + <ProductKey>$product_key</ProductKey> + </component> + <component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <RunSynchronous> + <RunSynchronousCommand wcm:action="add"> + <Path>C:\\Cygwin\\home\\root\\VCL\\Scripts\\sysprep_cmdlines.cmd > C:\\cygwin\\home\\root\\VCL\\Logs\\sysprep_cmdlines.log 2>&1</Path> + <Order>1</Order> + </RunSynchronousCommand> + </RunSynchronous> + </component> + <component name="Microsoft-Windows-Security-SPP-UX" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <SkipAutoActivation>true</SkipAutoActivation> + </component> + <component name="Microsoft-Windows-UnattendedJoin" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <Identification> + <JoinWorkgroup>VCL</JoinWorkgroup> + </Identification> + </component> + </settings> + <settings pass="auditSystem"> + <component name="Microsoft-Windows-PnpCustomizationsNonWinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <DriverPaths> + <PathAndCredentials wcm:action="add" wcm:keyValue="1"> + <Path>C:\\Cygwin\\home\\root\\VCL\\Drivers</Path> + </PathAndCredentials> + </DriverPaths> + </component> + </settings> + <settings pass="oobeSystem"> + <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <OOBE> + <HideEULAPage>true</HideEULAPage> + <NetworkLocation>Work</NetworkLocation> + <ProtectYourPC>3</ProtectYourPC> + </OOBE> + <UserAccounts> + <AdministratorPassword> + <Value>$WINDOWS_ROOT_PASSWORD</Value> + <PlainText>true</PlainText> + </AdministratorPassword> + </UserAccounts> + </component> + <component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <InputLocale>en-US</InputLocale> + <SystemLocale>en-US</SystemLocale> + <UILanguage>en-US</UILanguage> + <UserLocale>en-US</UserLocale> + </component> + </settings> +</unattend> +EOF + + #notify($ERRORS{'DEBUG'}, 0, "'$unattend_xml_file_path' contents:\n$unattend_xml_contents"); + if (!$self->create_text_file($unattend_xml_file_path, $unattend_xml_contents)) { + return; } + # Delete existing Panther directory, contains Sysprep log files + $self->delete_file('C:/Windows/Panther'); + + # Delete existing sysprep/Panther directory, contains Sysprep log files + $self->delete_file("$system32_path/sysprep/Panther"); + # Delete existing setupapi files - if (!$self->delete_file('C:/Windows/inf/setupapi*')) { - notify($ERRORS{'WARNING'}, 0, "unable to delete setupapi files, Sysprep will proceed"); - } + $self->delete_file('C:/Windows/inf/setupapi*'); # Delete existing INFCACHE files - if (!$self->delete_file('C:/Windows/inf/INFCACHE*')) { - notify($ERRORS{'WARNING'}, 0, "unable to delete INFCACHE files, Sysprep will proceed"); - } + $self->delete_file('C:/Windows/inf/INFCACHE*'); # Delete existing INFCACHE files - if (!$self->delete_file('C:/Windows/inf/oem*.inf')) { - notify($ERRORS{'WARNING'}, 0, "unable to delete INFCACHE files, Sysprep will proceed"); - } + $self->delete_file('C:/Windows/inf/oem*.inf'); # 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 Unattend.xml file - 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; - } + $self->delete_file("$system32_path/sysprep/Sysprep*.tag"); - # Update the Unattend.xml file with the time zone name configured for the management node - my $time_zone_name = $self->get_time_zone_name(); - my $base_directory = "$node_configuration_directory/Utilities/Sysprep/Unattend.xml"; - my $search_pattern = '<TimeZone>.*</TimeZone>'; - my $replace_string = '<TimeZone>' . $time_zone_name . '</TimeZone>'; - if ($self->search_and_replace_in_files($base_directory, $search_pattern, $replace_string)) { - notify($ERRORS{'DEBUG'}, 0, "updated Unattend.xml with the time zone configured for the management node: '$time_zone_name'"); - } - else { - notify($ERRORS{'WARNING'}, 0, "failed to update Unattend.xml with the time zone configured for the management node: '$time_zone_name'"); - return; - } - - # Update the Unattend.xml file with the KMS client product key for the installed OS - my $product_key = $self->get_kms_client_product_key(); - if (!$product_key) { - notify($ERRORS{'WARNING'}, 0, "KMS client product key could not be retrieved"); - return; - } - my $product_key_search_pattern = '<ProductKey>.*</ProductKey>'; - my $product_key_replace_string = '<ProductKey>' . $product_key . '</ProductKey>'; - if ($self->search_and_replace_in_files($base_directory, $product_key_search_pattern, $product_key_replace_string)) { - notify($ERRORS{'DEBUG'}, 0, "updated Unattend.xml with the KMS product key: $product_key"); - } - else { - notify($ERRORS{'WARNING'}, 0, "failed to update Unattend.xml with the KMS product key: $product_key"); - return; - } + # Delete existing MSDTC.LOG file + $self->delete_file("$system32_path/MsDtc/MSTTC.LOG"); - # Copy Unattend.xml file to sysprep 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{'WARNING'}, 0, "failed to copy Unattend.xml to $system32_path/sysprep, exit status: $cp_status, output:\n@{$cp_output}"); - return; - } - else { - notify($ERRORS{'WARNING'}, 0, "unable to run ssh command to copy Unattend.xml to $system32_path/sysprep"); - return; - } + # Delete existing VCL log files + $self->delete_file("C:/Cygwin/home/root/VCL/Logs/*"); - # Delete existing MSDTC.LOG file - if (!$self->delete_file("$system32_path/MsDtc/MSTTC.LOG")) { - notify($ERRORS{'WARNING'}, 0, "unable to delete MSTTC.LOG file, Sysprep will proceed"); - } + # Delete legacy Sysprep directory + $self->delete_file("C:/Cygwin/home/root/VCL/Utilities/Sysprep"); # Uninstall and reinstall MsDTC my $msdtc_command = "$system32_path/msdtc.exe -uninstall ; $system32_path/msdtc.exe -install"; @@ -2032,7 +2063,7 @@ sub wait_for_response { my $ssh_response_timeout_seconds; if ($self->data->get_imagemeta_sysprep()) { - $initial_delay_seconds = 240; + $initial_delay_seconds = 30; $ssh_response_timeout_seconds = 1800; } else { Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm?rev=1339295&r1=1339294&r2=1339295&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm Wed May 16 18:10:59 2012 @@ -975,7 +975,8 @@ sub get_master_image_directory_path { my $image_name = shift || $self->data->get_image_name(); my $master_image_base_directory_path = $self->get_master_image_base_directory_path(); - return "$master_image_base_directory_path/$image_name"; + #return "$master_image_base_directory_path/$image_name"; + return $master_image_base_directory_path; } #///////////////////////////////////////////////////////////////////////////// Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt/KVM.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt/KVM.pm?rev=1339295&r1=1339294&r2=1339295&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt/KVM.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt/KVM.pm Wed May 16 18:10:59 2012 @@ -527,54 +527,79 @@ sub copy_virtual_disk { my $source_file_count = scalar(@source_file_paths); my $source_file_paths_string; - my $convert_to_raw = 0; + my $raw_file_directory_path; # Check if the source file paths appear to be in the 2GB sparse vmdk format # qemu-img included in anything earlier than Fedora 16 doesn't handle this properly - if ($source_file_count > 1 && $source_file_paths[0] =~ /-s\d+\.vmdk$/i) { - $convert_to_raw = 1; - for my $source_file_path (@source_file_paths) { - my ($source_file_name, $source_directory_path, $source_file_extension) = fileparse($source_file_path, qr/\.[^.]*/); - - my $raw_file_path = "$destination_directory_path/$source_file_name.raw"; - $source_file_paths_string .= "\"$raw_file_path\" "; - - # Convert from raw to raw - # There seems to be a bug in qemu-img if you specify "-f vmdk", it results in a empty file - # Leaving the -f option off also results in an empty file - my $command = "qemu-img convert -f raw \"$source_file_path\" -O raw \"$raw_file_path\" && qemu-img info \"$raw_file_path\""; - - notify($ERRORS{'DEBUG'}, 0, "attempting to convert vmdk file to raw format: $source_file_path --> $raw_file_path"); - my ($exit_status, $output) = $self->vmhost_os->execute($command, 0, 1800); - if (!defined($exit_status)) { - notify($ERRORS{'WARNING'}, 0, "failed to execute command to convert vmdk file to raw format:\n$command"); - return; - } - elsif ($exit_status) { - notify($ERRORS{'WARNING'}, 0, "failed to convert vmdk file to raw format on $node_name\ncommand: '$command'\noutput:\n" . join("\n", @$output)); - return; - } - else { - notify($ERRORS{'DEBUG'}, 0, "converted vmdk file to raw format on $node_name: $source_file_path --> $raw_file_path, output:\n" . join("\n", @$output)); - } - } - - # Remove trailing last space - $source_file_paths_string =~ s/\s+$//; - } - else { + #if ($source_file_count > 1 && $source_file_paths[0] =~ /-s\d+\.vmdk$/i) { + # my $image_name = $self->data->get_image_name(); + # $raw_file_directory_path = "$destination_directory_path/raw_$image_name"; + # + # # Attempt to create the directory where the raw files will be stored + # if (!$self->vmhost_os->create_directory($raw_file_directory_path)) { + # notify($ERRORS{'WARNING'}, 0, "unable to copy virtual disk, failed to create temporary directory to store raw files: $raw_file_directory_path"); + # return; + # } + # + # for my $source_file_path (@source_file_paths) { + # my ($source_file_name, $source_directory_path, $source_file_extension) = fileparse($source_file_path, qr/\.[^.]*/); + # + # my $raw_file_path = "$raw_file_directory_path/$source_file_name.raw"; + # $source_file_paths_string .= "\"$raw_file_path\" "; + # + # ## Convert from raw to raw + # ## There seems to be a bug in qemu-img if you specify "-f vmdk", it results in a empty file + # ## Leaving the -f option off also results in an empty file + # #my $command = "qemu-img convert -f raw \"$source_file_path\" -O raw \"$raw_file_path\" && qemu-img info \"$raw_file_path\""; + # #notify($ERRORS{'DEBUG'}, 0, "attempting to convert vmdk file to raw format: $source_file_path --> $raw_file_path, command:\n$command"); + # #my ($exit_status, $output) = $self->vmhost_os->execute($command, 0, 1800); + # #if (!defined($exit_status)) { + # # notify($ERRORS{'WARNING'}, 0, "failed to execute command to convert vmdk file to raw format:\n$command"); + # # return; + # #} + # #elsif ($exit_status) { + # # notify($ERRORS{'WARNING'}, 0, "failed to convert vmdk file to raw format on $node_name\ncommand: '$command'\noutput:\n" . join("\n", @$output)); + # # return; + # #} + # #else { + # # notify($ERRORS{'DEBUG'}, 0, "converted vmdk file to raw format on $node_name: $source_file_path --> $raw_file_path\ncommand: '$command'\noutput:\n" . join("\n", @$output)); + # #} + # } + # + # # Remove trailing last space + # $source_file_paths_string =~ s/\s+$//; + # + # #my $raw_file_path_merged = "$raw_file_directory_path/$image_name.raw"; + # #my $cat_command = "cat $source_file_paths_string > \"$raw_file_path_merged\""; + # #notify($ERRORS{'DEBUG'}, 0, "attempting to merge split raw files into $raw_file_path_merged, command:\n$cat_command"); + # #my ($cat_exit_status, $cat_output) = $self->vmhost_os->execute($cat_command, 0, 1800); + # #if (!defined($cat_exit_status)) { + # # notify($ERRORS{'WARNING'}, 0, "failed to execute command to merge split raw files into $raw_file_path_merged, command: $cat_command"); + # # return; + # #} + # #elsif ($cat_exit_status) { + # # notify($ERRORS{'WARNING'}, 0, "failed to convert merge split raw files into $raw_file_path_merged\ncommand: '$cat_command'\noutput:\n" . join("\n", @$cat_output)); + # # return; + # #} + # #else { + # # notify($ERRORS{'DEBUG'}, 0, "merged split raw files into $raw_file_path_merged\ncommand: '$cat_command'\noutput:\n" . join("\n", @$cat_output)); + # # $source_file_paths_string = "\"$raw_file_path_merged\""; + # #} + #} + #else { # Join the array of file paths into a string - $source_file_paths_string = join('" "', @source_file_paths); - } + $source_file_paths_string = '"' . join('" "', @source_file_paths) . '"'; + #} + #my $command = "qemu-img convert -f vmdk -O $disk_format $source_file_paths_string \"$destination_file_path\" && qemu-img info \"$destination_file_path\""; my $command = "qemu-img convert $source_file_paths_string -O $disk_format \"$destination_file_path\" && qemu-img info \"$destination_file_path\""; + + ## If the image had to be converted to raw format first, add command to delete raw files + #if ($raw_file_directory_path) { + # $command .= " ; rm -f $raw_file_directory_path"; + #} - # If the image had to be converted to raw format first, add command to delete raw files - if ($convert_to_raw) { - $command .= " ; rm -f $source_file_paths_string"; - } - - notify($ERRORS{'DEBUG'}, 0, "attempting to copy/convert virtual disk to $disk_format format --> $destination_file_path"); + notify($ERRORS{'DEBUG'}, 0, "attempting to copy/convert virtual disk to $disk_format format --> $destination_file_path, command:\n$command"); my $start_time = time; my ($exit_status, $output) = $self->vmhost_os->execute($command, 0, 1800); @@ -887,7 +912,8 @@ EOF # Attempt to run virt-win-reg to merge the registry contents into the registry on the virtual disk notify($ERRORS{'DEBUG'}, 0, "attempting to merge $temp_reg_file_path into $virtual_disk_file_path"); - my ($exit_status, $output) = $self->vmhost_os->execute("virt-win-reg --merge $virtual_disk_file_path $temp_reg_file_path"); + my $command = "virt-win-reg --merge $virtual_disk_file_path $temp_reg_file_path"; + my ($exit_status, $output) = $self->vmhost_os->execute($command); if (!defined($output)) { notify($ERRORS{'WARNING'}, 0, "failed to execute command to merge $temp_reg_file_path into $virtual_disk_file_path"); return; @@ -897,7 +923,7 @@ EOF return 1; } elsif ($exit_status ne '0') { - notify($ERRORS{'WARNING'}, 0, "failed to merge $temp_reg_file_path into $virtual_disk_file_path, exit status: $exit_status, output:\n" . join("\n", @$output)); + notify($ERRORS{'WARNING'}, 0, "failed to merge $temp_reg_file_path into $virtual_disk_file_path, exit status: $exit_status, command: '$command', output:\n" . join("\n", @$output)); return; } else { Modified: incubator/vcl/trunk/managementnode/lib/VCL/utils.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=1339295&r1=1339294&r2=1339295&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/utils.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/utils.pm Wed May 16 18:10:59 2012 @@ -1847,7 +1847,7 @@ sub is_request_deleted { #notify($ERRORS{'DEBUG'}, 0,"state=$state_name, laststate=$laststate_name"); - if ($state_name eq 'deleted' || $laststate_name eq 'deleted') { + if ($state_name =~ /(deleted|makeproduction)/ || $laststate_name =~ /(deleted|makeproduction)/) { return 1; } @@ -1909,7 +1909,7 @@ sub is_reservation_deleted { #notify($ERRORS{'DEBUG'}, 0,"state=$state_name, laststate=$laststate_name"); - if ($state_name eq 'deleted' || $laststate_name eq 'deleted') { + if ($state_name =~ /(deleted|makeproduction)/ || $laststate_name =~ /(deleted|makeproduction)/) { return 1; } @@ -4065,17 +4065,9 @@ EOF my $imagemeta_root_access = $request_info->{reservation}{$reservation_id}{image}{imagemeta}{rootaccess}; - # Create an array containing the user IDs of the request user and users configured for the image - # If imagemeta.usergroupid is set, add the user group members to the hash, set ROOTACCESS to value configured for image - my @image_user_ids = ($user_id); - if (my $imagemeta_group_id = $request_info->{reservation}{$reservation_id}{image}{imagemeta}{usergroupid}) { - my $imagemeta_group_member_info = get_user_group_member_info($imagemeta_group_id); - push @image_user_ids, keys %$imagemeta_group_member_info; - } - for my $image_user_id (@image_user_ids) { - $request_info->{reservation}{$reservation_id}{users}{$image_user_id} = get_user_info($image_user_id); - $request_info->{reservation}{$reservation_id}{users}{$image_user_id}{ROOTACCESS} = $imagemeta_root_access; - } + # Add the request user to the hash, set ROOTACCESS to the value configured in imagemeta + $request_info->{reservation}{$reservation_id}{users}{$user_id} = get_user_info($user_id); + $request_info->{reservation}{$reservation_id}{users}{$user_id}{ROOTACCESS} = $imagemeta_root_access; # If server request and logingroupid is set, add user group members to hash, set ROOTACCESS to 0 if (my $login_group_id = $request_info->{reservation}{$reservation_id}{serverrequest}{logingroupid}) { @@ -4600,21 +4592,6 @@ EOF # Get the single row returned from the select statement my $imagemeta_info = $selected_rows[0]; - # Collect additional information - if (my $user_group_id = $imagemeta_info->{usergroupid}) { - - my $user_group_member_info = get_user_group_member_info($user_group_id); - - for my $user_id (keys %$user_group_member_info) { - my $user_unityid = $user_group_member_info->{$user_id}{unityid}; - my $user_uid = $user_group_member_info->{$user_id}{uid} || 0; - - $imagemeta_info->{USERGROUPMEMBERS}{$user_uid} = $user_unityid; - } - } - # Populate the count of user group members - $imagemeta_info->{USERGROUPMEMBERCOUNT} = scalar(keys(%{$imagemeta_info->{USERGROUPMEMBERS}})); - for my $column (keys %$imagemeta_info) { if (!defined($imagemeta_info->{$column})) { $imagemeta_info->{$column} = $default_imagemeta_info->{$column}; @@ -4666,9 +4643,6 @@ sub get_default_imagemeta_info { } } - $default_imagemeta_info->{USERGROUPMEMBERS} = {}; - $default_imagemeta_info->{USERGROUPMEMBERCOUNT} = 0; - $ENV{imagemeta_info}{default} = $default_imagemeta_info; my %default_imagemeta_info_copy = %{$ENV{imagemeta_info}{default}}; @@ -4875,8 +4849,8 @@ sub run_ssh_command { $port = 22 if (!$port); $timeout_seconds = 0 if (!$timeout_seconds); $identity_paths = get_management_node_info()->{keys} if (!defined $identity_paths || length($identity_paths) == 0); - -return VCL::Module::OS::execute_new($node, $command, $output_level, $timeout_seconds, $max_attempts, $port, $user); + +return VCL::Module::OS::execute_new($node, $command, $output_level, $timeout_seconds, $max_attempts, $port, $user, '', $identity_paths); # TODO: Add ssh path to config file and set global variable # Locate the path to the ssh binary @@ -7477,7 +7451,7 @@ sub get_user_info { return; } - return $ENV{user_info}{$user_identifier} if (!$no_cache && $ENV{user_info}{$user_identifier}); + #return $ENV{user_info}{$user_identifier} if (!$no_cache && $ENV{user_info}{$user_identifier}); # If affiliation identifier argument wasn't supplied, set it to % wildcard $affiliation_identifier = '%' if !$affiliation_identifier;