zfs-on-linux / CentOS und Replizierung der Daten

Hallo zusammen,

ich betreibe selber in einem kleinen Rechenzentrum ein ZFS-Storage, welches aus zwei Servern und einem Direct-Attached-Shelf besteht. Die beiden Server sind als Cluster/HA konfiguriert und können jeweils die ZFS-Pools übernehmen, sofern der Partner nicht mehr sauber arbeitet.

Für das eigentliche ZFS Cluster/HA kann ich nur den folgenden Artikel empfehlen – hier steht eigentlich alles wichtige soweit drin:
https://github.com/ewwhite/zfs-ha/wiki

Um hier jedoch noch ein weiteres Netz an Sicherheit einzubinden, habe ich mir kleine Skripte geschrieben. Diese sorgen dafür, dass eine regelmäßige Replizierung der Daten stattfindet (zu einem weiteren Host mit ZFS-Pools). Die Skripte sind leider nicht zu 100% komplett, jedoch möchte ich diese nicht vorenthalten.

Es gibt zwei grundlegende Dateien:
zfs-sync-cron – Wird in den Crontab eingebaut und für eine Ausführung alle 10 Minuten markiert (Executer)
zfs-sync-config – Auf der CLI, dennoch „Möchtegern-Grafische“ Konfiguration der Jobs

#!/bin/sh

myconfig=/etc/zfs-sync.conf
lockfile=/tmp/zfs-sync.lock
debug=false
checklock=true
runsnapshots=true
runreplication=true
runscrub=true
forcefullsync=false
backtitle="ZFS STORAGE MANAGEMENT - CRON SCRIPT WITH Debug ENABLED"
outlog=""

####
#### Check Requirements for Execution
####
if [ ! -f /usr/bin/dialog ]
then
    echo
    echo "Could not found requirement 'dialog'."
    echo "Please install package using 'yum install dialog'."
    echo
    exit 1
fi

if [ ! -f $myconfig ]
then
    echo
    echo "Could not found requirement '$myconfig'."
    echo "Please first run zfs-sync-config to create a configuration file."
    echo
    exit 1
fi

showhelp () {
    echo
    echo "Usage: $0 [OPTION]"
    echo
    echo "Options for Execution:"
    echo " -d  --debug        Enables Debug Output"
    echo " -h  --help         Prints this help message"
    echo " -f  --force        Run Script without checking Lock-File (be careful!)"
    echo " -R  --remove       Removes Lock-File BEFORE run"
    echo " -s  --snapshot     Only runs Snapshotting"
    echo " -r  --replication  Only runs Replication"
    echo " -S  --scrub        Only runs Scrubbing"
    echo " -F  --fullsync     Runs Replication in Full-Sync Mode (Initial!)"
    echo
    echo "Report Bugs to: simon(a)brecht.email"
    echo "Homepage: http://brecht.systems/"
    echo
    exit 1
}

removelock () {
    rm -rf "$lockfile"
}

####
#### Parse Arguments
####
for args in "$@"
do
    case "$args" in
        --debug)
            debug=true
            ;;
        -d)
            debug=true
            ;;
        --help)
            showhelp
            ;;
        -h)
            showhelp
            ;;
        --force)
            checklock=false
            ;;
        -f)
            checklock=false
            ;;
        --remove)
            removelock
            ;;
        -R)
            removelock
            ;;
        --snapshot)
            runreplication=false
            runscrub=false
            ;;
        -s)
            runreplication=false
            runscrub=false
            ;;
        --replication)
            runsnapshots=false
            runscrub=false
            ;;
        -r)
            runsnapshots=false
            runscrub=false
            ;;
        -S)
            runsnapshots=false
            runreplication=false
            ;;
        --scrub)
            runsnapshots=false
            runreplication=false
            ;;
        --fullsync)
            forcefullsync=true
            ;;
        -F)
            forcefullsync=true
            ;;
    esac
done

if [ "$checklock" == "true" ]
then
    if [ -f $lockfile ]
    then
        if [ "$debug" == "true" ]
        then
            echo
            echo "There is an existing lockfile. Please check operation or"
            echo "wait until existing process have been done."
            echo
            echo "Lockfile is located: $lockfile"
            echo
            echo
        fi
        exit 1
    else
        touch "$lockfile"
    fi
fi

aborted () {
    if [ "$debug" == "true" ]
    then
        dialog --backtitle "$backtitle" \
                --infobox "Aborted by user request..." 30 80
        sleep 3
    fi
}

showinfo () {
    outlog+="$1\n"
    if [ "$debug" == "true" ]
    then
        dialog --backtitle "$backtitle" \
                --infobox "$outlog" 30 80
        sleep 1
    fi
}

