線上書籍

Home

Proxmox 虛擬主機架設-從無到有(ZFS)

將下列的程式碼直接覆製後存為 1_rsync_1062_all 並放置在 /crond/crondphoto/ 目錄下
並將其設定為可執行
chmod +x 1_rsync_1062_all

 

#!/bin/bash

A=($@)                    # 取得命令列參數
test "${#A[@]}" == "0" && A[0]="rsync"    # 若沒有參數則指定第1個參數為 rsync 同步學校照片檔案 <---
echo ${A[0]}

# ------------------------------------------------------------------------------------------
bashlocaldir="/crond/crondphoto"                # 本程式路徑     
cd ${bashlocaldir}
datename=$(date +%Y-%m-%d-%H-%M-%S)                # 取得現在日期時間
exclude="--exclude-from=exclude-photo.list" #排除目錄 /        # 設定排除檔案設定

echo "設定陣列變數"
echo "設定主機名稱"        # 第一個保留 "--"
    node=("--" "pve" "pve2" "pve3" "pve4" "pvefs" "ezgo12")        # 修改
echo "設定本機端目錄路徑"    # 第一個保留 "00"
    mount_DS214play_nfs=("00" \
        "/nfs/1062/" "/nfs/1062/" "/nfs/1062/" "/nfs/1062/" "/nfs/1062/" "/nfs/1062/")
                # 第一個保留 "0"
    local_photo_path=("0" \
        "VM1/backupd/schoolphoto/1062"        "VM2/backupd/schoolphoto/1062" \
        "VM3/backupd/schoolphoto/1062"        "VM4/backupd/schoolphoto/1062" \
        "pool5T2/backupd/schoolphoto/1062"     "pool2T/backupd/schoolphoto/1062" )

echo "取得主機名稱"
    localname=$(hostname)
echo "設定掛載 NAS DS214play的目錄"

