Reputation: 465
Using Ubuntu 18.04. I have the following bash script to install and run the MongoDB. IT checks if MongoDB is installed or not and run some mongo shell commands:
#!/bin/bash
if [ -f /usr/bin/mongod ]; then
echo "MongoDB is installed on your machine."
kill -0 "$$" || exit
else
password=password
echo "********************* MongoDB 4.0 INSTALL **************************"
echo "MongoDB is is not installed."
echo "******************************************************************"
echo $password | sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 68818C72E52529D4
echo $password | sudo bash -c "echo deb http://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.0.list
sudo bash -c "apt update && apt upgrade -y"
sudo bash -c "apt-get install -y mongodb-org"
sudo bash -c "apt update && apt upgrade -y"
echo 'y' | sudo bash -c "apt autoremove && apt clean"
sudo bash -c "mkdir /data /data/db"
sudo bash -c "systemctl enable mongod" #enables Mongo on system startup
sudo bash -c "service mongod start"
sudo bash -c "service mongod restart"
kill -0 "$$" || exit
echo "********************* MongoDB Create DB and Collection **************************"
fi
mongod_status=`systemctl is-active mongod`
echo "${mongod_status}"
if [[ "${mongod_status}" == "active" ]]
then
echo "MongoDB is already running."
else
echo "MongoDB is not running"
rm /var/lib/mongodb/mongod.lock
sudo bash -c "service mongod start"
fi
mongo <<EOF
use fragment
db.createCollection("fragmenthash");
EOF
If my system is not installed with MongoDB, this script installs and start it. Then it checks the status, which is "active". But then when it executes mongo <<EOF section
, it returns
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
2021-05-19T10:06:01.134+0000 E QUERY [js] Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed: SocketException: Error connecting to 127.0.0.1:27017 :: caused by :: Connection refused :
connect@src/mongo/shell/mongo.js:356:17
@(connect):2:6
exception: connect failed
Even if the status of MongoDB is Active still it gives this error. Whereas, if MongoDB is already installed, it executes the whole script successfully with creating DB and collection. Please help.
Upvotes: 0
Views: 988
Reputation: 189936
Your script has a number of oddities which should probably be straightened out regardless of the immediate problem.
kill -0 "$$" || exit 0
is weird and probably does nothing useful. I guess you probably simply should do nothing in this case, as the purpose of the script seems to be to install the component if it's missing, and then proceed into the mongodb_status=
... part.Stylistically, everything which looks like sudo bash -c 'singlecommand'
should be just sudo singlecommand
; but with the proposed refactoring, you don't need these at all.
The immediate problem with your script seems to be that it takes a while for the server to start listening on the port you configured it for. I don't know enough about Mongo to tell you how to properly wait for it to tell you when it's up "for real" but adding a sleep
is a common (albeit crude) workaround. Another is to examine the log file, looking for the listening event.
#!/bin/bash
# Test for privileged access
test -w / ||
{ echo "$0: need to run privileged; aborting" >&2; exit 127; }
startit () {
local log=/var/log/mongodb/mongod.log
service mongod start
while true; do
test -e "$log" && break
sleep 1
done
grep -q 'port: 27017' "$log" ||
tail -0f "$log" |
grep -q 'port: 27017'
}
if [ -f /usr/bin/mongod ]; then
# Send diagnostic messages to standard error
echo "$0: MongoDB is installed on your machine." >&2
else
# Reduce eyesore
echo "$0: MongoDB is not installed; proceed with 4.0 install" >&2
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 68818C72E52529D4
echo "deb http://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse" >/etc/apt/sources.list.d/mongodb-org-4.0.list
apt update && apt upgrade -y
apt-get install -y mongodb-org
# not necessary or useful to do a second time
# apt update && apt upgrade -y
apt -y autoremove && apt clean
mkdir -p /data/db
systemctl enable mongod
startit
# service mongod restart # is this really useful and necessary?
fi
echo "$0: database initialization" >&2
# Prefer modern command substitution syntax
mongod_status=$(systemctl is-active mongod)
echo "$mongod_status" >&2
if [[ "${mongod_status}" == "active" ]]
then
echo "$0: MongoDB is already running." >&2
else
echo "$0: MongoDB is not running" >&2
rm -f /var/lib/mongodb/mongod.lock
startit
fi
mongo <<EOF
use fragment
db.createCollection("fragmenthash");
EOF
I'm not entirely happy with the startit
function -- at first it failed because I tried to open the log file when it did not yet exist, then it failed because the new lines in the log file already contained the startup message after the one-second sleep. Now it could still fail if the log file is being appended and the old logs contain the startup message from a previous session. But at least this should get you started in the right direction, I hope.
Here's a refactoring which might be more robust ...
startit () {
local log=/var/log/mongodb/mongod.log
sudo -u mongodb touch "$log"
service mongod start &
local launcher=$!
tail -0f "$log" |
grep -q 'port: 27017'
wait "$launcher"
sleep 1
}
The final sleep
is a bit of an act of desperation; it seems to take a jiffy after it logs the startup until it's properly up and listening; and/or maybe add a retry loop around the final mongo
command.
Upvotes: 1