if [ "$runsnapshots" == "true" ]
then
    ####
    #### Looping through Snapshots
    ####
    showinfo "Looping through Snapshots..."
    cat $myconfig | grep -o "SNAPSHOT=.*" | cut -d "=" -f 2 | while read snap
    do
        # Check if Volume for Snapshot is Local Managed
        snapvol=$(echo $snap | cut -d " " -f 1)
        snapdelta=$(echo $snap | cut -d " " -f 2)
        snapkeep=$(echo $snap | cut -d " " -f 3)
        showinfo "\nChecking if Volume ($snapvol) is locally managed..."
        if [ "`zfs list | cut -d " " -f 1 | grep -c "$snapvol"`" == "1" ]
        then
            # Volume is local and Snapshots are configured
            # lets check Delta
            showinfo "Snapshot ($snapvol) is locally managed. Comparing Dates..."
            mytime="`date +"%Y-%m-%d_%H-%M-%S"`"
            if [ "`zfs list -t snapshot | grep -c "$snapvol@auto-"`" == "0" ]
            then
                lasttime=NONE
            else
                while read -r exsnap
                do
                    lasttime=$(echo $exsnap | cut -d"@" -f2 | cut -d"-" -f2-)
                done <<< "`zfs list -t snapshot | cut -d " " -f 1 | grep -o "$snapvol@auto-.*" | sort`"
                showinfo "Local Time: $mytime - Last Snapshot Time: $lasttime"
            fi
            snapdo=no
            if [ "$lasttime" == "NONE" ]
            then
                showinfo "No Snapshots found, creating new one..."
                snapdo=yes
            fi
            if [ "$lasttime" != "NONE" ]
            then
                comparenow=$(echo $mytime | sed "s/_/ /g")
                read Y M D h m s <<< ${comparenow//[-: ]/ }
                comparenow=$(date -d "$Y$M$D $h:$m:$s" "+%s")
                comparesnap=$(echo $lasttime | sed "s/_/ /g")
                read Y M D h m s <<< ${comparesnap//[-: ]/ }
                comparesnap=$(date -d "$Y$M$D $h:$m:$s $snapdelta hours" "+%s")
                showinfo "CompareNow:  $comparenow"
                showinfo "CompareSnap: $comparesnap"
                if [ $comparenow -ge $comparesnap ]
                then
                    showinfo "Snapshot found, but is too old - creating new one..."
                    snapdo=yes
                fi
            fi
            if [ "$snapdo" == "yes" ]
            then
                # create snapshot
                zfs snapshot -r $snapvol@auto-$mytime
            fi
            # check cleanup
            snapcount=$(zfs list -t snapshot | grep -o "$snapvol@auto-" | sort | wc -l)
            if [ $snapcount -gt $snapkeep ]
            then
                showinfo "Time to Cleanup... Existing Snapshots: $snapcount (Keep: $snapkeep)"
                snapremove=$((snapcount-snapkeep))
                showinfo "Have to remove $snapremove Snapshots..."
                count=0
                while read -r snap
                do
                    if [ $snapremove -gt $count ]
                    then
                        showinfo "Removing Snapshot: $snap"
                        zfs destroy $snap
                    else
                        showinfo "Enough cleaning up ;-)"
                        break;
                    fi
                    count=$((count+1))
                done <<< "`zfs list -t snapshot | grep -o "$snapvol@auto-.*" | cut -d " " -f 1 | sort`"
            fi
        fi
    done
fi

if [ "$runreplication" == "true" ]
then
    showinfo "Looping through Replications..."
    cat $myconfig | grep -o "REPLICATION=.*" | cut -d "=" -f 2 | while read replsnap
    do
        # Check if Volume for Snapshot is Local Managed
        snapvol=$(echo $replsnap | cut -d " " -f 1)
        snapdsthost=$(echo $replsnap | cut -d " " -f 2)
        snapdstvol=$(echo $replsnap | cut -d " " -f 3)
        snapdstname=$(echo $snapvol | cut -d"/" -f2-)
        snapinitial=no
        snapinkremental=no
        snaplastnamelocal=
        snaplastnameremote=
        snapexisting=0
        showinfo "\nChecking if Volume ($snapvol) is locally managed..."
        if [ "`zfs list | cut -d " " -f 1 | grep -c "$snapvol"`" == "1" ]
        then
            showinfo "Volume ($snapvol) is locally managed... Checking Replication..."
            if [ "$forcefullsync" == "true" ]
            then
                showinfo "Full-Sync Flag is SET, cleaning up old Replications..."
                ssh $snapdsthost "zfs list -t snapshot | cut -d\" \" -f1 | grep \"$snapdstvol/$snapdstname@auto-\" | xargs -n1 zfs release -r keep" < /dev/null >/dev/null
                ssh $snapdsthost "zfs list -t snapshot | cut -d\" \" -f1 | grep \"$snapdstvol/$snapdstname@auto-\" | xargs -n1 zfs destroy" < /dev/null >/dev/null
                zfs list -t snapshot | cut -d" " -f1 | grep "$snapvol@auto-" | xargs -n1 zfs release -r keep
            fi
            if [ "`ssh $snapdsthost "zfs list -t snapshot" < /dev/null | grep -c "$snapdstvol/$snapdstname@auto-"`" == "0" ]
            then
                showinfo "Doing initial Sync of Snapshots..."
                snapinitial=yes
            else
                showinfo "Doing inkremental Sync of Snapshots..."
                snapinkremental=yes
            fi
            if [ "$snapinitial" == "yes" ]
            then
                # get first snapshot of volume
                firstsnap=$(zfs list -t snapshot | grep "$snapvol@auto-" | cut -d " " -f 1 | sort -r | tail --line=1)
                showinfo "Sending First Snapshot: $firstsnap to volume $snapdstvol"
                zfs send -R "$firstsnap" | ssh "$snapdsthost" zfs recv -Fdu "$snapdstvol"
                snaplastnamelocal="$firstsnap"
                snaplastnameremote=$(ssh $snapdsthost "zfs list -t snapshot" < /dev/null| grep "$snapdstvol/$snapdstname" | cut -d " " -f 1)
                zfs hold keep $firstsnap
                ssh "$snapdsthost" "zfs hold keep $snaplastnameremote"
                # check if more snapshots available
                countsnap=$(zfs list -t snapshot | grep -c "$snapvol@auto-")
                if [ "$countsnap" != "1" ]
                then
                    showinfo "More Snapshots available... Setting Inkremental to YES..."
                    snapinkremental=yes
                fi
            else
                snaplastnamelocal=$(ssh $snapdsthost "zfs list -t snapshot" < /dev/null| grep "$snapvol@auto-" | cut -d " " -f 1 | sort | tail --line=1)
            fi
            if [ "$snapinkremental" == "yes" ]
            then
                # fetching all local snapshots
                showinfo "Inkremental sending of Snapshots $snapvol..."
                while read -r localsnap
                do
                    # check if snapshot is available on remote site
                    snaptimestamp=$(echo "$localsnap" | cut -d"@" -f2- | cut -d"-" -f2-)
                    remotesnap="$snapdstvol/$snapdstname@auto-$snaptimestamp"
                    showinfo "$localsnap <> $remotesnap"
                    if [ "`ssh $snapdsthost "zfs list -t snapshot" < /dev/null | grep -c "$remotesnap"`" != "1" ]
                    then
                        showinfo "Snapshot $localsnap not found, sending inkremental (last snaps: $snaplastnamelocal)"
                        zfs send -R -I "$snaplastnamelocal" "$localsnap" | ssh "$snapdsthost" zfs recv -Fdu "$snapdstvol"
                        zfs release -r keep $snaplastnamelocal
                        zfs hold keep $localsnap
                        ssh "$snapdsthost" "zfs release -r keep $snaplastnameremote ; zfs hold keep $remotesnap" < /dev/null
                    fi
                    snaplastnamelocal="$localsnap"
                    snaplastnameremote="$remotesnap"
                done <<< "`zfs list -t snapshot | grep -o "$snapvol@auto-.*" | cut -d " " -f 1 | sort`"
            fi
        fi
    done
fi

if [ "$runscrub" == "true" ]
then
    ####
    #### Looping through Volumes
    ####
    showinfo "Looping through Volumes for Scrubbing..."
    cat $myconfig | grep -o "SCRUB=.*" | cut -d "=" -f 2 | while read snap
    do
        # Check if Volume for Snapshot is Local Managed
        scrubdo=no
        scrubvol=$(echo $snap | cut -d " " -f 1)
        scrubtime=$(echo $snap | cut -d " " -f 2)
        mytime="`date +"%Y-%m-%d_%H-%M-%S"`"
        showinfo "\nChecking if Volume ($scrubvol) is locally managed..."
        if [ "`zpool list -H -o "name" | grep -c "$scrubvol"`" == "1" ]
        then
            # Volume is local and Scrubbing is configured
            lastscrub=$(zpool status $scrubvol | grep scan)
            if [ "`echo $lastscrub | grep -c "progress"`" == "1" ]
            then
                showinfo "Scrubbing already in progress..."
            else
                if [ "`echo $lastscrub | grep -c "none"`" == "1" ]
                then
                    scrubdo=yes
                    showinfo "Scrubbing was never done. Setting Up Task for it..."
                else
                    comparenow=$(echo $mytime | sed "s/_/ /g")
                    read Y M D h m s <<< ${comparenow//[-: ]/ }
                    comparenow=$(date -d "$Y$M$D $h:$m:$s" "+%s")
                    comparescrub=$(echo $lastscrub | grep -o -E "on\W(.*)" | cut -d " " -f 2-)
                    scrubtime=$((scrubtime*24))
                    comparescrub=$(date -d "$comparescrub $scrubtime hours" +"%s")
                    showinfo "CompareNow  : $comparenow"
                    showinfo "CompareScrub: $comparescrub"
                    if [ $comparenow -ge $comparescrub ]
                    then
                        showinfo "Scrub found, but is too old - task a new one..."
                        scrubdo=yes
                    fi
                fi
            fi
            if [ "$scrubdo" == "yes" ]
            then
                zpool scrub $scrubvol
            fi
        fi
    done
fi


if [ "$checklock" == "true" ]
then
    removelock
fi

 

Und nun noch die zfs-sync-config:

#!/bin/sh

####
#### Check Requirements for Execution
####
if [ ! -f /usr/bin/dialog ]
then
    echo
    echo "Could not found requirement 'dialog'."
    echo "Please install package using 'yum install dialog'."
    echo
    exit 1
fi



submenu () {
    case "$1" in
        1)
            # Send Authorized Key to Remote-Host
            subret=$(dialog --stdout --title "Send Authorized Key to Remote-Host" \
                    --backtitle "$backtitle" \
                    --inputbox "Enter Remote Host" 8 50)
            case $? in
                0)
                    # Pressed OK
                    showinfo "Exchanging Hostkeys..."
                    if [ ! -f /root/.ssh/id_rsa ]
                    then
                        ssh-keygen -t rsa
                    fi
                    cat .ssh/id_rsa.pub | ssh root@$subret "mkdir -p .ssh ; cat >> .ssh/authorized_keys"
                    showinfo "Command completed."
                    ;;
                *)
                    # Pressed Cancel
                    aborted
                    ;;
            esac
            ;;
        2)
            # Manage Snapshot
            subret=$(dialog --stdout --title "Manage Snapshot" \
                    --backtitle "$backtitle" \
                    --no-cancel \
                    --menu "Please choose an option:" 15 80 10 \
                    1 "ZFS: List all local Snapshots" \
                    2 "ZFS: Remove dedicated Snapshot" \
                    3 "ZFS: Remove ALL Snapshots" \
                    4 "ZFS: Create manual Snapshot (recursive)" \
                    5 "ZFS: Schedule automatic Snapshot (recursive)" \
                    6 "ZFS: Un-Schedule automatic Snapshot" \
                    0 "Back to Main Menu" \
                    )
            if [ $subret -eq 0 ] || [ $? -eq 255 ]
            then
                echo
            else
                myret=$((subret+200))
                submenu $myret
            fi
            ;;
        201)
            # 2->1 List all local Snapshots
            showinfo "Retrieving local snapshots..."
            tempfile=$(mktemp)
            zfs list -t snapshot > "$tempfile"
            dialog --title "zfs list -t snapshot" \
                    --backtitle "$backtitle" \
                    --textbox "$tempfile" 15 80
            rm "$tempfile"
            submenu 2
            ;;
        202)
            # 2->2 Remove dedicated Snapshot
            showinfo "Retrieving local snapshots..."
            snapret=$(zfs list -t snapshot | cut -d " " -f 1 | grep -v -E "NAME"| awk -F\; '{print FNR" "$1""}' | xargs dialog \
                    --stdout \
                    --title "Remove dedicated Snapshot" \
                    --backtitle "$backtitle" \
                    --menu "Please choose an option:" 15 80 10
                    )
            if ([ -z $snapret ])
            then
                submenu 2
            else
                zfs list -t snapshot | cut -d " " -f 1 | grep -v -E "NAME"| awk -F\; '{print FNR" "$1""}' | while read snap
                do
                    snapid=`echo $snap | cut -d" " -f1`
                    snapname=`echo $snap | cut -d" " -f2`
                    if [ "$snapid" == "$snapret" ]
                    then
                        showinfo "Removing snapshot: $snapname"
                        zfs destroy -r "$snapname"
                    fi
                done
                submenu 202
            fi
            ;;
        203)
            # 2->3 Remove all local Snapshots
            showinfo "Removing all local Snapshots..."
            zfs list -t snapshot | cut -d " " -f 1 | grep -v -E "NAME" | xargs zfs destroy -r
            submenu 2
            ;;
        204)
            # 2->4 Create manual snapshot
            showinfo "Retrieving local zfs volumes..."
            volret=$(zfs list | cut -d " " -f 1 | grep -v -E "NAME"| awk -F\; '{print FNR" "$1""}' | xargs dialog \
                    --stdout \
                    --title "Create manual Snapshot" \
                    --backtitle "$backtitle" \
                    --menu "Please choose an option:" 15 80 10
                    )
            if ([ -z $volret ])
            then
                submenu 2
            else
                zfs list | cut -d " " -f 1 | grep -v -E "NAME"| awk -F\; '{print FNR" "$1""}' | while read zfsvol
                do
                    volid=`echo $zfsvol | cut -d" " -f1`
                    volname=`echo $zfsvol | cut -d" " -f2`
                    if [ "$volid" == "$volret" ]
                    then
                        subret=$(dialog --stdout --title "Create manual Snapshot ($volname)" \
                                --backtitle "$backtitle" \
                                --inputbox "Enter Snapshot Name" 8 50)
                        case $? in
                            0)
                                # Pressed OK
                                showinfo "Creating manual Snapshot (vol: $volname, name: $subret)"
                                zfs snapshot -r $volname@manual-$subret
                                showinfo "Command completed."
                                ;;
                            *)
                                # Pressed Cancel
                                aborted
                                ;;
                        esac
                    fi
                done
                submenu 2
            fi
            ;;
        205)
            # 2->5 Schedule automatic Snapshot
            showinfo "Retrieving local zfs volumes..."
            volret=$(zfs list | cut -d " " -f 1 | grep -v -E "NAME"| awk -F\; '{print FNR" "$1""}' | xargs dialog \
                    --stdout \
                    --title "Create manual Snapshot" \
                    --backtitle "$backtitle" \
                    --menu "Please choose an option:" 15 80 10
                    )
            if ([ -z $volret ])
            then
                submenu 2
            else
                zfs list | cut -d " " -f 1 | grep -v -E "NAME"| awk -F\; '{print FNR" "$1""}' | while read zfsvol
                do
                    volid=`echo $zfsvol | cut -d" " -f1`
                    volname=`echo $zfsvol | cut -d" " -f2`
                    if [ "$volid" == "$volret" ]
                    then
                        if [ "`grep -c "SNAPSHOT=$volname" $myconfig`" == "0" ]
                        then
                            subretinterval=$(dialog --stdout --title "Schedule automatic Snapshot ($volname)" \
                                    --backtitle "$backtitle" \
                                    --menu "Select Interval:" 15 80 10 \
                                    1 "1 hour" \
                                    2 "6 hours" \
                                    3 "12 hours" \
                                    4 "1 day" \
                                    )
                            case $? in
                                0)
                                    # Pressed OK
                                    subretkeep=$(dialog --stdout --title "Schedule automatic Snapshot ($volname)" \
                                            --backtitle "$backtitle" \
                                            --menu "Keep X existing Snapshots:" 15 80 10 \
                                            1 "Keep 1 Snapshot" \
                                            2 "Keep 5 Snapshots" \
                                            3 "Keep 7 Snapshots" \
                                            4 "Keep 30 Snapshots" \
                                            )
                                    case $? in
                                        0)
                                            # Pressed OK
                                            showinfo "Creating Configuration..."
                                            case $subretinterval in
                                                1)
                                                    snapint=1
                                                    ;;
                                                2)
                                                    snapint=6
                                                    ;;
                                                3)
                                                    snapint=12
                                                    ;;
                                                *)
                                                    snapint=24
                                                    ;;
                                            esac
                                            case $subretkeep in
                                                1)
                                                    snapkeep=1
                                                    ;;
                                                2)
                                                    snapkeep=5
                                                    ;;
                                                3)
                                                    snapkeep=7
                                                    ;;
                                                *)
                                                    snapkeep=30
                                                    ;;
                                            esac
                                            echo "SNAPSHOT=$volname $snapint $snapkeep" >> $myconfig
                                            showinfo "Command completed."
                                            ;;
                                        *)
                                            # Pressed Cancel
                                            aborted
                                            ;;
                                    esac
                                    ;;
                                *)
                                    # Pressed Cancel
                                    aborted
                                    ;;
                            esac
                        else
                            showinfo "Could not create task! Please check configuration, there is another task for this volume."
                            sleep 5
                        fi
                    fi
                done
                submenu 2
            fi
            ;;

        206)
            # 2->6 Unschedule automatic Snapshot
            showinfo "Retrieving local zfs volumes..."
            volret=$(cat $myconfig | grep -o "SNAPSHOT=.*" | cut -d "=" -f 2 | cut -d " " -f 1 | awk -F\; '{print FNR" "$1""}' | xargs dialog \
                    --stdout \
                    --title "Unschedule automatic Snapshot" \
                    --backtitle "$backtitle" \
                    --menu "Please choose an option:" 15 80 10
                    )
            if ([ -z $volret ])
            then
                submenu 2
            else
                cat $myconfig | grep -o "SNAPSHOT=.*" | cut -d "=" -f 2 | awk -F\; '{print FNR" "$1""}' | while read zfsvol
                do
                    volid=`echo $zfsvol | cut -d" " -f1`
                    volname=`echo $zfsvol | cut -d" " -f2`
                    if [ "$volid" == "$volret" ]
                    then
                        if [ "`grep -c "$volname" $myconfig`" == "0" ]
                        then
                            showinfo "Could not found any scheduled Snapshot for Volume $volname !"
                        else
                            tempfile=$(mktemp)
                            cat $myconfig | grep -v "SNAPSHOT=$volname" > $tempfile
                            cat $tempfile > $myconfig
                            rm $tempfile
                            showinfo "Scheduled Snapshot removed."
                        fi
                    fi
                done
                submenu 2
            fi
            ;;

        3)
            # Manage Replication
            subret=$(dialog --stdout --title "Manage Replication" \
                    --backtitle "$backtitle" \
                    --no-cancel \
                    --menu "Please choose an option:" 15 80 10 \
                    1 "List all Replications" \
                    2 "Add Replication Configuration" \
                    3 "Remove Replication Configuration" \
                    0 "Back to Main Menu" \
                    )
            if [ $subret -eq 0 ] || [ $? -eq 255 ]
            then
                echo
            else
                myret=$((subret+300))
                submenu $myret
            fi
            ;;

        301)
            # Show Replications
            showinfo "Retrieving configuration file..."
            tempfile=$(mktemp)
            cat $myconfig | grep -o "REPLICATION=.*" | cut -d "=" -f 2 > $tempfile
            dialog --title "Show Replication Config" \
                    --backtitle "$backtitle" \
                    --textbox "$tempfile" 15 80
            rm $tempfile
            submenu 3
            ;;

        302)
            # 3->2 Add Replication Config
            showinfo "Retrieving snapshot configuration..."
            if [ "`grep -c "SNAPSHOT=" $myconfig`" == "0" ]
            then
                showinfo "Please configure automatic Snapshot first - this is mandatory to configure replication!"
                sleep 5
                return
            fi
            volret=$(cat $myconfig | grep -o "SNAPSHOT=.*" | cut -d "=" -f 2 | cut -d " " -f 1 | awk -F\; '{print FNR" "$1""}' | xargs dialog \
                    --stdout \
                    --title "Add Replication Configuration" \
                    --backtitle "$backtitle" \
                    --menu "Please choose an option:" 15 80 10
                    )
            if ([ -z $volret ])
            then
                submenu 3
            else
                cat $myconfig | grep -o "SNAPSHOT=.*" | cut -d "=" -f 2 | awk -F\; '{print FNR" "$1""}' | while read zfsvol
                do
                    volid=`echo $zfsvol | cut -d" " -f1`
                    volname=`echo $zfsvol | cut -d" " -f2`
                    if [ "$volid" == "$volret" ]
                    then
                        subrethost=$(dialog --stdout --title "Add Replication Configuration ($volname)" \
                                --backtitle "$backtitle" \
                                --inputbox "Enter Remote Host:" 8 50)
                        case $? in
                            0)
                                # Pressed OK
                                subretvol=$(ssh root@$subrethost "zfs list" | cut -d " " -f 1 | grep -v -E "NAME"| awk -F\; '{print FNR" "$1""}' | xargs dialog \
                                        --stdout \
                                        --title "Add Replication Configuration ($volname to host $subrethost)" \
                                        --backtitle "$backtitle" \
                                        --menu "Please choose an option:" 15 80 10
                                        )
                                if [ -z $subretvol ]
                                then
                                    # Pressed Cancel
                                    aborted
                                    submenu 3
                                else
                                    # Pressed OK
                                    ssh root@$subrethost "zfs list" | cut -d " " -f 1 | grep -v -E "NAME"| awk -F\; '{print FNR" "$1""}' | while read zfsvol2
                                    do
                                        vol2id=`echo $zfsvol2 | cut -d" " -f1`
                                        vol2name=`echo $zfsvol2 | cut -d" " -f2`
                                        if [ "$vol2id" == "$subretvol" ]
                                        then
                                            showinfo "Creating Replication Configuration..."
                                            echo "REPLICATION=$volname $subrethost $vol2name" >> $myconfig
                                            showinfo "Command completed."
                                        fi
                                    done
                                fi
                                ;;
                            *)
                                # Pressed Cancel
                                aborted
                                ;;
                        esac
                    fi
                done
                submenu 3
            fi
            ;;

        303)
            # 3->3 Remove Replication Config
            showinfo "Retrieving configuration..."
            replret=$(cat $myconfig | grep -o "REPLICATION=.*" | cut -d "=" -f 2 | awk -F\; '{print FNR" \""$1"\""}' | xargs dialog \
                    --stdout \
                    --title "Remove Replication Config" \
                    --backtitle "$backtitle" \
                    --menu "Please choose an option:" 15 80 10
                    )
            if ([ -z $replret ])
            then
                submenu 3
            else
                cat $myconfig | grep -o "REPLICATION=.*" | cut -d "=" -f 2 | awk -F\; '{print FNR" \""$1"\""}' | while read repl
                do
                    replid=`echo $repl | cut -d" " -f1`
                    replname=`echo $repl | cut -d" " -f2- | sed s/\"//g`
                    if [ "$replid" == "$replret" ]
                    then
                        if [ "`grep -c "$replname" $myconfig`" == "0" ]
                        then
                            showinfo "Could not found any replication entry: $replname !"
                            sleep 5
                        else
                            tempfile=$(mktemp)
                            cat $myconfig | grep -v "REPLICATION=$replname" > $tempfile
                            cat $tempfile > $myconfig
                            rm $tempfile
                            showinfo "Replication Configuration removed."
                        fi
                    fi
                done
                submenu 3
            fi
            ;;

        4)
            # Manage Cluster
            showinfo "Retrieving Cluster Status..."
            tempfile=$(mktemp)
            pcs status > $tempfile
            dialog --title "Cluster Status (pcs status)" \
                    --backtitle "$backtitle" \
                    --textbox "$tempfile" 15 80
            rm $tempfile
            ;;


        5)
            # Show Configuration
            showinfo "Retrieving configuration file..."
            dialog --title "$myconfig" \
                    --backtitle "$backtitle" \
                    --textbox "$myconfig" 15 80
            ;;

        6)
            # Sync Configuration
            subret=$(dialog --stdout --title "Sync Configuration to Remote-Host" \
                    --backtitle "$backtitle" \
                    --inputbox "Enter Remote Host" 8 50)
            case $? in
                0)
                    # Pressed OK
                    showinfo "Synchronizing Configuration..."
                    scp $myconfig root@$subret:$myconfig
                    showinfo "Command completed."
                    ;;
                *)
                    # Pressed Cancel
                    aborted
                    ;;
            esac
            ;;

        8)
            # Command Line
            /bin/bash
            ;;

        9)
            # Manage ZFS Scrubs

            subret=$(dialog --stdout --title "Manage ZFS Scrubs" \
                    --backtitle "$backtitle" \
                    --no-cancel \
                    --menu "Please choose an option:" 15 80 10 \
                    1 "List all Scrubs" \
                    2 "Add Scrub Configuration" \
                    3 "Remove Scrub Configuration" \
                    0 "Back to Main Menu" \
                    )
            if [ $subret -eq 0 ] || [ $? -eq 255 ]
            then
                echo
            else
                myret=$((subret+900))
                submenu $myret
            fi
            ;;

        901)
            # Show Scrubs
            showinfo "Retrieving configuration file..."
            tempfile=$(mktemp)
            cat $myconfig | grep -o "SCRUB=.*" | cut -d "=" -f 2 > $tempfile
            dialog --title "Show Scrub Config" \
                    --backtitle "$backtitle" \
                    --textbox "$tempfile" 15 80
            rm $tempfile
            submenu 9
            ;;

        902)
            # 9->2 Add Scrub Config
            showinfo "Retrieving scrub configuration..."
            if [ "`zpool list -H -o "name" | wc -l`" == "0" ]
            then
                showinfo "Please configure an zfs pool first - it is mandatory for scrubbing!"
                sleep 5
                return
            fi
            scrubret=$(zpool list -H -o "name" | cut -d " " -f 1 | awk -F\; '{print FNR" "$1""}' | xargs dialog \
                    --stdout \
                    --title "Add Scrub Configuration" \
                    --backtitle "$backtitle" \
                    --menu "Please choose an option:" 15 80 10
                    )
            if ([ -z $scrubret ])
            then
                submenu 9
            else
                zpool list -H -o "name" | cut -d " " -f 1 | awk -F\; '{print FNR" \""$1"\""}' | while read scrub
                do
                    scrubid=`echo $scrub | cut -d" " -f1`
                    scrubname=`echo $scrub | cut -d" " -f2 | sed s/\"//g`
                    if [ "$scrubid" == "$scrubret" ]
                    then
                        subretinterval=$(dialog --stdout --title "Schedule automatic Scrubbing ($scrubname)" \
                                --backtitle "$backtitle" \
                                --menu "Select Interval:" 15 80 10 \
                                1 "1 day" \
                                2 "7 days" \
                                3 "30 days" \
                                4 "90 days" \
                                )
                        case $? in
                            0)
                                # Pressed OK
                                showinfo "Creating Configuration..."
                                case $subretinterval in
                                    1)
                                        scrubtime=1
                                        ;;
                                    2)
                                        scrubtime=7
                                        ;;
                                    3)
                                        scrubtime=30
                                        ;;
                                    *)
                                        scrubtime=90
                                        ;;
                                esac
                                echo "SCRUB=$scrubname $scrubtime" >> $myconfig
                                showinfo "Command completed."
                                ;;
                            *)
                                # Pressed Cancel
                                aborted
                                ;;
                        esac
                    fi
                done
                submenu 9
            fi
            ;;

        903)
            # 9->3 Remove Scrub Config
            showinfo "Retrieving configuration..."
            scrubret=$(cat $myconfig | grep -o "SCRUB=.*" | cut -d "=" -f 2 | cut -d " " -f 1 | awk -F\; '{print FNR" \""$1"\""}' | xargs dialog \
                    --stdout \
                    --title "Remove Scrub Config" \
                    --backtitle "$backtitle" \
                    --menu "Please choose an option:" 15 80 10
                    )
            if ([ -z $scrubret ])
            then
                submenu 9
            else
                cat $myconfig | grep -o "SCRUB=.*" | cut -d "=" -f 2 | cut -d " " -f 1 | awk -F\; '{print FNR" \""$1"\""}' | while read scrub
                do
                    scrubid=`echo $scrub | cut -d" " -f1`
                    scrubname=`echo $scrub | cut -d" " -f2- | sed s/\"//g`
                    if [ "$scrubid" == "$scrubret" ]
                    then
                        if [ "`grep -c "$scrubname" $myconfig`" == "0" ]
                        then
                            showinfo "Could not found any scrub entry: $replname !"
                            sleep 5
                        else
                            tempfile=$(mktemp)
                            cat $myconfig | grep -v "SCRUB=$scrubname" > $tempfile
                            cat $tempfile > $myconfig
                            rm $tempfile
                            showinfo "Scrub Configuration removed."
                        fi
                    fi
                done
                submenu 9
            fi
            ;;


    esac
}

