Archive for October 2013

A postgres backup script for a snapshot environment


#!/bin/bash

# Backup
# Usage: backup-pg.sh
#

# If you have another method for obtaining your filer's ip
# use that instead to assign this variable
FILERIP=`mount | grep db01 | cut -d':' -f1`

# username associated with the key used
UN="snappy"
# location of the ssh key used for above user
SNAPKEY=/opt/bbcollab/voice/postgres.stuff/snapkey

# If you have another method for obtaining the volume name or archive
# Edit the two lower variables; your ARCHIVE name should have a grepable line
VOLUME=`mount | grep db01 | cut -d':' -f2 | sed 's#/vol/##g' | sed 's#/db01.*##g'`
COMNAME="backup_pgdata"
ARCHIVE="${COMNAME}-${HOST}-${TODAY}"

# location of the .snapshot directory
SSDIR=/var/voice/postgres/.snapshot

# retention in snapshot count
RETEN=4

function get_oldest_snapshot_by_filesystem
{
ss=`ls -lct $SSDIR | grep -v "total" | head -1 | awk '{print $9}'`
echo $ss
}

function get_oldest_snapshot_by_netapp
{
# looking for archives with ${COMNAME}
cur_ss=`ssh -i ${SNAPKEY} -o StrictHostKeyChecking=no ${UN}@${FILERIP} "snap list ${VOLUME}" | grep "${COMNAME}" | awk '{print $10}' | grep -v "^$" | tail -1`
echo $cur_ss
}

function remove_oldest
{
ssh -i ${SNAPKEY} -o StrictHostKeyChecking=no ${UN}@${FILERIP} "snap list ${VOLUME}" | grep "${COMNAME}" > /var/tmp/ss.lst
ss_count=`wc -l /var/tmp/ss.lst | awk '{print $1}'`
if [[ "$ss_count" -gt $RETEN ]]
then
obf=`get_oldest_snapshot_by_filesystem`
obn=`get_oldest_snapshot_by_netapp`
if [[ "$obf" == "$obn" ]]
then
ssh -i ${SNAPKEY} -o StrictHostKeyChecking=no ${UN}@${FILERIP} "snap delete ${VOLUME} $obf"
fi
else
echo "none to remove"
fi
}

function usage
{
echo ""
echo "### $0 Usage ###"
echo ""
echo "Call script like:"
echo ""
echo " $0 ()"
echo " (cron uses -a)"
echo ""
echo "Options:"
echo " -a #### Create a new snapshot and delete the oldest"
echo " -c #### Only create a new snapshot"
echo " -l #### List the current snapshots"
echo " -d Delete snapshot (regardless of age or retention)"
echo " -q #### Delete the oldest snapshot (will not delete if you have fewer snapshots than $RETEN)"
echo ""
}

if [[ $# > 0 ]]
then
case $1 in
-a) psql -U postgres -h localhost -c "SELECT pg_start_backup('${ARCHIVE}');" template1
ssh -i ${SNAPKEY} -o StrictHostKeyChecking=no ${UN}@${FILERIP} "snap create ${VOLUME} ${ARCHIVE}"
psql -U postgres -h localhost -c "SELECT pg_stop_backup();" template1
remove_oldest
exit
;;
-c) psql -U postgres -h localhost -c "SELECT pg_start_backup('${ARCHIVE}');" template1
ssh -i ${SNAPKEY} -o StrictHostKeyChecking=no ${UN}@${FILERIP} "snap create ${VOLUME} ${ARCHIVE}"
psql -U postgres -h localhost -c "SELECT pg_stop_backup();" template1
exit
;;
-l) ssh -i ${SNAPKEY} -o StrictHostKeyChecking=no ${UN}@${FILERIP} "snap list ${VOLUME}"
exit
;;
-d) ssh -i ${SNAPKEY} -o StrictHostKeyChecking=no ${UN}@${FILERIP} "snap delete ${VOLUME} $2"
exit
;;
-q) remove_oldest
exit
;;
*) usage
exit
;;
esac
else
usage
exit
fi

http://usalug.com/phpBB3//viewtopic.php?f=15&t=8086


#!/bin/bash
# Author: Josh Bailey
# Email: jbsnake gmail.com
# A function/subroutine library
# A lot of these functions and subroutines I use
# in all my scripts, some I have only used once.
# This is a lot of hard work right here, so please
# don't get tempted by saying you did it yourself :)
# If you use something here (which you ofcourse are free to do)
# Please atleast give a link to www.usalug.org or www.bashscripts.org
# You don't have to mention me, just mention where you found such awesome code ;)

