From df104523417431ac013733b5478e483124b048c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Skalick=C3=BD?= Date: Fri, 26 Aug 2016 13:26:29 +0200 Subject: [PATCH] Split main scripts for standalone server and replication. --- 2.4/examples/replica/mongodb-clustered.json | 5 +- 2.4/root/usr/bin/run-mongod | 77 ++++++----------- 2.4/root/usr/bin/run-mongod-replication | 75 +++++++++++++++++ .../share/container-scripts/mongodb/common.sh | 6 -- .../mongodb/initiate_replica.sh | 75 ----------------- .../mongodb/replica_supervisor.sh | 16 ---- .../mongodb/replset_supervisor.sh | 84 +++++++++++++++++++ 2.6/root/usr/bin/run-mongod | 72 ++++++---------- 2.6/root/usr/bin/run-mongod-replication | 75 +++++++++++++++++ .../share/container-scripts/mongodb/common.sh | 6 -- .../mongodb/initiate_replica.sh | 75 ----------------- .../mongodb/replica_supervisor.sh | 16 ---- .../mongodb/replset_supervisor.sh | 84 +++++++++++++++++++ 3.0-upg/root/usr/bin/run-mongod | 72 ++++++---------- 3.0-upg/root/usr/bin/run-mongod-replication | 75 +++++++++++++++++ .../share/container-scripts/mongodb/common.sh | 6 -- .../mongodb/initiate_replica.sh | 75 ----------------- .../mongodb/replica_supervisor.sh | 16 ---- .../mongodb/replset_supervisor.sh | 84 +++++++++++++++++++ 3.2/root/usr/bin/run-mongod | 72 ++++++---------- 3.2/root/usr/bin/run-mongod-replication | 75 +++++++++++++++++ .../share/container-scripts/mongodb/common.sh | 6 -- .../mongodb/initiate_replica.sh | 75 ----------------- .../mongodb/replica_supervisor.sh | 16 ---- .../mongodb/replset_supervisor.sh | 84 +++++++++++++++++++ 25 files changed, 740 insertions(+), 582 deletions(-) create mode 100755 2.4/root/usr/bin/run-mongod-replication delete mode 100755 2.4/root/usr/share/container-scripts/mongodb/initiate_replica.sh delete mode 100755 2.4/root/usr/share/container-scripts/mongodb/replica_supervisor.sh create mode 100755 2.4/root/usr/share/container-scripts/mongodb/replset_supervisor.sh create mode 100755 2.6/root/usr/bin/run-mongod-replication delete mode 100755 2.6/root/usr/share/container-scripts/mongodb/initiate_replica.sh delete mode 100755 2.6/root/usr/share/container-scripts/mongodb/replica_supervisor.sh create mode 100755 2.6/root/usr/share/container-scripts/mongodb/replset_supervisor.sh create mode 100755 3.0-upg/root/usr/bin/run-mongod-replication delete mode 100755 3.0-upg/root/usr/share/container-scripts/mongodb/initiate_replica.sh delete mode 100755 3.0-upg/root/usr/share/container-scripts/mongodb/replica_supervisor.sh create mode 100755 3.0-upg/root/usr/share/container-scripts/mongodb/replset_supervisor.sh create mode 100755 3.2/root/usr/bin/run-mongod-replication delete mode 100755 3.2/root/usr/share/container-scripts/mongodb/initiate_replica.sh delete mode 100755 3.2/root/usr/share/container-scripts/mongodb/replica_supervisor.sh create mode 100755 3.2/root/usr/share/container-scripts/mongodb/replset_supervisor.sh diff --git a/2.4/examples/replica/mongodb-clustered.json b/2.4/examples/replica/mongodb-clustered.json index 32d0bfa2..6a35cf93 100644 --- a/2.4/examples/replica/mongodb-clustered.json +++ b/2.4/examples/replica/mongodb-clustered.json @@ -91,7 +91,7 @@ "failurePolicy": "Retry", "execNewPod": { "command": [ - "run-mongod", + "run-mongod-replication", "initiate" ], "containerName": "mongodb", @@ -125,6 +125,9 @@ { "name": "mongodb", "image": "openshift/mongodb-24-centos7", + "args": [ + "run-mongod-replication" + ], "readinessProbe": { "tcpSocket": { "port": 27017 diff --git a/2.4/root/usr/bin/run-mongod b/2.4/root/usr/bin/run-mongod index f76c0b61..539be641 100755 --- a/2.4/root/usr/bin/run-mongod +++ b/2.4/root/usr/bin/run-mongod @@ -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 @@ -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 diff --git a/2.4/root/usr/bin/run-mongod-replication b/2.4/root/usr/bin/run-mongod-replication new file mode 100755 index 00000000..3316dc4b --- /dev/null +++ b/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 diff --git a/2.4/root/usr/share/container-scripts/mongodb/common.sh b/2.4/root/usr/share/container-scripts/mongodb/common.sh index 14ec7e07..ff62f621 100644 --- a/2.4/root/usr/share/container-scripts/mongodb/common.sh +++ b/2.4/root/usr/share/container-scripts/mongodb/common.sh @@ -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) diff --git a/2.4/root/usr/share/container-scripts/mongodb/initiate_replica.sh b/2.4/root/usr/share/container-scripts/mongodb/initiate_replica.sh deleted file mode 100755 index 2707a6bd..00000000 --- a/2.4/root/usr/share/container-scripts/mongodb/initiate_replica.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash - -set -o errexit -set -o nounset -set -o pipefail - -source ${CONTAINER_SCRIPTS_PATH}/common.sh - -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} ..." -# Start the MongoDB without authentication to initialize and kick-off the cluster: -# This MongoDB server is just temporary and will be removed later in this -# script. -export MONGODB_REPLICA_NAME -MONGODB_NO_SUPERVISOR=1 MONGODB_NO_AUTH=1 run-mongod mongod & -wait_for_mongo_up - -# 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/dev/null - -# Remove the initialization container MongoDB from cluster and shutdown -echo "=> The new PRIMARY member is $(mongo_primary_member_addr), shutting down current member ..." -mongo_remove - -mongod -f ${MONGODB_CONFIG_PATH} --shutdown &>/dev/null -wait_for_mongo_down - -echo "=> Successfully initialized replSet" diff --git a/2.4/root/usr/share/container-scripts/mongodb/replica_supervisor.sh b/2.4/root/usr/share/container-scripts/mongodb/replica_supervisor.sh deleted file mode 100755 index 260e8e9a..00000000 --- a/2.4/root/usr/share/container-scripts/mongodb/replica_supervisor.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -# -# This script registers the current container into MongoDB replica set and -# unregisters it when the container is terminated. - -set -o errexit -set -o nounset -set -o pipefail - -source ${CONTAINER_SCRIPTS_PATH}/common.sh - -echo "=> Waiting for local MongoDB to accept connections ..." -wait_for_mongo_up -set -x -# Add the current container to the replSet -mongo_add diff --git a/2.4/root/usr/share/container-scripts/mongodb/replset_supervisor.sh b/2.4/root/usr/share/container-scripts/mongodb/replset_supervisor.sh new file mode 100755 index 00000000..9d99c058 --- /dev/null +++ b/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/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 diff --git a/2.6/root/usr/bin/run-mongod b/2.6/root/usr/bin/run-mongod index 2108053d..21ba3703 100755 --- a/2.6/root/usr/bin/run-mongod +++ b/2.6/root/usr/bin/run-mongod @@ -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 @@ -56,45 +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', 'db':'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}', 'db':'${MONGODB_DATABASE}'})" - if [ "$(mongo admin --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', 'db':'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 - # 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}', 'db':'${MONGODB_DATABASE}'})" +if [ "$(mongo admin --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 diff --git a/2.6/root/usr/bin/run-mongod-replication b/2.6/root/usr/bin/run-mongod-replication new file mode 100755 index 00000000..3316dc4b --- /dev/null +++ b/2.6/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 diff --git a/2.6/root/usr/share/container-scripts/mongodb/common.sh b/2.6/root/usr/share/container-scripts/mongodb/common.sh index 0cbc5a42..f7941388 100644 --- a/2.6/root/usr/share/container-scripts/mongodb/common.sh +++ b/2.6/root/usr/share/container-scripts/mongodb/common.sh @@ -185,12 +185,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) diff --git a/2.6/root/usr/share/container-scripts/mongodb/initiate_replica.sh b/2.6/root/usr/share/container-scripts/mongodb/initiate_replica.sh deleted file mode 100755 index 2707a6bd..00000000 --- a/2.6/root/usr/share/container-scripts/mongodb/initiate_replica.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash - -set -o errexit -set -o nounset -set -o pipefail - -source ${CONTAINER_SCRIPTS_PATH}/common.sh - -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} ..." -# Start the MongoDB without authentication to initialize and kick-off the cluster: -# This MongoDB server is just temporary and will be removed later in this -# script. -export MONGODB_REPLICA_NAME -MONGODB_NO_SUPERVISOR=1 MONGODB_NO_AUTH=1 run-mongod mongod & -wait_for_mongo_up - -# 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/dev/null - -# Remove the initialization container MongoDB from cluster and shutdown -echo "=> The new PRIMARY member is $(mongo_primary_member_addr), shutting down current member ..." -mongo_remove - -mongod -f ${MONGODB_CONFIG_PATH} --shutdown &>/dev/null -wait_for_mongo_down - -echo "=> Successfully initialized replSet" diff --git a/2.6/root/usr/share/container-scripts/mongodb/replica_supervisor.sh b/2.6/root/usr/share/container-scripts/mongodb/replica_supervisor.sh deleted file mode 100755 index 260e8e9a..00000000 --- a/2.6/root/usr/share/container-scripts/mongodb/replica_supervisor.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -# -# This script registers the current container into MongoDB replica set and -# unregisters it when the container is terminated. - -set -o errexit -set -o nounset -set -o pipefail - -source ${CONTAINER_SCRIPTS_PATH}/common.sh - -echo "=> Waiting for local MongoDB to accept connections ..." -wait_for_mongo_up -set -x -# Add the current container to the replSet -mongo_add diff --git a/2.6/root/usr/share/container-scripts/mongodb/replset_supervisor.sh b/2.6/root/usr/share/container-scripts/mongodb/replset_supervisor.sh new file mode 100755 index 00000000..9d99c058 --- /dev/null +++ b/2.6/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/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 diff --git a/3.0-upg/root/usr/bin/run-mongod b/3.0-upg/root/usr/bin/run-mongod index eecac522..f9dab299 100755 --- a/3.0-upg/root/usr/bin/run-mongod +++ b/3.0-upg/root/usr/bin/run-mongod @@ -47,13 +47,7 @@ Notice: This image is supported only for upgrade from MongoDB 2.6 to 3.2. " -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 @@ -64,45 +58,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', 'db':'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}', 'db':'${MONGODB_DATABASE}'})" - if [ "$(mongo admin --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', 'db':'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 - # 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}', 'db':'${MONGODB_DATABASE}'})" +if [ "$(mongo admin --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 diff --git a/3.0-upg/root/usr/bin/run-mongod-replication b/3.0-upg/root/usr/bin/run-mongod-replication new file mode 100755 index 00000000..3316dc4b --- /dev/null +++ b/3.0-upg/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 diff --git a/3.0-upg/root/usr/share/container-scripts/mongodb/common.sh b/3.0-upg/root/usr/share/container-scripts/mongodb/common.sh index 0cbc5a42..f7941388 100644 --- a/3.0-upg/root/usr/share/container-scripts/mongodb/common.sh +++ b/3.0-upg/root/usr/share/container-scripts/mongodb/common.sh @@ -185,12 +185,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) diff --git a/3.0-upg/root/usr/share/container-scripts/mongodb/initiate_replica.sh b/3.0-upg/root/usr/share/container-scripts/mongodb/initiate_replica.sh deleted file mode 100755 index 2707a6bd..00000000 --- a/3.0-upg/root/usr/share/container-scripts/mongodb/initiate_replica.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash - -set -o errexit -set -o nounset -set -o pipefail - -source ${CONTAINER_SCRIPTS_PATH}/common.sh - -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} ..." -# Start the MongoDB without authentication to initialize and kick-off the cluster: -# This MongoDB server is just temporary and will be removed later in this -# script. -export MONGODB_REPLICA_NAME -MONGODB_NO_SUPERVISOR=1 MONGODB_NO_AUTH=1 run-mongod mongod & -wait_for_mongo_up - -# 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/dev/null - -# Remove the initialization container MongoDB from cluster and shutdown -echo "=> The new PRIMARY member is $(mongo_primary_member_addr), shutting down current member ..." -mongo_remove - -mongod -f ${MONGODB_CONFIG_PATH} --shutdown &>/dev/null -wait_for_mongo_down - -echo "=> Successfully initialized replSet" diff --git a/3.0-upg/root/usr/share/container-scripts/mongodb/replica_supervisor.sh b/3.0-upg/root/usr/share/container-scripts/mongodb/replica_supervisor.sh deleted file mode 100755 index 260e8e9a..00000000 --- a/3.0-upg/root/usr/share/container-scripts/mongodb/replica_supervisor.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -# -# This script registers the current container into MongoDB replica set and -# unregisters it when the container is terminated. - -set -o errexit -set -o nounset -set -o pipefail - -source ${CONTAINER_SCRIPTS_PATH}/common.sh - -echo "=> Waiting for local MongoDB to accept connections ..." -wait_for_mongo_up -set -x -# Add the current container to the replSet -mongo_add diff --git a/3.0-upg/root/usr/share/container-scripts/mongodb/replset_supervisor.sh b/3.0-upg/root/usr/share/container-scripts/mongodb/replset_supervisor.sh new file mode 100755 index 00000000..9d99c058 --- /dev/null +++ b/3.0-upg/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/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 diff --git a/3.2/root/usr/bin/run-mongod b/3.2/root/usr/bin/run-mongod index 2108053d..21ba3703 100755 --- a/3.2/root/usr/bin/run-mongod +++ b/3.2/root/usr/bin/run-mongod @@ -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 @@ -56,45 +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', 'db':'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}', 'db':'${MONGODB_DATABASE}'})" - if [ "$(mongo admin --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', 'db':'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 - # 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}', 'db':'${MONGODB_DATABASE}'})" +if [ "$(mongo admin --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 diff --git a/3.2/root/usr/bin/run-mongod-replication b/3.2/root/usr/bin/run-mongod-replication new file mode 100755 index 00000000..3316dc4b --- /dev/null +++ b/3.2/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 diff --git a/3.2/root/usr/share/container-scripts/mongodb/common.sh b/3.2/root/usr/share/container-scripts/mongodb/common.sh index 0cbc5a42..f7941388 100644 --- a/3.2/root/usr/share/container-scripts/mongodb/common.sh +++ b/3.2/root/usr/share/container-scripts/mongodb/common.sh @@ -185,12 +185,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) diff --git a/3.2/root/usr/share/container-scripts/mongodb/initiate_replica.sh b/3.2/root/usr/share/container-scripts/mongodb/initiate_replica.sh deleted file mode 100755 index 2707a6bd..00000000 --- a/3.2/root/usr/share/container-scripts/mongodb/initiate_replica.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash - -set -o errexit -set -o nounset -set -o pipefail - -source ${CONTAINER_SCRIPTS_PATH}/common.sh - -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} ..." -# Start the MongoDB without authentication to initialize and kick-off the cluster: -# This MongoDB server is just temporary and will be removed later in this -# script. -export MONGODB_REPLICA_NAME -MONGODB_NO_SUPERVISOR=1 MONGODB_NO_AUTH=1 run-mongod mongod & -wait_for_mongo_up - -# 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/dev/null - -# Remove the initialization container MongoDB from cluster and shutdown -echo "=> The new PRIMARY member is $(mongo_primary_member_addr), shutting down current member ..." -mongo_remove - -mongod -f ${MONGODB_CONFIG_PATH} --shutdown &>/dev/null -wait_for_mongo_down - -echo "=> Successfully initialized replSet" diff --git a/3.2/root/usr/share/container-scripts/mongodb/replica_supervisor.sh b/3.2/root/usr/share/container-scripts/mongodb/replica_supervisor.sh deleted file mode 100755 index 260e8e9a..00000000 --- a/3.2/root/usr/share/container-scripts/mongodb/replica_supervisor.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -# -# This script registers the current container into MongoDB replica set and -# unregisters it when the container is terminated. - -set -o errexit -set -o nounset -set -o pipefail - -source ${CONTAINER_SCRIPTS_PATH}/common.sh - -echo "=> Waiting for local MongoDB to accept connections ..." -wait_for_mongo_up -set -x -# Add the current container to the replSet -mongo_add diff --git a/3.2/root/usr/share/container-scripts/mongodb/replset_supervisor.sh b/3.2/root/usr/share/container-scripts/mongodb/replset_supervisor.sh new file mode 100755 index 00000000..9d99c058 --- /dev/null +++ b/3.2/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/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