~ubuntu-branches/ubuntu/maverick/cluster-agents/maverick-proposed

« back to all changes in this revision

Viewing changes to heartbeat/vmware

  • Committer: Bazaar Package Importer
  • Author(s): Ante Karamatic
  • Date: 2010-02-17 21:46:00 UTC
  • Revision ID: james.westby@ubuntu.com-20100217214600-g44grvtkw7jbpciz
Tags: upstream-1.0.2
ImportĀ upstreamĀ versionĀ 1.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/bin/sh
 
2
#
 
3
# VMware OCF resource agent
 
4
#
 
5
# Copyright (c) 2008 Apra Sistemi s.r.l.
 
6
#                    All Rights Reserved.
 
7
#
 
8
# Description:  Manages a VMware server 2.0 as a High-Availability
 
9
#               resource
 
10
#
 
11
#
 
12
# Author:       Cristian Mammoli <c.mammoli AT apra DOT it>
 
13
# License:      GNU General Public License (GPL)
 
14
# Copyright:    (C) 2008 Apra Sistemi s.r.l.
 
15
#
 
16
# See usage() function below for more details...
 
17
#
 
18
# OCF instance parameters:
 
19
#  * OCF_RESKEY_VMXPATH (mandatory, full path to the virtual machine vmx file)
 
20
#  * OCF_RESKEY_VIMSHBIN (mandatory, full path to th vmware-vim-cmd executable)
 
21
#
 
22
# Requirements/caveats:
 
23
#  * vmware-server 2.0 RC1 installed and autostarted on all nodes
 
24
#  * vmdk files must be in the same directory of the vmx file
 
25
#  * vmx filenames must be unique, even if stored in different directories
 
26
#  * Default_Action_Timeout stock value (20 sec) isn't enough if you are
 
27
#    dealing with many virtual machines: raise it to something around 300 secs
 
28
#    or use operation attributes with the proposed values
 
29
 
 
30
# Initialization
 
31
#################################################################
 
32
 
 
33
# Source ocf shell functions
 
34
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
 
35
. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs
 
36
 
 
37
# Basic variables configuration
 
38
#################################################################
 
39
 
 
40
# Path to the virtual machine configuration file
 
41
VMXPATH="$OCF_RESKEY_vmxpath"
 
42
 
 
43
# Path to the vmware-vim-cmd executable
 
44
VIMSHBIN="$OCF_RESKEY_vimshbin"
 
45
 
 
46
# global variables
 
47
VMXDIR=
 
48
RELVMXPATH=
 
49
VMID=
 
50
VM=
 
51
VMAUTOMSG=
 
52
 
 
53
# vmware-vim-cmd functions
 
54
#################################################################
 
55
 
 
56
# Get virtual machine vid
 
57
vmware_get_vid() {
 
58
  $VIMSHBIN vmsvc/getallvms 2>/dev/null \
 
59
         | awk '/\/'"$1"'/ {print $1}'
 
60
}
 
61
 
 
62
# Is the vm waiting for input after a migration?
 
63
vmware_uuid_alt() {
 
64
  $VIMSHBIN vmsvc/message $1 2>/dev/null \
 
65
         | awk /^msg.uuid.altered/
 
66
}
 
67
 
 
68
# Get message id
 
69
vmware_get_msgid() {
 
70
  $VIMSHBIN vmsvc/message $1 2>/dev/null \
 
71
         | awk '/^Virtual machine message/ {print $4}' \
 
72
     | awk -F : '{print $1}'
 
73
}
 
74
 
 
75
# Answers message
 
76
vmware_answer_msg() {
 
77
  $VIMSHBIN vmsvc/message $1 $2 $3 >/dev/null 2>&1
 
78
}
 
79
 
 
80
# Register a virtual machine
 
81
vmware_register_vm() {
 
82
  $VIMSHBIN solo/registervm '"'$1'"' >/dev/null 2>&1
 
83
}
 
84
 
 
85
# Unregister a virtual machine
 
