# # Copyright 2006. VMware, Inc. The use of this code is subject to # your agreement to the terms of an applicable VMware license. # package VMware::Vix::Simple; # Simple Perl interface to Vix # Currently exposes only those functions documented. # Mission statement: # Hides all asynchronicity from caller. # Returns values as arrays whenever applicable, instead of # C-style reference #use 5.00503; # for debugging purposes use lib qw( blib/lib blib/auto ); use strict; use Carp; use VMware::Vix::API::API; use VMware::Vix::API::Job; use VMware::Vix::API::VM; use VMware::Vix::API::Host; use VMware::Vix::API::PropertyList; use VMware::Vix::API::Constants; require Exporter; require DynaLoader; #use AutoLoader; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); @ISA = qw(Exporter DynaLoader); # explcitly export things, to keep with the 'Simple' philosophy @EXPORT = qw( GetErrorText ReleaseHandle GetHandleType GetProperties GetNumProperties GetNthProperties AllocPropertyList HostConnect HostDisconnect FindRunningVMs FindItems HostOpenVM RegisterVM UnregisterVM VMOpen VMPowerOn VMPowerOff VMReset VMDelete VMSuspend VMWaitForToolsInGuest VMGetNumRootSnapshots VMGetRootSnapshot VMRemoveSnapshot VMRevertToSnapshot VMCreateSnapshot VMGetCurrentSnapshot VMGetNamedSnapshot VMInstallTools VMUpgradeVirtualHardware VMLoginInGuest VMLogoutFromGuest VMRunProgramInGuest VMRunProgramInGuestEx VMListProcessesInGuest VMKillProcessInGuest VMRunScriptInGuest VMRunScriptInGuestEx VMCopyFileFromHostToGuest VMCopyFileFromGuestToHost VMDeleteFileInGuest VMFileExistsInGuest VMRenameFileInGuest VMCreateTempFileInGuest VMGetFileInfoInGuest VMCreateDirectoryInGuest VMDeleteDirectoryInGuest VMDirectoryExistsInGuest VMListDirectoryInGuest VMGetNumSharedFolders VMGetSharedFolderState VMSetSharedFolderState VMAddSharedFolder VMRemoveSharedFolder VMEnableSharedFolders VMReadVariable VMWriteVariable VMPause VMUnpause VMClone VMCaptureScreenImage SnapshotGetNumChildren SnapshotGetChild SnapshotGetParent ); $VERSION = '0.02'; # Preloaded methods go here. =head1 NAME VMware::Vix::Simple - Simple interface to VMware Vix =head1 SYNOPSIS use VMware::Vix::Simple; use VMware::Vix::API::Constants; =head1 DESCRIPTION C provides a simple interface to the VMware Vix library. It hides the underlying asynchronous nature will still providing the core functionality. =head2 General Functions =item B ($err, $hostHandle) = HostConnect(VIX_API_VERSION, $hostType, $hostname, $hostport, $username, $password, $options, $propertyListHandle); Initializes the a remote host object; you must call this before calling any other Vix API. The host object will be used for all Vix operations. Returns an error code and the host handle. $hostType should be VIX_SERVICEPROVIDER_VMWARE_SERVER or VIX_SERVICEPROVIDER_VMWARE_WORKSTATION. $options should be 0. $propertyListHandle should be VIX_INVALID_HANDLE. =cut # General functions sub HostConnect($$$$$$$$) { my ($version, $hostType, $hostname, $hostport, $username, $password, $options, $propertyListHandle) = @_; my $err; my $hostHandle = VIX_INVALID_HANDLE; my $job = VIX_INVALID_HANDLE; $job = VMware::Vix::API::Host::Connect($version, $hostType, $hostname, $hostport, $username, $password, $options, $propertyListHandle, 0, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_JOB_RESULT_HANDLE, $hostHandle, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err, $hostHandle; }; =item B HostDisconnect($hostHandle); Shuts down a host handle returned by HostConnect. =cut sub HostDisconnect($) { my ($host) = @_; VMware::Vix::API::Host::Disconnect($host); } =item B @vmlist = FindRunningVMs($hostHandle, $timeoutInSeconds); Returns the the VMs running on the host associated with the hostHandle. The first element in the list is an error code. =cut sub FindRunningVMs($$) { my ($hostHandle, $timeout) = @_; my @vms; return VMware::Vix::API::Host::FindItems($hostHandle, VIX_FIND_RUNNING_VMS, VIX_INVALID_HANDLE, $timeout, undef, undef); } =item B @vmlist = FindItems($hostHandle, $searchType, $timeoutInSeconds); Returns the the VMs running on the host associated with the hostHandle matching the given $searchType. The first element in the list is an error code. =cut sub FindItems($$$) { my ($hostHandle, $searchType, $timeout) = @_; my @vms; return VMware::Vix::API::Host::FindItems($hostHandle, $searchType, VIX_INVALID_HANDLE, $timeout, undef, undef); } =item B ($err, $vmHandle) = HostOpenVM($hostHandle, $vmxPath, $options, $propertyListHandle); Opens the virtual machine in $vmxPath on the host identified by $hostHandle. This supercedes VMOpen(), since it provides options and property list parameters. =cut sub HostOpenVM($$$$) { my ($hostHandle, $vmxPath, $options, $propertyListHandle) = @_; my $err; my $job; my $vmHandle = VIX_INVALID_HANDLE; $job = VMware::Vix::API::Host::OpenVM($hostHandle, $vmxPath, $options, $propertyListHandle, undef, undef); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_JOB_RESULT_HANDLE, $vmHandle, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err, $vmHandle; }; =item B $err = RegisterVM($hostHandle, $vmxFilePath); Register the VM with the host associated with the hostHandle. VMs must be registered before they can be opened. =cut sub RegisterVM($$) { my ($hostHandle, $vmxFilePath) = @_; my $job; my $err; $job = VMware::Vix::API::Host::RegisterVM($hostHandle, $vmxFilePath, undef, undef); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; } =item B $err = UnregisterVM($hostHandle, $vmxFilePath); Unregister the VM with the host associated with the hostHandle. VMs must be registered before they can be opened. =cut sub UnregisterVM($$) { my ($hostHandle, $vmxFilePath) = @_; my $job; my $err; $job = VMware::Vix::API::Host::UnregisterVM($hostHandle, $vmxFilePath, undef, undef); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; } =item B ReleaseHandle($handle); Can be used on any handle when it is no longer needed. Do not use a handle once it has been Released. =cut sub ReleaseHandle($) { my ($handle) = @_; VMware::Vix::API::API::ReleaseHandle($handle); } =item B $type = GetHandleType($handle); Returns the type of handle referred to by $handle. =cut sub GetHandleType($) { my ($handle) = @_; return VMware::Vix::API::API::GetHandleType($handle); } =item B $errstring = GetErrorText($err); Returns the human-readable error string associated with an error code. =cut sub GetErrorText($) { my ($err) = @_; VMware::Vix::API::API::GetErrorText($err, ""); } =item B @properties = GetProperties($handle, prop1, prop2, ...); Returns the values of the requested properties from the object pointed to by $handle. The first element in the list is an error code. =cut sub GetProperties { my $handle = shift @_; my $err; my $val = undef; my @retval; push @retval, VIX_OK; if (@_ < 1) { $retval[0] = VIX_E_FAIL; die ("GetProperties must have at least two arguments\n"); return @retval; } foreach (@_) { my $property = $_; $err = VMware::Vix::API::API::GetProperties($handle, $property, $val, VIX_PROPERTY_NONE); $retval[0] = $err; push @retval, $val; if ($err != VIX_OK) { last; } } return @retval; } =item B ($err, $propertyListHandle) = AllocPropertyList($hostHandle, $prop1, $val1, ...); Creates a new properylist with the given properties. Currently supports only a single property. =cut sub AllocPropertyList { my $err; my $propertyListHandle = VIX_INVALID_HANDLE; my $prop1; my $val1; my $hostHandle; if (@_ < 4) { $err = VIX_E_FAIL; die ("AllocPropertyList must have at least four arguments\n"); return $err; } $hostHandle = shift @_; $prop1 = shift @_; $val1 = shift @_; $err = VMware::Vix::API::PropertyList::AllocPropertyList($hostHandle, $propertyListHandle, $prop1, $val1, VIX_PROPERTY_NONE); return $err, $propertyListHandle; } # VM functions =head2 VM Functions =item B ($err, $vmHandle) = VMOpen($hostHandle, $vmxPathName); Opens the virtual machine in $vmxPathName on the host identified by $hostHandle. =cut sub VMOpen($$) { my ($host, $vmxPath) = @_; my $err; my $job; my $vm = VIX_INVALID_HANDLE; $job = VMware::Vix::API::VM::Open($host, $vmxPath, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_JOB_RESULT_HANDLE, $vm, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err, $vm; }; =item B $err = VMDelete($vmHandle, $options); Deletes the virtual machine $vmHandle returned by C. $options should be VIX_VMDELETE_DISK_FILES, or only on Workstation, 0 to not delete .vmdk files. =cut sub VMDelete($$) { my ($vm, $options) = @_; my $err; my $job; $job = VMware::Vix::API::VM::Delete($vm, $options, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; } =item B $err = VMPowerOn($vmHandle, $options, $propertyListHandle); Powers on the VM. $options should be 0. $propertyListHandle should be VIX_INVALID_HANDLE. =cut sub VMPowerOn($$$) { my ($vm, $options, $propertyListHandle) = @_; my $err; my $job; $job = VMware::Vix::API::VM::PowerOn($vm, $options, $propertyListHandle, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B $err = VMPowerOff($vmHandle, $options); Powers off the VM. $options should be 0. =cut sub VMPowerOff($$) { my ($vm, $options) = @_; my $err; my $job; $job = VMware::Vix::API::VM::PowerOff($vm, $options, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B $err = VMReset($vmHandle, $options); Restarts the VM. $options should be 0. =cut sub VMReset($$) { my ($vm, $options) = @_; my $err; my $job; $job = VMware::Vix::API::VM::Reset($vm, $options, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B $err = VMSuspend($vmHandle, $options); Suspends the VM. $options should be 0. =cut sub VMSuspend($$) { my ($vm, $options) = @_; my $err; my $job; $job = VMware::Vix::API::VM::Suspend($vm, $options, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B $err = VMWaitForToolsInGuest($vmHandle, $timeoutInSeconds); This function will return when the VMware tools have successfully started in the guest or $timeoutInSeconds have elapsed. =cut sub VMWaitForToolsInGuest($$) { my ($vm, $timeoutInSeconds) = @_; my $err; my $job; $job = VMware::Vix::API::VM::WaitForToolsInGuest($vm, $timeoutInSeconds, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B $err = VMLoginInGuest($vmHandle, $userName, $password, $options); Validates a connection on the guest OS for further guest OS operations. $options should be 0. =cut sub VMLoginInGuest($$$$) { my ($vm, $userName, $password, $options) = @_; my $err; my $job; $job = VMware::Vix::API::VM::LoginInGuest($vm, $userName, $password, $options, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B $err = VMLogoutFromGuest($vmHandle); Resets the guest OS login authorization for a connection. =cut sub VMLogoutFromGuest($) { my ($vm) = @_; my $err; my $job; $job = VMware::Vix::API::VM::LogoutFromGuest($vm, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B $err = VMRunProgramInGuest($vmHandle, $guestProgramName, $commandLineArgs, $options, $propertyListHandle); This will run $guestProgramName with $commandLineArgs. If $options is VIX_RUNPROGRAM_RETURN_IMMEDIATELY, it will not wait for the $guestProgramName to complete before returning. $propertyListHandle should be VIX_INVALID_HANDLE. LoginInGuest() must be called first. =cut sub VMRunProgramInGuest($$$$$) { my ($vm, $guestProgramName, $commandLineArgs, $options, $propertyListHandle) = @_; my $err; my $job; $job = VMware::Vix::API::VM::RunProgramInGuest($vm, $guestProgramName, $commandLineArgs, $options, $propertyListHandle, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B ($err, %processInfo) = VMRunProgramInGuestEx($vmHandle, $guestProgramName, $commandLineArgs, $options, $propertyListHandle); This will run $guestProgramName with $commandLineArgs. If $options is VIX_RUNPROGRAM_RETURN_IMMEDIATELY, it will not wait for the $guestProgramName to complete before returning. %processInfo is a hash, containing information about the process. The hash keys are PROCESS_ID, EXIT_CODE and ELPASED_TIME. $propertyListHandle should be VIX_INVALID_HANDLE. LoginInGuest() must be called first. =cut sub VMRunProgramInGuestEx($$$$$) { my ($vm, $guestProgramName, $commandLineArgs, $options, $propertyListHandle) = @_; my $err; my $job; my $exitCode; my $pid; my $elapsedTime; my %procInfo; $job = VMware::Vix::API::VM::RunProgramInGuest($vm, $guestProgramName, $commandLineArgs, $options, $propertyListHandle, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_JOB_RESULT_GUEST_PROGRAM_EXIT_CODE, $exitCode, VIX_PROPERTY_JOB_RESULT_GUEST_PROGRAM_ELAPSED_TIME, $elapsedTime, VIX_PROPERTY_JOB_RESULT_PROCESS_ID, $pid, VIX_PROPERTY_NONE); # If we're not waiting for the answer, we'll get junk back, # so make it obvious with a value of 'undef'. if ($options & VIX_RUNPROGRAM_RETURN_IMMEDIATELY) { %procInfo = ( "PROCESS_ID" => $pid, "EXIT_CODE" => undef, "ELAPSED_TIME" => undef, ); } else { %procInfo = ( "PROCESS_ID" => $pid, "EXIT_CODE" => $exitCode, "ELAPSED_TIME" => $elapsedTime, ); } VMware::Vix::API::API::ReleaseHandle($job); return $err, %procInfo; }; =item B ($err, @processProperties) = VMListProcessesInGuest($vmHandle, $options); This will list the process running in the guest OS. $options should be 0. @processProperties is an array of hashes, each containing the list of property names and values associated with the process. The hash keys are PROCESS_NAME, PROCESS_ID, PROCESS_OWNER and PROCESS_COMMAND. example: print "Process name: $processProperties[0]{'PROCESS_NAME'}\n"; LoginInGuest() must be called first. =cut sub VMListProcessesInGuest($$) { my ($vm, $options) = @_; my $err; my $job; my @proplist; my $num; my $i; my $proc_name; my $proc_id; my $proc_owner; my $proc_command; $job = VMware::Vix::API::VM::ListProcessesInGuest($vm, $options, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); $num = VMware::Vix::API::Job::GetNumProperties($job, VIX_PROPERTY_JOB_RESULT_ITEM_NAME); foreach $i (1..$num) { $err = VMware::Vix::API::Job::GetNthProperties($job, $i - 1, VIX_PROPERTY_JOB_RESULT_ITEM_NAME, $proc_name, VIX_PROPERTY_JOB_RESULT_PROCESS_ID, $proc_id, VIX_PROPERTY_JOB_RESULT_PROCESS_OWNER, $proc_owner, VIX_PROPERTY_JOB_RESULT_PROCESS_COMMAND, $proc_command, VIX_PROPERTY_NONE); $proplist[$i-1] = { "PROCESS_NAME" => $proc_name, "PROCESS_ID" => $proc_id, "PROCESS_OWNER" => $proc_owner, "PROCESS_COMMAND" => $proc_command, }; } VMware::Vix::API::API::ReleaseHandle($job); return $err, @proplist; }; =item B $err = VMKillProcessInGuest($vmHandle, $pid, $options); This will kill the process $pid in the guest OS. $options should be 0. LoginInGuest() must be called first. =cut sub VMKillProcessInGuest($$$) { my ($vm, $pid, $options) = @_; my $err; my $job; $job = VMware::Vix::API::VM::KillProcessInGuest($vm, $pid, $options, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B $err = VMRunScriptInGuest($vmHandle, $interpreter, $scriptText, $options, $propertyListHandle); This will run the script contained in $scriptText, using $interpreter. $options should be 0. $propertyListHandle should be VIX_INVALID_HANDLE. LoginInGuest() must be called first. =cut sub VMRunScriptInGuest($$$$$) { my ($vm, $interpreter, $scriptText, $options, $propertyListHandle) = @_; my $err; my $job; $job = VMware::Vix::API::VM::RunScriptInGuest($vm, $interpreter, $scriptText, $options, $propertyListHandle, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B ($err, %processInfo) = VMRunScriptInGuestEx($vmHandle, $interpreter, $scriptText, $options, $propertyListHandle); This will run the script contained in $scriptText, using $interpreter. $options should be 0. %processInfo is a hash, containing information about the process. The hash keys are PROCESS_ID, EXIT_CODE and ELPASED_TIME. $propertyListHandle should be VIX_INVALID_HANDLE. LoginInGuest() must be called first. =cut sub VMRunScriptInGuestEx($$$$$) { my ($vm, $interpreter, $scriptText, $options, $propertyListHandle) = @_; my $err; my $job; my $exitCode; my $pid; my $elapsedTime; my %procInfo; $job = VMware::Vix::API::VM::RunScriptInGuest($vm, $interpreter, $scriptText, $options, $propertyListHandle, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_JOB_RESULT_GUEST_PROGRAM_EXIT_CODE, $exitCode, VIX_PROPERTY_JOB_RESULT_GUEST_PROGRAM_ELAPSED_TIME, $elapsedTime, VIX_PROPERTY_JOB_RESULT_PROCESS_ID, $pid, VIX_PROPERTY_NONE); # If we're not waiting for the answer, we'll get junk back, # so make it obvious with a value of 'undef'. if ($options & VIX_RUNPROGRAM_RETURN_IMMEDIATELY) { %procInfo = ( "PROCESS_ID" => $pid, "EXIT_CODE" => undef, "ELAPSED_TIME" => undef, ); } else { %procInfo = ( "PROCESS_ID" => $pid, "EXIT_CODE" => $exitCode, "ELAPSED_TIME" => $elapsedTime, ); } VMware::Vix::API::API::ReleaseHandle($job); return $err, %procInfo; }; =item B $err = VMCopyFileFromHostToGuest($vmHandle, $hostFilePath, $guestFilePath, $options, $propertyListHandle); This will copy $hostFilePath to $guestFilePath. $options should be 0. $propertyListHandle should be VIX_INVALID_HANDLE. LoginInGuest() must be called first. =cut sub VMCopyFileFromHostToGuest($$$$$) { my ($vm, $hostFilePath, $guestFilePath, $options, $propertyListHandle) = @_; my $err; my $job; $job = VMware::Vix::API::VM::CopyFileFromHostToGuest($vm, $hostFilePath, $guestFilePath, $options, $propertyListHandle, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B $err = VMCopyFileFromGuestToHost($vmHandle, $guestFilePath, $hostFilePath, $options, $propertyListHandle); This will copy $guestFilePath to $hostFilePath. $options should be 0. $propertyListHandle should be VIX_INVALID_HANDLE. LoginInGuest() must be called first. =cut sub VMCopyFileFromGuestToHost($$$$$) { my ($vm, $guestFilePath, $hostFilePath, $options, $propertyListHandle) = @_; my $err; my $job; $job = VMware::Vix::API::VM::CopyFileFromGuestToHost($vm, $guestFilePath, $hostFilePath, $options, $propertyListHandle, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B $err = VMDeleteFileInGuest($vmHandle, $guestFilePath); This will delete $guestFilePath in the guest OS. LoginInGuest() must be called first. =cut sub VMDeleteFileInGuest($$) { my ($vm, $guestFilePath) = @_; my $err; my $job; $job = VMware::Vix::API::VM::DeleteFileInGuest($vm, $guestFilePath, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B ($err, $exists) = VMFileExistsInGuest($vmHandle, $guestFilePath); This will test the existance of $guestFilePath in the guest OS. LoginInGuest() must be called first. =cut sub VMFileExistsInGuest($$) { my ($vm, $guestFilePath) = @_; my $err; my $job; my $exists; $job = VMware::Vix::API::VM::FileExistsInGuest($vm, $guestFilePath, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_JOB_RESULT_GUEST_OBJECT_EXISTS, $exists, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err, $exists; }; =item B $err = VMRenameFileInGuest($vmHandle, $oldName, $newName, $options, $propertyListHandle); This will rename the file $oldname to $newName. $options should be 0. $propertyListHandle should be VIX_INVALID_HANDLE. LoginInGuest() must be called first. =cut sub VMRenameFileInGuest($$$$$) { my ($vm, $oldName, $newName, $options, $propertyFileHandle) = @_; my $err; my $job; $job = VMware::Vix::API::VM::RenameFileInGuest($vm, $oldName, $newName, $options, $propertyFileHandle, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B ($err, $tempFileName) = VMCreateTempFileInGuest($vmHandle, $options, $propertyListHandle); Creates a temporary file in the the guest OS. $options should be 0. $propertyListHandle should be VIX_INVALID_HANDLE. LoginInGuest() must be called first. =cut sub VMCreateTempFileInGuest($$$) { my ($vm, $options, $propertyFileHandle) = @_; my $err; my $job; my $tempFileName; $job = VMware::Vix::API::VM::CreateTempFileInGuest($vm, $options, $propertyFileHandle, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_JOB_RESULT_ITEM_NAME, $tempFileName, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err, $tempFileName; }; =item B ($err, %fileInfo) = VMGetFileInfoInGuest($vmHandle, $pathName); Returns information about $pathName in the guest OS. LoginInGuest() must be called first. @fileInfo is a hash, containing the information for $pathName. The hash keys are FILE_SIZE, FILE_FLAGS and FILE_MOD_TIME. =cut sub VMGetFileInfoInGuest($$) { my ($vm, $pathName) = @_; my $err; my $job; my $attr; my $size; my $modtime; my %info; $job = VMware::Vix::API::VM::GetFileInfoInGuest($vm, $pathName, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_JOB_RESULT_FILE_SIZE, $size, VIX_PROPERTY_JOB_RESULT_FILE_FLAGS, $attr, VIX_PROPERTY_JOB_RESULT_FILE_MOD_TIME, $modtime, VIX_PROPERTY_NONE); %info = ( "FILE_SIZE" => $size, "FILE_FLAGS" => $attr, "FILE_MOD_TIME" => $modtime, ); VMware::Vix::API::API::ReleaseHandle($job); return $err, %info; }; =item B $err = VMCreateDirectoryInGuest($vmHandle, $pathName, $propertyListHandle); This will create the directory $pathName in the guest OS. $propertyListHandle should be VIX_INVALID_HANDLE. LoginInGuest() must be called first. =cut sub VMCreateDirectoryInGuest($$$) { my ($vm, $pathName, $propertyFileHandle) = @_; my $err; my $job; $job = VMware::Vix::API::VM::CreateDirectoryInGuest($vm, $pathName, $propertyFileHandle, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B $err = VMDeleteDirectoryInGuest($vmHandle, $pathName, $options); This will delete the directory $pathName in the guest OS. $options should be 0. LoginInGuest() must be called first. =cut sub VMDeleteDirectoryInGuest($$$) { my ($vm, $pathName, $options) = @_; my $err; my $job; $job = VMware::Vix::API::VM::DeleteDirectoryInGuest($vm, $pathName, $options); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B ($err, $exists) = VMDirectoryExistsInGuest($vmHandle, $pathName); This will test the existance $pathName in the guest OS. $propertyListHandle should be VIX_INVALID_HANDLE. LoginInGuest() must be called first. =cut sub VMDirectoryExistsInGuest($$) { my ($vm, $pathName) = @_; my $err; my $job; my $exists; $job = VMware::Vix::API::VM::DirectoryExistsInGuest($vm, $pathName, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_JOB_RESULT_GUEST_OBJECT_EXISTS, $exists, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err, $exists; }; =item B ($err, @directoryContents) = VMListDirectoryInGuest($vmHandle, $pathName, $options); This list the contents of directory $pathName in the guest OS. $propertyListHandle should be VIX_INVALID_HANDLE. LoginInGuest() must be called first. @directoryContents is an arry of hashes, each containing the list of property names and values associated with the directory contents. The hash keys are FILE_NAME and FILE_ATTRIBUTES. =cut sub VMListDirectoryInGuest($$$) { my ($vm, $pathName, $options) = @_; my $err; my $job; my $exists; my $i; my $num; my $attr; my $name; my @filenames; $job = VMware::Vix::API::VM::ListDirectoryInGuest($vm, $pathName, $options, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); $num = VMware::Vix::API::Job::GetNumProperties($job, VIX_PROPERTY_JOB_RESULT_ITEM_NAME); foreach $i (1..$num) { $err = VMware::Vix::API::Job::GetNthProperties($job, $i - 1, VIX_PROPERTY_JOB_RESULT_ITEM_NAME, $name, VIX_PROPERTY_JOB_RESULT_FILE_FLAGS, $attr, VIX_PROPERTY_NONE); $filenames[$i-1] = { "FILE_NAME" => $name, "FILE_ATTRIBUTES" => $attr, }; } VMware::Vix::API::API::ReleaseHandle($job); return $err, @filenames; }; =head2 Screen Capture =item B ($err, $imageSize, $imageBytes) = VMCaptureScreenImage($vmHandle, $options, $propertyListHandle); Captures the screen of the guest operating system. =cut sub VMCaptureScreenImage($$$) { my ($vm, $options, $propertyListHandle) = @_; my $err; my $job; my $imageSize; my $imageBytes; $job = VMware::Vix::API::VM::CaptureScreenImage($vm, $options, $propertyListHandle, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_JOB_RESULT_SCREEN_IMAGE_DATA, $imageSize, $imageBytes, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err, $imageSize, $imageBytes; }; =head2 Clone =item B ($err, $cloneHandle) = VMClone($vmHandle, $snapshotHandle, $cloneType, $destConfigPathName, $options, $propertyListHandle); Creates a copy of the virtual machine specified by $vmHandle. =cut sub VMClone($$$$$$) { my ($vm, $ss, $cloneType, $destPath, $options, $propertyListHandle) = @_; my $err; my $job; my $cloneHandle; $job = VMware::Vix::API::VM::Clone($vm, $ss, $cloneType, $destPath, $options, $propertyListHandle, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_JOB_RESULT_HANDLE, $cloneHandle, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err, $cloneHandle; }; =head2 VM Snapshot Functions =item B ($err, $numRootSnapshots) = VMGetNumRootSnapshots($vmHandle); Returns the number of top-level snapshots in a VM. =cut sub VMGetNumRootSnapshots($) { my ($vm) = @_; my $num = 0; my $err = VMware::Vix::API::VM::GetNumRootSnapshots($vm, $num); return $err, $num; } =item B ($err, $snapshotHandle) = VMGetRootSnapshot($vmHandle, $index); Returns a handle to the $index snapshot (numbered from 0 to n-1). =cut sub VMGetRootSnapshot($$) { my ($vm, $index) = @_; my $snapshot = VIX_INVALID_HANDLE; my $err = VMware::Vix::API::VM::GetRootSnapshot($vm, $index, $snapshot); return $err, $snapshot; } =item B $err = VMRemoveSnapshot($vmHandle, $snapshotHandle, $options); Removes the snapshot from a VM. $options should be 0. =cut sub VMRemoveSnapshot($$$) { my ($vm, $snapshot, $options) = @_; my $job = VMware::Vix::API::VM::RemoveSnapshot($vm, $snapshot, $options, undef, 0); my $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; } =item B $err = VMRevertToSnapshot($vmHandle, $snapshotHandle, $options, $propertyListHandle); Revert the state of the VM to the state when the snapshot was created. $options should be 0. $propertyListHandle should be VIX_INVALID_HANDLE. =cut sub VMRevertToSnapshot($$$$) { my ($vm, $snapshot, $options, $propertyListHandle) = @_; my $job = VMware::Vix::API::VM::RevertToSnapshot($vm, $snapshot, $options, $propertyListHandle, undef, 0); my $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; } =item B ($err, $snapshotHandle) = VMGetCurrentSnapshot($vmHandle); Returns the current snapshot. Returns an error code and the handle to the newly created snapshot. =cut sub VMGetCurrentSnapshot($) { my ($vm) = @_; my $snapshot = VIX_INVALID_HANDLE; my $err = VMware::Vix::API::VM::GetCurrentSnapshot($vm, $snapshot); return $err, $snapshot; } =item B ($err, $snapshotHandle) = VMGetNamedSnapshot($vmHandle, $name); Returns the snapshot with the given $name. Returns an error code and the handle to the newly created snapshot. =cut sub VMGetNamedSnapshot($$) { my ($vm, $name) = @_; my $snapshot = VIX_INVALID_HANDLE; my $err = VMware::Vix::API::VM::GetNamedSnapshot($vm, $name, $snapshot); return $err, $snapshot; } =item B ($err, $snapshotHandle) = VMCreateSnapshot($vmHandle, $name, $description, $options, $propertyListHandle); Creates a new snapshot of the current VM state and stores it as $name with description $description. $options should be 0. $propertyListHandle should be VIX_INVALID_HANDLE. Returns an error code and the handle to the newly created snapshot. =cut sub VMCreateSnapshot($$$$$) { my ($vm, $name, $description, $options, $propertyListHandle) = @_; my $snapshot = VIX_INVALID_HANDLE; my $job = VMware::Vix::API::VM::CreateSnapshot($vm, $name, $description, $options, $propertyListHandle, undef, undef); my $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_JOB_RESULT_HANDLE, $snapshot, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err, $snapshot; } =item B $err = VMUpgradeVirtualHardware($vmHandle, $options); Upgrade the virtual hadware of the VM. The VM must be powered off to perform this operation. $options should be 0. =cut sub VMUpgradeVirtualHardware($$) { my ($vm, $options) = @_; my $job = VMware::Vix::API::VM::UpgradeVirtualHardware($vm, $options, undef, undef); my $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; } =item B $err = VMInstallTools($vmHandle, $options, $commandLineArgs); Installs the latest version of the tools onto the VM. The VM must be powered on. $options should be 0. $commandLineArgs should be undef. =cut sub VMInstallTools($$$) { my ($vm, $options, $commandLineArgs) = @_; my $job = VMware::Vix::API::VM::InstallTools($vm, $options, $commandLineArgs, undef, undef); my $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; } =head2 VM Shared Folder Functions =item B ($err, $num) = VMGetNumSharedFolders($vmHandle); Returns the number of shared folders in $vmHandle. =cut sub VMGetNumSharedFolders($) { my ($vm) = @_; my $num = 0; my $err; my $job; $job = VMware::Vix::API::VM::GetNumSharedFolders($vm, undef, undef); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_JOB_RESULT_SHARED_FOLDER_COUNT, $num, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err, $num; }; =item B ($err, $flags, $name, $host) = VMGetSharedFolderState($vmHandle, $index); Returns the state of the shared folder at $index. =cut sub VMGetSharedFolderState($$) { my ($vm, $index) = @_; my $err; my $job; my $flags = 0; my $name = undef; my $host = undef; $job = VMware::Vix::API::VM::GetSharedFolderState($vm, $index, undef, undef); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_JOB_RESULT_SHARED_FOLDER_FLAGS, $flags, VIX_PROPERTY_JOB_RESULT_ITEM_NAME, $name, VIX_PROPERTY_JOB_RESULT_SHARED_FOLDER_HOST, $host, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err, $flags, $name, $host; }; =item B $err = VMSetSharedFolderState($vmHandle, $shareName, $hostPathName, $flags); Edits the state of the shared folder. =cut sub VMSetSharedFolderState($$$$) { my ($vm, $shareName, $hostPathName, $flags) = @_; my $err; my $job; $job = VMware::Vix::API::VM::SetSharedFolderState($vm, $shareName, $hostPathName, $flags, undef, undef); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B $err = VMAddSharedFolder($vmHandle, $shareName, $hostPathName, $flags); Adds the shared folder. =cut sub VMAddSharedFolder($$$$) { my ($vm, $shareName, $hostPathName, $flags) = @_; my $err; my $job; $job = VMware::Vix::API::VM::AddSharedFolder($vm, $shareName, $hostPathName, $flags, undef, undef); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B $err = VMRemoveSharedFolder($vmHandle, $shareName, $flags); Removes the shared folder. =cut sub VMRemoveSharedFolder($$$) { my ($vm, $shareName, $flags) = @_; my $err; my $job; $job = VMware::Vix::API::VM::RemoveSharedFolder($vm, $shareName, $flags, undef, undef); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B $err = VMEnableSharedFolders($vmHandle, $enable, $options); Enables shared folders in the vitual machine. $options should be 0. =cut sub VMEnableSharedFolders($$$) { my ($vm, $shareName, $options) = @_; my $err; my $job; $job = VMware::Vix::API::VM::EnableSharedFolders($vm, $shareName, $options, undef, undef); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B ($err, $value) = VMReadVariable($vmHandle, $variableType, $variableName, $options); This will read variables from the virtual machine state. $variableType can be VIX_VM_GUEST_VARIABLE, VIX_VM_CONFIG_RUNTIME_ONLY or VIX_GUEST_ENVIRONMENT_VARIABLE. $variableName is the name of the variable. $options should be 0. =cut sub VMReadVariable($$$$) { my ($vm, $varType, $name, $options) = @_; my $err; my $job; my $value; $job = VMware::Vix::API::VM::ReadVariable($vm, $varType, $name, $options, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_JOB_RESULT_VM_VARIABLE_STRING, $value, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err, $value; }; =item B $err = VMWriteVariable($vmHandle, $variableType, $variableName, $value, $options); This will write variables in the virtual machine state. $variableType can be VIX_VM_GUEST_VARIABLE, VIX_VM_CONFIG_RUNTIME_ONLY or VIX_GUEST_ENVIRONMENT_VARIABLE. $variableName is the name of the variable. $value is the value it the variable will be set to. $options should be 0. =cut sub VMWriteVariable($$$$$) { my ($vm, $varType, $name, $value, $options) = @_; my $err; my $job; $job = VMware::Vix::API::VM::WriteVariable($vm, $varType, $name, $value, $options, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B $err = VMPause($vmHandle, $options, $propertyListHandle); Pauses the replaying of a virtual machine's recording. =cut sub VMPause($$$) { my ($vm, $options, $propertyListHandle) = @_; my $err; my $job; $job = VMware::Vix::API::VM::Pause($vm, $options, $propertyListHandle, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =item B $err = VMUnpause($vmHandle, $options, $propertyListHandle); Resumes replaying a paused a virtual machine's recording. =cut sub VMUnpause($$$) { my ($vm, $options, $propertyListHandle) = @_; my $err; my $job; $job = VMware::Vix::API::VM::Unpause($vm, $options, $propertyListHandle, undef, 0); $err = VMware::Vix::API::Job::Wait($job, VIX_PROPERTY_NONE); VMware::Vix::API::API::ReleaseHandle($job); return $err; }; =head2 Snapshot Functions =item B ($err, $numChildSnapshots) = SnapshotGetNumChildren($snapshotHandle); Returns the number child snapshots of $snapshotHandle. =cut sub SnapshotGetNumChildren($) { my ($snapshot) = @_; my $num = 0; my $err = VMware::Vix::API::Snapshot::GetNumChildren($snapshot, $num); return $err, $num; } =item B ($err, $childSnapshot) = SnapshotGetChild($snapshotHandle, $index); Returns the $index child snapshot of $snapshotHandle. =cut sub SnapshotGetChild($$) { my ($snapshot, $index) = @_; my $child = 0; my $err = VMware::Vix::API::Snapshot::GetChild($snapshot, $index, $child); return $err, $child; } =item B ($err, $parentSnapshot) = SnapshotGetParent($snapshotHandle); Returns the parent snapshot of $snapshotHandle. =cut sub SnapshotGetParent($) { my ($snapshot) = @_; my $parent = 0; my $err = VMware::Vix::API::Snapshot::GetParent($snapshot, $parent); return $err, $parent; } =begin comment This may be useful to anyone that wants to mix Simple with the lower level interfaces, but since Job handles are not exposed by Simple, there are hidden here. Don't forget to put them back in the EXPORT list if you need them. =head2 Handle Property Functions =item B $num = JobGetNumProperties($handle, $propertyID); Returns the number of $propertyID definitions associated with the $handle. This value can be used to build the index used by JobGetNthProperties. =cut sub JobGetNumProperties($$) { my ($handle, $propertyID) = @_; my $num; $num = VMware::Vix::API::Job::GetNumProperties($handle, $propertyID); return $num; } =item B @properties = JobGetNthProperties($handle, $index, $propertyID, ...); Returns the requested property values from $handle at $index. The first element in the return list is an error code. =cut sub JobGetNthProperties($$) { my $handle = shift @_; my $index = shift @_; my $err; my $val = 0; my @retval; push @retval, VIX_OK; if (@_ < 1) { $retval[0] = VIX_E_FAIL; die ("JobGetNthProperties must have at least three arguments\n"); return @retval; } foreach (@_) { my $property = $_; $err = VMware::Vix::API::Job::GetNthProperties($handle, $index, $property, $val, VIX_PROPERTY_NONE); $retval[0] = $err; push @retval, $val; if ($err != VIX_OK) { last; } } return @retval; } =end comment # Autoload methods go after =cut, and are processed by the autosplit program. 1; __END__