1#!/usr/local/bin/perl 2# External STONITH module for VMWare Server Guests 3# 4# Copyright (c) 2004 SUSE LINUX AG - Andrew Beekhof <abeekhof@suse.de> 5# 6# This program is free software; you can redistribute it and/or modify 7# it under the terms of version 2 of the GNU General Public License as 8# published by the Free Software Foundation. 9# 10# This program is distributed in the hope that it would be useful, but 11# WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13# 14# Further, this software is distributed without any warranty that it is 15# free of the rightful claim of any third person regarding infringement 16# or the like. Any license provided herein, whether implied or 17# otherwise, applies only to this software file. Patent licenses, if 18# any, provided herein do not apply to combinations of this program with 19# other software, or any other product whatsoever. 20# 21# You should have received a copy of the GNU General Public License 22# along with this program; if not, write the Free Software Foundation, 23# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 24# 25 26sub supply_default 27{ 28 my $name = $_[0]; 29 my $value = $_[1]; 30 31 if ( defined $ENV{$name} ) { 32 #print "Set: $name=$ENV{$name}\n"; 33 } else { 34 $ENV{$name} = $value; 35 #print "Default: $name=$ENV{$name}\n"; 36 } 37} 38 39sub vmware_command 40{ 41 my $config = $_[0]; 42 my $action = $_[1]; 43 my @lines; 44 45 my $device = $ENV{'device_host'}; 46 47 if ( $device =~ /localhost/ ) { 48 @lines = readpipe "vmware-cmd $config $action"; 49 50 } else { 51 @lines = readpipe "ssh $device \"vmware-cmd \\\"$config\\\" $action\""; 52 } 53 54 #print @lines; 55 return @lines; 56} 57 58sub is_host_active 59{ 60 my $config = config_for_host($_[0]); 61 my @lines = vmware_command($config, "getstate"); 62 foreach $line (@lines) { 63 if ( $line =~ /getstate.* = on/ ) { 64 return 1; 65 } 66 } 67 return 0; 68} 69 70sub supported_hosts 71{ 72 my $line; 73 my @lines; 74 75 if ( defined $ENV{'host_map'} ) { 76 @lines = split(/;/, $ENV{'host_map'}); 77 foreach $line (@lines){ 78 @config = split(/=/, $line); 79 $host = $config[0]; 80 if ( is_host_active($host) == 1 ) { 81 print "$host\n"; 82 } 83 } 84 85 } else { 86 @lines = vmware_command("-l"); 87 foreach $line (@lines){ 88 my @elements = split(/\//, $line); 89 $host = $elements[$#elements-1]; 90 if ( is_host_active($host) == 1 ) { 91 print "$host\n"; 92 } 93 } 94 } 95} 96 97sub config_for_host 98{ 99 my $line; 100 my @lines; 101 my $target = $_[0]; 102 103 if ( defined $ENV{'host_map'} ) { 104 @lines = split(/;/, $ENV{'host_map'}); 105 foreach $line (@lines){ 106 if ( $line =~ /^$target=/ ) { 107 @config = split(/=/, $line); 108 return $config[1]; 109 } 110 } 111 112 } else { 113 @lines = vmware_command("-l"); 114 115 foreach $line (@lines){ 116 if ( $line =~ /\/$target\// ) { 117 chop($line); 118 return $line; 119 } 120 } 121 } 122} 123 124$command = $ARGV[0]; 125if ( defined $ARGV[1] ) { 126 $targetHost = $ARGV[1]; 127} 128 129supply_default("device_host", "localhost"); 130 131if ( $command =~ /^gethosts$/ ) { 132 supported_hosts; 133 134} elsif ( $command =~ /^getconfignames$/ ) { 135 print "device_host\n"; 136 137} elsif ( $command =~ /^getinfo-devid$/ ) { 138 print "VMware Server STONITH device\n"; 139} elsif ( $command =~ /^getinfo-devname$/ ) { 140 print "VMware Server STONITH device\n"; 141} elsif ( $command =~ /^getinfo-devdescr$/ ) { 142 print "VMware Server STONITH device\n"; 143} elsif ( $command =~ /^getinfo-devurl$/ ) { 144 print "http://www.vmware.com/"; 145 146} elsif ( $command =~ /^on$/ ) { 147 $config = config_for_host($targetHost); 148 my @lines = vmware_command($config, "start hard"); 149 print @lines; 150 151} elsif ( $command =~ /^off$/ ) { 152 $config = config_for_host($targetHost); 153 my @lines = vmware_command($config, "stop hard"); 154 print @lines; 155 156} elsif ( $command =~ /^reset$/ ) { 157 $config = config_for_host($targetHost); 158 my @lines = vmware_command($config, "reset hard"); 159 print @lines; 160 161} elsif ( $command =~ /^status$/ ) { 162 my $rc = 7; 163 my $device = $ENV{'device_host'}; 164 if ( $device =~ /localhost/ ) { 165 $rc = 0; 166 # TODO: Check for the vmware process 167 print "Local version: always running\n"; 168 169 } else { 170 print "Remote version: running ping\n"; 171 @lines = readpipe "ping -c1 $device"; 172 print @lines; 173 174 foreach $line ( @lines ) { 175 if ( $line =~ /0% packet loss/ ) { 176 $rc = 0; 177 last; 178 } 179 } 180 } 181 exit($rc); 182 183} elsif ( $command =~ /^getinfo-xml$/ ) { 184 $metadata = <<END; 185<parameters> 186<parameter name="host_map" unique="0" required="0"> 187<content type="string" /> 188<shortdesc lang="en"> 189Host Map 190</shortdesc> 191<longdesc lang="en"> 192A mapping of hostnames to config paths supported by this device. 193Eg. host1=/config/path/1;host2=/config/path/2;host3=/config/path/3; 194</longdesc> 195</parameter> 196<parameter name="device_host" unique="0" required="0"> 197<content type="string" /> 198<shortdesc lang="en"> 199Device Host 200</shortdesc> 201<longdesc lang="en"> 202The machine _hosting_ the virtual machines 203</longdesc> 204</parameter> 205</parameters> 206END 207 208print $metadata; 209 210} else { 211 print "Command $command: not supported\n"; 212 exit(3); # Not implemented 213} 214 215 216exit(0); 217