86
vmware_unregister_vm() {
 
87
  $VIMSHBIN  vmsvc/unregister $1 >/dev/null 2>&1
 
88
}
 
89
 
 
90
# Start a virtual machine
 
91
vmware_poweron_vm() {
 
92
  $VIMSHBIN vmsvc/power.on $1 >/dev/null 2>&1
 
93
}
 
94
 
 
95
# Suspend a virtual machine
 
96
vmware_suspend_vm() {
 
97
  $VIMSHBIN vmsvc/power.suspend $1 >/dev/null 2>&1
 
98
}
 
99
 
 
100
# Get virtual machine power state
 
101
vmware_get_status() {
 
102
  $VIMSHBIN vmsvc/power.getstate $1 2>/dev/null \
 
103
         | awk '/^Powered on/ || /^Powered off/ || /^Suspended/'
 
104
}
 
105
 
 
106
# Get vid of missing virtual machines
 
107
vmware_get_broken() {
 
108
  $VIMSHBIN vmsvc/getallvm 2>&1 \
 
109
         | awk -F "'" '/^Skipping/ {print $2}'
 
110
}
 
111
 
 
112
# Variables depending on the above functions
 
113
#################################################################
 
114
 
 
115
set_environment() {
 
116
        # Directory containing the virtual machine
 
117
        VMXDIR="`dirname "$VMXPATH"`"
 
118
 
 
119
        # Basename of the configuration file
 
120
        RELVMXPATH="`basename "$VMXPATH"`"
 
121
 
 
122
        # Vid of the virtual machine (can be empty if the vm is not registered)
 
123
        VMID=`vmware_get_vid "$RELVMXPATH"`
 
124
 
 
125
        # Virtual machine name
 
126
        VM="`awk -F '"' '/^displayName/ {print $2}' "$VMXPATH"`"
 
127
 
 
128
        # msg.autoAnswer value in config file
 
129
        VMAUTOMSG="`awk -F '"' '/^msg.autoAnswer/ {print $2}' "$VMXPATH"`"
 
130
}
 
131
 
 
132
# Main functions
 
133
#################################################################
 
134
 
 
135
# Print usage summary
 
136
vmware_usage() {
 
137
    cat <<END
 
138
usage: $0 {start|stop|status|monitor|meta-data|validate-all}
 
139
 
 
140
Expects to have a fully populated OCF RA-compliant environment set.
 
141
END
 
142
}
 
143
 
 
144
# Check for dependencies
 
145
# Check for mandatory files presence and consistency
 
146
vmware_validate() {
 
147
  if [ -z "`pidof vmware-hostd`" ]; then
 
148
    ocf_log warn "vmware-hostd is not running"
 
149
    return $OCF_ERR_GENERIC
 
150
  fi
 
151
 
 
152
  if [ ! -x "$VIMSHBIN" ]; then
 
153
    ocf_log warn "vmware-vimsh executable missing or not in path ($VIMSHBIN)"
 
154
    return $OCF_ERR_INSTALLED
 
155
  fi
 
156
 
 
157
  if [ ! -f "$VMXPATH" ]; then
 
158
    ocf_log warn "Specified vmx file ($VMXPATH) does not exist"
 
159
    return $OCF_ERR_ARGS
 
160
  fi
 
161
 
 
162
  if [ -z "$VM" ]; then
 
163
    ocf_log warn "Could not find out virtual machine name"
 
164
    return $OCF_ERR_ARGS
 
165
  fi
 
166
 
 
167
  if [ "$VMAUTOMSG" != "TRUE" ]; then
 
168
    ocf_log warn "Please set msg.autoAnswer = \"TRUE\" in your config file"
 
169
  fi
 
170
 
 
171
  # $VMID is allowed to be empty in case we are validating a
 
172
  # virtual machine which is not registered
 
173
 
 
174
  return $OCF_SUCCESS
 
175
}
 
176
 
 
177
# Start a virtual machine
 
