Skip to content

Commit

Permalink
Split main scripts for standalone server and replication.
Browse files Browse the repository at this point in the history
  • Loading branch information
Marek Skalický committed Aug 26, 2016
1 parent c0a5332 commit df10452
Show file tree
Hide file tree
Showing 25 changed files with 740 additions and 582 deletions.
5 changes: 4 additions & 1 deletion 2.4/examples/replica/mongodb-clustered.json
Expand Up @@ -91,7 +91,7 @@
"failurePolicy": "Retry",
"execNewPod": {
"command": [
"run-mongod",
"run-mongod-replication",
"initiate"
],
"containerName": "mongodb",
Expand Down Expand Up @@ -125,6 +125,9 @@
{
"name": "mongodb",
"image": "openshift/mongodb-24-centos7",
"args": [
"run-mongod-replication"
],
"readinessProbe": {
"tcpSocket": {
"port": 27017
Expand Down
77 changes: 25 additions & 52 deletions 2.4/root/usr/bin/run-mongod
Expand Up @@ -39,13 +39,7 @@ function cleanup() {
exit 0
}

if [ $# -gt 0 ] && [ "$1" == "initiate" ]; then
if ! [[ -v MONGODB_USER && -v MONGODB_PASSWORD && -v MONGODB_DATABASE && -v MONGODB_ADMIN_PASSWORD ]]; then
usage
fi
setup_keyfile
exec ${CONTAINER_SCRIPTS_PATH}/initiate_replica.sh
fi
trap 'cleanup' SIGINT SIGTERM

# If user provides own config file use it and do not generate new one
if [ ! -s $MONGODB_CONFIG_PATH ]; then
Expand All @@ -56,50 +50,29 @@ fi
# Need to cache the container address for the cleanup
cache_container_addr
mongo_common_args="-f $MONGODB_CONFIG_PATH"
if [ -z "${MONGODB_REPLICA_NAME-}" ]; then
if ! [[ -v MONGODB_USER && -v MONGODB_PASSWORD && -v MONGODB_DATABASE && -v MONGODB_ADMIN_PASSWORD ]]; then
usage
fi
# Run the MongoDB in 'standalone' mode
mongod $mongo_common_args &
wait_for_mongo_up
js_command="db.system.users.count({'user':'admin'})"
if [ "$(mongo admin --quiet --eval "$js_command")" == "1" ]; then
echo "=> Admin user is already created. Resetting password ..."
mongo_reset_admin
else
mongo_create_admin
fi
js_command="db.system.users.count({'user':'${MONGODB_USER}'})"
if [ "$(mongo ${MONGODB_DATABASE} --quiet --eval "$js_command")" == "1" ]; then
echo "=> MONGODB_USER user is already created. Resetting password ..."
mongo_reset_user
else
mongo_create_user
fi
# Restart the MongoDB daemon to bind on all interfaces
mongod $mongo_common_args --shutdown
wait_for_mongo_down
unset_env_vars
exec mongod $mongo_common_args --auth
if ! [[ -v MONGODB_USER && -v MONGODB_PASSWORD && -v MONGODB_DATABASE && -v MONGODB_ADMIN_PASSWORD ]]; then
usage
fi

# Run the MongoDB in 'standalone' mode
mongod $mongo_common_args &
wait_for_mongo_up
js_command="db.system.users.count({'user':'admin'})"
if [ "$(mongo admin --quiet --eval "$js_command")" == "1" ]; then
echo "=> Admin user is already created. Resetting password ..."
mongo_reset_admin
else
setup_keyfile
# Run the MongoDB in 'clustered' mode with --replSet
if [ ! -v MONGODB_NO_SUPERVISOR ]; then
run_mongod_supervisor
trap 'cleanup' SIGINT SIGTERM
fi
# In MongoDB 2.4 --keyFile does not imply authentication, so enabling it explicitly
# When not initializing the MongoDB cluster, we have to run with authentication
if [ -v MONGODB_NO_AUTH ]; then
mongo_common_args+=" --auth"
fi
# Run `unset_env_vars` and `mongod` in a subshell because
# MONGODB_ADMIN_PASSWORD should still be defined when the trapped call to
# `cleanup` references it.
(
unset_env_vars
mongod $mongo_common_args --replSet "${MONGODB_REPLICA_NAME}"
) &
wait
mongo_create_admin
fi
js_command="db.system.users.count({'user':'${MONGODB_USER}'})"
if [ "$(mongo ${MONGODB_DATABASE} --quiet --eval "$js_command")" == "1" ]; then
echo "=> MONGODB_USER user is already created. Resetting password ..."
mongo_reset_user
else
mongo_create_user
fi
# Restart the MongoDB daemon to bind on all interfaces
mongod $mongo_common_args --shutdown
wait_for_mongo_down
unset_env_vars
exec mongod $mongo_common_args --auth
75 changes: 75 additions & 0 deletions 2.4/root/usr/bin/run-mongod-replication
@@ -0,0 +1,75 @@
#!/bin/bash
#
# Run mongod which connect to replSet
# $1 - "initiate" (optional) -> this mongod will initiate a replSet
#
# If this script is terminated it removes mongod from replSet

set -o errexit
set -o nounset
set -o pipefail

source ${CONTAINER_SCRIPTS_PATH}/common.sh

function usage() {
echo "You must specify the following environment variables:"
echo " MONGODB_USER"
echo " MONGODB_PASSWORD"
echo " MONGODB_DATABASE"
echo " MONGODB_ADMIN_PASSWORD"
echo " MONGODB_REPLICA_NAME"
echo "Optional variables:"
echo " MONGODB_INITIAL_REPLICA_COUNT"
echo "MongoDB settings:"
echo " MONGODB_NOPREALLOC (default: true)"
echo " MONGODB_SMALLFILES (default: true)"
echo " MONGODB_QUIET (default: true)"
exit 1
}

# Make sure env variables don't propagate to mongod process.
function unset_env_vars() {
unset MONGODB_USER MONGODB_PASSWORD MONGODB_DATABASE MONGODB_ADMIN_PASSWORD
}

function cleanup() {
if [ -n "${MONGODB_REPLICA_NAME-}" ]; then
mongo_remove
fi
echo "=> Shutting down MongoDB server ..."
if pgrep mongod; then
pkill -2 mongod
fi
wait_for_mongo_down
exit 0
}

trap 'cleanup' SIGINT SIGTERM

# If user provides own config file use it and do not generate new one
if [ ! -s $MONGODB_CONFIG_PATH ]; then
# Generate config file for MongoDB
envsubst < ${CONTAINER_SCRIPTS_PATH}/mongodb.conf.template > $MONGODB_CONFIG_PATH
fi

# Need to cache the container address for the cleanup
cache_container_addr
mongo_common_args="-f $MONGODB_CONFIG_PATH"
if ! [[ -v MONGODB_USER && -v MONGODB_PASSWORD && -v MONGODB_DATABASE && -v MONGODB_ADMIN_PASSWORD && -v MONGODB_REPLICA_NAME ]]; then
usage
fi

# Run the MongoDB in 'replicated' mode
setup_keyfile

# Run the supervisor in background to manage replset
${CONTAINER_SCRIPTS_PATH}/replset_supervisor.sh "${1:-}" "$$" &

# Run `unset_env_vars` and `mongod` in a subshell because
# MONGODB_ADMIN_PASSWORD should still be defined when the trapped call to
# `cleanup` references it.
(
unset_env_vars
mongod $mongo_common_args --replSet "${MONGODB_REPLICA_NAME}"
) &
wait
6 changes: 0 additions & 6 deletions 2.4/root/usr/share/container-scripts/mongodb/common.sh
Expand Up @@ -186,12 +186,6 @@ function mongo_add() {
--host "${primary_addr}" --eval "rs.add('${mongo_addr}');"
}

# run_mongod_supervisor runs the MongoDB replica supervisor that manages
# registration of the new members to the MongoDB replica cluster
function run_mongod_supervisor() {
${CONTAINER_SCRIPTS_PATH}/replica_supervisor.sh 2>&1 &
}

# mongo_create_admin creates the MongoDB admin user with password: MONGODB_ADMIN_PASSWORD
# $1 - login parameters for mongo (optional)
# $2 - host where to connect (localhost by default)
Expand Down
75 changes: 0 additions & 75 deletions 2.4/root/usr/share/container-scripts/mongodb/initiate_replica.sh

This file was deleted.

16 changes: 0 additions & 16 deletions 2.4/root/usr/share/container-scripts/mongodb/replica_supervisor.sh

This file was deleted.

84 changes: 84 additions & 0 deletions 2.4/root/usr/share/container-scripts/mongodb/replset_supervisor.sh
@@ -0,0 +1,84 @@
#!/bin/bash

set -o errexit
set -o nounset
set -o pipefail

source ${CONTAINER_SCRIPTS_PATH}/common.sh

# Initiate replicaset and exit
if [[ "$1" == "initiate" ]]; then
main_process_id=$2
current_endpoints=$(endpoints)
if [ -n "${MONGODB_INITIAL_REPLICA_COUNT:-}" ]; then
echo -n "=> Waiting for $MONGODB_INITIAL_REPLICA_COUNT MongoDB endpoints ..."
while [[ "$(echo "${current_endpoints}" | wc -l)" -lt ${MONGODB_INITIAL_REPLICA_COUNT} ]]; do
sleep 2
current_endpoints=$(endpoints)
done
else
echo "Attention: MONGODB_INITIAL_REPLICA_COUNT is not set and it could lead to a improperly configured replica set."
echo "To fix this, set MONGODB_INITIAL_REPLICA_COUNT variable to the number of members in the replica set in"
echo "the configuration of post deployment hook."

echo -n "=> Waiting for MongoDB endpoints ..."
while [ -z "${current_endpoints}" ]; do
sleep 2
current_endpoints=$(endpoints)
done
fi
echo "${current_endpoints}"

# Let initialize the first member of the cluster
mongo_node="$(echo -n ${current_endpoints} | cut -d ' ' -f 1):${CONTAINER_PORT}"

echo "=> Waiting for all endpoints to accept connections..."
for node in ${current_endpoints}; do
wait_for_mongo_up ${node} &>/dev/null
done

echo "=> Initiating the replSet ${MONGODB_REPLICA_NAME} ..."
# This will perform the 'rs.initiate()' command on the current MongoDB.
mongo_initiate "${current_endpoints}"

echo "=> Creating MongoDB users ..."
mongo_create_admin
mongo_create_user "-u admin -p ${MONGODB_ADMIN_PASSWORD}"

echo "=> Waiting for replication to finish ..."
# TODO: Replace this with polling or a Mongo script that will check if all
# members of the cluster are now properly replicated (user accounts are
# created on all members).
sleep 10

# Some commands will force MongoDB client to re-connect. This is not working
# well in combination with '--eval'. In that case the 'mongo' command will fail
# with return code 254.
echo "=> Initiate Pod giving up the PRIMARY role ..."
mongo admin -u admin -p "${MONGODB_ADMIN_PASSWORD}" --quiet --eval "rs.stepDown(120);" &>/dev/null || true

# Wait till the new PRIMARY member is elected
echo "=> Waiting for the new PRIMARY to be elected ..."
mongo admin -u admin -p "${MONGODB_ADMIN_PASSWORD}" --quiet --host ${mongo_node} --eval "var done=false;while(done==false){var members=rs.status().members;for(i=0;i<members.length;i++){if(members[i].stateStr=='PRIMARY' && members[i].name!='$(mongo_addr)'){done=true}};sleep(500)};" &>/dev/null

# Remove the initialization container MongoDB from cluster and shutdown
echo "=> The new PRIMARY member elected, shutting down current member ..."
mongo_remove

mongod -f ${MONGODB_CONFIG_PATH} --shutdown &>/dev/null
wait_for_mongo_down

echo "=> Successfully initialized replSet"

# Exit this pod
kill ${main_process_id}

# Try to add node into replicaset
else
echo "=> Waiting for local MongoDB to accept connections ..."
wait_for_mongo_up
set -x
# Add the current container to the replSet
mongo_add

fi

0 comments on commit df10452

Please sign in to comment.