diff --git a/heartbeat/lxc b/heartbeat/lxc index eaf0f277c..725e0aeac 100755 --- a/heartbeat/lxc +++ b/heartbeat/lxc @@ -1,318 +1,302 @@ #!/bin/bash # Should now conform to guidlines: http://www.linux-ha.org/doc/dev-guides/ra-dev-guide.html # # LXC (Linux Containers) OCF RA. # Used to cluster enable the start, stop and monitoring of a LXC container. # # Copyright (c) 2011 AkurIT.com.au, Darren Thompson # All Rights Reserved. # # Without limiting the rights of the original copyright holders # This resource is licensed under GPL version 2 # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it would be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Further, this software is distributed without any warranty that it is # free of the rightful claim of any third person regarding infringement # or the like. Any license provided herein, whether implied or # otherwise, applies only to this software file. Patent licenses, if # any, provided herein do not apply to combinations of this program with # other software, or any other product whatsoever. # # You should have received a copy of the GNU General Public License # along with this program; if not, write the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. # OCF instance parameters # OCF_RESKEY_container # OCF_RESKEY_LXC_BCP # OCF_RESKEY_root # OCF_RESKEY_LXC_CF_FILENAME # # Whilst testing, fix these values so that the OCF can run from command line # This does not conform to the guidlines, so each line should be prefixed with "#" in production # # OCF_RESKEY_container_default="test1" # OCF_RESKEY_LXC_BCP_default="/etc/lxc" # OCF_RESKEY_root_default="/srv/lxc" # OCF_RESKEY_LXC_CF_FILENAME_default="config" # : ${OCF_RESKEY_container=${OCF_RESKEY_container_default}} # : ${OCF_RESKEY_LXC_BCP=${OCF_RESKEY_LXC_BCP_default}} # : ${OCF_RESKEY_root=${OCF_RESKEY_root_default}} # : ${OCF_RESKEY_LXC_CF_FILENAME=${OCF_RESKEY_LXC_CF_FILENAME_default}} # OCF_ROOT="/usr/lib/ocf" # : OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat # # Initialization: : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs # Set default TRANS_RES_STATE (temporary file to "flag" if resource was stated but not stopped) TRANS_RES_STATE="${HA_RSCTMP}/LXC_${OCF_RESKEY_container}-${OCF_RESOURCE_INSTANCE}.state" -# It would be "Bad" if the container were to be run on more than one node, using lock file in shared configration directory to prevent it. -LOCKFILE="${OCF_RESKEY_LXC_BCP}/${OCF_RESKEY_container}/${OCF_RESKEY_container}.lock" -## ocf_release_lock_on_exit $LOCKFILE # does not work as I would expect ti too :-( # - - meta_data() { cat < 0.1 This is derived from the generic OCF RA, to manage LXC containers. It allow LXC continers to be managed by the cluster Manages LXC containers The unique name for this 'Container Instance' e.g. 'test1'. Container Name The path to the directories holding each containers configuration files e.g. '/etc/lxc'. Full path to the config root The path to the directories holding each containers "root" filesystem e.g. '/srv/lxc'. Full path to the parent containers "root" filesystems The file holding the specific configuration for this container e.g. 'config'. The LXC config file. END } LXC_usage() { cat <${CGROUP_MOUNT_POINT}/notify_on_release return 0 } LXC_start() { # put this here as it's so long it gets messy later!!! STARTCMD="screen -dmS ${OCF_RESKEY_container} lxc-start -f ${OCF_RESKEY_LXC_CF_FILENAME} -n ${OCF_RESKEY_container}" cgroup_mounted ret=$? if [ $ret ]; then if LXC_validate ; then if ! LXC_monitor ; then -# ocf_take_lock $LOCKFILE # does not work as I would expect ti too :-( # - if [ -f $LOCKFILE ] ; then - ocf_log err "Starting of" ${OCF_RESKEY_container} "aborted as there is already a lock file!" - ocf_log info "If you are SURE that this resource is not running elswhere, just delete the file" $LOCKFILE - exit ${OCF_ERR_GENERIC} - else - touch $LOCKFILE - touch $TRANS_RES_STATE - ocf_log info "Starting" ${OCF_RESKEY_container} - cd ${OCF_RESKEY_LXC_BCP}/${OCF_RESKEY_container}/ - ocf_run ${STARTCMD} || exit $OCF_ERR_GENERIC - fi + touch $TRANS_RES_STATE + ocf_log info "Starting" ${OCF_RESKEY_container} + cd ${OCF_RESKEY_LXC_BCP}/${OCF_RESKEY_container}/ + ocf_run ${STARTCMD} || exit $OCF_ERR_GENERIC else # If already running, consider start successful ocf_log debug ${OCF_RESOURCE_INSTANCE}: ${OCF_RESKEY_container} "is already running" return $OCF_SUCCESS fi return $OCF_SUCCESS else ret=$? return $ret fi else return $OCF_ERR_GENERIC fi } LXC_stop() { cgroup_mounted ret=$? if [ $ret ]; then # If the container is running "init" and is able to perform and orderly shutdown, then it should be done. typeset -i PID=0 lxc-ps -C init -opid |while read CN PID ;do [[ $PID -gt 1 ]] || continue [[ "$CN" = "${OCF_RESKEY_container}" ]] || continue grep -q 'p0::powerfail:/sbin/init 0' ${OCF_RESKEY_root}/${OCF_RESKEY_container}/etc/inittab || continue kill -PWR $PID if [ -n "$OCF_RESKEY_stop_timeout" ] then # Allow 2/3 of the stop timeout for the orderly shutdown # (The origin unit is ms, hence the conversion) stop_timeout=$((OCF_RESKEY_stop_timeout/1500)) elif [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then # Allow 2/3 of the action timeout for the orderly shutdown # (The origin unit is ms, hence the conversion) stop_timeout=$((OCF_RESKEY_CRM_meta_timeout/1500)) else stop_timeout=10 fi sleep $stop_timeout done # If the container is still running, it will be stopped now. regardless of state! lxc-stop -n ${OCF_RESKEY_container} - if [ -f $LOCKFILE ]; then - rm $LOCKFILE - fi if [ -f $TRANS_RES_STATE ]; then rm $TRANS_RES_STATE else ocf_log err "Dolt!" ${OCF_RESKEY_container} "does not seem to be started!" return ${OCF_ERR_GENERIC} fi return $OCF_SUCCESS else return $OCF_ERR_GENERIC fi } LXC_monitor() { S=`lxc-info -n ${OCF_RESKEY_container}` ocf_log info "$S" if [[ "${S##* }" = "RUNNING" ]] ; then if [ -f $TRANS_RES_STATE ]; then return $OCF_SUCCESS else return $OCF_ERR_GENERIC fi else if [ -f $TRANS_RES_STATE ]; then ocf_log err "Dolt!" ${OCF_RESKEY_container} "should be running!" return $OCF_ERR_GENERIC fi return $OCF_NOT_RUNNING fi } LXC_validate() { # Quick check that all required attributes are set if [ -z "${OCF_RESKEY_container}" ]; then ocf_log err "LXC container name not set!" exit $OCF_ERR_CONFIGURED fi if [ -z "${OCF_RESKEY_LXC_BCP}" ]; then ocf_log err "LXC configuration directory not set!" exit $OCF_ERR_CONFIGURED else if ! [ -d "${OCF_RESKEY_LXC_BCP}"/"${OCF_RESKEY_container}" ]; then ocf_log err "LXC configuration directory "${OCF_RESKEY_LXC_BCP}"/"${OCF_RESKEY_container}" is not present on this node!" exit $OCF_ERR_INSTALLED fi fi if [ -z "${OCF_RESKEY_root}" ]; then ocf_log err "LXC container root filesystem directory not set!" exit $OCF_ERR_CONFIGURED else if ! [ -d "${OCF_RESKEY_root}"/"${OCF_RESKEY_container}" ]; then ocf_log err "LXC container root filesystem directory "${OCF_RESKEY_root}${OCF_RESKEY_container}" is not present on this node!" exit $OCF_ERR_INSTALLED fi fi if [ -z "${OCF_RESKEY_LXC_CF_FILENAME}" ]; then ocf_log err "LXC configuration filename name not set!" exit $OCF_ERR_CONFIGURED else if ! [ -f "${OCF_RESKEY_LXC_BCP}"/"${OCF_RESKEY_container}"/"${OCF_RESKEY_LXC_CF_FILENAME}" ]; then ocf_log err "LXC configuration file "${OCF_RESKEY_LXC_BCP}"/"${OCF_RESKEY_container}"/"${OCF_RESKEY_LXC_CF_FILENAME}" missing or not found!" exit $OCF_ERR_INSTALLED fi fi # Quick check that CGROUPS are corrrectly mounted if ! [ -f ${CGROUP_MOUNT_POINT}/notify_on_release ]; then exit $OCF_ERR_INSTALLED fi # Quick check that required executables are present check_binary lxc-start check_binary lxc-stop check_binary lxc-ps check_binary lxc-info check_binary screen return $OCF_SUCCESS } case $__OCF_ACTION in meta-data) meta_data exit $OCF_SUCCESS ;; start) LXC_start;; stop) LXC_stop;; monitor) LXC_monitor;; migrate_to) ocf_log info "Moving ${OCF_RESOURCE_INSTANCE} to ${OCF_RESKEY_CRM_meta_migrate_to}." LXC_stop ;; migrate_from) ocf_log info "Moving ${OCF_RESOURCE_INSTANCE} to ${OCF_RESKEY_CRM_meta_migrated_from}." LXC_start ;; reload) ocf_log err "Reloading..." LXC_stop LXC_start ;; validate-all) LXC_validate;; usage|help) LXC_usage exit $OCF_SUCCESS ;; *) LXC_usage ocf_log err "$0 was called with unsupported arguments: $*" exit $OCF_ERR_UNIMPLEMENTED ;; esac rc=$? ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc" exit $rc