#!/bin/sh
#
#
# Support:      linux-ha@lists.linux-ha.org
# License:      GNU General Public License (GPL)
#
#	Resource Agent for the Xen Hypervisor.
#	Manages Xen virtual machine instances by
#	mapping cluster resource start and stop,  
#	to Xen create and shutdown, respectively.
#
#	usage: $0  {start|stop|status|monitor|meta-data}
#
#	  OCF parameters are as below:
#		OCF_RESKEY_xmfile
#			Absolute path to the Xen control file,
#			for this virtual machine.
#		OCF_RESKEY_allow_migrate
#			Use migration where possible

#######################################################################
# Initialization:

. ${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs

#######################################################################

DOMAIN_NAME="$OCF_RESOURCE_INSTANCE"

usage() {
  cat <<-!
	usage: $0 {start|stop|status|monitor|meta-data|validate-all}
	!
}

meta_data() {
	cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="Xen">
<version>1.0</version>

<longdesc lang="en">
Resource Agent for the Xen Hypervisor.
Manages Xen virtual machine instances by
mapping cluster resource start and stop,  
to Xen create and shutdown, respectively.

Para-virtualized guests can also be migrated by enabling the
meta_attribute allow_migrate.

</longdesc>
<shortdesc lang="en">Manages Xen DomUs</shortdesc>

<parameters>

<parameter name="xmfile" unique="0" required="1">
<longdesc lang="en">
Absolute path to the Xen control file,
for this virtual machine.
</longdesc>
<shortdesc lang="en">Xen control file</shortdesc>
<content type="string" default="" />
</parameter>

<parameter name="allow_migrate" unique="0" required="1">
<longdesc lang="en">
Use migration where possible.
</longdesc>
<shortdesc lang="en">use migration</shortdesc>
<content type="boolean" default="0" />
</parameter>
</parameters>

<actions>
<action name="start" timeout="30" />
<action name="stop" timeout="30" />
<action name="migrate_from" timeout="120" />
<action name="migrate_to" timeout="120" />
<action name="status" depth="0" timeout="30" interval="10" start-delay="30" />
<action name="monitor" depth="0" timeout="30" interval="10" start-delay="30" />
<action name="meta-data" timeout="5" />
<action name="validate-all" timeout="5" />
</actions>
</resource-agent>
END
}

Xen_Status() {
  STATUS=`xm list --long $DOMAIN_NAME | grep status 2>/dev/null`
  STATUS_NOSPACES=`echo "$STATUS" | awk '{ print $1,$2}'`
  if [ "$STATUS_NOSPACES" = "(status 2)" -o "$STATUS_NOSPACES" = "(status 1)" ] ; then
    return $OCF_SUCCESS
  else 
    return $OCF_NOT_RUNNING
  fi
}

Xen_Monitor() {
  Xen_Status
}

Xen_Start() {
  if
    Xen_Status
  then
    ocf_log info "Xen domain $DOMAIN_NAME already running."
    return $OCF_SUCCESS
  else
    xm create $OCF_RESKEY_xmfile name=$DOMAIN_NAME
    rc=$?
    if
      [ $rc -ne 0 ]
    then
      return $OCF_ERR_PERM
    else 
      return $OCF_SUCCESS
    fi
  fi  
}

Xen_Stop() {
  if
    Xen_Status
  then
    # TODO: If after 50% of our timeout this one doesn't return, we
    # should instead switch to xm destroy
    # TODO: Should we just always use xm destroy here in the meantime
    # to make sure we indeed always stop?
    xm shutdown -w $DOMAIN_NAME
    rc=$?
    if
      [ $rc -ne 0 ]
    then
      return $OCF_ERR_PERM
    else 
      return $OCF_SUCCESS
    fi
  else
    ocf_log info "Xen domain $DOMAIN_NAME already stopped."
    return $OCF_SUCCESS
  fi
}

Xen_Migrate_To() {
  target_node="$OCF_RESKEY_CRM_meta_migrate_target"
  if 
    Xen_Status
  then
    ocf_log info "$DOMAIN_NAME: Starting xm migrate to $target_node"
    xm migrate --live $DOMAIN_NAME $target_node
    rc=$?
    if
      [ $rc -ne 0 ]
    then
      ocf_log err "$DOMAIN_NAME: xm migrate to $target_node failed: $rc"
      return $OCF_ERR_PERM
    else 
      ocf_log err "$DOMAIN_NAME: xm migrate to $target_node succeeded."
      return $OCF_SUCCESS
    fi
  else
    ocf_log err "$DOMAIN_NAME: migrate_to: Not active locally!"
    return $OCF_ERR_PERM
  fi
}

Xen_Migrate_From() {
  if 
    Xen_Status
  then
    ocf_log info "$DOMAIN_NAME: Active locally, migration successful"
    return $OCF_SUCCESS
  else
    ocf_log err "$DOMAIN_NAME: Not active locally, migration failed!"
    return $OCF_ERR_PERM
  fi
}

Xen_Validate_All() {
  return $OCF_SUCCESS
}

if [ $# -ne 1 ]; then
  usage
  exit $OCF_ERR_ARGS
fi

case $1 in
  meta-data)		meta_data
			exit $OCF_SUCCESS
			;;
  start)		Xen_Start
			;;
  stop)			Xen_Stop
			;;
  migrate_to)		Xen_Migrate_To
			;;
  migrate_from)		Xen_Migrate_From
			;;
  monitor)		Xen_Monitor
			;;
  status)		Xen_Status
			;;
  validate-all)		Xen_Validate_All
			;;
  usage)		usage
			exit $OCF_SUCCESS
			;;
  *)			usage
			exit $OCF_ERR_ARGS
			;;
esac
exit $?

