-
Notifications
You must be signed in to change notification settings - Fork 4
/
replicaset.sh
165 lines (134 loc) · 6.42 KB
/
replicaset.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#!/bin/bash
# Copyright The KubeDB Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ref: https://github.com/kubernetes/charts/blob/master/stable/mongodb-replicaset/init/on-start.sh
source /init-scripts/common.sh
replica_set="$REPLICA_SET"
script_name=${0##*/}
sleep $DEFAULT_WAIT_SECS
if [[ "$AUTH" == "true" ]]; then
admin_user="$MONGO_INITDB_ROOT_USERNAME"
admin_password="$MONGO_INITDB_ROOT_PASSWORD"
admin_creds=(-u "$admin_user" -p "$admin_password" --authenticationDatabase admin)
auth_args=(--clusterAuthMode ${CLUSTER_AUTH_MODE} --sslMode ${SSL_MODE} --auth --keyFile=/data/configdb/key.txt)
fi
my_hostname=$(uname -n)
log "Bootstrapping MongoDB replica set member: $my_hostname"
log "Reading standard input..."
while read -ra line; do
if [[ "${line}" == *"${my_hostname}"* ]]; then
service_name="$line"
continue
fi
peers=("${peers[@]}" "$line")
done
# set the cert files as ssl_args
if [[ ${SSL_MODE} != "disabled" ]]; then
ca_crt=/var/run/mongodb/tls/ca.crt
pem=/var/run/mongodb/tls/mongo.pem
client_pem=/var/run/mongodb/tls/client.pem
if [[ ! -f "$ca_crt" ]] || [[ ! -f "$pem" ]] || [[ ! -f "$client_pem" ]]; then
log "ENABLE_SSL is set to true, but $ca_crt or $pem or $client_pem file does not exist"
exit 1
fi
ssl_args=(--tls --tlsCAFile "$ca_crt" --tlsCertificateKeyFile "$pem")
auth_args=(--clusterAuthMode ${CLUSTER_AUTH_MODE} --sslMode ${SSL_MODE} --tlsCAFile "$ca_crt" --tlsCertificateKeyFile "$pem" --keyFile=/data/configdb/key.txt)
fi
log "Peers: ${peers[*]}"
log "Waiting for MongoDB to be ready..."
retry mongo "$ipv6" --host localhost "${ssl_args[@]}" --eval "db.adminCommand('ping')"
# check rs.isMaster() (we can run this without authentication) on self to see it is ready
retry mongo admin "$ipv6" --host localhost "${ssl_args[@]}" --quiet --eval "JSON.stringify(rs.isMaster())"
# check rs.isMaster() on each peer to see each of them are ready
for peer in "${peers[@]}"; do
retry mongo admin "$ipv6" --host "$peer" "${ssl_args[@]}" --quiet --eval "JSON.stringify(rs.isMaster())"
done
log "Initialized."
sleep $DEFAULT_WAIT_SECS
if [[ $(mongo admin "$ipv6" --host localhost "${admin_creds[@]}" "${ssl_args[@]}" --quiet --eval "rs.status().myState") == '1' ]]; then
log "($service_name) is already master"
log "Good bye."
exit 0
fi
if [[ $(mongo admin "$ipv6" --host localhost "${admin_creds[@]}" "${ssl_args[@]}" --quiet --eval "rs.status().myState") == '2' ]]; then
log "($service_name) is already added in replicaset"
log "Good bye."
exit 0
fi
# try to find a master and add yourself to its replica set.
for peer in "${peers[@]}"; do
# re-check rs.isMaster() on the peer to see it is ready
retry mongo admin "$ipv6" --host "$peer" "${admin_creds[@]}" "${ssl_args[@]}" --quiet --eval "JSON.stringify(rs.isMaster())"
out=$(mongo admin "$ipv6" --host "$peer" "${admin_creds[@]}" "${ssl_args[@]}" --quiet --eval "JSON.stringify(rs.isMaster())")
log "$out"
if echo "$out" | jq -r '.ismaster' | grep 'true'; then
log "Found master: $peer"
# Retrying command until successful
log "Adding myself ($service_name) to replica set..."
retry mongo admin "$ipv6" --host "$peer" "${admin_creds[@]}" "${ssl_args[@]}" --quiet --eval "JSON.stringify(rs.add('$service_name'))"
sleep $DEFAULT_WAIT_SECS
log 'Waiting for replica to reach SECONDARY state...'
until printf '.' && [[ $(mongo admin "$ipv6" --host localhost "${admin_creds[@]}" "${ssl_args[@]}" --quiet --eval "rs.status().myState") == '2' ]]; do
sleep 1
done
log '✓ Replica reached SECONDARY state.'
log "Good bye."
exit 0
fi
done
# else initiate a replica set with yourself.
if mongo "$ipv6" --host localhost "${ssl_args[@]}" --eval "rs.status()" | grep "no replset config has been received"; then
# Retrying command until successful
log "Initiating a new replica set with myself ($service_name)..."
retry mongo "$ipv6" --host localhost "${ssl_args[@]}" --quiet --eval "JSON.stringify(rs.initiate({'_id': '$replica_set', 'writeConcernMajorityJournalDefault': false, 'members': [{'_id': 0, 'host': '$service_name'}]}))"
sleep $DEFAULT_WAIT_SECS
log 'Waiting for replica to reach PRIMARY state...'
until printf '.' && [[ $(mongo "$ipv6" --host localhost "${ssl_args[@]}" --quiet --eval "rs.isMaster().ismaster") == 'true' ]]; do
sleep 1
done
log '✓ Replica reached PRIMARY state.'
if [[ "$AUTH" == "true" ]]; then
log "Creating admin user..."
mongo admin "$ipv6" --host localhost "${ssl_args[@]}" --quiet --eval "db.createUser({user: '$admin_user', pwd: '$admin_password', roles: [{role: 'root', db: 'admin'}]})"
fi
# Initialize Part for KubeDB.
# ref: https://github.com/docker-library/mongo/blob/a499e81e743b05a5237e2fd700c0284b17d3d416/3.4/docker-entrypoint.sh#L302
# Start
export MONGO_INITDB_DATABASE="${MONGO_INITDB_DATABASE:-test}"
log "Initialize init scripts"
echo
ls -la /docker-entrypoint-initdb.d
for f in /docker-entrypoint-initdb.d/*; do
case "$f" in
*.sh)
log "$0: running $f"
. "$f"
;;
*.js)
log "$0: running $f 1"
log "$(mongo "$ipv6" --host localhost --quiet "$MONGO_INITDB_DATABASE" "${admin_creds[@]}" "${ssl_args[@]}" "$f")"
;;
*) log "$0: ignoring $f" ;;
esac
echo
done
# END
log "Done."
fi
if [[ ${SSL_MODE} != "disabled" ]] && [[ -f "$client_pem" ]]; then
#xref: https://docs.mongodb.com/manual/tutorial/configure-x509-client-authentication/#procedures
log "Creating root user ${INJECT_USER} for SSL..."
mongo admin "$ipv6" --host localhost "${admin_creds[@]}" "${ssl_args[@]}" --eval "db.getSiblingDB(\"\$external\").runCommand({createUser: \"${INJECT_USER}\",roles:[{role: 'root', db: 'admin'}],})"
fi
log "Good bye."