pysmbd: Add SMB_ACL_EXECUTE to the mask set by make_simple_acl()
[Samba/gebeck_regimport.git] / source4 / selftest / win / VMHost.pm
blob1f02f21c284a1f02cf7d0316e34a713c6da0e922
1 #!/usr/bin/perl -w
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.
8 # VMware Perl API
9 use VMware::VmPerl;
10 use VMware::VmPerl::VM;
11 use VMware::VmPerl::ConnectParams;
13 # VMware C bindings
14 use VMware::Vix::Simple;
15 use VMware::Vix::API::Constants;
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;
24 my $err_code = 0;
25 my $err_str = "";
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;
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);
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);
52 if ($vm_power_state == VMware::VmPerl::VM_EXECUTION_STATE_OFF
53 || $vm_power_state ==
54 VMware::VmPerl::VM_EXECUTION_STATE_SUSPENDED)
56 if (!$perl_vm->start()) {
57 ($err_code, $err_str) =
58 $perl_vm->get_last_error();
59 return ($err_code);
61 while ($perl_vm->get_tools_last_active() == 0) {
62 sleep(60);
65 return ($err_code);
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) = @_;
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);
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);
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);
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);
126 # Login to $vix_vm guest OS.
127 $err_code = VMware::Vix::Simple::VMLoginInGuest($vix_vm,
128 $guest_admin_username, $guest_admin_password,
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);
138 return ($err_code);
141 sub host_disconnect {
142 undef $perl_vm;
144 $perl_vm = VMware::VmPerl::VM::new();
145 if (!$perl_vm) {
146 $err_code = 1;
147 $err_str = "Error creating new VmPerl object";
150 undef $vix_vm;
151 VMware::Vix::Simple::HostDisconnect($vix_vm_host);
152 VMware::Vix::Simple::ReleaseHandle($vix_vm_host);
153 return ($err_code);
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);
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);
174 return ($err_code);
177 sub create_snapshot {
178 my $snapshot;
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);
185 VMware::Vix::Simple::ReleaseHandle($snapshot);
187 if ($err_code != VMware::Vix::Simple::VIX_OK) {
188 $err_str =
189 VMware::Vix::Simple::GetErrorText($err_code);
190 return $err_code;
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);
200 return ($err_code);
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;
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);
222 return ($err_code);
225 # $dest_path must exist. It doesn't get created.
226 sub copy_files_to_guest {
227 shift @_;
228 my (%files) = @_;
230 my $src_file;
231 my $dest_file;
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;
246 return $err_code;
249 sub copy_to_guest {
250 # Read parameters $src_path, $dest_path.
251 shift @_;
252 my ($src_path, $dest_dir) = @_;
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);
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);
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;
289 foreach $file (readdir DIR_HANDLE) {
290 my $src_file = $src_path . $file;
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);
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;
305 # Add $src_path => $dest_path to %files.
306 $files{$src_path} = $dest_path;
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);
316 return ($err_code);
319 sub run_on_guest {
320 # Read parameters $cmd, $cmd_args.
321 shift @_;
322 my ($cmd, $cmd_args) = @_;
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);
333 return ($err_code);
336 sub get_guest_ip {
337 my $guest_ip = $perl_vm->get_guest_info('ip');
339 if (!defined($guest_ip)) {
340 ($err_code, $err_str) = $perl_vm->get_last_error();
341 return NULL;
344 if (!($guest_ip)) {
345 $err_code = 1;
346 $err_str = "Guest did not set the 'ip' variable";
347 return NULL;
349 return $guest_ip;
352 sub DESTROY {
353 host_disconnect();
354 undef $perl_vm;
355 undef $vix_vm_host;
359 return TRUE;