Skip to content

Instantly share code, notes, and snippets.

@ernestohs
Last active July 11, 2016 04:22
Show Gist options
  • Save ernestohs/790f1d332acf07de9b76f15be4c83746 to your computer and use it in GitHub Desktop.
Save ernestohs/790f1d332acf07de9b76f15be4c83746 to your computer and use it in GitHub Desktop.
CouchDB quick and dirty dump script
#!/usr/bin/env bash
set -o errexit
set -o nounset
LOG_LEVEL=5
NO_COLOR=false
set -o pipefail
read -r -d '' usage <<-'EOF' || true # exits non-zero when EOF encountered
-u --username [arg] username (admin) couchdb.
-p --password [arg] password for username.
-s --host [arg] database server (localhost if empty).
-o --port [arg] port.
-d --db [arg] database name.
-t --target [arg] json filename.
-h --help help.
EOF
### Functions
#####################################################################
function _fmt () {
local color_debug="\x1b[35m"
local color_info="\x1b[32m"
local color_notice="\x1b[34m"
local color_warning="\x1b[33m"
local color_error="\x1b[31m"
local color_critical="\x1b[1;31m"
local color_alert="\x1b[1;33;41m"
local color_emergency="\x1b[1;4;5;33;41m"
local colorvar=color_$1
local color="${!colorvar:-$color_error}"
local color_reset="\x1b[0m"
if [ "${NO_COLOR}" = "true" ] || [[ "${TERM:-}" != "xterm"* ]] || [ -t 1 ]; then
# Don't use colors on pipes or non-recognized terminals
color=""; color_reset=""
fi
echo -e "$(date -u +"%Y-%m-%d %H:%M:%S UTC") ${color}$(printf "[%9s]" ${1})${color_reset}";
}
function emergency () { echo "$(_fmt emergency) ${@}" 1>&2 || true; exit 1; }
function alert () { [ "${LOG_LEVEL}" -ge 1 ] && echo "$(_fmt alert) ${@}" 1>&2 || true; }
function critical () { [ "${LOG_LEVEL}" -ge 2 ] && echo "$(_fmt critical) ${@}" 1>&2 || true; }
function error () { [ "${LOG_LEVEL}" -ge 3 ] && echo "$(_fmt error) ${@}" 1>&2 || true; }
function warning () { [ "${LOG_LEVEL}" -ge 4 ] && echo "$(_fmt warning) ${@}" 1>&2 || true; }
function notice () { [ "${LOG_LEVEL}" -ge 5 ] && echo "$(_fmt notice) ${@}" 1>&2 || true; }
function info () { [ "${LOG_LEVEL}" -ge 6 ] && echo "$(_fmt info) ${@}" 1>&2 || true; }
function debug () { [ "${LOG_LEVEL}" -ge 7 ] && echo "$(_fmt debug) ${@}" 1>&2 || true; }
function help () {
echo "" 1>&2
echo " ${@}" 1>&2
echo "" 1>&2
echo " ${usage}" 1>&2
echo "" 1>&2
exit 1
}
while read line; do
opt="$(echo "${line}" |awk '{print $1}' |sed -e 's#^-##')"
long_opt="$(echo "${line}" |awk '/\-\-/ {print $2}' |sed -e 's#^--##')"
long_opt_mangled="$(sed 's#-#_#g' <<< $long_opt)"
varname="short_opt_${long_opt_mangled}"
eval "${varname}=\"${opt}\""
varname="has_arg_${opt}"
if ! echo "${line}" |egrep '\[.*\]' >/dev/null 2>&1; then
init="0"
eval "${varname}=0"
else
opt="${opt}:"
init=""
eval "${varname}=1"
fi
opts="${opts:-}${opt}"
varname="arg_${opt:0:1}"
if ! echo "${line}" |egrep '\. Default=' >/dev/null 2>&1; then
eval "${varname}=\"${init}\""
else
match="$(echo "${line}" |sed 's#^.*Default=\(\)#\1#g')"
eval "${varname}=\"${match}\""
fi
done <<< "${usage}"
opts="${opts}-:"
OPTIND=1
set +o nounset
while getopts "${opts}" opt; do
[ "${opt}" = "?" ] && help "Invalid use of script: ${@} "
if [ "${opt}" = "-" ]; then
if [[ "${OPTARG}" =~ .*=.* ]]; then
long=${OPTARG/=*/}
long_mangled="$(sed 's#-#_#g' <<< $long)"
eval "opt=\"\${short_opt_${long_mangled}}\""
OPTARG=${OPTARG#*=}
else
long_mangled="$(sed 's#-#_#g' <<< $OPTARG)"
eval "opt=\"\${short_opt_${long_mangled}}\""
eval "OPTARG=\"\${@:OPTIND:\${has_arg_${opt}}}\""
((OPTIND+=has_arg_${opt}))
fi
fi
varname="arg_${opt:0:1}"
default="${!varname}"
value="${OPTARG}"
if [ -z "${OPTARG}" ] && [ "${default}" = "0" ]; then
value="1"
fi
eval "${varname}=\"${value}\""
debug "cli arg ${varname} = ($default) -> ${!varname}"
done
set -o nounset
shift $((OPTIND-1))
[ "${1:-}" = "--" ] && shift
if [ "${arg_h}" = "1" ]; then
help "Help using ${0}"
fi
SOLO=false
TIMESTAMP=`date +"%Y-%m-%d_%H-%M-%S"`
username=$arg_u
password=$arg_p
server=$arg_s
port=$arg_o
target=$arg_t
db=$arg_d
[ -z "${arg_d:-}" ] && help "Setting a database name with -d or --db is required"
[ -z "${arg_u:-}" ] || [ -z "${arg_p:-}" ] && SOLO=true && warning "username or password missing the dump will continue without credentials"
[ -z "${arg_s:-}" ] && server=localhost && warning "server missing the dump will asume localhost as the target server"
[ -z "${arg_o:-}" ] && port=80 && notice "port missing the dump will asume 80"
[ -z "${arg_t:-}" ] && target="$db-$TIMESTAMP.json" && notice "filename missing the dump will use $target"
username=$arg_u
password=$arg_p
if $SOLO ; then
curl -X GET http://$server:$port/$db/_all_docs?include_docs=true | jq '{"docs": [.rows[].doc]}' | jq 'del(.docs[]._rev)' > $target
else
curl -u $username:$password -X GET http://$server:$port/$db/_all_docs?include_docs=true | jq '{"docs": [.rows[].doc]}' | jq 'del(.docs[]._rev)' > $target
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment