#!/bin/bash -x
# 集群基础配置

if [ -z "$SSH" ];then
    source /unas/sbin/dualcontroller/config/prepare
fi

CONFFILE=/tmp/dualcontroller
ENVFILE=/unas/etc/dualcontroller/env

if [ -z "$CLUSTER" ];then
    # Example:
    # CLUSTER=unas_cluster
    # CLUSTER_IP=(192.168.0.250 192.168.0.251)
    # HOSTS=(UNASHRX1DTP4V UNAS18Q71DTVZV)
    # IPS=(192.168.0.117 192.168.0.28)
    # HB_IPS=(10.0.0.117 10.0.0.28)
    # PASSES=(password password)
    # DISK=(/dev/nas/data /dev/nas/data2)
    # IPMIIP=(192.168.0.240 192.168.0.241)
    # IPMIUSER=(ADMIN ADMIN)
    # IPMIPASS=(PASSWORD PASSWORD)
    # SMB=1
    # NFS=1
    # FTP=1
    # AFP=1
    # ISCSI=1
    if [ -f $CONFFILE ];then
        source $CONFFILE
        export RUNMODE
        export CLUSTER
        echo "RUNMODE=$RUNMODE" > $ENVFILE
        echo "CLUSTER=$CLUSTER" >> $ENVFILE
    else
        exit 1
    fi
fi

/unas/sbin/dualcontroller/tool/genkey

log_file="/tmp/unas_dc"
echo 0 $STATUS_START > $log_file
cib_file="/tmp/unas_cfg"
export PCS="pcs"
#export PCS="pcs -f $cib_file"

pcs cluster destroy

