Merge lp:~gandelman-a/charms/precise/hacluster/ocf into lp:charms/hacluster

Proposed by Adam Gandelman
Status: Merged
Merged at revision: 14
Proposed branch: lp:~gandelman-a/charms/precise/hacluster/ocf
Merge into: lp:charms/hacluster
Diff against target: 349 lines (+308/-1)
3 files modified
hooks/hooks.py (+11/-0)
ocf/ceph/rbd (+296/-0)
revision (+1/-1)
To merge this branch: bzr merge lp:~gandelman-a/charms/precise/hacluster/ocf
Reviewer Review Type Date Requested Status
James Page Needs Fixing
Review via email: mp+151345@code.launchpad.net

Description of the change

This ships the ceph RBD resource agent directly in the charm, copied from the version of ceph shipped /w quantal (.48) This is a complicated matter currently and hopefully this is only a temporary solution:

- The .46 ceph-resource-agents in precise do not include the rbd RA.
- The .48 ceph-resource-agents in quantal does. However, setting up cloud-archive access to install it would also upgrade any ceph packages installed by the principle.
- The .56 ceph-resource-agents in raring is not compatible /w the rbd CLI in .46 or .48.

I'd like to ping the OCF author about possibly supporting different versions /w a single RA.

Until then, ACAICS best solution is to ship and install RA's /w the charm.

To post a comment you must log in.
Revision history for this message
James Page (james-page) wrote :

Adam - generally looks OK;

1) Ceph resource agents still gets installed - think we need to drop this right?

    if True in [ra.startswith('ocf:ceph')
                for ra in resources.itervalues()]:
        utils.install('ceph-resource-agents')

Other than that look good to me.

review: Needs Fixing
Revision history for this message
Adam Gandelman (gandelman-a) wrote :

The rbd OCF is not included in the .041 release, but it is /w .48 + .56. The .56 OCF is updated for rbd syntax changes. I thought the easiest way to keep this charm able to deploy across all versions would be to install the rbd OCF packaged with the charm along with the package, so that if it is included /w the package proper, it will override the one copied from the charm.

Revision history for this message
James Page (james-page) wrote :

