diff --git a/mongo/hooks/mongo_database-relation-joined b/mongo/hooks/mongo_database-relation-joined index ce5cba53..41409a4f 100755 --- a/mongo/hooks/mongo_database-relation-joined +++ b/mongo/hooks/mongo_database-relation-joined @@ -10,29 +10,35 @@ DBNAME=$(relation-get dbname) || { } -dbs=$(mongo:db:ls) || exit 1 -if matching_db=$(e "$dbs" | egrep "[a-zA-Z0-9.-_]*_${DBNAME}"); then - if e "$dbs" | grep "^${DBNAME}$"; then - err "Error: unexpected database '$matching_db'" \ - "found along with database named '${DBNAME}'." - exit 1 - fi - ## Let's take for granted that only current source service is - ## concerned by the database. We need to restart source service - ## container only if already running. - container_ids=($(get_running_containers_for_service "$MASTER_BASE_SERVICE_NAME")) - for container_id in "${container_ids[@]}"; do - mongo_url=$(docker:container:env_get "$container_id" MONGO_URL) || return 1 - if [[ "$mongo_url" == */"${matching_db}"* ]]; then - info "Attempting to stop current containers of service $MASTER_BASE_SERVICE_NAME" - docker stop -t 5 "$container_id" +ensure_db_docker_running + +if dbs=$(mongo:db:ls); then + if matching_db=$(e "$dbs" | egrep "[a-zA-Z0-9.-_]*_${DBNAME}"); then + if e "$dbs" | grep "^${DBNAME}$"; then + err "Error: unexpected database '$matching_db'" \ + "found along with database named '${DBNAME}'." + exit 1 fi - done - - mongo:db:rename "$matching_db" "${DBNAME}" - - ## we DO NOT want to start the stopped container again as they are not - ## properly configured + ## Let's take for granted that only current source service is + ## concerned by the database. We need to restart source service + ## container only if already running. + container_ids=($(get_running_containers_for_service "$MASTER_BASE_SERVICE_NAME")) + for container_id in "${container_ids[@]}"; do + mongo_url=$(docker:container:env_get "$container_id" MONGO_URL) || return 1 + if [[ "$mongo_url" == */"${matching_db}"* ]]; then + info "Attempting to stop current containers of service $MASTER_BASE_SERVICE_NAME" + docker stop -t 5 "$container_id" + fi + done + + mongo:db:rename "$matching_db" "${DBNAME}" + + ## we DO NOT want to start the stopped container again as they are not + ## properly configured + fi +else + err "Failed to query for database list" + exit 14 fi ## ReplicaSet initialization diff --git a/mongo/lib/common b/mongo/lib/common index 7ed32372..9824eeef 100644 --- a/mongo/lib/common +++ b/mongo/lib/common @@ -20,23 +20,60 @@ _set_server_db_params() { _set_db_params() { local docker_ip="$1" docker_network="$2" + ## XXXvlab: include this in compose-core + if [ "${_db_params}" != "$docker_ip:$docker_network" ]; then + db_docker_opts+=("--network" "$docker_network") - db_docker_opts+=("--network" "$docker_network") - - db_cmd_opts+=("--host" "$docker_ip") - check_command="db.serverStatus().ok" + db_cmd_opts+=("--host" "$docker_ip") + check_command="db.serverStatus().ok" + _db_params="$docker_ip:$docker_network" + echo callers: "${FUNCNAME[@]}" >&2 + fi } + ddb() { dcmd mongo --quiet "$@"; } +djson() { + local out err + if ! out=$(ddb); then + err "Mongo call failed" + return 128 + fi + if [ -z "$out" ]; then + err "Mongo replied with empty output" + return 64 + fi + if [ "$(e "$out" | jq -r .ok)" != "1" ]; then + if ! e "$out" | jq . >/dev/null 2>&1; then + err "Mongo didn't output JSON, output follows:" + e "$out" | prefix " | " + return 32 + fi >&2 + errmsg=$(e "$out" | jq -r '.errmsg') + code_name=$(e "$out" | jq -r '.codeName') + err "Mongo failed with error message: $errmsg (code: ${code_name})" + e "$out" + return 32 + fi + e "$out" + return 0 +} + mongo:db:ls() { local out - if ! out=$(ddb < <(echo "JSON.stringify(db.adminCommand( { listDatabases: 1 } ))")); then + if out=$(djson < <(echo "JSON.stringify(db.adminCommand( { listDatabases: 1 } ))")); then + e "$out" | jq -r '.databases[] | .name' + return 0 + else + if [ "$(e "$out" | jq -r '.codeName')" == "NotMasterNoSlaveOk" ]; then + ## equivalent to having no databases + return 0 + fi err "Could not query list of databases." return 1 fi - e "$out" | jq -r '.databases[] | .name' }