178
vmware_start() {
 
179
  # Don't start a VM if it's already running
 
180
  if vmware_monitor; then
 
181
    ocf_log info "Virtual machine $VM is already running"
 
182
    return $OCF_SUCCESS
 
183
  else
 
184
    # Removes stale lockfiles and missing virtual machines
 
185
    # in case of a crash.
 
186
    # Do not use with a clustered filesystem or you could
 
187
    # end up starting the same VM in more than one node
 
188
    ocf_log info "Removing stale lockfiles"
 
189
    find "$VMXDIR" -name \*.lck -type f -exec rm "{}" \;
 
190
    for BVM in `vmware_get_broken`; do
 
191
      ocf_log info "Unregistering missing virtual machine $BVM"
 
192
      vmware_unregister_vm $BVM
 
193
    done
 
194
    if [ -z "$VMID" ]; then
 
195
      # VM is not registered, need to register
 
196
      ocf_log info "Virtual machine $VM is not registered"
 
197
      ocf_log info "Registering Virtual machine $VM"
 
198
      vmware_register_vm "$VMXPATH"
 
199
      VMID=`vmware_get_vid "$RELVMXPATH"`
 
200
      if [ -z "$VMID" ]; then
 
201
        ocf_log err "Could not register virtual machine $VM: aborting."
 
202
        exit $OCF_ERR_GENERIC
 
203
      fi
 
204
      ocf_log info "Virtual machine $VM registered with ID $VMID"
 
205
    fi
 
206
    ocf_log info "Powering on virtual machine $VM"
 
207
    vmware_poweron_vm $VMID
 
208
    # Give the VM some time to initialize
 
209
    sleep 10
 
210
 
 
211
    if [ "$VMAUTOMSG" != "TRUE" ]; then
 
212
      # msg.autoAnswer is not set: we try to deal with the
 
213
      # most common question: msg.uuid.altered
 
214
      ocf_log info  "Checking msg.uuid.altered on VM $VM"
 
215
      if [ -n "`vmware_uuid_alt $VMID`" ]; then
 
216
        MSGID=`vmware_get_msgid $VMID`
 
217
        vmware_answer_msg $VMID $MSGID 2
 
218
      fi
 
219
    fi
 
220
 
 
221
    # Check if the VM is running. We don't bother
 
222
    # with timeouts: we rely on the CRM for that.
 
223
    while :; do
 
224
          vmware_monitor && break
 
225
      ocf_log info "Virtual machine $VM is still stopped: delaying 10 seconds"
 
226
      sleep 10
 
227
    done
 
228
 
 
229
    ocf_log info "Virtual machine $VM is running"
 
230
    return $OCF_SUCCESS
 
231
  fi
 
232
}
 
233
 
 
234
# Stop a virtual machine
 
235
vmware_stop() {
 
236
  # Don't stop a VM if it's not registered
 
237
  if [ -z "$VMID" ]; then
 
238
    ocf_log info "Virtual machine $VM is not registered"
 
239
    return $OCF_SUCCESS
 
240
  else
 
241
    # Don't stop a VM if it's already stopped
 
242
    if vmware_monitor; then
 
243
      # If the VM is running send a suspend signal and wait
 
244
      # until it is off. We don't bother with timeouts: we
 
245
      # rely on the CRM for that.
 
246
      ocf_log info "Virtual machine $VM is running: suspending it"
 
247
      vmware_suspend_vm $VMID
 
248
      sleep 5
 
249
      while vmware_monitor; do
 
250
        ocf_log info "Virtual machine $VM is still running: delaying 10 seconds"
 
251
        sleep 10
 
252
      done
 
253
    else
 
254
      ocf_log info "Virtual machine $VM is already stopped"
 
255
    fi
 
256
    ocf_log info "Unregistering virtual machine $VM"
 
257
    vmware_unregister_vm $VMID
 
258
    VMID=`vmware_get_vid "$RELVMXPATH"`
 
259
    if [ -n "$VMID" ]; then
 
260
      ocf_log err "Could not unregister virtual machine $VM: aborting."
 
261
      exit $OCF_ERR_GENERIC
 
262
    fi
 
263
    ocf_log info "Virtual machine $VM is stopped"
 
264
    return $OCF_SUCCESS
 
265
  fi
 
266
}
 
