1#!@BASH_SHELL@
2#
3#	ManageVE OCF RA. Manages OpenVZ Virtual Environments (VEs)
4#
5#   (c) 2006-2010 Matthias Dahl, Florian Haas,
6#                 and Linux-HA contributors
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of version 2 of the GNU General Public License as
10# published by the Free Software Foundation.
11#
12# This program is distributed in the hope that it would be useful, but
13# WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15#
16# Further, this software is distributed without any warranty that it is
17# free of the rightful claim of any third person regarding infringement
18# or the like.  Any license provided herein, whether implied or
19# otherwise, applies only to this software file.  Patent licenses, if
20# any, provided herein do not apply to combinations of this program with
21# other software, or any other product whatsoever.
22#
23# You should have received a copy of the GNU General Public License
24# along with this program; if not, write the Free Software Foundation,
25# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
26#
27#
28# This OCF compliant resource agent manages OpenVZ VEs and thus requires
29# a proper OpenVZ installation including a recent vzctl util.
30#
31# rev. 1.00.4
32#
33# Changelog
34#
35# 21/Oct/10 1.00.4 implement migrate_from/migrate_to
36# 12/Sep/06 1.00.3 more cleanup
37# 12/Sep/06 1.00.2 fixed some logic in start_ve
38#                  general cleanup all over the place
39# 11/Sep/06 1.00.1 fixed some typos
40# 07/Sep/06 1.00.0 it's alive... muahaha... ALIVE... :-)
41#
42
43###
44: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
45. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
46
47# Parameter defaults
48
49OCF_RESKEY_veid_default=""
50
51: ${OCF_RESKEY_veid=${OCF_RESKEY_veid_default}}
52
53###
54
55# required utilities
56VZCTL=/usr/sbin/vzctl
57
58#
59# usage()
60#
61usage()
62{
63	cat <<-EOF
64	usage: $0 {start|stop|status|monitor|migrate_from|migrate_to|validate-all|usage|meta-data}
65	EOF
66}
67
68#
69# meta_data()
70#
71meta_data()
72{
73	cat <<END
74<?xml version="1.0"?>
75<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
76<resource-agent name="ManageVE">
77  <version>1.00.4</version>
78
79  <longdesc lang="en">
80    This OCF compliant resource agent manages OpenVZ VEs and thus requires
81    a proper OpenVZ installation including a recent vzctl util.
82  </longdesc>
83
84  <shortdesc lang="en">Manages an OpenVZ Virtual Environment (VE)</shortdesc>
85
86  <parameters>
87    <parameter name="veid" unique="0" required="1">
88      <longdesc lang="en">
89        OpenVZ ID of virtual environment (see output of vzlist -a for all assigned IDs)
90      </longdesc>
91      <shortdesc lang="en">OpenVZ ID of VE</shortdesc>
92      <content type="integer" default="${OCF_RESKEY_veid_default}" />
93    </parameter>
94  </parameters>
95
96  <actions>
97    <action name="start" timeout="75s" />
98    <action name="stop" timeout="75s" />
99    <action name="status" depth="0" timeout="10s" interval="10s" />
100    <action name="monitor" depth="0" timeout="10s" interval="10s" />
101    <action name="migrate_to" timeout="75s" />
102    <action name="migrate_from" timeout="75s" />
103    <action name="validate-all" timeout="5s" />
104    <action name="meta-data" timeout="5s" />
105  </actions>
106</resource-agent>
107END
108}
109
110#
111# start_ve()
112#
113# Starts a VE, or simply logs a message if the VE is already running.
114#
115start_ve()
116{
117  if status_ve; then
118	ocf_log info "VE $VEID already running."
119	return $OCF_SUCCESS
120  fi
121
122  ocf_run $VZCTL start $VEID || exit $OCF_ERR_GENERIC
123
124  return $OCF_SUCCESS
125}
126
127#
128# stop_ve()
129#
130# ATTENTION: The following code relies on vzctl's exit codes, especially:
131#
132#   0 : success
133#
134# In case any of those exit codes change, this function will need fixing.
135#
136stop_ve()
137{
138  status_ve
139  if [ $? -eq $OCF_NOT_RUNNING ]; then
140	ocf_log info "VE $VEID already stopped."
141	return $OCF_SUCCESS
142  fi
143
144  ocf_run $VZCTL stop $VEID || exit $OCF_ERR_GENERIC
145
146  return $OCF_SUCCESS
147}
148
149#
150# migrate_to_ve()
151#
152# In the process of a resource migration, checkpoints the VE. For this
153# to work, vzctl must obviously create the dump file in a place which
154# the migration target has access to (an NFS mount, a DRBD device,
155# etc.).
156#
157migrate_to_ve()
158{
159  if ! status_ve; then
160    ocf_log err "VE $VEID is not running, aborting"
161    exit $OCF_ERR_GENERIC
162  fi
163  ocf_run $VZCTL chkpnt $VEID || exit $OCF_ERR_GENERIC
164  return $OCF_SUCCESS
165}
166
167#
168# migrate_to_ve()
169#
170# In the process of a resource migration, restores the VE. For this to
171# work, vzctl must obviously have access to the dump file which was
172# created on the migration source (on an NFS mount, a DRBD device,
173# etc.).
174#
175migrate_from_ve()
176{
177  ocf_run $VZCTL restore $VEID || exit $OCF_ERR_GENERIC
178  return $OCF_SUCCESS
179}
180
181#
182# status_ve()
183#
184# ATTENTION: The following code relies on vzctl's status output. The fifth
185# column is interpreted as the VE status (either up or down).
186#
187# In case the output format should change, this function will need fixing.
188#
189status_ve()
190{
191  declare -i retcode
192
193  veexists=`$VZCTL status $VEID 2>/dev/null | $AWK '{print $3}'`
194  vestatus=`$VZCTL status $VEID 2>/dev/null | $AWK '{print $5}'`
195  retcode=$?
196
197  if [[ $retcode != 0 ]]; then
198    # log error only if expected to find running
199    if [ "$__OCF_ACTION" = "monitor" ] && ! ocf_is_probe; then
200      ocf_log err "vzctl status $VEID returned: $retcode"
201    fi
202    exit $OCF_ERR_GENERIC
203  fi
204
205  if [[ $veexists != "exist" ]]; then
206    ocf_log err "vzctl status $VEID returned: $VEID does not exist."
207    return $OCF_NOT_RUNNING
208  fi
209
210  case "$vestatus" in
211    running)
212        return $OCF_SUCCESS
213        ;;
214    down)
215	return $OCF_NOT_RUNNING
216        ;;
217    *)
218	ocf_log err "vzctl status $VEID, wrong output format. (5th column: $vestatus)"
219	exit $OCF_ERR_GENERIC
220        ;;
221  esac
222}
223
224#
225# validate_all_ve()
226#
227# ATTENTION: The following code relies on vzctl's status output. The fifth
228# column is interpreted as the VE status (either up or down).
229#
230# In case the output format should change, this function will need fixing.
231#
232validate_all_ve()
233{
234  declare -i retcode
235
236  # VEID should be a valid VE
237  `status_ve`
238  retcode=$?
239
240  if [[ $retcode != $OCF_SUCCESS && $retcode != $OCF_NOT_RUNNING ]]; then
241    return $retcode
242  fi
243
244  return $OCF_SUCCESS
245}
246
247
248if [[ $# != 1 ]]; then
249  usage
250  exit $OCF_ERR_ARGS
251fi
252
253case "$1" in
254  meta-data)
255	meta_data
256	exit $OCF_SUCCESS
257	;;
258  usage)
259	usage
260	exit $OCF_SUCCESS
261	;;
262  *)
263	;;
264esac
265
266#
267# check relevant environment variables for sanity and security
268#
269
270# empty string?
271`test -z "$OCF_RESKEY_veid"`
272
273declare -i veidtest1=$?
274
275# really a number?
276`echo "$OCF_RESKEY_veid" | egrep -q '^[[:digit:]]+$'`
277
278if [[ $veidtest1 != 1 || $? != 0 ]]; then
279  ocf_log err "OCF_RESKEY_veid not set or not a number."
280  exit $OCF_ERR_ARGS
281fi
282
283declare -i VEID=$OCF_RESKEY_veid
284
285#
286# check that all relevant utilities are available
287#
288check_binary $VZCTL
289check_binary $AWK
290
291#
292# finally... let's see what we are ordered to do :-)
293#
294case "$1" in
295  start)
296	start_ve
297	;;
298  stop)
299	stop_ve
300	;;
301  status|monitor)
302	status_ve
303	;;
304  migrate_to)
305    migrate_to_ve
306    ;;
307  migrate_from)
308    migrate_from_ve
309    ;;
310  validate-all)
311	validate_all_ve
312	;;
313  *)
314	usage
315	exit $OCF_ERR_UNIMPLEMENTED
316	;;
317esac
318
319exit $?
320
321