• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/source4/selftest/win/
1#!/usr/bin/perl -w
2
3# A perl object to provide a simple, unified method of handling some
4# VMware Server VM management functions using the perl and VIX API's.
5# Copyright Brad Henry <brad@samba.org> 2006
6# Released under the GNU GPL version 3 or later.
7
8# VMware Perl API
9use VMware::VmPerl;
10use VMware::VmPerl::VM;
11use VMware::VmPerl::ConnectParams;
12
13# VMware C bindings
14use VMware::Vix::Simple;
15use VMware::Vix::API::Constants;
16
17# Create a class to abstract from the Vix and VMPerl APIs.
18{ package VMHost;
19	my $perl_vm = VMware::VmPerl::VM::new();
20	my $perl_vm_credentials;
21	my $vix_vm;
22	my $vix_vm_host;
23
24	my $err_code = 0;
25	my $err_str = "";
26
27	my $hostname;
28	my $port;
29	my $username;
30	my $password;
31	my $vm_cfg_path;
32	my $guest_admin_username;
33	my $guest_admin_password;
34
35	sub error {
36		my $old_err_code = $err_code;
37		my $old_err_str = $err_str;
38		$err_code = 0;
39		$err_str = "";
40		return ($old_err_code, $old_err_str);
41	}
42
43	# Power on the guest if it isn't already running.
44	# Returns 0 when the guest is already running, and
45	# if not, it waits until it is started.
46	sub start_guest {
47		my $vm_power_state = $perl_vm->get_execution_state();
48		if (!defined($vm_power_state)) {
49			($err_code, $err_str) = $perl_vm->get_last_error();
50			return ($err_code);
51		}
52		if ($vm_power_state == VMware::VmPerl::VM_EXECUTION_STATE_OFF
53			|| $vm_power_state ==
54				VMware::VmPerl::VM_EXECUTION_STATE_SUSPENDED)
55		{
56			if (!$perl_vm->start()) {
57				($err_code, $err_str) =
58					$perl_vm->get_last_error();
59				return ($err_code);
60			}
61			while ($perl_vm->get_tools_last_active() == 0) {
62				sleep(60);
63			}
64		}
65		return ($err_code);
66	}
67
68	sub host_connect {
69		# When called as a method, the first parameter passed is the
70		# name of the method. Called locally, this function will lose
71		# the first parameter.
72		shift @_;
73		($hostname, $port, $username, $password, $vm_cfg_path,
74			$guest_admin_username, $guest_admin_password) = @_;
75
76		# Connect to host using vmperl api.
77		$perl_vm_credentials =
78			VMware::VmPerl::ConnectParams::new($hostname, $port,
79				$username, $password);
80		if (!$perl_vm->connect($perl_vm_credentials, $vm_cfg_path)) {
81			($err_code, $err_str) = $perl_vm->get_last_error();
82			undef $perl_vm;
83			return ($err_code);
84		}
85
86		# Connect to host using vix api.
87		($err_code, $vix_vm_host) =
88			VMware::Vix::Simple::HostConnect(
89				VMware::Vix::Simple::VIX_API_VERSION,
90				VMware::Vix::Simple::VIX_SERVICEPROVIDER_VMWARE_SERVER,
91				$hostname, $port, $username, $password,
92				0, VMware::Vix::Simple::VIX_INVALID_HANDLE);
93		if ($err_code != VMware::Vix::Simple::VIX_OK) {
94			$err_str =
95				VMware::Vix::Simple::GetErrorText($err_code);
96			undef $perl_vm;
97			undef $vix_vm;
98			undef $vix_vm_host;
99			return ($err_code);
100		}
101
102		# Power on our guest os if it isn't already running.
103		$err_code = start_guest();
104		if ($err_code != 0) {
105			my $old_err_str = $err_str;
106			$err_str = "Starting guest power after connect " .
107					"failed: " . $old_err_str;
108			undef $perl_vm;
109			undef $vix_vm;
110			undef $vix_vm_host;
111			return ($err_code);
112		}
113
114		# Open VM.
115		($err_code, $vix_vm) =
116			VMware::Vix::Simple::VMOpen($vix_vm_host, $vm_cfg_path);
117		if ($err_code != VMware::Vix::Simple::VIX_OK) {
118			$err_str =
119				VMware::Vix::Simple::GetErrorText($err_code);
120			undef $perl_vm;
121			undef $vix_vm;
122			undef $vix_vm_host;
123			return ($err_code);
124		}
125
126		# Login to $vix_vm guest OS.
127		$err_code = VMware::Vix::Simple::VMLoginInGuest($vix_vm,
128				$guest_admin_username, $guest_admin_password,
129				0);
130		if ($err_code != VMware::Vix::Simple::VIX_OK) {
131			$err_str =
132				VMware::Vix::Simple::GetErrorText($err_code);
133			undef $perl_vm;
134			undef $vix_vm;
135			undef $vix_vm_host;
136			return ($err_code);
137		}
138		return ($err_code);
139	}
140
141	sub host_disconnect {
142		undef $perl_vm;
143
144		$perl_vm = VMware::VmPerl::VM::new();
145		if (!$perl_vm) {
146			$err_code = 1;
147			$err_str = "Error creating new VmPerl object";
148		}
149
150		undef $vix_vm;
151		VMware::Vix::Simple::HostDisconnect($vix_vm_host);
152		VMware::Vix::Simple::ReleaseHandle($vix_vm_host);
153		return ($err_code);
154	}
155
156	sub host_reconnect {
157		$err_code = host_disconnect();
158		if ($err_code != 0) {
159			my $old_err_str = $err_str;
160			$err_str = "Disconnecting from host failed: " .
161					$old_err_str;
162			return ($err_code);
163		}
164
165		$err_code = host_connect(NULL, $hostname, $port, $username,
166				$password, $vm_cfg_path, $guest_admin_username,
167				$guest_admin_password);
168		if ($err_code != 0) {
169			my $old_err_str = $err_str;
170			$err_str = "Re-connecting to host failed: " .
171					$old_err_str;
172			return ($err_code);
173		}
174		return ($err_code);
175	}
176
177	sub create_snapshot {
178		my $snapshot;
179
180		($err_code, $snapshot) =
181			VMware::Vix::Simple::VMCreateSnapshot($vix_vm,
182			"Snapshot", "Created by vm_setup.pl", 0,
183			VMware::Vix::Simple::VIX_INVALID_HANDLE);
184
185		VMware::Vix::Simple::ReleaseHandle($snapshot);
186
187		if ($err_code != VMware::Vix::Simple::VIX_OK) {
188			$err_str =
189				VMware::Vix::Simple::GetErrorText($err_code);
190			return $err_code;
191		}
192
193		$err_code = host_reconnect();
194		if ($err_code != 0) {
195			my $old_err_str = $err_str;
196			$err_str = "Reconnecting to host after creating " .
197					"snapshot: " . $old_err_str;
198			return ($err_code);
199		}
200		return ($err_code);
201	}
202
203	sub revert_snapshot {
204		# Because of problems with VMRevertToSnapshot(), we have to
205		# rely on the guest having set 'Revert to Snapshot' following
206		# a power-off event.
207		$err_code = VMware::Vix::Simple::VMPowerOff($vix_vm, 0);
208		if ($err_code != VMware::Vix::Simple::VIX_OK) {
209			$err_str =
210				VMware::Vix::Simple::GetErrorText($err_code);
211			return $err_code;
212		}
213
214		# host_reconnect() will power-on a guest in a non-running state.
215		$err_code = host_reconnect();
216		if ($err_code != 0) {
217			my $old_err_str = $err_str;
218			$err_str = "Reconnecting to host after reverting " .
219					"snapshot: " . $old_err_str;
220			return ($err_code);
221		}
222		return ($err_code);
223	}
224
225	# $dest_path must exist. It doesn't get created.
226	sub copy_files_to_guest {
227		shift @_;
228		my (%files) = @_;
229
230		my $src_file;
231		my $dest_file;
232
233		foreach $src_file (keys(%files)) {
234			$dest_file = $files{$src_file};
235			$err_code =
236				VMware::Vix::Simple::VMCopyFileFromHostToGuest(
237					$vix_vm, $src_file, $dest_file, 0,
238					VMware::Vix::Simple::VIX_INVALID_HANDLE);
239			if ($err_code != VMware::Vix::Simple::VIX_OK) {
240				$err_str = "Copying $src_file: " .
241					VMware::Vix::Simple::GetErrorText(
242						$err_code);
243				return $err_code;
244			}
245		}
246		return $err_code;
247	}
248
249	sub copy_to_guest {
250		# Read parameters $src_path, $dest_path.
251		shift @_;
252		my ($src_path, $dest_dir) = @_;
253
254		my $len = length($dest_dir);
255		my $idx = rindex($dest_dir, '\\');
256		if ($idx != ($len - 1)) {
257			$err_code = -1;
258			$err_str = "Destination $dest_dir must be a " .
259					"directory path";
260			return ($err_code);
261		}
262
263		# Create the directory $dest_path on the guest VM filesystem.
264		my $cmd = "cmd.exe ";
265		my $cmd_args = "/C MKDIR " . $dest_dir;
266		$err_code = run_on_guest(NULL, $cmd, $cmd_args);
267		if ( $err_code != 0) {
268			my $old_err_str = $err_str;
269			$err_str = "Creating directory $dest_dir on host: " .
270					$old_err_str;
271			return ($err_code);
272		}
273
274		# If $src_filepath specifies a file, create it in $dest_path
275		# and keep the same name.
276		# If $src_path is a directory, create the files it contains in
277		# $dest_path, keeping the same names.
278		$len = length($src_path);
279		my %files;
280		$idx = rindex($src_path, '/');
281		if ($idx == ($len - 1)) {
282			# $src_path is a directory.
283			if (!opendir (DIR_HANDLE, $src_path)) {
284				$err_code = -1;
285				$err_str = "Error opening directory $src_path";
286				return $err_code;
287			}
288
289			foreach $file (readdir DIR_HANDLE) {
290				my $src_file = $src_path . $file;
291
292				if (!opendir(DIR_HANDLE2, $src_file)) {
293					# We aren't interested in subdirs.
294					my $dest_path = $dest_dir . $file;
295					$files{$src_file} = $dest_path;
296				} else {
297					closedir(DIR_HANDLE2);
298				}
299			}
300		} else {
301			# Strip if preceeding path from $src_path.
302			my $src_file = substr($src_path, ($idx + 1), $len);
303			my $dest_path = $dest_dir . $src_file;
304
305			# Add $src_path => $dest_path to %files.
306			$files{$src_path} = $dest_path;
307		}
308
309		$err_code = copy_files_to_guest(NULL, %files);
310		if ($err_code != 0) {
311			my $old_err_str = $err_str;
312			$err_str = "Copying files to host after " .
313				"populating %files: " . $old_err_str;
314			return ($err_code);
315		}
316		return ($err_code);
317	}
318
319	sub run_on_guest {
320		# Read parameters $cmd, $cmd_args.
321		shift @_;
322		my ($cmd, $cmd_args) = @_;
323
324		$err_code = VMware::Vix::Simple::VMRunProgramInGuest($vix_vm,
325				$cmd, $cmd_args, 0,
326				VMware::Vix::Simple::VIX_INVALID_HANDLE);
327		if ($err_code != VMware::Vix::Simple::VIX_OK) {
328			$err_str = VMware::Vix::Simple::GetErrorText(
329					$err_code);
330			return ($err_code);
331		}
332
333		return ($err_code);
334	}
335
336	sub get_guest_ip {
337		my $guest_ip = $perl_vm->get_guest_info('ip');
338
339		if (!defined($guest_ip)) {
340			($err_code, $err_str) = $perl_vm->get_last_error();
341			return NULL;
342		}
343
344		if (!($guest_ip)) {
345			$err_code = 1;
346			$err_str = "Guest did not set the 'ip' variable";
347			return NULL;
348		}
349		return $guest_ip;
350	}
351
352	sub DESTROY {
353		host_disconnect();
354		undef $perl_vm;
355		undef $vix_vm_host;
356	}
357}
358
359return TRUE;
360