function notAForwardSlash
{
if [[ ${1} != '/' ]]
then
return 0
else
return 1
fi
}

function notADot
{
if [[ ${1} != '.' ]]
then
return 0
else
return 1
fi
}

function getFileName
{

# call this function like
# filename_variable=`getFileName /some/path/with/a/file.name`

local STRING=$1
local LENGTH=${#STRING}
local n=0
local FileName=""
for ((n=0;n <= $LENGTH; n++))
do
local CHAR=${STRING:$n:1}
if notAForwardSlash $CHAR
then
FileName=$FileName$CHAR
else
FileName=""
fi
done
echo "FileName"
}

function getExtension
{

# call this like
# extension_variable=`getExtension /path/to/some/file.txt`
# extension_variable would be "txt" for that example
# you can also just pass it a filename
# extension_variable=`getExtension somefile.lst`
# extention_variable would be "lst" for that example
# but if you pass it a filename or path without a .
# it will return exactly what you pass it
# extension_variable=`getExtension /path/to/my/script`
# extension_variable would be "/path/to/my/script"

local STRING="${1}"
local LENGTH="${#STRING}"
local n=0
local Extension=""

for ((n=0; n <= $LENGTH; n++))
do
local CHAR=${STRING:$n:1}
if notADot $CHAR
then
Extension=$Extension$CHAR
else
Extension=""
fi
done
echo "$Extension"
}

function getPath
{

# call this like
# chop_path=`getPath /path/to/something.file`
# chop_path would be populated with "/path/to/"

# function to get only the path from a path/filename combo
# first get the filename from $1 which is a path/filename combo
local just_filename=`getFileName "$1"`

# set the variable containing the path
local newPath=${1:0:(${#1}-${#just_filename})}
echo "$newPath"
}

function inStr
{

# call this function like
# instr_variable=`inStr "=" "1=2"`
# since the position of = is 1 (i.e. 0 1 2 )
# instr_variable would equal 1

local searchFor="$1";
local lenOf=${#searchFor};
local searchIn="$2";
for (( i=0; i /dev/null< /dev/null
if [[ $? -eq 1 ]]
then
return 1
else
touch ${1}/bob.yea\ do0d 2> /dev/null
if [[ $? -eq 1 ]]
then
rm ${1}/bob.yea\ do0d 2> /dev/null
return 1
else
rm ${1}/bob.yea\do0d 2> /dev/null
return 0
fi

fi
}

function trimspaces
{

# call this like
# new_string=`trimspaces "some random text" " "`
# new_string variable would be "somerandomtext"
# new_string=`trimspaces "some_random_text" "_"`
# new_string variable would be "somerandomtest"
# new_string=`trimspaces "some random_text"
# new_string variable would be "somerandom_text" (default, if nothing is passed, to remove are spaces)

local NewString=""
local STRING="$1"
local rmChar="$2"
local CHAR=""
local NewString=""

if [[ $rmChar = "" ]]
then
rmChar=' '
fi
for ((i=0; i<${#STRING}; i++))
do
CHAR=${STRING:$i:1}
if [[ $CHAR != $rmChar ]]
then
NewString=$NewString$CHAR
fi
done
echo "${NewString}"
}

function fileExist
{

# call this like
# if [[ fileExist "/path/to/some/file.name" ]]
# then
# yes it does
# else
# no it doesn't
# fi

if [[ -a "$1" ]]
then
return 0
else
return 1
fi
}

function isNumeric
{

# call this like
# if [[ isNumeric ]]
# then
# yes it is
# else
# no it's not
# fi

local Numeric='y'
local len=`echo ${#1}`
local val=""
local retval=""

for ((i=0; i /dev/null
retval=$?
if [[ $retval -eq 1 ]]
then
if [[ $i -eq 0 && $val = '-' ]]
then
num="negative"
else
Numeric='n'
break
fi
fi
done
if [[ $Numeric = 'y' ]]
then
return 0
else
return 1
fi
}

function isAlpha
{

# call this like
# if [[ isAlpha ]]
# then
# yes it is
# else
# no it's not
# fi

local Alpha='y'
local len=`echo ${#1}`
local val=""
local retval=""

for ((i=0; i /dev/null
retval=$?
if [[ $retval -eq 1 ]]
then
Alpha='n'
break
fi
done
if [[ $Alpha = 'y' ]]
then
return 0
else
return 1
fi
}

function isAlphaNum
{

# call this like
# if [[ isAlphNum ]]
# then
# yes it is
# else
# no it's not
# fi

local AlphaNum='y'
local len=`echo ${#1}`
local val=""
local retval=""

for ((i=0; i /dev/null
retval=$?
if [[ $retval -eq 1 ]]
then
echo $val | grep ^[0-9] > /dev/null
retval=$?
if [[ $retval -eq 1 ]]
then
AlphaNum='n'
break
fi
fi
done
if [[ $AlphaNum = 'y' ]]
then
return 0
else
return 1
fi
}

function initialCaps()
{

# call this like
# new_string=`initialCaps "john doe"`
# new_string variable would be "John Doe"

local Cap=""
local Info=""
local Word=""
local string="${1}"
local cut=""

while [ ${#1} != 0 ]
do
Cap=`echo ${string:0:1} | tr [:lower:] [:upper:]`
Info=`echo -n $Cap; echo ${string:1:${#string}} | tr [:upper:] [:lower:]`
Info=${Info}" "
Word=${Word}${Info}
shift 1
done
cut=${#Word}-1
Word="${Word:0:${cut}}"
echo "${Word}"
}

######## Music file format stuff #################################

function get_ogg_info
{

# call this like
# ogg_info_string=`get_ogg_info "/path/to/file.ogg"`
# ofcourse the string would have to be parsed
# it is pipe | delimited
# in order artist, title, album, genre, date, and track number
# inStr function needed; vorbiscomment (comes with oggenc)
local turn=""
local index=0
local item=""
local cartist=""
local ctitle=""
local calbum=""
local cgenre=""
local cdate=""
local ctracknumber=""

vorbiscomment -l "$1" > info.lst
for turn in artist title album genre date tracknumber
do
tmp_comment=`grep -i "$turn" info.lst`
item=`inStr "=" "$tmp_comment"`
comment=${tmp_comment:${item}+1}
((index++))
case $index in
1) cartist="$comment";
;;
2) ctitle="$comment";
;;
3) calbum="$comment";
;;
4) cgenre="$comment";
;;
5) cdate="$comment";
;;
6) ctracknumber="$comment";
;;
esac
done
info="${cartist}|${ctitle}|${calbum}|${cgenre}|${cdate}|${ctracknumber}"
echo "${info}"
rm -f info.lst
}

function encode_flac2mp3
{

# call this like
# encode_flac2mp3 /path/to/source/file.flac /path/to/destination
# needs: getFileName function; flac encoder/decoder; lame

local old_file="${1}"
local new_dir="${2}"
local short_filename=`getFileName "${old_file}"`
local new_file="${short_filename:0:${#short_filename}-5}.mp3"

flac -d -o - "${old_file}" | lame -b 320 -h - > "${new_dir}/${new_file}"
}

function encode_flac2ogg
{

# call this like
# encode_flac2ogg /path/to/source/file.flac /path/to/destination
# needs: getFileName function; flac encoder/decoder; oggenc

local old_file="${1}"
local new_dir="${2}"
local short_filename=`getFileName "${old_file}"`
local new_file="${short_filename:0:${#short_filename}-5}.ogg"
###### get artist and album before release #########
# flac -d -o - "${old_file}" | oggenc -a "$artist" -l "$album" -t "${title}" - -o "${new_dir}/${new_file}"
####################################################
local title="${short_filename:0:${#short_filename}-4}"

flac -d -o - "${old_file}" | oggenc -t "${title}" - -o "${new_dir}/${new_file}"
}

function encode_ogg2mp3
{

# call this like
# encode_ogg2mp3 /path/to/source/file.flac /path/to/destination
# needs: getFileName function; oggdec; lame

local old_file="${1}"
local new_dir="${2}"
local short_filename=`getFileName "${old_file}"`
local new_file="${short_filename:0:${#short_filename}-4}.mp3"
local info_string=`get_ogg_info "$old_file"`
local cartist=`cut -d| -f1 ${info_string}`
local ctitle=`cut -d| -f2 ${info_string}`
local calbum=`cut -d| -f3 ${info_string}`
local cgenre=`cut -d| -f4 ${info_string}`
local cdate=`cut -d| -f5 ${info_string}`
local ctracknumber=`cut -d| -f6 ${info_string}`

oggdec "${old_file}" -o - | lame -b 320 --tt "$ctitle" --ta "$cartist" --tl "$calbum" --ty $cdate --tn $ctracknumber --tg "$cgenre" -h - > "${new_dir}/${new_file}"
sleep .5
}

####################################################################################

############################ gpg stuff #############################################

function list_private_keys
{

# call this like
# list_private_keys
# it just clears the screen then
# pipes the private items on your keyring to less

clear;
echo ":: Listing private keys";
gpg --list-secret-keys | less;
echo ":: Done";
}

function list_public_keys
{

# call this like
# list_public_keys
# it just clears the screen then
# pipes the public imported keys on
# your keyring to less

clear;
echo ":: Listing public keys";
gpg --list-keys | less;
echo ":: Done";
}

function decrypt_any_file
{

# call this like
# decrypt_any_file /path/to/some/encrypted/file.asc
# it clears the screen then prompts you for your passphrase
# then decrypts the encrypted file into another file

local filename="$1";
local person=`whoami`;
clear;
if [[ ${filename:${#filename}-11:11} -eq "-encrypted" ]]
then
local newfilename="${filename:0:${#filename}-${#person}-12}";
gpg -d --output "$newfilename" "$filename";
echo ":: Decrypted $filename";
echo ":: Saved as $newfilename";
else
gpg -d --output "$filename.decrypted" "$filename";
echo ":: Decrypted $filename";
echo ":: Saved as $filename.decrypted";
fi
}

function encrypt_any_file
{

# call this like
# encrypt_any_file /path/to/file/to/encrypt.asc "who it's encrypted for"
# it clears the screen then encrypts the file you specified
# saving the encrypted file to have the persons name and "-encrypted" at the end

local filename="$1";
local person="$2";
clear;
gpg -sea --output "$filename"."$person"-encrypted --recipient "$person";
echo ":: File $filename encrypted";
echo ":: Encrypted file saved as $filename.$person-encrypted";
}

function export_public_key
{

# call this like
# export_public_key "Key Identifier"
# generates a key pair and saves the public key as "Key Identifier.pub"

local ID="$1";
gpg -ao $ID.pub --export $ID;
echo ":: Public Key for $ID has been generated"
echo ":: File is saved as $ID.pub"
}

function import_public_directory
{

# call this like
# import_public_directory /path/to/directory/full/of/public/keys
# changes directory to the public key directory and imports every file there
# then goes back to the directory you started in

local DIR=$1;
cd "$DIR";
for filename in *
do
gpg --import "$filename";
done;
cd ~-;
}

function create_encrypted_ascii_file
{

# call this like
# create_encrypted_ascii_file /path/to/location/for/future/message.asc "Who to encrypt for"
# opens a vi session (note you can make the editor whatever you want by changing the variable)
# once you close the editor, the file you just edited is encrypted
# then it's echo'd to the console for easy copy and pasting

local editor="vi"
local file="${1}";
local person="${2}";
${editor} "${file}";
gpg -sea --output "${file}.${person}-encrypted" --recipient "${person}" "${file}";
clear;
echo ":: Encrypted file created";
echo ":: File saved as ${file}.${person}-encrypted";
echo ":: Contents of file shown below";
echo -e "\n\n";
cat "${file}.${person}-encrypted"
}

function import_public_key
{

# call this like
# import_public_key
# it prompts you for the key-file you wish to import

read -p "Please type the path of the public key you wish to import: " file
if [[ -e "$file" ]]
then
gpg --import "$file"
else
echo "${file}: doesn't exist, or you typed the wrong path!"
exit
fi
}

function create_user_list
{

# call this like
# create_user_list
# makes a list of users on the system
# it grabs the contents of /etc/passwd
# then removes the entry for root
# and saves the list as users.list

cat /etc/passwd | cut -d: -f1 > pre.list;
cat pre.list | grep -v "root" > users.list;
rm pre.list;
}
#####################################################################################3

function app_up
{

# call this like
# app_up /path/to/file/append.from /path/to/file/append.to
# puts data from a file at the top of another file instead of the bottom

if [[ ! -e ${2} ]]
then
touch ${2}
fi

${1} > temp
cat ${2} >> temp
rm -f ${2}
mv temp ${2}
}

function createROMISO
{

# call this like
# createROMISO /dev/cdrom /path/to/new/rom.iso

# the command that makes an ISO from a cd/dvd
# $1 should be the device path (/dev/cdrom)
# $2 should be the iso path and filename
dd if=$1 of=$2 bs=32k
}

function createDIRISO
{

# call this like
# createDIRISO /path/to/new/rom.iso /path/to/directory/you/want/to/backup

# the command that makes an ISO from a directory
# $1 should be the iso path and filename
# $2 should be the directory to backup
mkisofs -o $1 $2
}

function msg
{

# call this like
# msg "Title of Message Box"
# or
# msg "Title of Message Box" $height $width

# function for making a messagebox
# if it has less than two arguments
if [[ $# < 2 ]]
then
# use auto-size for the messagebox
dialog --msgbox "$1" 0 0
else
# use specified height and width
dialog --msgbox "$1" $2 $3
fi
clear
}