array_length=${#HOSTS[@]}

# 认证各机器
machines=""
for (( i=0; i<$array_length; i+=1 ))
do
    echo "$PROCESS_AUTH $STATUS_START ${HOSTS[$i]}" >> $log_file
    if HOST=${HOSTS[$i]} ADDR=${IPS[$i]} HB_IP=${HB_IPS[$i]} USERNAME=hacluster PASSWORD=${PASSES[$i]} /unas/sbin/dualcontroller/config/host auth;then
        echo "$PROCESS_AUTH $STATUS_SUCCESS ${HOSTS[$i]}" >> $log_file
        machines="$machines ${HOSTS[$i]} addr=${IPS[$i]} addr=${HB_IPS[$i]}"
    else
        echo "$PROCESS_AUTH $STATUS_FAILED ${HOSTS[$i]}" >> $log_file
        exit 1
    fi
done

# 启用集群
echo "$PROCESS_CLUSTER_SETUP $STATUS_START $CLUSTER" >> $log_file
if pcs cluster setup "$CLUSTER" $machines --enable --start;then
    echo "$PROCESS_CLUSTER_SETUP $STATUS_SUCCESS $CLUSTER" >> $log_file
else
    echo "$PROCESS_CLUSTER_SETUP $STATUS_FAILED $CLUSTER" >> $log_file
    exit 1
fi

if [ "$RUNMODE" == "aa" ]; then
    # 初始化dlm和lvm锁
    # 这两个必须先启动才能执行后续集群配置，比如 Using lock start and lock stop requires lvmlockd
    pcs resource create dlm ocf:pacemaker:controld op monitor interval=30s
    pcs resource clone dlm meta clone-max=2 clone-node-max=1 interleave=true ordered=false
    pcs resource create lvmlockd ocf:heartbeat:lvmlockd op monitor interval=30s
    pcs resource clone lvmlockd meta clone-max=2 clone-node-max=1 notify=true
    pcs constraint colocation add lvmlockd-clone with dlm-clone
    pcs constraint order dlm-clone then lvmlockd-clone kind=Optional
fi

# 不配置stonith它不会启动
for (( i=0; i<$array_length; i+=1 ))
do
    # IPMI，必须先配进stonith让集群启动
    HOST=${HOSTS[$i]} IPMIIP=${IPMIIP[$i]} IPMIUSER=${IPMIUSER[$i]} IPMIPASS=${IPMIPASS[$i]} /unas/sbin/dualcontroller/config/stonith
done

if [ "$RUNMODE" == "aa" ]; then
    # 等到lvmlockd启动完成
    wait_resource lvmlockd-clone
fi

# 清理服务，同时标记为主服务
$PCS resource create UNAS_Main_Node systemd:dc-res-clr op stop timeout=5 on-fail=ignore
if [ "$RUNMODE" == "aa" ]; then
    $PCS resource clone UNAS_Main_Node meta clone-max=2 clone-node-max=1 notify=true
    $PCS constraint order UNAS_Main_Node-clone then dlm-clone kind=Optional
else
    # 至少第一次在当前节点启动，确保配置生效，后续会删
    $PCS constraint location UNAS_Main_Node prefers $(hostname)=100
fi

/unas/sbin/dualcontroller/tool/distribute $ENVFILE

for (( i=0; i<$array_length; i+=1 ))
do
    if [ "$RUNMODE" == "aa" ]; then
        # 资源间的亲和性，避免同一节点上运行多个服务IP
        # 服务IP
        $PCS resource create UNAS_Node_IP$i ocf:heartbeat:IPaddr2 ip=${CLUSTER_IP[$i]} cidr_netmask=32 op monitor interval=30s
        $PCS constraint location UNAS_Node_IP$i prefers ${HOSTS[$i]}=100
        for (( j=0; j<$i; j+=1 ))
        do
            $PCS constraint colocation add UNAS_Node_IP$i with UNAS_Node_IP$j -100
        done
    else
        # 主备模式，绑定主节点
        $PCS resource create UNAS_Node_IP$i ocf:heartbeat:IPaddr2 ip=${CLUSTER_IP[$i]} cidr_netmask=32 op monitor interval=30s
        $PCS constraint colocation add UNAS_Node_IP$i with UNAS_Main_Node
    fi
done

# 给心跳口配置一个IP资源，用来给独占资源进行通信
# 一般HB_IPS[0]就是本地的心跳IP
HB_IP=${HB_IPS[0]}
subnet=$(ip route show src $HB_IP | awk '{print $1}')
# 随机找个能用的IP，避免和现有IP冲突
export HEARTBEAT_IP=$(PING_CHECK=1 /unas/sbin/dualcontroller/tool/rand_ip "$subnet")
$PCS resource create UNAS_Heartbeat_IP ocf:heartbeat:IPaddr2 ip=${HEARTBEAT_IP} cidr_netmask=32 op monitor interval=30s

# 中间状态同步锁
# 在lvm和mount之间，确保挂载时磁盘已经准备好
$PCS resource create disk_ready ocf:heartbeat:Dummy op monitor interval=10s on-fail=ignore
$PCS constraint colocation add disk_ready with UNAS_Main_Node
# mount和服务之间，确保服务启动时磁盘已经挂载好
$PCS resource create mount_ready ocf:heartbeat:Dummy op monitor interval=10s on-fail=ignore
$PCS constraint colocation add mount_ready with UNAS_Main_Node

# 接管存储池
# 由于双控共享存储池的特殊性，所有存储池都必须被集群接管，不然要出错
if [ "$RUNMODE" == "aa" ]; then
    # mdadm
    /unas/sbin/dualcontroller/config/mdadm
    # nvmet
    /unas/sbin/dualcontroller/config/nvmet
fi
# lvm
/unas/sbin/dualcontroller/config/lvm
# zfs
/unas/sbin/dualcontroller/config/zfs

# 初始化配置存储池
if [ "$RUNMODE" == "aa" ]; then
    # 双活模式 挂载配置盘 目前只支持lvm
    CLUNAME=$CLUSTER DISK=$CONFDISK MOUNTPOINT=/unas/etc/dualcontroller/cfg FORMAT=1 /unas/sbin/dualcontroller/config/ocfs2
    wait_resource ocfs0-clone
else
    # 主备模式，直接在本地创建共享卷，后续流程会在集群中创建资源
    # 检查盘类型
    DISK=$CONFDISK MOUNTPOINT=/unas/etc/dualcontroller/cfg /unas/sbin/dualcontroller/config/mount
fi

function takeover_storage() {
    # 初始化配置存储池
    if [ "$RUNMODE" == "aa" ]; then
        # 双活模式 目前只支持lvm
        CLUNAME=$CLUSTER DISK=$datapool MOUNTPOINT=`echo $datapool | sed 's#^/dev#/mnt#g'` /unas/sbin/dualcontroller/config/ocfs2
        wait_resource ocfs0-clone
    else
        # 主备模式
        DISK=$datapool MOUNTPOINT=`echo $datapool | sed 's#^/dev#/mnt#g'` /unas/sbin/dualcontroller/config/mount
    fi
}

for datapool in "${DISK[@]}"
do
if [ -b "$datapool" ] || lvs "$datapool" >/dev/null 2>&1 && [ "$datapool" != $CONFDISK ];then
    takeover_storage
fi
done

# 配置服务

export MAIN_SRV=1
source /unas/sbin/dualcontroller/config/service

# 环境配置，根据需要配
$PCS resource defaults update migration-threshold=2
$PCS resource defaults update resource-stickiness=100
$PCS property set no-quorum-policy=ignore

# 清理不需要的默认资源和约束
main_node_location_id=$(pcs constraint location --full| grep -Eo "location-UNAS_Main_Node-.*-100")
pcs constraint location delete "$main_node_location_id"

# 配置生效
echo "$PROCESS_EFFECT $STATUS_SUCCESS $CLUSTER" >> $log_file

# 额外配置，仲裁服务器

rm $CONFFILE
rm $log_file
