Skip to content

Instantly share code, notes, and snippets.

@kobus-v-schoor
Created February 28, 2021 20:59
Show Gist options
  • Save kobus-v-schoor/0d2408f9052ce08949fd9b8caf08e170 to your computer and use it in GitHub Desktop.
Save kobus-v-schoor/0d2408f9052ce08949fd9b8caf08e170 to your computer and use it in GitHub Desktop.
#! /bin/bash
# A Pacemaker resource agent that runs LXC containers using Ceph as a storage
# backend.
# Place in /usr/lib/ocf/resource.d/custom to use with your Pacemaker
# installation
LXC="/var/lib/lxc"
# Init OCF
: ${OCF_FUNCTIONS=${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs}
. ${OCF_FUNCTIONS}
USAGE="Usage: $0 {start|stop|monitor|meta-data}"
CONTAINER=$OCF_RESKEY_container
POOL=$OCF_RESKEY_pool
function usage() {
echo $USAGE >&2
}
function metadata() {
cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="LXC_Ceph" version="1.0">
<version>1.0</version>
<longdesc lang="en">
This will start/stop LXC containers using Ceph as a distributed storage system
</longdesc>
<shortdesc lang="en">
This will start/stop LXC containers using Ceph as a distributed storage system
</shortdesc>
<parameters>
<parameter name="container" unique="1" required="1">
<longdesc lang="en">
Name of the container
</longdesc>
<shortdesc lang="en">Container name</shortdesc>
<content type="string" />
</parameter>
<parameter name="pool" unique="0" required="1">
<longdesc lang="en">
Name of the Ceph storage pool
</longdesc>
<shortdesc lang="en">Ceph storage pool</shortdesc>
<content type="string" />
</parameter>
</parameters>
<actions>
<action name="start" timeout="60" />
<action name="stop" timeout="60" />
<action name="monitor" timeout="120" interval="10" />
<action name="meta-data" timeout="5" />
</actions>
</resource-agent>
END
}
# checks if the container is running using lxc-ls
function is_running() {
if [[ -n $(lxc-ls --running --filter=$CONTAINER) ]]; then
return 0
else
return 1
fi
}
# checks if a container's image is mounted
function is_mounted() {
if mount | grep -q "$LXC/$CONTAINER"; then
return 0
else
return 1
fi
}
# checks if a container's RBD image is mapped
function is_mapped() {
if [[ -b /dev/rbd/$POOL/$CONTAINER ]]; then
return 0
else
return 1
fi
}
# maps a container's image to this node
function map() {
rbd map "$POOL/$CONTAINER"
}
# unmaps a container's image
function unmap() {
rbd unmap "$POOL/$CONTAINER"
}
# mounts the container's image in the LXC containers directory
function fmount() {
mkdir -p "$LXC/$CONTAINER"
mount /dev/rbd/$POOL/$CONTAINER "$LXC/$CONTAINER"
}
# unmount the container's image
function unmount() {
umount "$LXC/$CONTAINER" && rmdir "$LXC/$CONTAINER"
}
# starts the container (needs to mapped + mounted first)
function start_container() {
lxc-start $CONTAINER
}
# stops the container (do this before unmounting + unmapping)
function stop_container() {
lxc-stop $CONTAINER
}
# main start function
function start() {
is_mapped || map
is_mapped || return $OCF_ERR_GENERIC
fmount
is_mounted || return $OCF_ERR_GENERIC
start_container
is_running || return $OCF_ERR_GENERIC
}
# main stopping function
function stop() {
is_running && stop_container
is_running && return $OCF_ERR_GENERIC
# try for 10 seconds long to unmount the container's image (sometimes it
# complains that the mountpoint is still in use)
counter=0
while is_mounted && [[ $counter -lt 10 ]]; do
unmount && continue
sleep 1s
((counter++))
done
is_mounted && return $OCF_ERR_GENERIC
unmap
is_mapped && return $OCF_ERR_GENERIC
return 0
}
# checks that everything is still up and running
function monitor {
is_running && return $OCF_SUCCESS
is_mounted && return $OCF_ERR_GENERIC
is_mapped && return $OCF_ERR_GENERIC
return $OCF_NOT_RUNNING
}
case $1 in
usage) usage;;
start) start;;
stop) stop;;
monitor) monitor;;
meta-data) metadata;;
*) usage;;
esac
exit $?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment