-
Hahn Axel (hahn) authoredHahn Axel (hahn) authored
localdump_couchdb.sh 6.82 KiB
#!/bin/bash
# ================================================================================
#
# LOCALDUMP :: COUCHDB
# create gzipped plain text backups from each scheme
#
# --------------------------------------------------------------------------------
# ah - Axel Hahn <axel.hahn@iml.unibe.ch>
# ds - Daniel Schueler <daniel.schueler@iml.unibe.ch>
#
# 2017-03-24 ah,ds v0.9 backup
# 2017-03-27 ..... v1.0 restore
# ================================================================================
if [ -z $BACKUP_TARGETDIR ]; then
echo ERROR: you cannot start `basename $0` directly
rc=$rc+1
exit 1
fi
# --------------------------------------------------------------------------------
# CONFIG
# --------------------------------------------------------------------------------
dirPythonPackages=/usr/lib/python2.7/site-packages
# --------------------------------------------------------------------------------
# FUNCTIONS
# --------------------------------------------------------------------------------
# make an couch api request
# param string method ... one of GET|POST|DELETE
# param string relative url, i.e. _all_dbs or _stats
function _couchapi(){
method=$1
apiurl=$2
outfile=$3
sParams=
# sParams="$sParams -u ${couchdbuser}:${couchdbpw}"
sParams="$sParams -X ${method}"
sParams="$sParams ${COUCHDB_URL}${apiurl}"
if [ ! -z $outfile ]; then
sParams="$sParams -o ${outfile}"
fi
curl $sParams 2>/dev/null
}
function _couchGet(){
_couchapi GET $*
}
function _getDblist(){
_couchGet _all_dbs | sed 's#\"#\n#g' | egrep -v "^(\[|\,|\])$"
}
# ---------- CONFIG/ INSTANCES
# get valid configured instances
function getInstances(){
for mycfg in `ls -1 ~/.iml_backup/couchdb/*.config`
do
. $mycfg
if [ $? -eq 0 ]; then
echo `basename "${mycfg}" | cut -f 1 -d "."`
fi
done
}
# load the config of an existing instance
# see getInstances to get valid names
# param string name of the instance to load
function loadInstance(){
COUCHDB_URL=
. ~/.iml_backup/couchdb/${1}.config
if [ $? -ne 0 ]; then
color error
echo ERROR: invalid instance: $1 - the config file cannot be sourced
color reset
exit 1
fi
if [ -z ${COUCHDB_URL} ]; then
color error
echo ERROR: invalid instance: $1 - the config file has no COUCHDB_URL
color reset
exit 1
fi
# parse ${COUCHDB_URL} ...
couchdbhost=`echo ${COUCHDB_URL} | cut -f 3 -d "/" | cut -f 2 -d "@" | cut -f 1 -d ":"`
couchdbport=`echo ${COUCHDB_URL} | cut -f 3 -d "/" | cut -f 2 -d "@" | cut -f 2 -d ":"`
couchdbuser=`echo ${COUCHDB_URL} | cut -f 3 -d "/" | cut -f 1 -d "@" | cut -f 1 -d ":"`
couchdbpw=`echo ${COUCHDB_URL} | cut -f 3 -d "/" | cut -f 1 -d "@" | cut -f 2 -d ":"`
}
# ---------- BACKUP
# backup with loop over instances
function doBackup(){
# for mycfg in `ls -1 ~/.iml_backup/couchdb/*.config`
for COUCHDB_INSTANCE in `getInstances`
do
loadInstance $COUCHDB_INSTANCE
echo --- instance: $COUCHDB_INSTANCE
curl --head -X GET $COUCHDB_URL 2>/dev/null | grep "^HTTP.*\ 200\ "
if [ $? -eq 0 ]; then
_doBackupOfSingleInstance
else
rc=$rc+1
color error
echo ERROR: couch DB instance is not available or canot be accessed with these credentials in config file
# repeat curl to show the error message
curl -X GET $COUCHDB_URL
color reset
fi
echo
echo --- `date` done.
echo
done
}
# make backup of all databases in a couchdb instance
# global: COUCHDB_URL
# global: COUCHDB_INSTANCE
function _doBackupOfSingleInstance(){
create_targetdir
mkdir -p ${BACKUP_TARGETDIR}/${COUCHDB_INSTANCE} 2>/dev/null
echo
echo " DUMP databases of instance ${COUCHDB_INSTANCE}"
echo " couchdbhost $couchdbhost on port $couchdbport with user $couchdbuser"
echo
for dbname in `_getDblist`
do
echo ----- `date` ${COUCHDB_INSTANCE} -- ${dbname}
OUTFILE=${BACKUP_TARGETDIR}/${COUCHDB_INSTANCE}/`get_outfile ${dbname}`.couchdbdump
python ${dirPythonPackages}/couchdb/tools/dump.py ${COUCHDB_URL}/${dbname} >${OUTFILE}
fetchrc
# $myrc is last returncode - set in fetchrc
if [ $myrc -eq 0 ]; then
echo -n "gzip ... "
compress_file $OUTFILE
else
echo "ERROR occured - no gzip"
fi
ls -l $OUTFILE*
echo
done
}
# ---------- RESTORE
# restore a single backup file; the instance and db name will be detected from file
# param string filename of db dump (full path or relative to BACKUP_TARGETDIR)
function restoreByFile(){
sMyfile=$1
sMyDb=$2
echo
h2 "analyze dump $sMyfile"
COUCHDB_INSTANCE=`echo $sMyfile | sed "s#${BACKUP_TARGETDIR}##g" | sed "s#\./##g" | sed "s#^/##g" | cut -f 1 -d "/"`
echo "detected COUCHDB_INSTANCE : [${COUCHDB_INSTANCE}]"
if [ -z $sMyDb ]; then
sMyDb=`guessDB $sMyfile`
echo "detected db schema from file: [${sMyDb}]"
else
echo "db schema from param 2: [${sMyDb}]"
fi
echo
loadInstance $COUCHDB_INSTANCE
echo connect $couchdbhost on port $couchdbport with user $couchdbuser
curl --head -X GET $COUCHDB_URL 2>/dev/null | grep "^HTTP.*\ 200\ " >/dev/null
if [ $? -ne 0 ]; then
color error
echo ERROR: couch DB instance is not available
curl -X GET $COUCHDB_URL
color reset
exit 1
fi
color ok
echo OK
color reset
echo
# _getDblist | grep "^${sMyDb}$"
# if [ $? -eq 0 ]; then
# echo DB exists ... need to drop it first
# fi
h2 deleting database [$sMyDb] ...
color cmd
_couchapi DELETE $sMyDb
fetchrc
color reset
h2 creating database [$sMyDb] ...
color cmd
_couchapi PUT $sMyDb
fetchrc
color reset
h2 import file ...
color cmd
zcat ${sMyfile} | python ${dirPythonPackages}/couchdb/tools/load.py $COUCHDB_URL/$sMyDb
fetchrc
color reset
echo
}
# --------------------------------------------------------------------------------
# MAIN
# --------------------------------------------------------------------------------
# ----- check requirements
# --- is a couchd here
j_requireProcess "couchdb" 1
# --- very specific :-/ ... check available config files
ls -1 ~/.iml_backup/couchdb/* >/dev/null 2>&1
rc=$rc+$?
if [ $rc -eq 0 ]; then
echo OK: couchdb was found on this system ... checking requirements for backup ...
j_requireBinary "curl" 1
ls ${dirPythonPackages}/couchdb/tools/dump.py ${dirPythonPackages}/couchdb/tools/load.py >/dev/null && echo "OK: python couchdb tools were found"
rc=$rc+$?
if [ $rc -eq 0 ]; then
echo
if [ "$1" = "restore" ]; then
echo
shift 1
restoreByFile $*
else
doBackup
fi
else
color error
echo ERROR: Couchdb is here but I am missing things for the backup :-/
color reset
fi
else
rc=0
echo "SKIP: couchdb seems not to be here"
fi
echo $0 $* [couchdb] final returncode rc=$rc
# --------------------------------------------------------------------------------