OK - testing with the mysql and rabbitmq updates which use these features - will verify on raring and precise.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'hooks/hooks.py'
2--- hooks/hooks.py 2013-02-20 10:10:42 +0000
3+++ hooks/hooks.py 2013-03-02 03:56:20 +0000
4@@ -7,6 +7,7 @@
5 # Andres Rodriguez <andres.rodriguez@canonical.com>
6 #
7
8+import shutil
9 import sys
10 import time
11 import os
12@@ -20,10 +21,17 @@
13 utils.juju_log('INFO', 'Begin install hook.')
14 utils.configure_source()
15 utils.install('corosync', 'pacemaker', 'python-netaddr', 'ipmitool')
16+ # XXX rbd OCF only included with newer versions of ceph-resource-agents.
17+ # Bundle /w charm until we figure out a better way to install it.
18+ if not os.path.exists('/usr/lib/ocf/resource.d/ceph'):
19+ os.makedirs('/usr/lib/ocf/resource.d/ceph')
20+ if not os.path.isfile('/usr/lib/ocf/resource.d/ceph/rbd'):
21+ shutil.copy('ocf/ceph/rbd', '/usr/lib/ocf/resource.d/ceph/rbd')
22 utils.juju_log('INFO', 'End install hook.')
23
24
25 def get_corosync_conf():
26+ conf = {}
27 for relid in utils.relation_ids('ha'):
28 for unit in utils.relation_list(relid):
29 conf = {
30@@ -39,6 +47,9 @@
31 }
32 if None not in conf.itervalues():
33 return conf
34+ missing = [k for k, v in conf.iteritems() if v == None]
35+ utils.juju_log('INFO',
36+ 'Missing required principle configuration: %s' % missing)
37 return None
38
39
40
41=== added directory 'ocf'
42=== added directory 'ocf/ceph'
43=== added file 'ocf/ceph/rbd'
44--- ocf/ceph/rbd 1970-01-01 00:00:00 +0000
45+++ ocf/ceph/rbd 2013-03-02 03:56:20 +0000
46@@ -0,0 +1,296 @@
47+#!/bin/sh
48+#
49+# OCF resource agent for mapping and unmapping
50+# RADOS Block Devices (RBDs)
51+#
52+# License: GNU Lesser General Public License (LGPL) 2.1
53+# (c) 2012 Florian Haas, hastexo
54+#
55+
56+# Initialization:
57+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
58+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
59+
60+# Convenience variables
61+# When sysconfdir isn't passed in as a configure flag,
62+# it's defined in terms of prefix
63+prefix=/usr
64+
65+# Defaults
66+OCF_RESKEY_pool_default="rbd"
67+OCF_RESKEY_cephconf_default="/etc/ceph/ceph.conf"
68+: ${OCF_RESKEY_pool=${OCF_RESKEY_pool_default}}
69+: ${OCF_RESKEY_cephconf=${OCF_RESKEY_cephconf_default}}
70+
71+rbd_meta_data() {
72+ cat <<EOF
73+<?xml version="1.0"?>
74+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
75+<resource-agent name="rbd" version="0.1">
76+ <version>0.1</version>
77+ <longdesc lang="en">
78+Manages RADOS Block Devices (RBDs) as a highly available
79+resource. Maps and unmaps RBDs as needed.
80+ </longdesc>
81+ <shortdesc lang="en">Maps and unmaps RADOS Block Devices</shortdesc>
82+ <parameters>
83+ <parameter name="name" unique="0" required="1">
84+ <longdesc lang="en">
85+ Name of the RBD device.
86+ </longdesc>
87+ <shortdesc lang="en">RBD device name</shortdesc>
88+ <content type="string"/>
89+ </parameter>
90+ <parameter name="pool" unique="0" required="0">
91+ <longdesc lang="en">
92+ Name of the RADOS pool where the RBD has been created
93+ </longdesc>
94+ <shortdesc lang="en">RADOS pool name</shortdesc>
95+ <content type="string" default="${OCF_RESKEY_pool_default}"/>
96+ </parameter>
97+ <parameter name="snap" unique="0" required="0">
98+ <longdesc lang="en">
99+ Name of the device snapshot to map.
100+ </longdesc>
101+ <shortdesc lang="en">Snapshot name</shortdesc>
102+ <content type="string"/>
103+ </parameter>
104+ <parameter name="cephconf" unique="0" required="0">
105+ <longdesc lang="en">
106+ Location of the Ceph configuration file
107+ </longdesc>
108+ <shortdesc lang="en">Ceph configuration file</shortdesc>
109+ <content type="string" default="${OCF_RESKEY_cephconf_default}"/>
110+ </parameter>
111+ <parameter name="mon" unique="0" required="0">
112+ <longdesc lang="en">
113+ Address (or comma-separated list of addresses) of
114+ monitor servers to connect to. Overrides values from
115+ configuration file.
116+ </longdesc>
117+ <shortdesc lang="en">Monitor address(es)</shortdesc>
118+ <content type="string"/>
119+ </parameter>
120+ <parameter name="user" unique="0" required="0">
121+ <longdesc lang="en">
122+ Username to use when mapping the device. Required
123+ if Ceph authentication is enabled on the monitor.
124+ </longdesc>
125+ <shortdesc lang="en">Authentication username</shortdesc>
126+ <content type="string"/>
127+ </parameter>
128+ <parameter name="secret" unique="0" required="0">
129+ <longdesc lang="en">
130+ File containing an authentication secret. Required
131+ if Ceph authentication is enabled on the monitor.
132+ </longdesc>
133+ <shortdesc lang="en">Authentication secret file</shortdesc>
134+ <content type="string"/>
135+ </parameter>
136+ </parameters>
137+ <actions>
138+ <action name="start" timeout="20" />
139+ <action name="stop" timeout="20" />
140+ <action name="monitor" timeout="20"
141+ interval="10" depth="0" />
142+ <action name="meta-data" timeout="5" />
143+ <action name="validate-all" timeout="20" />
144+ </actions>
145+</resource-agent>
146+EOF
147+}
148+
149+rbd_usage() {
150+ cat <<EOF
151+usage: $0 {start|stop|status|monitor|validate-all|meta-data}
152+
153+Expects to have a fully populated OCF RA-compliant environment set.
154+EOF
155+}
156+
157+# rbd command wrapper: builds an option string for invoking RBD based
158+# on resource parameters, and invokes rbd through ocf_run.
159+do_rbd() {
160+ local rbd_options
161+
162+ if [ -n "${OCF_RESKEY_cephconf}" ]; then
163+ rbd_options="$rbd_options -c ${OCF_RESKEY_cephconf}"
164+ fi
165+ if [ -n "${OCF_RESKEY_mon}" ]; then
166+ rbd_options="$rbd_options -m ${OCF_RESKEY_mon}"
167+ fi
168+
169+ ocf_run rbd $rbd_options $@
170+}
171+
172+# Convenience function that uses "rbd showmapped" to retrieve the
173+# mapped device name from the pool, RBD name, and snapshot.
174+find_rbd_dev() {
175+ local sedpat
176+
177+ # Example output from "rbd showmapped" (tab separated):
178+ # id pool image snap device
179+ # 0 rbd test - /dev/rbd0
180+
181+ # Build the sed pattern, substituting "-" for the snapshot name if
182+ # it's unset
183+ sedpat="[0-9]\+\t${OCF_RESKEY_pool}\t${OCF_RESKEY_name}\t${OCF_RESKEY_snap:--}\t\(/dev/rbd[0-9]\+\)"
184+
185+ # Run rbd showmapped, filter out the header line, then try to
186+ # extract the device name
187+ rbd showmapped | tail -n +2 | sed -n -e "s,$sedpat,\1,p"
188+}
189+
190+rbd_validate_all() {
191+ # Test for configuration errors first
192+ if [ -z "$OCF_RESKEY_name" ]; then
193+ ocf_log err 'Required parameter "name" is unset!'
194+ exit $OCF_ERR_CONFIGURED
195+ fi
196+
197+ # Test for required binaries
198+ check_binary rbd
199+
200+ return $OCF_SUCCESS
201+}
202+
203+rbd_monitor() {
204+ local rc
205+ local rbd_dev
206+
207+ if ! [ -d /sys/bus/rbd ]; then
208+ ocf_log debug "rbd module is not loaded"
209+ return $OCF_NOT_RUNNING
210+ fi
211+
212+ rbd_dev=`find_rbd_dev`
213+
214+ if [ -z "$rbd_dev" ]; then
215+ ocf_log debug "RBD device is unmapped"
216+ rc=$OCF_NOT_RUNNING
217+ elif [ -b "$rbd_dev" ]; then
218+ ocf_log debug "RBD device is mapped to $rbd_dev"
219+ rc=$OCF_SUCCESS
220+ else
221+ # Device is listed, but the corresponding path is not a block
222+ # device.
223+ ocf_log err "$rbd_dev is not a block device!"
224+ rc=$OCF_ERR_GENERIC
225+ fi
226+
227+ return $rc
228+}
229+
230+rbd_start() {
231+ local rbd_map_options
232+ local rbd_name
233+
234+ # if resource is already running, bail out early
235+ if rbd_monitor; then
236+ ocf_log info "Resource is already running"
237+ return $OCF_SUCCESS
238+ fi
239+
240+ # actually start up the resource here (make sure to immediately
241+ # exit with an $OCF_ERR_ error code if anything goes seriously
242+ # wrong)
243+
244+ if [ ! -d /sys/bus/rbd ]; then
245+ ocf_run modprobe -v rbd || exit $OCF_ERR_INSTALLED
246+ fi
247+
248+ if [ -n "${OCF_RESKEY_user}" ]; then
249+ rbd_map_options="--user ${OCF_RESKEY_user}"
250+ fi
251+ if [ -n "${OCF_RESKEY_secret}" ]; then
252+ rbd_map_options="$rbd_map_options --secret ${OCF_RESKEY_secret}"
253+ fi
254+
255+ rbd_name="${OCF_RESKEY_pool}/${OCF_RESKEY_name}"
256+ if [ -n "${OCF_RESKEY_snap}" ]; then
257+ rbd_name="$rbd_name@${OCF_RESKEY_snap}"
258+ fi
259+
260+ do_rbd map $rbd_name $rbd_map_options || exit $OCF_ERR_GENERIC
261+
262+ # After the resource has been started, check whether it started up
263+ # correctly. If the resource starts asynchronously, the agent may
264+ # spin on the monitor function here -- if the resource does not
265+ # start up within the defined timeout, the cluster manager will
266+ # consider the start action failed
267+ while ! rbd_monitor; do
268+ ocf_log debug "Resource has not started yet, waiting"
269+ sleep 1
270+ done
271+
272+ # only return $OCF_SUCCESS if _everything_ succeeded as expected
273+ return $OCF_SUCCESS
274+}
275+
276+rbd_stop() {
277+ local rc
278+ local rbd_dev
279+
280+ rbd_monitor
281+ rc=$?
282+ case "$rc" in
283+ "$OCF_SUCCESS")
284+ # Currently running. Normal, expected behavior.
285+ ocf_log debug "Resource is currently running"
286+ ;;
287+ "$OCF_NOT_RUNNING")
288+ # Currently not running. Nothing to do.
289+ ocf_log info "Resource is already stopped"
290+ return $OCF_SUCCESS
291+ ;;
292+ esac
293+
294+ # actually shut down the resource here (make sure to immediately
295+ # exit with an $OCF_ERR_ error code if anything goes seriously
296+ # wrong)
297+ rbd_dev=`find_rbd_dev`
298+ do_rbd unmap $rbd_dev || exit $OCF_ERR_GENERIC
299+
300+ # After the resource has been stopped, check whether it shut down
301+ # correctly. If the resource stops asynchronously, the agent may
302+ # spin on the monitor function here -- if the resource does not
303+ # shut down within the defined timeout, the cluster manager will
304+ # consider the stop action failed
305+ while rbd_monitor; do
306+ ocf_log debug "Resource has not stopped yet, waiting"
307+ sleep 1
308+ done
309+
310+ # only return $OCF_SUCCESS if _everything_ succeeded as expected
311+ return $OCF_SUCCESS
312+
313+}
314+
315+# Make sure meta-data and usage always succeed
316+case $__OCF_ACTION in
317+meta-data) rbd_meta_data
318+ exit $OCF_SUCCESS
319+ ;;
320+usage|help) rbd_usage
321+ exit $OCF_SUCCESS
322+ ;;
323+esac
324+
325+# Anything other than meta-data and usage must pass validation
326+rbd_validate_all || exit $?
327+
328+# Translate each action into the appropriate function call
329+case $__OCF_ACTION in
330+start) rbd_start;;
331+stop) rbd_stop;;
332+status|monitor) rbd_monitor;;
333+validate-all) ;;
334+*) rbd_usage
335+ exit $OCF_ERR_UNIMPLEMENTED
336+ ;;
337+esac
338+rc=$?
339+
340+# The resource agent may optionally log a debug message
341+ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION returned $rc"
342+exit $rc
343
344=== modified file 'revision'
345--- revision 2013-02-13 23:44:37 +0000
346+++ revision 2013-03-02 03:56:20 +0000
347@@ -1,1 +1,1 @@
348-61
349+66

Subscribers

People subscribed via source and target branches