Skip to content

Commit

Permalink
Merge pull request #133 from i5okie/fix/backup-mongo-zombies
Browse files Browse the repository at this point in the history
Fix mongo backups leaving zombie processes
  • Loading branch information
esune authored Aug 20, 2024
2 parents 10fc51c + 06c46d4 commit f75e489
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 58 deletions.
7 changes: 7 additions & 0 deletions docker/Dockerfile_Mongo
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ ADD https://github.com/$SOURCE_REPO/go-crond/releases/download/$GOCROND_VERSION/

USER root

# Add Tini
ENV TINI_VERSION v0.19.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini

RUN chmod +x /usr/bin/go-crond
RUN chown -R $user:root /data/db && \
chmod -R ug+rw /data/db
Expand All @@ -41,5 +46,7 @@ RUN echo $TZ > /etc/timezone
# Important - Reset to the base image's user account.
USER $uid

# Overwrite entrypoint with dubm-init
ENTRYPOINT ["/tini", "--"]
# Set the default CMD.
CMD bash /backup.sh
114 changes: 56 additions & 58 deletions docker/backup.mongo.plugin
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ function onRestoreDatabase(){
}

function onDatabaseInit() {
(
local OPTIND
local unset flags
while getopts : FLAG; do
Expand All @@ -79,41 +80,43 @@ function onDatabaseInit() {
done
shift $((OPTIND-1))

# Retrieve database details
local _databaseSpec=${1}
local _database=$(getDatabaseName "${_databaseSpec}")
local _username=$(getUsername "${_databaseSpec}")
local _password=$(getPassword "${_databaseSpec}")

# Check if the database already exists
if mongosh --quiet --eval "db.getMongo().getDBNames().indexOf('$_database') >= 0"; then
echoYellow "Database '$_database' already exists, skipping initialization."
return 0
fi

# Initialize the database by creating the user with the roles
mongosh "$_database" --quiet --eval "
db.createUser({
user: '$_username',
pwd: '$_password',
roles: [
{ role: 'dbOwner', db: '$_database' },
{ role: 'readWrite', db: '$_database' },
{ role: 'clusterAdmin', db: 'admin' }
]
});
"

# Check the exit status of the createUser command
if [ $? -eq 0 ]; then
echoGreen "Database '$_database' initialized successfully."
return 0
else
echoRed "Failed to initialize database '$_database'."
return 1
fi
}
# Retrieve database details
_databaseSpec=${1}
_database=$(getDatabaseName "${_databaseSpec}")
_username=$(getUsername "${_databaseSpec}")
_password=$(getPassword "${_databaseSpec}")

# Check if the database already exists
result=$(mongosh --eval "db.getMongo().getDBNames().indexOf('$_database')")

if [ ! -z "$result" ] && [ "$result" -ge 0 ]; then
echoYellow "Database '$_database' already exists, skipping initialization."
return 0
fi

# Initialize the database by creating the user with the roles
mongosh "$_database" --quiet --eval "
db.createUser({
user: '$_username',
pwd: '$_password',
roles: [
{ role: 'dbOwner', db: '$_database' },
{ role: 'readWrite', db: '$_database' },
{ role: 'clusterAdmin', db: 'admin' }
]
});
" > /dev/null 2>&1 &

# Check the exit status of the createUser command
if [ $? -eq 0 ]; then
echoGreen "Database '$_database' initialized successfully."
return 0
else
echoRed "Failed to initialize database '$_database'."
return 1
fi
)
}

function onStartServer(){
(
Expand All @@ -127,11 +130,15 @@ function onStartServer(){
shift $((OPTIND-1))

_databaseSpec=${1}

_hostname=$(getHostname ${flags} ${_databaseSpec})

# Start a local MongoDb instance
mongod --bind_ip $_hostname > /dev/null 2>&1 &
exec mongod --bind_ip $_hostname --quiet >/dev/null 2>&1 &

# Wait for mongodb to be ready
while ! mongosh --host $_hostname --eval "db.adminCommand('ping')" > /dev/null 2>&1; do
sleep 1
done

# Initialize database if necessary
onDatabaseInit "${_databaseSpec}"
Expand All @@ -150,26 +157,25 @@ function onStopServer(){
shift $((OPTIND-1))

_databaseSpec=${1}

_hostname=$(getHostname ${flags} ${_databaseSpec})

mongosh ${_hostname}/admin --quiet --eval "db.shutdownServer()" > /dev/null 2>&1

# Wait for server to stop ...
local startTime=$(date +%s%N)
local timeout=30

mongosh --host $_hostname --eval "db.getSiblingDB('admin').shutdownServer()" &
mongosh_pid=$!

printf "waiting for server to stop"
while onPingDbServer -l ${@}; do
printf "."
local duration_ns=$(($(date +%s%N) - $startTime))
if (( ${duration_ns} >= ${DATABASE_SERVER_TIMEOUT_NS} )); then
echoRed "\nThe server failed to stop within $(getElapsedTimeFromDuration ${duration})."
echoRed "Killing the mongod process ...\n"
pkill -INT mongod
# Wait for mongosh to finish or timeout
while kill -0 $mongosh_pid 2>/dev/null; do
if [ $(($(date +%s) - startTime)) -ge $timeout ]; then
kill $mongosh_pid
break
fi
sleep 1
done

# Ensure mongod is stopped
pkill -f "mongod --bind_ip $_hostname"
)
}

Expand Down Expand Up @@ -197,18 +203,10 @@ function onPingDbServer(){
shift $((OPTIND-1))

_databaseSpec=${1}

_hostname=$(getHostname ${flags} ${_databaseSpec})
_database=$(getDatabaseName ${_databaseSpec})
_port=$(getPort ${flags} ${_databaseSpec})
_portArg=${_port:+"--port ${_port}"}
_username=$(getUsername ${_databaseSpec})
_password=$(getPassword ${_databaseSpec})

_dbAddressArg=${_hostname}${_port:+:${_port}}${_database:+/${_database}}
_authDbArg=${MONGODB_AUTHENTICATION_DATABASE:+"--authenticationDatabase ${MONGODB_AUTHENTICATION_DATABASE}"}

mongosh --host $_hostname --eval "db.adminCommand('ping')" > /dev/null 2>&1

mongosh ${_dbAddressArg} ${_authDbArg} -u "${_username}" -p "${_password}" --quiet --eval='db.runCommand("ping").ok' > /dev/null 2>&1
local mongoshExitCode=$?

if (( ${mongoshExitCode} != 0 )); then
Expand Down

0 comments on commit f75e489

Please sign in to comment.