svn commit: samba r16722 - in branches/SOC/bnh/perl: .
brad at samba.org
brad at samba.org
Sat Jul 1 02:15:53 GMT 2006
Author: brad
Date: 2006-07-01 02:15:52 +0000 (Sat, 01 Jul 2006)
New Revision: 16722
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=16722
Log:
Fixed error handling when working with the vix perl api.
Added functionality to host_connect() function to log into windows as a user.
This allows us to copy files and run commands on the windows vm.
The initial_setup.conf parameters GUEST_ADMIN_USERNAME and GUEST_ADMIN_PASSWORD specify this account.
Added function run_on_guest() to execute programs on the guest vm as the user mentioned above.
Added function copy_to_guest() which takes a local src directory or filename and remote directory as parameters, and creates an associative list of local-remote file paths.
The function passes this list to copy_files_to_guest() to perform the actual copy to the guest vm.
With this update, these scripts can automatically setup a windows guest on vmware server with the only preconfiguration being that vmware tools is installed and the guest os has an ip address configured.
I'll put together a zip file containing the set of scripts needed to make this happen as well as a README file a little later.
Modified:
branches/SOC/bnh/perl/initial_setup.conf
branches/SOC/bnh/perl/vm_setup.pl
Changeset:
Modified: branches/SOC/bnh/perl/initial_setup.conf
===================================================================
--- branches/SOC/bnh/perl/initial_setup.conf 2006-07-01 01:03:27 UTC (rev 16721)
+++ branches/SOC/bnh/perl/initial_setup.conf 2006-07-01 02:15:52 UTC (rev 16722)
@@ -20,8 +20,13 @@
# Where these scripts will be copied from on the unix host.
# I don't know how this will work if the unix host is a different
# system than the vmware server host.
-export LOCAL_SCRIPT_PATH="./windows-scripts"
+export LOCAL_SCRIPT_PATH="./windows-scripts/"
+# In order to copy files and execute programs on the guest vm,
+# we need administrator-level credentials to log in with.
+export GUEST_ADMIN_USERNAME="administrator"
+export GUEST_ADMIN_PASSWORD="adminpass"
+
# These parameters are optional, and change the windows guest
# hostname and workgroup if set.
#export GUEST_HOSTNAME="tortureguest"
Modified: branches/SOC/bnh/perl/vm_setup.pl
===================================================================
--- branches/SOC/bnh/perl/vm_setup.pl 2006-07-01 01:03:27 UTC (rev 16721)
+++ branches/SOC/bnh/perl/vm_setup.pl 2006-07-01 02:15:52 UTC (rev 16722)
@@ -35,6 +35,8 @@
my $username;
my $password;
my $vm_cfg_path;
+ my $guest_admin_username;
+ my $guest_admin_password;
sub error {
my $old_err_code = $err_code;
@@ -45,7 +47,7 @@
}
# Power on the guest if it isn't already running.
- # Returns 0 when the guest is already running, and
+ # Returns 0 when the guest is already running, and
# if not, it waits until it is started.
sub start_guest {
my $vm_power_state = $perl_vm->get_execution_state();
@@ -58,7 +60,7 @@
VMware::VmPerl::VM_EXECUTION_STATE_SUSPENDED)
{
if (!$perl_vm->start()) {
- ($err_code, $err_str) =
+ ($err_code, $err_str) =
$perl_vm->get_last_error();
return ($err_code);
}
@@ -74,10 +76,11 @@
# name of the method. Called locally, this function will lose
# the first parameter.
shift @_;
- ($hostname, $port, $username, $password, $vm_cfg_path) = @_;
+ ($hostname, $port, $username, $password, $vm_cfg_path,
+ $guest_admin_username, $guest_admin_password) = @_;
# Connect to host using vmperl api.
- $perl_vm_credentials =
+ $perl_vm_credentials =
VMware::VmPerl::ConnectParams::new($hostname, $port,
$username, $password);
if (!$perl_vm->connect($perl_vm_credentials, $vm_cfg_path)) {
@@ -94,7 +97,8 @@
$hostname, $port, $username, $password,
0, VMware::Vix::Simple::VIX_INVALID_HANDLE);
if ($err_code != VMware::Vix::Simple::VIX_OK) {
- ($err_code, $err_str) = $vix_vm_host->get_last_error();
+ $err_str =
+ VMware::Vix::Simple::GetErrorText($err_code);
undef $perl_vm;
undef $vix_vm;
undef $vix_vm_host;
@@ -114,15 +118,29 @@
}
# Open VM.
- ($err_code, $vix_vm) =
+ ($err_code, $vix_vm) =
VMware::Vix::Simple::VMOpen($vix_vm_host, $vm_cfg_path);
if ($err_code != VMware::Vix::Simple::VIX_OK) {
- ($err_code, $err_str) = $vix_vm->get_last_error();
+ $err_str =
+ VMware::Vix::Simple::GetErrorText($err_code);
undef $perl_vm;
undef $vix_vm;
undef $vix_vm_host;
return ($err_code);
}
+
+ # Login to $vix_vm guest OS.
+ $err_code = VMware::Vix::Simple::VMLoginInGuest($vix_vm,
+ $guest_admin_username, $guest_admin_password,
+ 0);
+ if ($err_code != VMware::Vix::Simple::VIX_OK) {
+ $err_str =
+ VMware::Vix::Simple::GetErrorText($err_code);
+ undef $perl_vm;
+ undef $vix_vm;
+ undef $vix_vm_host;
+ return ($err_code);
+ }
return ($err_code);
}
@@ -134,7 +152,7 @@
$err_code = 1;
$err_str = "Error creating new VmPerl object";
}
-
+
undef $vix_vm;
VMware::Vix::Simple::HostDisconnect($vix_vm_host);
VMware::Vix::Simple::ReleaseHandle($vix_vm_host);
@@ -151,7 +169,8 @@
}
$err_code = host_connect(NULL, $hostname, $port, $username,
- $password, $vm_cfg_path);
+ $password, $vm_cfg_path, $guest_admin_username,
+ $guest_admin_password);
if ($err_code != 0) {
my $old_err_str = $err_str;
$err_str = "Re-connecting to host failed: " .
@@ -164,7 +183,7 @@
sub create_snapshot {
my $snapshot;
- ($err_code, $snapshot) =
+ ($err_code, $snapshot) =
VMware::Vix::Simple::VMCreateSnapshot($vix_vm,
"Snapshot", "Created by vm_setup.pl", 0,
VMware::Vix::Simple::VIX_INVALID_HANDLE);
@@ -172,7 +191,8 @@
VMware::Vix::Simple::ReleaseHandle($snapshot);
if ($err_code != VMware::Vix::Simple::VIX_OK) {
- ($err_code, $err_str) = $vix_vm->get_last_error();
+ $err_str =
+ VMware::Vix::Simple::GetErrorText($err_code);
return $err_code;
}
@@ -189,17 +209,18 @@
sub revert_snapshot {
my $snapshot;
- # We are passing 0 to VMGetRootSnapshot because we can only
+ # We are passing 0 to VMGetRootSnapshot because we can only
# have one snapshot in vmware server, and it has an id of 0.
- ($err_code, $snapshot) =
+ ($err_code, $snapshot) =
VMware::Vix::Simple::VMGetRootSnapshot($vix_vm, 0);
if ($err_code != VMware::Vix::Simple::VIX_OK) {
- ($err_code, $err_str) = $vix_vm->get_last_error();
+ $err_str =
+ VMware::Vix::Simple::GetErrorText($err_code);
return ($err_code);
}
my $job = VMware::Vix::API::VM::RevertToSnapshot($vix_vm,
- $snapshot, 0,
+ $snapshot, 0,
VMware::Vix::Simple::VIX_INVALID_HANDLE,
undef,0);
@@ -226,17 +247,103 @@
return ($err_code);
}
+ # $dest_path must exist. It doesn't get created.
+ sub copy_files_to_guest {
+ shift @_;
+ my (%files) = @_;
+
+ my $src_file;
+ my $dest_file;
+
+ foreach $src_file (keys(%files)) {
+ $dest_file = $files{$src_file};
+ $err_code =
+ VMware::Vix::Simple::VMCopyFileFromHostToGuest(
+ $vix_vm, $src_file, $dest_file, 0,
+ VMware::Vix::Simple::VIX_INVALID_HANDLE);
+ if ($err_code != VMware::Vix::Simple::VIX_OK) {
+ $err_str = "Copying $src_file: " .
+ VMware::Vix::Simple::GetErrorText(
+ $err_code);
+ return $err_code;
+ }
+ }
+ return $err_code;
+ }
+
sub copy_to_guest {
- $err_code = -1;
- $err_str = "Function copy_to_guest() is not yet implemented";
+ # Read parameters $src_path, $dest_path.
+ shift @_;
+ my ($src_path, $dest_dir) = @_;
+ my $len = length($dest_dir);
+ my $idx = rindex($dest_dir, '\\');
+ if ($idx != ($len - 1)) {
+ $err_code = -1;
+ $err_str = "Destination $dest_dir must be a " .
+ "directory path";
+ return ($err_code);
+ }
+
+ # If $src_filepath specifies a file, create it in $dest_path
+ # and keep the same name.
+ # If $src_path is a directory, create the files it contains in
+ # $dest_path, keeping the same names.
+ $len = length($src_path);
+ my %files;
+ $idx = rindex($src_path, '/');
+ if ($idx == ($len - 1)) {
+ # $src_path is a directory.
+ if (!opendir (DIR_HANDLE, $src_path)) {
+ $err_code = -1;
+ $err_str = "Error opening directory $src_path";
+ return $err_code;
+ }
+
+ foreach $file (readdir DIR_HANDLE) {
+ my $src_file = $src_path . $file;
+
+ if (!opendir(DIR_HANDLE2, $src_file)) {
+ # We aren't interested in subdirs.
+ my $dest_path = $dest_dir . $file;
+ $files{$src_file} = $dest_path;
+ } else {
+ closedir(DIR_HANDLE2);
+ }
+ }
+ } else {
+ # Strip if preceeding path from $src_path.
+ my $src_file = substr($src_path, ($idx + 1), $len);
+ my $dest_path = $dest_dir . $src_file;
+
+ # Add $src_path => $dest_path to %files.
+ $files{$src_path} = $dest_path;
+ }
+
+ $err_code = copy_files_to_guest(NULL, %files);
+ if ($err_code != 0) {
+ my $old_err_str = $err_str;
+ $err_str = "Copying files to host after " .
+ "populating %files: " . $old_err_str;
+ return ($err_code);
+ }
return ($err_code);
}
sub run_on_guest {
- $err_code = -1;
- $err_str = "Function run_on_guest() is not yet implemented";
+ # Read parameters $cmd, $cmd_args.
+ shift @_;
+ my ($cmd, $cmd_args) = @_;
+ $err_code = VMware::Vix::Simple::VMRunProgramInGuest($vix_vm,
+ $cmd, $cmd_args, 0,
+ VMware::Vix::Simple::VIX_INVALID_HANDLE);
+ if ($err_code != VMware::Vix::Simple::VIX_OK) {
+ $err_str = VMware::Vix::Simple::GetErrorText(
+ $err_code);
+ return ($err_code);
+ }
+
return ($err_code);
}
@@ -286,6 +393,9 @@
my $host_username = $ENV{'HOST_USERNAME'};
my $host_password = $ENV{'HOST_PASSWORD'};
+my $guest_admin_username = $ENV{'GUEST_ADMIN_USERNAME'};
+my $guest_admin_password = $ENV{'GUEST_ADMIN_PASSWORD'};
+
my $guest_username = $ENV{'GUEST_USERNAME'};
my $guest_password = $ENV{'GUEST_PASSWORD'};
my $guest_hostname = $ENV{'GUEST_HOSTNAME'};
@@ -295,7 +405,8 @@
my $vm = VMHost;
$vm->host_connect($host_server_name, $host_server_port, $host_username,
- $host_password, $vm_cfg_path);
+ $host_password, $vm_cfg_path, $guest_admin_username,
+ $guest_admin_password);
check_error($vm, "Error in \$vm->connect().\n");
print "Connected successfully to VM.\n";
@@ -309,15 +420,26 @@
print "Snapshot creation has started.\n";
# Copy the windows setup scripts to the VM.
-$vm->copy_to_guest($local_script_path,$guest_script_path);
+$vm->copy_to_guest($local_script_path, $guest_script_path);
check_error($vm, "Error in \$vm->copy_to_guest().\n");
print "Windows setup scripts have been copied to the VM.\n";
-# Run win_setup.wsh on the VM.
-$cmd = "cscript $guest_script_path win_setup.wsf /username:$guest_username" .
- "/password: $guest_password";
-$vm->run_on_guest($cmd);
-check_error($vm, "Error in \$vm->run_on_guest() executing " . $cmd . ".\n");
+# Run win_setup.wsf on the VM.
+$cmd = "C:\\WINDOWS\\system32\\cscript.exe ";
+$cmd_args = $guest_script_path . "win_setup.wsf /username:" .
+ $guest_username . " /password:" . $guest_password;
+
+if ($guest_hostname) {
+ $cmd_args = $cmd_args . " /hostname:" . $guest_hostname;
+}
+
+if ($guest_workgroup) {
+ $cmd_args = $cmd_args . " /workgroup:" . $guest_workgroup;
+}
+
+$vm->run_on_guest($cmd, $cmd_args);
+check_error($vm, "Error in \$vm->run_on_guest() while executing: " .
+ $cmd . $cmd_args . ".\n");
print "Windows setup scripts have been successfully executed on the VM.\n";
# Destroy the vm object and disconnect from the vm.
More information about the samba-cvs
mailing list