eole-one-master/postservice/30-one-mng
Philippe Caseiro 78a27b4fdd Ajout du support OpenNebula HA dans Hâpy
Ajouter la possibilité de créer une grappe haute disponibilité entre
plusieurs Hâpy (https://docs.opennebula.org/5.6/advanced_components/ha/index.html)

Pré-requis : Les datastores doivent être partagés entre tous les Hâpy
via NFS ou tout autre système de fichiers accécibles de manière
concurrente entre les serveurs (Glusterfs, Ceph, DRBD).

Pour faire ce développement nous nous sommes basés sur eole-glusterfs
qui permet de créer une grappe glusterfs (https://dev-eole.ac-dijon.fr/projects/eole-glusterfs)
2019-03-01 16:42:14 +01:00

495 lines
11 KiB
Bash
Executable File

#!/usr/bin/env bash
. /usr/lib/eole/utils.sh
function error()
{
MSG=${1}
echo "[ERROR][${MSG}]"
exit 1
}
function get_user_home()
{
HOMEDIR=$(getent passwd ${1} | cut -d ':' -f 6)
echo ${HOMEDIR}
}
function get_one_auth()
{
CMD="cat"
HOME=$(get_user_home oneadmin)
FILE="${HOME}/.one/one_auth"
${CMD} ${FILE}
}
function check_default_cluster()
{
name="${1}"
cmd="onecluster show 0"
auth=$(get_one_auth)
DEFAULT_NAME=$(${cmd} --user ${auth%:*} --password ${auth#*:} | awk '/^NAME/ {print $3}')
[[ "${name}" = "${DEFAULT_NAME}" ]]
}
function rename_default_cluster()
{
NAME="${1}"
CMD="onecluster rename 0 ${NAME}"
AUTH=$(get_one_auth)
if ! check_default_cluster "${NAME}"
then
if ${CMD} --user ${AUTH%:*} --password ${AUTH#*:}
then
echo "The default cluster name is now '${NAME}'"
else
error "The default cluster can not be renamed"
fi
else
echo "The default cluster name is already \"${NAME}\""
fi
}
function check_host()
{
name="${1}"
cmd="onehost"
opt="list"
auth=$(get_one_auth)
res=0
clst_list=$(${cmd} ${opt} --user ${auth%:*} --password ${auth#*:} | tail -n +2 | awk -F ' ' '{print $2}')
for hst in ${clst_list}
do
[[ "${NAME}" = "${hst}" ]] && res=$((res+1))
done
return ${res}
}
# Fix host creation error from 5.6.1 with sync methode rsync
function sync_host()
{
CMD="onehost"
OPT="sync -f --rsync"
AUTH=$(get_one_auth)
res=$(su - oneadmin -c "${CMD} ${OPT} --user ${AUTH%:*} --password ${AUTH#*:}")
if [[ ${?} -ne 0 ]]
then
error "Hosts sync failed"
else
echo "Hosts sync OK"
fi
}
function manage_host()
{
NAME=${1}
CMD="onehost"
IM_MAD='kvm'
VM_MAD='kvm'
OPT="create ${NAME} -i ${IM_MAD} -v ${VM_MAD}"
AUTH=$(get_one_auth)
check_host ${NAME}
if [[ ${?} -eq 0 ]]
then
res=$(${CMD} ${OPT} --user ${AUTH%:*} --password ${AUTH#*:})
if [[ ${?} -ne 0 ]]
then
error "Host creation failed"
else
echo "Host ${NAME} created"
fi
else
echo "Host ${NAME} already exist"
fi
}
function get_cluster_id_by_name()
{
name=${1}
cmd="onecluster"
opt="show ${name}"
opt="list -l ID,NAME -f NAME=${name} --csv"
res=$(${cmd} ${opt} --user ${AUTH%:*} --password ${AUTH#*:} | awk -F ',' '/^[0-9]/ { print $1 }')
if [[ ${?} -eq 0 ]]
then
echo ${res#*:}
return 0
else
echo ""
return 1
fi
}
#
# Get Host ID by a name
#
function get_host_id_by_name()
{
name=${1}
cmd="onehost"
opt="show ${name}"
res=$(${cmd} ${opt} --user ${AUTH%:*} --password ${AUTH#*:} | grep "ID.*:")
if [[ ${?} -eq 0 ]]
then
echo ${res#*:}
return 0
else
echo ""
return 1
fi
}
#
# Get Datastore ID by a name
#
function get_ds_id_by_name()
{
name=${1}
cmd="onedatastore"
opt="show ${name}"
res=$(${cmd} ${opt} --user ${AUTH%:*} --password ${AUTH#*:} | grep "ID.*:")
if [[ ${?} -eq 0 ]]
then
echo ${res#*:}
return 0
else
echo "ERR"
return 1
fi
}
#
# check_host_in_cluster
# if host is attached to cluster : return 0
# if host not attached to cluster : return 1
#
function check_host_in_cluster()
{
hst=${1}
clst=${2}
auth=$(get_one_auth)
cmd="onehost"
opt="show ${hst} --user ${AUTH%:*} --password ${AUTH#*:}"
RES=$(${cmd} ${opt} | grep CLUSTER)
cluster=${RES#*:}
# clean Outpu
cluster="${cluster#"${cluster%%[![:space:]]*}"}" # remove leading whitespace characters
cluster="${cluster%"${cluster##*[![:space:]]}"}" # remove trailing whitespace characters
if [[ "${cluster}" = "${clst}" ]]
then
return 0
else
return 1
fi
}
#
# Attach a host to a cluster
#
function attach_host()
{
HOST=${1}
CLST=${2}
# ref https://dev-eole.ac-dijon.fr/issues/16797
#CLST_ID=$(get_cluster_id_by_name ${CLST})
CLST_ID=0
HST_ID=$(get_host_id_by_name ${HOST})
AUTH=$(get_one_auth)
CMD="onecluster"
OPT="addhost ${CLST_ID} ${HST_ID}"
check_host_in_cluster ${HOST} ${CLST}
if [[ ${?} -eq 1 ]]
then
if [[ -n ${CLST_ID} ]]
then
if [[ -n ${HST_ID} ]]
then
RES=$(${CMD} ${OPT} --user ${AUTH%:*} --password ${AUTH#*:})
if [[ ${?} -ne 0 ]]
then
error "Attaching ${HOST} to ${CLST} failed"
else
echo "${HOST} attached to ${CLST}"
return 0
fi
else
error "No host id for ${HOST}"
fi
else
error "No Cluster id for ${CLST}"
fi
else
echo "Host ${HOST} already present in cluster ${CLST}"
fi
return 0
}
#
# Attach a datastore to a cluster
#
# ref https://dev-eole.ac-dijon.fr/issues/16797
#function attach_ds_to_cluster()
#{
# DS=${1}
# CLST=${2}
# CLST_ID=$(get_cluster_id_by_name ${CLST})
# DS_ID=$(get_ds_id_by_name ${ds_name})
# AUTH=$(get_one_auth)
# CMD="onecluster"
# OPT="adddatastore ${CLST_ID} ${DS_ID}"
#
# RES=$(${CMD} ${OPT} --user ${AUTH%:*} --password ${AUTH#*:})
# if [[ ${?} -ne 0 ]]
# then
# error "Attaching ${DS} to ${CLST} failed."
# else
# echo "Datastore ${DS} attached to ${CLST}."
# return 0
# fi
# return 0
#}
function create_datastore()
{
ds_type="${1}"
ds_name="${2}"
local ha=$(CreoleGet activer_one_ha)
# ref https://dev-eole.ac-dijon.fr/issues/16797
#ds_cluster="${3}"
if [[ $(CreoleGet activer_multinode 2>&1) == 'oui' ]] && [[ ${ha} == "non" ]]
then
SYS_TM_MAD='ssh'
ISO_TM_MAD='ssh'
IMG_TM_MAD='ssh'
else
SYS_TM_MAD='shared'
ISO_TM_MAD='shared'
IMG_TM_MAD='qcow2'
fi
echo "Creating datastore ${ds_name}"
TMPL_FILE=$(mktemp)
case ${ds_type} in
"SYSTEM")
cat <<__EOF__ > ${TMPL_FILE}
NAME = ${ds_name}
TM_MAD = ${SYS_TM_MAD}
TYPE = SYSTEM_DS
__EOF__
;;
"ISO")
cat <<__EOF__ > ${TMPL_FILE}
NAME = ${ds_name}
DS_MAD = fs
TM_MAD = ${ISO_TM_MAD}
TYPE = IMAGE_DS
__EOF__
;;
"IMAGE")
cat <<__EOF__ > ${TMPL_FILE}
NAME = ${ds_name}
DS_MAD = fs
TM_MAD = ${ISO_TM_MAD}
TYPE = IMAGE_DS
__EOF__
;;
*) echo "Nothing to do with ${ds_type}"
;;
esac
auth=$(get_one_auth)
cmd="onedatastore"
opt="create --user ${AUTH%:*} --password ${AUTH#*:} ${TMPL_FILE}"
RUN=$(${cmd} ${opt})
if [[ ${?} -eq 0 ]]
then
# ref https://dev-eole.ac-dijon.fr/issues/16797
#attach_ds_to_cluster ${ds_name} ${ds_cluster}
rm ${TMPL_FILE}
return 0
else
return 1
fi
}
function update_datastore()
{
local auth=${1}
local ds_id=${2}
local cmd="onedatastore"
local opt="show"
local multinode=$(CreoleGet activer_multinode 2>&1)
local ha=$(CreoleGet activer_one_ha)
ds_type=""
ds_mad=""
ds_name=""
TMPL_FILE=$(mktemp)
if [[ ${multinode} == 'oui' ]] && [[ ${ha} == "non" ]]
then
SYS_TM_MAD='ssh'
ISO_TM_MAD='ssh'
IMG_TM_MAD='ssh'
else
SYS_TM_MAD='shared'
ISO_TM_MAD='shared'
IMG_TM_MAD='qcow2'
fi
out=$(${cmd} ${opt} ${ds_id} --user ${auth%:*} --password ${auth#*:} | \
awk -F ':' '/^DATASTORE.*INFORMATION/,/DATASTORE CAPACITY/ {gsub(" |\t",""); print $1 ":" $2 " " }')
for line in ${out}
do
[[ ${line} =~ ^TM_MAD ]] && ds_mad=${line#*:}
[[ ${line} =~ ^NAME ]] && ds_name=${line#*:}
[[ ${line} =~ ^TYPE ]] && ds_type=${line#*:}
done
if [[ ${ds_name} == "$(CreoleGet one_ds_system_prefix 2>&1)$(CreoleGet one_cluster_name 2>&1)" ]]
then
cat <<__EOF__ > ${TMPL_FILE}
NAME = ${ds_name}
TM_MAD = ${SYS_TM_MAD}
TYPE = SYSTEM_DS
__EOF__
elif [[ ${ds_name} == "$(CreoleGet one_ds_iso_name 2>&1)" ]]
then
cat <<__EOF__ > ${TMPL_FILE}
NAME = ${ds_name}
DS_MAD = fs
TM_MAD = ${ISO_TM_MAD}
TYPE = IMAGE_DS
__EOF__
elif [[ ${ds_name} == "$(CreoleGet one_ds_image_name 2>&1)" ]]
then
cat <<__EOF__ > ${TMPL_FILE}
NAME = ${ds_name}
DS_MAD = fs
TM_MAD = ${ISO_TM_MAD}
TYPE = IMAGE_DS
__EOF__
else
echo "Nothing to do with ${ds_name}"
fi
if [[ -s ${TMPL_FILE} ]]
then
echo "Updating ${ds_name} datastore"
opt="update ${ds_id} --user ${AUTH%:*} --password ${AUTH#*:} ${TMPL_FILE}"
RUN=$(${cmd} ${opt})
rm ${TMPL_FILE}
return ${?}
else
rm ${TMPL_FILE}
return 1
fi
}
function manage_datastores()
{
# ref https://dev-eole.ac-dijon.fr/issues/16797
#cluster=${1}
AUTH=$(get_one_auth)
# ref https://dev-eole.ac-dijon.fr/issues/16797
#SYSTEM_DS="$(CreoleGet 'one_ds_system_prefix')${cluster}"
SYSTEM_DS="$(CreoleGet 'one_ds_system_prefix')default"
ISO_DS=$(CreoleGet 'one_ds_iso_name')
IMAGE_DS=$(CreoleGet 'one_ds_image_name')
echo "Configuring datastores for Cluster"
sid=$(get_ds_id_by_name ${SYSTEM_DS})
if [[ ${sid} = "ERR" ]]
then
# ref https://dev-eole.ac-dijon.fr/issues/16797
#create_datastore "SYSTEM" "${SYSTEM_DS}" "${cluster}"
create_datastore "SYSTEM" "${SYSTEM_DS}"
else
update_datastore ${AUTH} ${sid}
fi
imgid=$(get_ds_id_by_name ${IMAGE_DS})
if [[ ${imgid} = "ERR" ]]
then
# ref https://dev-eole.ac-dijon.fr/issues/16797
#create_datastore "IMAGE" "${IMAGE_DS}" "${cluster}"
create_datastore "IMAGE" "${IMAGE_DS}"
else
update_datastore ${AUTH} ${imgid}
fi
isoid=$(get_ds_id_by_name ${ISO_DS})
if [[ ${isoid} = "ERR" ]]
then
# ref https://dev-eole.ac-dijon.fr/issues/16797
#create_datastore "ISO" "${ISO_DS}" "${cluster}"
create_datastore "ISO" "${ISO_DS}"
else
update_datastore ${AUTH} ${isoid}
fi
return 0
}
function main()
{
wait_true_retcode "Wait for oned to be started" "onecluster show 0 > /dev/null"
if [ "$(CreoleGet activer_one_ha)" = "oui" ]; then
if [ "$(CreoleGet one_ha_server_index)" != "0" ]; then
# ne pas faire sur les followers
return
fi
fi
#
# Rename default cluster
clst_name=$(CreoleGet one_cluster_name)
rename_default_cluster "${clst_name}"
# Wait 4 seconds for service (ref #16848)
sleep 4
#
# Creating Host
#
if [ ! "$(CreoleGet activer_one_ha)" = "oui" ]; then
if [[ $(CreoleGet eole_module non) != 'hapy-master' ]]
then
host=$(CreoleGet nom_machine)
manage_host ${host}
fi
fi
#
# Attaching Host to the Cluster
#
attach_host ${host} "${clst_name}"
#
# Force host synchronisation
#
sync_host
#
# Création des Datastores
#
manage_datastores "${clst_name}"
}
main $@
exit 0