267
 
 
268
# Monitor a virtual machine
 
269
vmware_monitor() {
 
270
  if [ "`vmware_get_status $VMID`" = "Powered on" ]; then
 
271
    ocf_log debug "Virtual machine $VM (ID $VMID) is running..."
 
272
    return $OCF_SUCCESS
 
273
  else
 
274
    ocf_log debug "Virtual machine $VM is stopped/suspended/not registered"
 
275
    return $OCF_NOT_RUNNING
 
276
  fi
 
277
}
 
278
 
 
279
# Print metadata informations
 
280
meta_data() {
 
281
    cat <<END
 
282
<?xml version="1.0"?>
 
283
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
 
284
<resource-agent name="vmware">
 
285
<version>0.1</version>
 
286
<longdesc lang="en">
 
287
OCF compliant script to control vmware server 2.0 virtual machines.
 
288
</longdesc>
 
289
<shortdesc lang="en">Manages VMWare Server 2.0 virtual machines</shortdesc>
 
290
 
 
291
<parameters>
 
292
<parameter name="vmxpath" unique="0" required="1">
 
293
<longdesc lang="en">
 
294
VMX configuration file path
 
295
</longdesc>
 
296
<shortdesc lang="en">VMX file path</shortdesc>
 
297
<content type="string"/>
 
298
</parameter>
 
299
 
 
300
<parameter name="vimshbin" unique="0" required="1">
 
301
<longdesc lang="en">
 
302
vmware-vim-cmd executable path
 
303
</longdesc>
 
304
<shortdesc lang="en">vmware-vimsh path</shortdesc>
 
305
<content type="string" default="/usr/bin/vmware-vim-cmd"/>
 
306
</parameter>
 
307
</parameters>
 
308
 
 
309
<actions>
 
310
<action name="start"        timeout="300" />
 
311
<action name="stop"         timeout="300" />
 
312
<action name="monitor"      timeout="30" interval="300" depth="0"
 
313
start-delay="0" />
 
314
<action name="meta-data"    timeout="5" />
 
315
</actions>
 
316
</resource-agent>
 
317
END
 
318
}
 
319
 
 
320
# See how we were called
 
321
#################################################################
 
322
 
 
323
case "$1" in
 
324
meta-data)
 
325
  meta_data
 
326
  exit $OCF_SUCCESS
 
327
  ;;
 
328
usage|help)
 
329
  vmware_usage
 
330
  exit $OCF_SUCCESS
 
331
  ;;
 
332
esac
 
333
 
 
334
vmware_validate
 
335
rc=$?
 
336
if [ $rc -ne 0 ]; then
 
337
  case "$1" in
 
338
    stop)       ocf_log info "validate failed, vmware considered stopped"
 
339
                exit $OCF_SUCCESS;;
 
340
    monitor)    exit $OCF_NOT_RUNNING;;
 
341
    status)     exit $LSB_STATUS_STOPPED;;
 
342
    *) # it's safe to bail out now
 
343
                ocf_log err "vmware_validate failed"
 
344
                exit $rc
 
345
        ;;
 
346
  esac
 
347
elif [ "$1" = "validate-all" ]; then
 
348
        exit $OCF_SUCCESS
 
349
fi
 
350
set_environment
 
351
 
 
352
case "$1" in
 
353
start)
 
354
  vmware_start
 
355
  ;;
 
356
 
 
357
stop)
 
358
  vmware_stop
 
359
  ;;
 
360
 
 
361
status|monitor)
 
362
  vmware_monitor
 
363
  ;;
 
364
 
 
365
*)
 
366
  vmware_usage
 
367
  exit $OCF_ERR_UNIMPLEMENTED
 
368
  ;;
 
369
 
 
370
esac