aborted () {
    dialog --backtitle "$backtitle" \
            --infobox "Aborted by user request..." 5 60
    sleep 1
}

showinfo () {
    dialog --backtitle "$backtitle" \
            --infobox "$1" 5 60
    sleep 1
}


exitcode=-1
myhostname=`hostname`
backtitle="ZFS STORAGE MANAGEMENT (Node: `echo $myhostname`)"
myconfig=/etc/zfs-sync.conf

if [ ! -f $myconfig ]
then
    touch $myconfig
fi
while [ $exitcode -lt 0 ]
do
    ret=$(dialog --stdout --title "Main Menu" \
            --backtitle "$backtitle" \
            --no-cancel \
            --menu "Please choose an option:" 15 80 10 \
            1 "Send Authorized Key to Remote-Host" \
            2 "Manage Snapshot" \
            3 "Manage Replication" \
            4 "Manage Cluster (Pakemaker/Corosync)" \
            5 "Display Configuration" \
            6 "Synchronize Configuration" \
            7 "Install Cron-Daemon File" \
            8 "Command Line Interface" \
            9 "Manage ZFS Scrubs" \
            0 "Logout" \
            )
    if [ $ret -eq 0 ] || [ $? -eq 255 ]
    then
        exitcode=0
    else
        submenu $ret
    fi
done

 

Fröhliches Synchronisieren wünsche ich! ;-)

Empfohlene Beiträge

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Schaltfläche "Zurück zum Anfang"