echo "依主機名稱設定本機備份路徑"
        # 設定主機序號
        for ((i=1; i < ${#node[@]}; i++ ));do
        if [ "${localname}" == "${node[$i]}" ];then
            node[0]=$i                    # 設定主機序號
            if [ "${local_photo_path[$i]}" == "" ];then
                echo "本機未做 學校照片 備份 Storage,程式結束!"
                exit
            fi

            mount_DS214play_nfs[0]=${mount_DS214play_nfs[$i]}    # 設定掛載nfs路徑
            local_photo_path[0]=/${local_photo_path[$i]}/        # 設定本機存放路徑]
            echo ${mount_DS214play_nfs[0]}
            echo ${local_photo_path[0]}
        fi
        done

        if [ "${node[0]}" == "--" ];then
            echo "本機主機 ${localname} 並未在設定主機群列表中"
            echo "程式執行中斷"
            exit
        fi
# ------------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------------
function listhelp() {
    echo ""
    echo "-----------------------------------------------------------------------------------"
    echo "-----------------------------------------------------------------------------------"
    echo "$0 語法:"
    echo "$0   rsync (或無參數)                  --->  將 NAS 的指定目錄同步到本機"
    echo "$0       snap                          --->  將本機的儲存目錄建立snapshot"
    echo "$0   sendsnap 本機代號  遠端主機代號   --->  將本機快照同步至遠端主機"
    echo "$0   listsnap                          --->  列出本機端儲存目錄的最後20筆snapshot"
    echo "$0       copy 本機代號  遠端主機代號   --->  將本機最後快照複蓋至遠端主機"
    echo "-----------------------------------------------------------------------------------"
    echo "-----------------------------------------------------------------------------------"
    echo "本機:${localname}  代號:${node[0]} 本機掛載nfs目錄:${mount_DS214play_nfs[0]} 本機儲存目錄:${local_photo_path[0]}"
        for ((i=1; i < ${#node[@]}; i++ ));do
            if [ ${node[$i]} != "" -a ${mount_DS214play_nfs[$i]} != "" -a \
                ${local_photo_path[$i]} != "" ] ; then
                echo "主機代號= $i  主機名稱:${node[$i]} 本機掛載nfs目錄:${mount_DS214play_nfs[$i]} zfs資料集:${local_photo_path[$i]}"
            fi
        done
    echo ""
    echo ""
}
# --------------------------------------------------------------------------------------------------
function get_last_snap() {
#     zfssnaplist_local;        # 本機快照列表檔名
#     zfssnaplist_remote;        # 遠端快照列表檔名
    lastsnapcount=10        # 顯示最後n筆快照
    echo --------------------------
    echo 列出 本機/遠端虛擬機 ${local_photo_path[${node[0]}]} dataset 快照列表的最後10個
    # 設定暫存檔 0 本機 1 遠端
    # 快照 @snap
    zfssnaplist_local[0]="/tmp/sendcopy_"`od -vAn -N8 -tu8 /dev/urandom |sed -e 's/ *//'` # 暫存檔-本機-快照列表
    zfssnaplist_remote[0]=${zfssnaplist_local[0]}_${node[${target_pve}]}                   # 暫存檔-遠端-快照列表
#    echo ${zfssnaplist_local[0]}    # local  snapshot
#    echo ${zfssnaplist_remote[0]}    # remote snapshot
    # -----------------------------------------------------------------------------------------
    echo ${localname}
    echo ${node[${node[0]}]}
    echo ${A[1]}
    echo ${A[2]}
    echo ${node[0]}

    # -----------------------------------------------------------------------------------------
    echo "檢測本機設定"
    test "${A[1]}" != "${node[0]}" && echo "指定來源不是本機,所以程式中斷"
    test "${A[1]}" != "${node[0]}" && exit

    echo "檢測遠端主機設定"
    # 遠端主機代號 >0       遠端主機代號在 ${#node[@]} 範圍內
    if [ "${A[2]}" -gt  "0" ] && [ "${A[2]}" -lt "${#node[@]}" ] && \
        [ ${local_photo_path[${A[2]}]} != "--" ]           && \
        [ "${A[2]}" != "${node[0]}" ] ; then    # 而且遠端主機有備份目錄
        echo "遠端主機 ${node[${A[2]}]} 備份目錄 ${local_photo_path[${A[2]}]} 設定存在"
    else
        echo "---------------------"
        echo "遠端主機 ${node[${A[2]}]} 未設定備份目錄"
        echo "或與本機相同"
        echo "程式停止執行"
        echo "---------------------"
        exit
    fi
    # ------------------------------------------------------------------------
        # 設定遠端主機:${target_pve}
        target_pve=${A[2]}

        echo 遠端主機:${target_pve}
        echo 遠端主機:${node[${target_pve}]}

        # 檢測遠端主機是否開機
        ping -c1 -w1 -t5 ${node[${target_pve}]} > /dev/null
        if [ $? -eq 1 ]; then                   # 檢測遠端主機是否有開機 0 有開機 1 無 $
                       echo "遠端主機 ${target_host} 未回應,遠端主機快照取消!"
                exit
            else
                       echo "遠端主機 ${target_host} 已回應!"
        fi
    # -----------------------------------------------------------------------------------------
    # -----------------------------------------------------------------------------------------
    echo "-------------------------- # 取得快照資料 --------------------"

    echo "取得本機快照資料中..."
    /sbin/zfs list -t snap|grep ${local_photo_path[${node[0]}]} > ${zfssnaplist_local[0]}
    zfssnaplist_local[1]=$(cat ${zfssnaplist_local[0]}|tail -n 1|awk '{print $1}'|cut -d "@" -f 2)
    #echo ${zfssnaplist_local[1]}
    echo ${local_photo_path[${node[0]}]}@${zfssnaplist_local[1]}

    if [ "${A[0]}" == "sendsnap" ];then
        echo "取得遠端主機快照中..."
            ssh root@${node[${target_pve}]} \
        /sbin/zfs list -t snap|grep ${local_photo_path[${target_pve}]} > ${zfssnaplist_remote[0]}
        zfssnaplist_remote[1]=$(cat ${zfssnaplist_remote[0]}|tail -n 1|awk '{print $1}'| \
                    cut -d "@" -f 2)

        #echo ${zfssnaplist_remote[1]}
        echo ${local_photo_path[${target_pve}]}@${zfssnaplist_remote[1]}
    fi

    echo "取得資料完成"

    echo -------------------------------------------------------------------
    echo "本機端最後快照名稱:"${zfssnaplist_local[1]}
    test "${A[0]}" == "sendsnap" && echo "遠端主機最後快照名稱:"${zfssnaplist_remote[1]}

    echo -------------------------------------------------------------------
    echo ${local_photo_path[${node[0]}]}@${zfssnaplist_local[1]}        # 本機
    # 遠端
    test "${A[0]}" == "sendsnap" && echo "${local_photo_path[${target_pve}]}@${zfssnaplist_remote[1]}"
    test "${A[0]}" == "copy"     && echo "${local_photo_path[${target_pve}]}"
    echo -------------------------------------------------------------------
}
# --------------------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------------

# --------------------------
case ${A[0]} in
    "rsync")

    test "$1" = "" && listhelp
        if [ "$1" = "" ] ; then        # 未指定參數
        echo "未指定參數 ---> 自動代入預設 rsync 同步指令"
        echo ""
            read -p "按 Enter 繼續 (取消同步請按 Ctrl-C) 等待1000秒自動執行:" -t 1000 choicekey
            test "$choicekey" != "" && echo "取消同步"
            test "$choicekey" != "" && exit
        fi

    if [ -d /${mount_DS214play_nfs[0]}/ ] && [ -d /${local_photo_path[0]}/ ]; then
        echo "----------------------------------------------------------------"
        echo "同步: NAS ${mount_DS214play}${datasettxt[$i]}/ ---> "
        echo     "本機 ${local_photo_path}${dataset[$i]}"
        echo "指令︰"
        echo ${localname}"#" rsync -avP -e ssh --delete
        echo "            ${exclude}"
        echo "            ${mount_DS214play_nfs[0]}   ${local_photo_path[0]}"

                 rsync -avP -e ssh --delete  \
                ${exclude}         \
                ${mount_DS214play_nfs[0]}     ${local_photo_path[0]}
        echo "--------------------------------------------------------------------------"
        echo "同步: NAS ${mount_DS214play_nfs[0]} ---> " \
            "本機 ${local_photo_path[0]}"" 完成"
        echo "--------------------------------------------------------------------------"
        echo "----------------------------------------------------------------"
    else
        test ! -d ${mount_DS214play_nfs[0]} && echo "掛載遠端nfs目錄 ${mount_DS214play_nfs[0]} 目錄不存在"
        test ! -d ${local_photo_path[0]}    && echo "本地端存放學校照片目錄 ${local_path[0]} 不存在"
        exit
    fi
        ;;
    "snap")
        if [ "${local_photo_path[${node[0]}]}" == \
        "$(/sbin/zfs list|grep ${local_photo_path[${node[0]}]}|awk '{print $1}')" ] ; then
        echo "本地端 zfs dataset ${local_photo_path[${node[0]}]} 存在"
        echo "開始建立快照"
        echo "/sbin/zfs snap ${local_photo_path[0]}@${datename}"
        /sbin/zfs snap ${local_photo_path[${node[0]}]}@${datename}
            if [ $? == 0 ]; then
            echo "快照建立完成(最後20筆快照)"
                /sbin/zfs list -t snap|grep ${local_photo_path[${node[0]}]}|tail -n 20
            else
                echo "快照建立失敗"
            fi
        fi
        ;;
    "listsnap")
        echo "--------------------------------------------------------------------------"
        if [ "${local_photo_path[${node[0]}]}" == \
        "$(/sbin/zfs list|grep ${local_photo_path[${node[0]}]}|awk '{print $1}')" ] ; then
        echo "本地端 zfs dataset ${local_photo_path[${node[0]}]} 存在"
        echo "開始列出 ${local_photo_path[${node[0]}]} 最後20筆快照"
        echo "--------------------------------------------------------------------------"
            /sbin/zfs list -t snap|grep ${local_photo_path[${node[0]}]}|tail -n 20
        fi
        echo "--------------------------------------------------------------------------"
        ;;
    "copy")
        get_last_snap        # 呼叫函式取的本機/遠端最後的快照名稱


    # 遠端
        echo "/sbin/zfs send -v ${local_photo_path[${node[0]}]}@${zfssnaplist_local[1]} | \ "
        echo "          ssh ${node[${target_pve}]} /sbin/zfs receive ${local_photo_path[${target_pve}]} -F"
read
        /sbin/zfs send -v ${local_photo_path[${node[0]}]}@${zfssnaplist_local[1]} \
             | ssh ${node[${target_pve}]} /sbin/zfs receive ${local_photo_path[${target_pve}]} -F
        ;;
    "sendsnap")
        get_last_snap        # 呼叫函式取的本機/遠端最後的快照名稱
# --------------------------------------------------------------------------------------------------
       echo -n "同步 ${local_photo_path[${node[0]}]}@${zfssnaplist_local[1]} 到 "
       echo          ${local_photo_path[${target_pve}]}@${zfssnaplist_remote[1]}

       if [ ${zfssnaplist_local[1]} == ${zfssnaplist_remote[1]} ]; then
        echo "狀態:遠端主機已有相同快照"
        echo "同步:不須同步傳送"
       else
        echo "同步:開始同步傳送"
        echo "/sbin/zfs send -v -I ${local_photo_path[${node[0]}]}@${zfssnaplist_remote[1]}   \ "
        echo "            ${local_photo_path[${node[0]}]}@${zfssnaplist_local[1]} | \ "
        echo "ssh ${node[${target_pve}]} /sbin/zfs receive ${local_photo_path[${target_pve}]} -F "

        /sbin/zfs send -v -I ${local_photo_path[${node[0]}]}@${zfssnaplist_remote[1]}  \
                     ${local_photo_path[${node[0]}]}@${zfssnaplist_local[1]} | \
         ssh ${node[${target_pve}]} /sbin/zfs receive ${local_photo_path[${target_pve}]} -F
       fi
       echo ---------------

        if [ "$?" == "0" ];then
            echo "同步完成!"
            else
                echo "--------------------"
                echo "--------------------"
                echo "同步錯誤!"
                echo "zfs send/receive 失敗!"
                echo "--------------------"
                echo "--------------------"
        fi

    echo -------------------------------------------------------------------
    rm ${zfssnaplist_local[0]};         # 刪除本機暫存檔
    rm ${zfssnaplist_remote[0]};        # 刪除遠端主機快照列表在本機的暫存檔

        ;;

    "*")
        ;;
esac