#!/bin/bash ############ ## ##THIS NEW SCRIPT WILL RESIDE ON TOMCAT AND DO THE FOLLOWING ## ## ##NEEDED UPGRADES ## Check if required servers are online ## If not, activate them via WOL, wait, anc check again ## ## 8/6/2019 - changed builtar to not use chown. Instead, use chgrp to change to familyshare ## MUST ensure sync function works with this change on ENTERPRISE!! ## This eliminates need for sudo to run script ## ## ADD command -v wol2 to check if script is installed ## ## use wol2 to start and stop enterprise ## ## Build debian to place this script in either: ## - /.local for user ## - /usr/local/bin for global ## Symlink to /usr/local/bin for ease of use ## ## Interactive Menu Mode: ## ## If no flags passed, start interactive mode with promopts for: ## - What needs to be done (build tar, sync, or clean) ## - Based on result, what source and destintation (if syncing or building tar) ## - ## ############# ## DEFINE VARIABLES ## DATE=$(date +%b-%d-%T) VERSION=0.04 LOCALARCHIVEPATH=/storage/backup #PIHOMEPATHTOFILES=home/pi/ ## Folder containing data that will be backed up PIHOMEPATHTOFILES=home/pi/scripts ## USE THIS PROFILE ONLY FOR TESTING- ARCHIVES ONLY A SMALL FOLDER PIHOMEFOLDER=PiHomeBackup ## Name of Folder that will store the archives PIHOMEFILENAME=PiHomeBackup-$DATE.tar.gz ## Filename structure for archives #OWNCLOUDPATHTOFILES=storage/owncloud/ ## Folder containing data that will be backed up OWNCLOUDPATHTOFILES=storage/owncloud/data/mike/files/Network ## Folder containing data that will be backed up OWNCLOUDFOLDER=PiOwncloudBackup ## Name of Folder that will store the archives OWNCLOUDFILENAME=PiOwncloudArchive-$DATE.tar.gz ## Filename structure for archives ENTERPRISESTORAGE=/storage/backup/ ENTERPRISESHARE=/storage/ENTERPRISESHARE PCSHARE=/storage/PCSHARE PATHTOLOG=/var/log/TOMCAT.log VERBOSITY=2 ## Default Verbosity Normal (Debug Level 1 -C flag, Critical Level 3 -S flag) LOGLEVEL=1 PIHOMEKEEPFILES=4 ## Number of local backups that will be kept after cleaning OWNCLOUDKEEPFILES=10 ## Number of local backups that will be kept after cleaning ## Arrays for servers to sync ## ## arrNAME=(Common Name, IP, remote folder to mount, local location for mount, username, password) ## arrENTERPRISE=(ENTERPRISE 192.168.100.27 /backup $ENTERPRISESHARE mike cherokee2) arrPC=(PC 192.168.100.51 /Mavrick_Pictures $PCSHARE NetworkUser cherokee2) ## FLAGS ## FLAGBUILD=0 FLAGSYNC=0 FLAGHOME=0 FLAGOWNCLOUD=0 FLAGPICTURES=0 FLAGPHONE=0 FLAGCLEAN=0 ## If 0, -C must be called to clean after archiving. If 1, cleaning will occur automatically FLAGTESTING=0 ## TEST MODE ACTIVE IF 1 OR HIGHER ## ## END VARIABLES ## ## BEGIN FUNCTIONS ## addtolog () { ####LOG LEVELS#### # Log levels: # 0 - Write to log file only # 1 - Write to Log file and screen at debug verbosity level (useful for debugging) # 2 - Write to Log file and screen at Normal Verbosity Level # 3 - Write to Log File and screen at CRITICAL Verbosity Level # default - level 1 (debgug verbosity) ################## if [ -z "$2" ]; then intLOGLEVEL="2" #if no variable passed, assume level 2 else intLOGLEVEL="$2" #otherwise, use variable passed fi # echo "$intLOGLEVEL $VERBOSITY message: $1" DATESTAMP=$(date +%b-%d-%T) echo "$DATESTAMP | $USER | $1" >> $PATHTOLOG if [ $intLOGLEVEL -gt "0" ]; then #If verbosity level is greater than zero, pass message to write() write "$1" $intLOGLEVEL # echo "wrote $1" fi } write () { ##This function will write to the terminal screen based on the set VERBOSITY level## ##This function takes arguments [string] and intVERBOSITY" ## NEW PROTOCOL ## ## default verbosity (set by VERBOSITY flag = 2 (Normal Verbosity) ## ## -C argument sets verbosity to 0 (debug Verbosity) (show all higher than 0) ## -S argument sets verbosity to 3 (Silent / Only Critical Verbosity) ## ## Level 0 - Not used ## Level 1 - Debug Messages ## Level 2 - Normal (default) ## Level 3 - Critical ## ######## if [ -z "$2" ]; then ##if no verbosity level is given, assume level 2 (default) intVERBOSE="2" else intVERBOSE="$2" ##Otherwise, use the provided verbosity level" fi # echo "write got $1 at $intVERBOSE with $VERBOSITY" if [ $intVERBOSE -ge $VERBOSITY ]; then echo "$1" fi } buildtar () { addtolog "buildtar: buildtar started for $1." case $1 in PiHome) FILENAME=$PIHOMEFOLDER/$PIHOMEFILENAME PATHTOFILES=$PIHOMEPATHTOFILES KEEPFILES=$PIHOMEKEEPFILES #Number of archives to keep on TOMCAT ;; Owncloud) FILENAME=$OWNCLOUDFOLDER/$OWNCLOUDFILENAME PATHTOFILES=$OWNCLOUDPATHTOFILES KEEPFILES=$OWNCLOUDKEEPFILES #Number of archives to keep on TOMCAT ;; esac if [ ! $FLAGTESTING -gt "0" ]; then tar -czf $LOCALARCHIVEPATH/$FILENAME -C / $PATHTOFILES 2>> $PATHTOLOG if [ "$?" = "0" ]; then addtolog "buildtar: successfully archived $PATHTOFILES to $LOCALARCHIVEPATH/$FILENAME" else addtolog "buildtar: FAILED to build .tar for $1." fi else addtolog "buildtar: TEST MODE: .tar not built" addtolog "buildtar: SIMULATED backup of $PATHTOFILES" addtolog "buildtar: SIMULATED archive built $LOCALARCHIVEPATH/$FILENAME" fi if [ ! $FLAGTESTING -gt 0 ]; then if [ "$EUID" -ne 0 ]; then chgrp familyshare $LOCALARCHIVEPATH/$FILENAME && addtolog "buildtar: set permissions on $FILENAME" || addtolog "buildtar: FAILED to set permissions on $FILENAME" else chown pi:familyshare $LOCALARCHIVEPATH/$FILENAME && addtolog "buildtar: set permissions on $FILENAME from root" || addtolog "buildtar: FAILED to change permissions on $FILENAME" fi else addtolog "Test Mode - File Permission change not attempted" fi if [ $FLAGCLEAN -gt "0" ]; then cleanfiles $1 $KEEPFILES fi } mountfiles () { addtolog "mountfiles: mountfiles started for $1." if mount | grep $4 > /dev/null; then addtolog "mountfiles: $1 files already mounted." else # sudo mount -t cifs //$2$3 $4 -o username=$5,password=$6 >> $PATHTOLOG 2>&1 && # addtolog "mountfiles: successfully mounted $1 files." || # addtolog "mountfiles: FAILED to mount $1." & failscript sudo mount -t cifs //$2$3 $4 -o username=$5,password=$6 >> $PATHTOLOG 2>&1 if sudo mountpoint -q $4; then addtolog "mountfiles: successfully mounted $1 files." else addtolog "mountfiles: FAILED to mount $1." & failscript fi fi } unmountfiles () { addtolog "unmountfiles: unmountfiles started for $1." if mount | grep $4 > /dev/null; then sudo umount $4 && addtolog "unmountfiles: successfully unmounted $1 files." || addtolog "unmountfiles: FAILED to unmount $1" else addtolog "unmountfiles: $1 Files already unmounted." fi } checkpackage () { ## This script is used to check for the installation of other packages / scripts required if [ -z "$1" ]; then addtolog "checkpackages: Package Variable to received. Exiting" 3 failscript else command -v $1 1>/dev/null 2>&1 && PACKAGEEXISTS=1 return 0 || PACKAGEEXISTS=0 return 1 addtolog "checkpackages: Package $1 - flag set to $PACKAGEEXISTS" 1 fi } cleanfiles () { ##### ## This Function will be run manually, or automatically after Tomcat builds a new Owncloud backup .tar file ## This Funtion take the following arguments: ## 1 - Name of server to clean (currently Enterprise or Owncloud) ## 2 - (optional) number of files to keep (default 4) #### if [ -z "$2" ]; then # If argument 2 is not set filestokeep=4 # Default to 4 else filestokeep="$2" # Otherwise use argument fi addtolog "cleanfiles: cleanfiles started for $1. Keeping $filestokeep files." case $1 in Enterprise) ##This is a future upgrade ##Endure share is mounted ##Sort and delete files ##Log files deleted addtolog "Enterprise cleanfiles not available at this time." 3 ;; PiHome) cleanpath="$LOCALARCHIVEPATH/$PIHOMEFOLDER" ;; Owncloud) cleanpath="$LOCALARCHIVEPATH/$OWNCLOUDFOLDER" ;; *) addtolog "Cannot call cleanfiles with $1" 3 failscript esac arrFiles=($(ls -t -- $cleanpath/*.tar.gz 2>/dev/null)) totalfiles=${#arrFiles[@]} addtolog "cleanfiles: found $totalfiles files in $cleanpath" if [ "$totalfiles" -le "$filestokeep" ] then addtolog "cleanfiles will not delete files on $cleanpath. Total Files is less than or equal to $filestokeep" else filestoremove=$((totalfiles - filestokeep)) addtolog "cleanfiles will attempt to remove the oldest $filestoremove files" for index in "${!arrFiles[@]}" do if [ "$index" -gt "$((filestokeep - 1))" ]; then #Array is 0 based, so -1 if [ $FLAGTESTING -lt "1" ]; then #Do Nothing if Testing flag is set true rm -f ${arrFiles[$index]} addtolog "cleanfiles: DELETED: ${arrFiles[$index]}" else addtolog "cleanfiles: TEST MODE | SIMULATED DELETE: ${arrFiles[$index]}" fi fi done fi } syncfiles () { addtolog "syncfiles: syncfiles started for $1." # determine server shares needed and file paths SOURCEPATH=$LOCALARCHIVEPATH DESTPATH=$ENTERPRISESHARE case $1 in PiHome) SOURCEPATH=${SOURCEPATH}/$PIHOMEFOLDER/$PIHOMEFILENAME DESTPATH=${DESTPATH}/TOMCAT/PiHomeDir/ # DESTPATH=/home/pi/ mountfiles ${arrENTERPRISE[@]} ;; Owncloud) SOURCEPATH=${SOURCEPATH}/$OWNCLOUDFOLDER/ DESTPATH=${DESTPATH}/TOMCAT/Owncloud/ mountfiles ${arrENTERPRISE[@]} ;; Pictures) SOURCEPATH=$PCSHARE/ DESTPATH=${DESTPATH}/Pictures/ mountfiles ${arrENTERPRISE[@]} mountfiles ${arrPC[@]} ;; phone) SOURCEPATH=/storage/backup/phone/mike/ DESTPATH=${DESTPATH}/TOMCAT/phone/mike/ mountfiles ${arrENTERPRISE[@]} esac # Perform rsync # echo "$DATE | syncfiles: I will rsync $SOURCEPATH to $DESTPATH" addtolog "syncfiles: syncing $SOURCEPATH to $DESTPATH." 3 rsync -avP --no-o --no-g --stats --progress --chown=mike:mike $SOURCEPATH $DESTPATH 2>> $PATHTOLOG && ## rsync modified 2/9/2019 to remove -z flag. This will eliminate rsync compression ## and should lead to faster trasnfers addtolog "syncfiles: successfully rsynced $SOURCEPATH to $DESTPATH." 3 || addtolog "syncfiles: FAILED to rsync $SOURCEPATH to $DESTPATH." 3 unmountfiles ${arrENTERPRISE[@]} unmountfiles ${arrPC[@]} } checkusersudo () { ## For Some operations, user must have sudo privileges ## This will check for sudo ## and stop script if user need additional privileges if [ "$EUID" -ne 0 ]; then MESSAGE="Must run as sudo. This program requires sudo privileges to archive Owncloud files." addtolog "$MESSAGE" 3 failscript fi } startscript() { #Prepare Log file for new execution# addtolog "---------------------------------------------------------" 0 addtolog "$0 Script starting" 3 } failscript() { addtolog "$0 script failed. Exiting." 3 addtolog "--------------------------------------------------------" 0 exit 1 } endscript() { addtolog "$0 script complete. Exiting." 3 addtolog "---------------------------------------------------------" 0 exit 0 } ############### # HELP FILE # ############### display_help() { echo "This script will build .tar archives of the Pi Home Directory and Owncloud files, and can sync archives and PC pictures folder to ENTERPRISE." echo " " echo " -h This help file" echo " -B, Build .tar files" echo " -S, Sync files between machines" echo " -C, Cleanup. Used to manually clean acrchives. Normally automatic with -B or -S" echo " -p, Perform actions on PiHome Directory" echo " -o, Perform actions on Owncloud" echo " -i, Perform actions on Photos" echo " -t, Perform actions on Phone Backup" echo " -T, Testing Mode. No Deletions" echo " -m, Mount filesystems only (used for testing)" echo " -u, Unmount filesystems only (used for testing)" echo " -s, Silent Mode. Supress all output except errors." echo " -V, Verbose Mode. Show all debugging on screen." echo " -v, Version. Display Version information." echo addtolog "$0 help menu displayed." 0 } ############## # END HELP # ############## trap ctrl_c 2 3 6 15 ctrl_c () { addtolog "SIGINT CTRL_C. Unmounting files and stopping." 3 addtolog "Aborting Script. Waiting for processes to finish." 3 sleep 2 addtolog "Unmounting file shares" 3 sleep 2 unmountfiles ${arrENTERPRISE[@]} && addtolog "Enterpise unmounted" || addtolog "Failed to unmount ENTERPRISE" 3 unmountfiles ${arrPC[@]} && addtolog "PC unmounted" || addtolog "Failed to unmount PC" 3 addtolog "$0 Script has stopped. Exiting." 3 exit 1 } startscript startlog="$0 script starting with the commands:" options=':hBSCpoitmusTVv' while getopts $options option do case $option in h ) startlog="$startlog help menu" addtolog "$startlog" display_help endscript;; s ) startlog="$startlog silent mode " VERBOSITY=0;; V ) startlog="$startlog verbose mode " VERBOSITY=2;; B ) FLAGBUILD=1 startlog="$startlog BUILD ";; S ) FLAGSYNC=1 echo $index echo $index echo $index echo $index echo $index startlog="$startlog SYNC ";; C ) startlog="$startlog CLEANUP " FLAGCLEAN=1;; p ) FLAGHOME=1 startlog="$startlog PiHome ";; o ) FLAGOWNCLOUD=1 startlog="$startlog owncloud ";; i ) FLAGPICTURES=1 startlog="$startlog PC Pictures ";; t ) FLAGPHONE=1 startlog="$startlog, Phone Backup ";; T ) FLAGTESTING=1 startlog="$startlog TESTING MODE";; m ) startlog="$startlog mount files only" echo "mounting" addtolog "$startlog" mountfiles ${arrENTERPRISE[@]} mountfiles ${arrPC[@]} endscript;; u ) startlog="$startlog unmount files only" addtolog "$startlog" unmountfiles ${arrENTERPRISE[@]} unmountfiles ${arrPC[@]} endscript;; v ) startlog="$startlog, Display Version - $VERSION" echo "$0 - Version $VERSION" # addtolog "$startlog" # endscript exit 0;; * ) display_help endscript ;; /? ) addtolog "unknown menu option $1. Exiting." 3; exit 1;; esac done addtolog "$startlog" 3 #################### # DONE ARGUMENTS # #################### if [ $FLAGTESTING -gt "0" ]; then VERBOSITY=0 addtolog "**TESTING MODE ACTIVE**" 3 addtolog "Verbose mode implied by testing mode" 3 echo "Set Verbosity to $VERBOSITY" # if [ $FLAGCLEAN -gt "0" ]; then # cleanfiles Owncloud $OWNCLOUDKEEPFILES # fi fi addtolog "Test Versoty message" 1 checkpackage wol3 || addtolog "Wol2 Package not found. Needed for sync operations." 1 ## Check SYNC or BUILD flags have appropriate action## if [ $FLAGSYNC -eq "1" -o $FLAGBUILD -eq "1" ]; then if ! [ $FLAGHOME -eq "1" -o $FLAGOWNCLOUD -eq "1" -o $FLAGPICTURES -eq "1" -o $FLAGPHONE -eq "1" ]; then addtolog "FAIL: FLAGSYNC or FLAGBUILD did not have -p,o,i, or t action declared. See -h for help." 3 exit 1 fi fi ## Check PiHome Flag ## if [ $FLAGHOME -eq "1" ]; then ##Perform actiong on PiHome Directory addtolog "Perform Actions on PiHomeDirectory" 1 if [ $FLAGBUILD -eq "1" ]; then addtolog "Perform Tar Build on PiHomeDirectory" 1 buildtar PiHome fi if [ $FLAGSYNC -eq "1" ]; then addtolog "Perform Sync on PiHomeDirectory" 1 ##PERFORM ACTIONS TO SYNC FILES## syncfiles PiHome fi fi ## Check Owncloud Flag ## if [ $FLAGOWNCLOUD -eq "1" ]; then ##Perform action on Owncloud Directory if [ $FLAGBUILD -eq "1" ]; then checkusersudo && buildtar Owncloud fi if [ $FLAGSYNC -eq "1" ]; then #echo "Perform Sync on Owncloud Directory" ##PERFORM ACTIONS TO SYNC FILES## syncfiles Owncloud fi fi ## Check Pictures Flag ## if [ $FLAGPICTURES -eq "1" ]; then ##Perform action on Pictures Directory #echo "Perform Actions on Pictrues Directory" if [ $FLAGBUILD -eq "1" ]; then addtolog "Cannot Perform Compression of Pictures. Sync only. Exiting." 3 endscript fi if [ $FLAGSYNC -eq "1" ]; then #echo "Perform Sync on Pictures" ##PERFORM ACTIONS TO SYNC FILES## syncfiles Pictures fi fi ## Check Phone Flag ## if [ $FLAGPHONE -eq "1" ]; then ##Perform actiong on Phone Directory #echo "Perform Actions on Phone Backup Directory" if [ $FLAGBUILD -eq "1" ]; then addtolog "Cannot build archive of Phone Backup. Sync only. Exiting." 3 endscript fi if [ $FLAGSYNC -eq "1" ]; then # echo "Cannot Sync Phone Backup Files. FUTURE UPGRADE" syncfiles phone fi fi endscript