Skip to content
Snippets Groups Projects
Select Git revision
  • a9c760563b8af8a5d7ed550d8174a2421eff9c6d
  • master default protected
  • 7771-harden-postgres-backup
  • pgsql-dump-with-snapshots
  • update-colors
  • update-docs-css
  • usb-repair-stick
  • desktop-notification
  • 7000-corrections
  • db-detector
10 results

couchdb.sh

Blame
  • 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
    
    # --------------------------------------------------------------------------------