-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathentrypoint.sh
More file actions
executable file
·347 lines (287 loc) · 12.6 KB
/
entrypoint.sh
File metadata and controls
executable file
·347 lines (287 loc) · 12.6 KB
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
#!/bin/sh
if [ -n "${DEBUG:-}" ]; then
set -x
fi
# set -eu
keystore_pass="${TOMCAT_KEYSTORE_PASSWORD:-}"
keystore_filename="${TOMCAT_KEYSTORE_FILENAME:-labkey.p12}"
keystore_alias="${TOMCAT_KEYSTORE_ALIAS:-}"
keystore_format="${TOMCAT_KEYSTORE_FORMAT:-}"
LABKEY_CUSTOM_PROPERTIES_S3_URI="${LABKEY_CUSTOM_PROPERTIES_S3_URI:=none}"
LABKEY_OPTIONAL_APP_PROPERTIES_S3_URI="${LABKEY_OPTIONAL_APP_PROPERTIES_S3_URI:=none}"
LABKEY_DEFAULT_PROPERTIES_S3_URI="${LABKEY_DEFAULT_PROPERTIES_S3_URI:=none}"
LOG4J_CONFIG_FILE="${LOG4J_CONFIG_FILE:=log4j2.xml}"
# below assumes using local log4j2.xml file, as the embedded version is not available for edits until after server is running
JSON_OUTPUT="${JSON_OUTPUT:-false}"
# for ecs/datadog, optionally enable APM and JMX metrics
DD_COLLECT_APM="${DD_COLLECT_APM:-false}"
JAVA_RMI_SERVER_HOSTNAME="${JAVA_RMI_SERVER_HOSTNAME:-}"
# set age past which old heap and error log directories and system maintenance files are removed
PURGE_HEAP_AND_ERROR_LOGS_OLDER_THAN_DAYS="${PURGE_HEAP_AND_ERROR_LOGS_OLDER_THAN_DAYS:-90}"
PURGE_MTNC_LOGS_OLDER_THAN_DAYS="${PURGE_MTNC_LOGS_OLDER_THAN_DAYS:-90}"
# set path to external modules)
LABKEY_EXTERNAL_MODULES="${LABKEY_EXTERNAL_MODULES:-/labkey/files/externalModules}"
export LABKEY_EXTERNAL_MODULES=$LABKEY_EXTERNAL_MODULES
SLEEP="${SLEEP:=0}"
main() {
random_string() {
length="${1:-32}"
# generate a random string 2 chars longer than request to weed out trailing
# equal signs common to openssl output and then trim out some
# shell-sensitive characters and then trim to desired length
openssl rand -base64 "$(( length + 2 ))" \
| tr '/' '#' | tr -d "'" | cut "-c1-${length}" | tr -d '\n' \
2>/dev/null
}
debug_string='false'
if [ -n "$DEBUG" ]; then
debug_string='true'
#
# see Dockerfile for default LOGGER_PATTERN value
#
# shellcheck disable=SC2034
export \
LOG_LEVEL_LABKEY_DEFAULT='INFO' \
LOG_LEVEL_API_MODULELOADER='TRACE' \
LOG_LEVEL_API_SETTINGS='TRACE' \
\
LOGGER_PATTERN='%-80.80logger{79}'
env | sort
fi
if [ -n "$keystore_format" ]; then
openssl_format_flag="$(
echo "$keystore_format" | tr '[:upper:]' '[:lower:]'
)"
else
openssl_format_flag='pkcs12'
fi
#
# relative paths below here are relative to LABKEY_HOME
#
cd "$LABKEY_HOME" || exit 1
OLD_IFS="$IFS"
IFS="$(printf '\nx')" && IFS="${IFS%x}" # ensure IFS is a single newline
for key_value in $(
# list all LABKEY_* ENVs, ignore optional ones like GUID or MEK
env \
| grep -E '^LABKEY_' \
| grep -vE 'GUID' \
| grep -vE 'MEK' \
| grep -vE 'STARTUP' \
| grep -vE 'INITIAL_USER' \
;
); do
if [ -z "${key_value#*=}" ]; then
>&2 echo "value required for '${key_value%%=*}'"
exit 1
fi
done
export IFS="$OLD_IFS"
if \
echo "$LABKEY_BASE_SERVER_URL" \
| grep -v -qs -E "https*://.+" \
; then
>&2 echo "value for 'LABKEY_BASE_SERVER_URL' did not resemble a URI"
exit 1
fi
if [ -n "$LABKEY_CREATE_INITIAL_USER" ]; then
>&2 echo "initial user creation triggered for ${LABKEY_INITIAL_USER_EMAIL}"
>&2 echo "use the \"forgot password\" link to set the initial user's password"
LABKEY_STARTUP_BASIC_EXTRA="$(
echo "
UserRoles.${LABKEY_INITIAL_USER_EMAIL};startup = org.labkey.api.security.roles.${LABKEY_INITIAL_USER_ROLE}
UserGroups.${LABKEY_INITIAL_USER_EMAIL};startup = ${LABKEY_INITIAL_USER_GROUP}
" | sed -e 's/\ \{2,\}//g'
)"
if [ -n "$LABKEY_CREATE_INITIAL_USER_APIKEY" ]; then
if [ -z "$LABKEY_INITIAL_USER_APIKEY" ]; then
generated_password="$(random_string)"
export LABKEY_INITIAL_USER_APIKEY="$generated_password"
>&2 echo "generated initial user apikey: apikey|${LABKEY_INITIAL_USER_APIKEY}"
fi
LABKEY_STARTUP_BASIC_EXTRA="
${LABKEY_STARTUP_BASIC_EXTRA}
ApiKey.${LABKEY_INITIAL_USER_EMAIL} = apikey|${LABKEY_INITIAL_USER_APIKEY}
"
fi
export LABKEY_STARTUP_BASIC_EXTRA
fi
# optional s3 uris to files with default or custom startup properties, formatted like startup/basic.properties
if [ $LABKEY_DEFAULT_PROPERTIES_S3_URI != 'none' ]; then
echo "trying to s3 cp '$LABKEY_DEFAULT_PROPERTIES_S3_URI'"
awsclibin/aws s3 cp $LABKEY_DEFAULT_PROPERTIES_S3_URI startup/
fi
if [ $LABKEY_CUSTOM_PROPERTIES_S3_URI != 'none' ]; then
echo "trying to s3 cp '$LABKEY_CUSTOM_PROPERTIES_S3_URI'"
awsclibin/aws s3 cp $LABKEY_CUSTOM_PROPERTIES_S3_URI startup/
fi
if [ $LABKEY_OPTIONAL_APP_PROPERTIES_S3_URI != 'none' ]; then
echo "trying to s3 cp '$LABKEY_OPTIONAL_APP_PROPERTIES_S3_URI'"
awsclibin/aws s3 cp $LABKEY_OPTIONAL_APP_PROPERTIES_S3_URI config/
fi
# echo "deleting awscli and unsetting AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, & AWS_SESSION_TOKEN, if set..."
# rm -rf awsclibin aws-cli
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
# echo "sleeping for $SLEEP seconds..."
# sleep $SLEEP
for prop_file in startup/*.properties config/application.properties; do
envsubst < "$prop_file" > "${prop_file}.tmp" \
&& mv "${prop_file}.tmp" "$prop_file"
done
if [ -z "$keystore_pass" ]; then
keystore_pass="$(random_string 64)"
fi
# below only works if server.tomcat.accesslog settings in application.properties are set to go to file instead of stdout
if [ -n "$TOMCAT_ENABLE_ACCESS_LOG" ]; then
ln -sfv /proc/1/fd/1 /tmp/access.log
fi
openssl req \
-x509 \
-newkey rsa:4096 \
-keyout 'privkey.pem' \
-out 'cert.pem' \
-days 365 \
-nodes \
-subj "/C=${CERT_C:?}/ST=${CERT_ST:?}/L=${CERT_L}/O=${CERT_O}/OU=${CERT_OU}/CN=${CERT_CN}" \
>/dev/null 2>&1
openssl "$openssl_format_flag" \
-export \
-out "$keystore_filename" \
-inkey 'privkey.pem' \
-in 'cert.pem' \
-name "$keystore_alias" \
-passout "pass:${keystore_pass}" \
>/dev/null 2>&1
if [ -n "${DEBUG:-}" ]; then
tail -n+1 \
config/*.properties \
startup/*.properties \
"${JAVA_HOME:-}"/release
if command -v tree >/dev/null 2>&1; then
tree .
fi
sleep 1
openssl "$openssl_format_flag" \
-nokeys \
-info \
-in "$keystore_filename" \
-passin "pass:${keystore_pass}"
fi
echo "Adding secrets to config/application.properties from environment variables..."
sed -i "s/@@jdbcUrl@@/jdbc:postgresql:\/\/${POSTGRES_HOST:-localhost}:${POSTGRES_PORT:-5432}\/${POSTGRES_DB:-${POSTGRES_USER}}${POSTGRES_PARAMETERS:-}/" config/application.properties
sed -i "s/@@jdbcUser@@/${POSTGRES_USER:-postgres}/" config/application.properties
sed -i "s/@@jdbcPassword@@/${POSTGRES_PASSWORD:-}/" config/application.properties
sed -i "s/@@smtpHost@@/${SMTP_HOST}/" config/application.properties
sed -i "s/@@smtpUser@@/${SMTP_USER}/" config/application.properties
sed -i "s/@@smtpPort@@/${SMTP_PORT}/" config/application.properties
sed -i "s/@@smtpPassword@@/${SMTP_PASSWORD}/" config/application.properties
sed -i "s/@@smtpAuth@@/${SMTP_AUTH}/" config/application.properties
sed -i "s/@@smtpFrom@@/${SMTP_FROM}/" config/application.properties
sed -i "s/@@smtpStartTlsEnable@@/${SMTP_STARTTLS}/" config/application.properties
sed -i "s/@@encryptionKey@@/${LABKEY_EK}/" config/application.properties
# Check if we want JSON output, and/or if we are using the base log4j2.xml config
export LOG4J_CONFIG_OPTION=""
if [ "${JSON_OUTPUT}" = "true" ] && [ "${LOG4J_CONFIG_FILE}" = "log4j2.xml" ]; then
echo "JSON_OUTPUT==true && LOG4J_CONFIG_FILE==log4j2.xml, so using the base log4j2.xml with labkey.log4j2.xml overrides, to send JSON output to console"
export LOG4J_CONFIG_OPTION="-Dlog4j.configurationFile=log4j2.xml,config/labkey.log4j2.xml"
# if the override file exists and isn't empty, use that to override whatever was set in LOG4J_CONFIG_FILE (which might still be server default of log4j2.xml)
elif [ -f "config/${LOG4J_CONFIG_OVERRIDE}" ] && [ -s "config/${LOG4J_CONFIG_OVERRIDE}" ]; then
echo "LOG4J_CONFIG_OVERRIDE==${LOG4J_CONFIG_OVERRIDE}, so using that to override default settings in LOG4J_CONFIG_FILE (${LOG4J_CONFIG_FILE})"
export LOG4J_CONFIG_OPTION="-Dlog4j.configurationFile=${LOG4J_CONFIG_FILE:=log4j2.xml},config/${LOG4J_CONFIG_OVERRIDE}"
elif [ "${LOG4J_CONFIG_FILE}" = "log4j2.xml" ]; then
echo "saw JSON_OUTPUT=$JSON_OUTPUT and LOG4J_CONFIG_FILE=$LOG4J_CONFIG_FILE and LOG4J_CONFIG_OVERRIDE=$LOG4J_CONFIG_OVERRIDE (which, if defined, was empty)"
echo "... so configuring nothing for LOG4J_CONFIG_OPTION"
fi
echo "Log4j configuration option(s): $LOG4J_CONFIG_OPTION"
export DD_JAVA_AGENT=""
export DD_JMX=""
if [ "$DD_COLLECT_APM" = "true" ]; then
echo "DD_COLLECT_APM==true , so adding EC2 host's private IP to env vars as DD_AGENT_HOST"
export TOKEN=$(curl --max-time 3 -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600");
export DD_AGENT_HOST=$(curl --max-time 3 -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/local-ipv4);
echo "Adding -javaagent and jmx settings to java command"
export DD_JAVA_AGENT="-javaagent:./datadog/dd-java-agent.jar -Ddd.profiling.enabled=true -Ddd.logs.injection=true -XX:FlightRecorderOptions=stackdepth=256 -Ddd.trace.remove.integration-service-names.enabled=true"
export DD_JMX="-Dspring.jmx.enabled=true \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.local.only=false \
-Dcom.sun.management.jmxremote.port=7199 \
-Dcom.sun.management.jmxremote.rmi.port=7199 \
-Djava.rmi.server.hostname=${JAVA_RMI_SERVER_HOSTNAME}"
fi
echo "Creating new heap/error log directory..."
HEAP_AND_ERROR_PATH="$LABKEY_HOME/files/heap_dumps_and_errors_$(date +%Y%m%d_%H%M%S)"
mkdir -pv $HEAP_AND_ERROR_PATH
echo "Creating externalModules directory if it does not already exist..."
mkdir -pv $LABKEY_EXTERNAL_MODULES
# set up required add-opens options
JAVA_ADD_OPENS="--add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.desktop/java.awt.font=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED"
# purge old heap/error directories
echo "Purging heap/error log directories older than $PURGE_HEAP_AND_ERROR_LOGS_OLDER_THAN_DAYS days..."
find "$LABKEY_HOME/files/" -mindepth 1 -maxdepth 1 -type d -ctime +${PURGE_HEAP_AND_ERROR_LOGS_OLDER_THAN_DAYS} -name "heap*" | xargs rm -rf
# purge old system maintenance files
echo "Purging system maintenance files older than $PURGE_MTNC_LOGS_OLDER_THAN_DAYS days..."
find "$LABKEY_HOME/files/@files" -mindepth 1 -maxdepth 1 -type d -ctime +${PURGE_MTNC_LOGS_OLDER_THAN_DAYS} -name "system_maintenance*" | xargs rm -rf
echo "sleeping for $SLEEP seconds..."
sleep $SLEEP
echo "Purging secrets and other bits from environment variables..."
unset POSTGRES_USER POSTGRES_PASSWORD POSTGRES_HOST POSTGRES_PORT POSTGRES_DB POSTGRES_PARAMETERS
unset SMTP_HOST SMTP_USER SMTP_PORT SMTP_PASSWORD SMTP_AUTH SMTP_FROM SMTP_STARTTLS
unset LABKEY_CREATE_INITIAL_USER LABKEY_CREATE_INITIAL_USER_APIKEY LABKEY_INITIAL_USER_APIKEY LABKEY_INITIAL_USER_EMAIL LABKEY_INITIAL_USER_GROUP LABKEY_INITIAL_USER_ROLE
unset LABKEY_EK SLEEP CONTAINER_PRIVATE_IP
# shellcheck disable=SC2086
exec java \
\
-Duser.timezone="${JAVA_TIMEZONE}" \
\
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath="${HEAP_AND_ERROR_PATH}" \
\
-XX:MaxRAMPercentage="${MAX_JVM_RAM_PERCENT}" \
\
-XX:+UseContainerSupport \
\
-XX:ErrorFile="${HEAP_AND_ERROR_PATH}/error_%p.log" \
\
-Djava.net.preferIPv4Stack=true \
\
-Dlabkey.home="$LABKEY_HOME" \
-Dlabkey.log.home="${LABKEY_HOME}/logs" \
\
-Djava.library.path=/usr/lib:/usr/lib/x86_64-linux-gnu \
\
-Djava.security.egd=file:/dev/./urandom \
\
-Djava.io.tmpdir="$JAVA_TMPDIR" \
\
-Dlogback.debug="$debug_string" \
\
-Dlog4j.debug="$debug_string" \
${LOG4J_CONFIG_OPTION} \
\
-Dorg.apache.catalina.startup.EXIT_ON_INIT_FAILURE=true \
\
-DsynchronousStartup=false \
-DterminateOnExistingConnections=false \
-DterminateOnStartupFailure=true \
\
${DD_JAVA_AGENT} \
\
${DD_JMX} \
\
${JAVA_ADD_OPENS} \
\
${JAVA_PRE_JAR_EXTRA} \
\
-jar labkeyServer.jar \
\
${JAVA_POST_JAR_EXTRA} \
\
--server.ssl.key-store-password="$keystore_pass" \
--server.ssl.key-store="$TOMCAT_KEYSTORE_FILENAME" \
--server.ssl.key-alias="$keystore_alias" \
\
;
}
main