Skip to content

Instantly share code, notes, and snippets.

@muhqu
Created December 16, 2011 08:18
Show Gist options
  • Select an option

  • Save muhqu/1485096 to your computer and use it in GitHub Desktop.

Select an option

Save muhqu/1485096 to your computer and use it in GitHub Desktop.
#!/bin/bash
set -e
usage() {
cat <<USAGE
usage: $(basename $0) REPL_JSON COUCH_URL [ --cancel | --advance SEQ ] [ --cycle [SLEEP] ]
USAGE
}
usageHelp() {
usage;
cat <<HELP
options:
REPL_JSON JSON data that is passed to couchdb's /_replicate handler
COUCH_URL url to the couchdb that will do the replication
--cancel just adds 'cancel':true to the json data and stops repl.
--advance SEQ set the sequence number to the specified value
--cycle [SLEEP] loop forever and show status, default SLEEP 5 sec
example:
couch-repl '{
"source":"http://some-host:5984/some-db",
"target":"other-db",
"filter":"design-doc/filter-name",
"continuous":true
}' 'http://other-host:5984'
HELP
}
json_get() {
python -c 'import simplejson as json,sys;J=json.loads(sys.stdin.read());print(J.get("'$1'") or "");'
}
if [ $# -lt 2 ]; then
usageHelp;
exit 1;
fi
REPL_JSON="$1"
COUCH_URL="$2"
shift;shift;
SOURCE=$(echo "$REPL_JSON" | json_get source)
if [ -z "$SOURCE" ]; then
echo "error: missing 'source' in REPL_JSON"
exit 1;
fi
TARGET=$(echo "$REPL_JSON" | json_get target)
if [ -z "$TARGET" ]; then
echo "error: missing 'target' in REPL_JSON"
exit 1;
fi
[[ "$SOURCE" == *://* ]] || SOURCE="$COUCH_URL/$SOURCE"
[[ "$TARGET" == *://* ]] || TARGET="$COUCH_URL/$TARGET"
FILTER=$(echo "$REPL_JSON" | json_get filter)
ADVANCE=""
CYCLE=""
CANCEL=""
until [ -z "$1" ]; do
case $1 in
--advance)
shift; if [ ! -z "$1" -a "${1:1:0}" != "-" ]; then
ADVANCE="$[0+${1:-1}]"; shift
fi
if [ -z "$ADVANCE" ]; then
echo "invalid or missing value for option: --advance";
usage;
exit 1
fi
;;
--cycle)
shift;
CYCLE=5
if [ ! -z "$1" -a "${1:1:0}" != "-" ]; then
CYCLE="$[0+${1:-1}]"; shift
fi
;;
--cancel)
shift;
CANCEL="YES"
;;
*)
echo "unknown option: $1";
usage;
exit 1
;;
esac
done
printf "%-20s = %s\n" "Source" "$SOURCE"
printf "%-20s = %s\n" "Target" "$TARGET"
if [ ! -z "$FILTER" ]; then
printf "%-20s = %s\n" "Filter" "$FILTER"
fi
if [ "$CANCEL" = "YES" ]; then
echo -n " cancel repl ... "
REPL_CANCEL_JSON=$(echo "$REPL_JSON" | python -c 'import simplejson as json,sys;J=json.loads(sys.stdin.read());J["cancel"]=True;print json.dumps(J);')
LOCAL_ID=$(curl -s -X POST -H 'Content-Type: application/json' -d "$REPL_CANCEL_JSON" "$COUCH_URL/_replicate" | json_get _local_id)
echo "ok"
printf "%-20s = %s\n" "Local ID" "$LOCAL_ID"
exit 0;
fi
REP_OUT=$(curl -s -X POST -H 'Content-Type: application/json' -d "$REPL_JSON" "$COUCH_URL/_replicate")
LOCAL_ID=$(echo "$REP_OUT" | json_get _local_id)
printf "%-20s = %s\n" "Local ID" "$LOCAL_ID"
showSeqInfo(){
SOURCE_SEQ=$(curl -s -X GET "$SOURCE" | json_get update_seq)
printf "%-20s = %10d\n" "Source Seq." "$SOURCE_SEQ"
REPL_SEQ=$(curl -s -X GET "$SOURCE/_local/$LOCAL_ID" | json_get source_last_seq)
printf "%-20s = %10d\n" "Source Seq. checked" "$REPL_SEQ"
CHANGES_TO_GO=$(( $SOURCE_SEQ - $REPL_SEQ ))
CHANGES_PERC=$(echo "scale=4; $REPL_SEQ * 100 / $SOURCE_SEQ" | bc)
printf "%-20s = %10d ( %6.2f %% done )\n" "Source Seq. to go" "$CHANGES_TO_GO" "$CHANGES_PERC"
}
showSeqInfoChanges(){
SOURCE_SEQ=$(curl -s -X GET "$SOURCE" | json_get update_seq)
REPL_SEQ=$(curl -s -X GET "$SOURCE/_local/$LOCAL_ID" | json_get source_last_seq)
CHANGES_TO_GO=$(( $SOURCE_SEQ - $REPL_SEQ ))
CHANGES_PERC=$(echo "scale=4; $REPL_SEQ * 100 / $SOURCE_SEQ" | bc)
printf "Status: %10d - %10d = %10d ( %6.2f %% done ) @ %s\n" "$SOURCE_SEQ" "$REPL_SEQ" "$CHANGES_TO_GO" "$CHANGES_PERC" "$(date)"
}
showSeqInfo;
if [ ! -z "$ADVANCE" ]; then
echo "";
echo "advance to Seq. $ADVANCE:"
echo -n " cancel repl ... "
REPL_CANCEL_JSON=$(echo "$REPL_JSON" | python -c 'import simplejson as json,sys;J=json.loads(sys.stdin.read());J["cancel"]=True;print json.dumps(J);')
LOCAL_ID=$(curl -s -X POST -H 'Content-Type: application/json' -d "$REPL_CANCEL_JSON" "$COUCH_URL/_replicate" | json_get _local_id)
echo "ok"
echo -n " update local doc ... "
LOCAL_DOC_JSON=$(curl -s -X GET "$SOURCE/_local/$LOCAL_ID")
LOCAL_DOC_ADV_JSON=$(echo "$LOCAL_DOC_JSON" | python -c 'import simplejson as json,sys;J=json.loads(sys.stdin.read()); J["source_last_seq"]='$ADVANCE'; print json.dumps(J);')
OK=$(curl -s -X PUT -H 'Content-Type: application/json' -d "$LOCAL_DOC_ADV_JSON" "$SOURCE/_local/$LOCAL_ID" | json_get ok)
echo "ok"
echo -n " re-start repl ... "
REP_OUT=$(curl -s -X POST -H 'Content-Type: application/json' -d "$REPL_JSON" "$COUCH_URL/_replicate")
echo "ok"
echo "";
sleep 1;
showSeqInfo;
fi
if [ ! -z "$CYCLE" ]; then
echo "";
echo "entering status update loop, update every $CYCLE seconds:"
while true; do
showSeqInfoChanges;
sleep $CYCLE;
done
fi
#!/bin/bash
set -e
usage() {
cat <<USAGE
usage: $(basename $0) COUCH_URL
USAGE
}
couchRestart() {
COUCH="$1";
echo "restarting $COUCH"
curl -s -X POST -H 'Content-Type: application/json' $COUCH/_restart >/dev/null || true;
echo -n "wait unitl up again ."
while true; do
curl -X GET $COUCH/_active_tasks 2>/dev/null >/dev/null && break || (
echo -n ".";
sleep 1;
)
done
echo " ok"
}
if [ $# -lt 1 ]; then
usage;
exit 1;
fi
couchRestart "$1"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment