Skip to content

Add jsyaml to parse mongod.conf (especially to remove problematic sections for our initdb logic) #225

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 27 additions & 13 deletions 3.0/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,33 @@ RUN apt-get update \
procps \
&& rm -rf /var/lib/apt/lists/*

# grab gosu for easy step-down from root
ENV GOSU_VERSION 1.7
RUN set -x \
&& apt-get update && apt-get install -y --no-install-recommends wget && rm -rf /var/lib/apt/lists/* \
&& wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \
&& wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \
&& export GNUPGHOME="$(mktemp -d)" \
&& gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
&& gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \
&& rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \
&& chmod +x /usr/local/bin/gosu \
&& gosu nobody true \
&& apt-get purge -y --auto-remove wget
# grab gosu for easy step-down from root (https://github.com/tianon/gosu/releases)
ENV GOSU_VERSION 1.10
# grab "js-yaml" for parsing mongod's YAML config files (https://github.com/nodeca/js-yaml/releases)
ENV JSYAML_VERSION 3.10.0

RUN set -ex; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
wget \
; \
rm -rf /var/lib/apt/lists/*; \
\
dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
export GNUPGHOME="$(mktemp -d)"; \
gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc; \
chmod +x /usr/local/bin/gosu; \
gosu nobody true; \
\
wget -O /js-yaml.js "https://github.com/nodeca/js-yaml/raw/${JSYAML_VERSION}/dist/js-yaml.js"; \
# TODO some sort of download verification here
\
apt-get purge -y --auto-remove wget

RUN mkdir /docker-entrypoint-initdb.d

Expand Down
102 changes: 80 additions & 22 deletions 3.0/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,24 @@ _mongod_hack_have_arg() {
done
return 1
}
# _mongod_hack_get_arg_val '--some-arg' "$@"
_mongod_hack_get_arg_val() {
local checkArg="$1"; shift
while [ "$#" -gt 0 ]; do
local arg="$1"; shift
case "$arg" in
"$checkArg")
echo "$1"
return 0
;;
"$checkArg"=*)
echo "${arg#$checkArg=}"
return 0
;;
esac
done
return 1
}
declare -a mongodHackedArgs
# _mongod_hack_ensure_arg '--some-arg' "$@"
# set -- "${mongodHackedArgs[@]}"
Expand Down Expand Up @@ -98,7 +116,47 @@ _mongod_hack_ensure_arg_val() {
done
mongodHackedArgs+=( "$ensureArg" "$ensureVal" )
}
# TODO what do to about "--config" ? :(

# _js_escape 'some "string" value'
_js_escape() {
jq --null-input --arg 'str' "$1" '$str'
}

tempConfigFile="${TMPDIR:-/tmp}/docker-entrypoint-temp-config.json"
_parse_config() {
if [ -s "$tempConfigFile" ]; then
return 0
fi

local configPath
if configPath="$(_mongod_hack_get_arg_val --config "$@")"; then
# if --config is specified, parse it into a JSON file so we can remove a few problematic keys (especially SSL-related keys)
# see https://docs.mongodb.com/manual/reference/configuration-options/
mongo --norc --nodb --quiet --eval "load('/js-yaml.js'); printjson(jsyaml.load(cat($(_js_escape "$configPath"))))" \
| jq 'del(.systemLog, .processManagement, .net, .security)' \
> "$tempConfigFile"
return 0
fi

return 1
}
dbPath=
_dbPath() {
if [ -n "$dbPath" ]; then
echo "$dbPath"
return
fi

if ! dbPath="$(_mongod_hack_get_arg_val --dbpath "$@")"; then
if _parse_config "$@"; then
dbPath="$(jq '.storage.dbPath' "$tempConfigFile")"
fi
fi

: "${dbPath:=/data/db}"

echo "$dbPath"
}

if [ "$originalArgOne" = 'mongod' ]; then
file_env 'MONGO_INITDB_ROOT_USERNAME'
Expand Down Expand Up @@ -134,11 +192,12 @@ if [ "$originalArgOne" = 'mongod' ]; then

# check for a few known paths (to determine whether we've already initialized and should thus skip our initdb scripts)
if [ -n "$shouldPerformInitdb" ]; then
dbPath="$(_dbPath "$@")"
for path in \
/data/db/WiredTiger \
/data/db/journal \
/data/db/local.0 \
/data/db/storage.bson \
"$dbPath/WiredTiger" \
"$dbPath/journal" \
"$dbPath/local.0" \
"$dbPath/storage.bson" \
; do
if [ -e "$path" ]; then
shouldPerformInitdb=
Expand All @@ -148,17 +207,11 @@ if [ "$originalArgOne" = 'mongod' ]; then
fi

if [ -n "$shouldPerformInitdb" ]; then
if _mongod_hack_have_arg --config "$@"; then
echo >&2
echo >&2 'warning: database is not yet initialized, and "--config" is specified'
echo >&2 ' the initdb database startup might fail as a result!'
echo >&2
mongodHackedArgs=( "$@" )
if _parse_config "$@"; then
_mongod_hack_ensure_arg_val --config "$tempConfigFile" "${mongodHackedArgs[@]}"
fi

pidfile="$(mktemp)"
trap "rm -f '$pidfile'" EXIT

_mongod_hack_ensure_arg_val --bind_ip 127.0.0.1 "$@"
_mongod_hack_ensure_arg_val --bind_ip 127.0.0.1 "${mongodHackedArgs[@]}"
_mongod_hack_ensure_arg_val --port 27017 "${mongodHackedArgs[@]}"

sslMode="$(_mongod_hack_have_arg '--sslPEMKeyFile' "$@" && echo 'allowSSL' || echo 'disabled')" # "BadValue: need sslPEMKeyFile when SSL is enabled" vs "BadValue: need to enable SSL via the sslMode flag when using SSL configuration parameters"
Expand All @@ -169,12 +222,16 @@ if [ "$originalArgOne" = 'mongod' ]; then
# https://github.com/docker-library/mongo/issues/164#issuecomment-293965668
_mongod_hack_ensure_arg_val --logpath "/proc/$$/fd/1" "${mongodHackedArgs[@]}"
else
echo >&2 "warning: initdb logs cannot write to '/proc/$$/fd/1', so they are in '/data/db/docker-initdb.log' instead"
_mongod_hack_ensure_arg_val --logpath /data/db/docker-initdb.log "${mongodHackedArgs[@]}"
initdbLogPath="$(_dbPath "$@")/docker-initdb.log"
echo >&2 "warning: initdb logs cannot write to '/proc/$$/fd/1', so they are in '$initdbLogPath' instead"
_mongod_hack_ensure_arg_val --logpath "$initdbLogPath" "${mongodHackedArgs[@]}"
fi
_mongod_hack_ensure_arg --logappend "${mongodHackedArgs[@]}"

pidfile="${TMPDIR:-/tmp}/docker-entrypoint-temp-mongod.pid"
rm -f "$pidfile"
_mongod_hack_ensure_arg_val --pidfilepath "$pidfile" "${mongodHackedArgs[@]}"

"${mongodHackedArgs[@]}" --fork

mongo=( mongo --host 127.0.0.1 --port 27017 --quiet )
Expand Down Expand Up @@ -209,9 +266,9 @@ if [ "$originalArgOne" = 'mongod' ]; then

"${mongo[@]}" "$rootAuthDatabase" <<-EOJS
db.createUser({
user: $(jq --arg 'user' "$MONGO_INITDB_ROOT_USERNAME" --null-input '$user'),
pwd: $(jq --arg 'pwd' "$MONGO_INITDB_ROOT_PASSWORD" --null-input '$pwd'),
roles: [ { role: 'root', db: $(jq --arg 'db' "$rootAuthDatabase" --null-input '$db') } ]
user: $(_js_escape "$MONGO_INITDB_ROOT_USERNAME"),
pwd: $(_js_escape "$MONGO_INITDB_ROOT_PASSWORD"),
roles: [ { role: 'root', db: $(_js_escape "$rootAuthDatabase") } ]
})
EOJS

Expand All @@ -235,8 +292,7 @@ if [ "$originalArgOne" = 'mongod' ]; then
done

"$@" --pidfilepath="$pidfile" --shutdown
rm "$pidfile"
trap - EXIT
rm -f "$pidfile"

echo
echo 'MongoDB init process complete; ready for start up.'
Expand All @@ -246,4 +302,6 @@ if [ "$originalArgOne" = 'mongod' ]; then
unset "${!MONGO_INITDB_@}"
fi

rm -f "$tempConfigFile"

exec "$@"
42 changes: 28 additions & 14 deletions 3.2/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,38 @@ RUN groupadd -r mongodb && useradd -r -g mongodb mongodb

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
ca-certificates \
jq \
numactl \
&& rm -rf /var/lib/apt/lists/*

# grab gosu for easy step-down from root
ENV GOSU_VERSION 1.7
RUN set -x \
&& apt-get update && apt-get install -y --no-install-recommends wget && rm -rf /var/lib/apt/lists/* \
&& wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \
&& wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \
&& export GNUPGHOME="$(mktemp -d)" \
&& gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
&& gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \
&& rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \
&& chmod +x /usr/local/bin/gosu \
&& gosu nobody true \
&& apt-get purge -y --auto-remove wget
# grab gosu for easy step-down from root (https://github.com/tianon/gosu/releases)
ENV GOSU_VERSION 1.10
# grab "js-yaml" for parsing mongod's YAML config files (https://github.com/nodeca/js-yaml/releases)
ENV JSYAML_VERSION 3.10.0

RUN set -ex; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
wget \
; \
rm -rf /var/lib/apt/lists/*; \
\
dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
export GNUPGHOME="$(mktemp -d)"; \
gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc; \
chmod +x /usr/local/bin/gosu; \
gosu nobody true; \
\
wget -O /js-yaml.js "https://github.com/nodeca/js-yaml/raw/${JSYAML_VERSION}/dist/js-yaml.js"; \
# TODO some sort of download verification here
\
apt-get purge -y --auto-remove wget

RUN mkdir /docker-entrypoint-initdb.d

Expand Down
Loading