Skip to content

Commit 37eda76

Browse files
committed
patched 5 debugging changes to 4.4
1 parent 77fae65 commit 37eda76

File tree

1 file changed

+111
-64
lines changed

1 file changed

+111
-64
lines changed

docker-image-src/4.4/docker-entrypoint.sh

Lines changed: 111 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,18 @@ function secure_mode_enabled
1212
test "${SECURE_FILE_PERMISSIONS:=no}" = "yes"
1313
}
1414

15+
function debugging_enabled
16+
{
17+
test "${NEO4J_DEBUG+yes}" = "yes"
18+
}
19+
20+
function debug_msg
21+
{
22+
if debugging_enabled; then
23+
echo "$@"
24+
fi
25+
}
26+
1527
function containsElement
1628
{
1729
local e match="$1"
@@ -71,13 +83,6 @@ function is_writable
7183
return 1
7284
}
7385

74-
function expand_commands_optionally
75-
{
76-
if [ "${EXTENDED_CONF+"yes"}" == "yes" ]; then
77-
echo "--expand-commands"
78-
fi
79-
}
80-
8186
function print_permissions_advice_and_fail
8287
{
8388
_directory=${1}
@@ -96,6 +101,7 @@ If the folder is owned by the current user, this can be done by adding this flag
96101
function check_mounted_folder_readable
97102
{
98103
local _directory=${1}
104+
debug_msg "checking ${_directory} is readable"
99105
if ! is_readable "${_directory}"; then
100106
print_permissions_advice_and_fail "${_directory}"
101107
fi
@@ -126,6 +132,7 @@ function check_mounted_folder_writable_with_chown
126132
# (This is a very unlikely use case).
127133

128134
local mountFolder=${1}
135+
debug_msg "checking ${mountFolder} is writable"
129136
if running_as_root && ! secure_mode_enabled; then
130137
# check folder permissions
131138
if ! is_writable "${mountFolder}" ; then
@@ -138,9 +145,7 @@ function check_mounted_folder_writable_with_chown
138145
chown -R "${userid}":"${groupid}" "${mountFolder}"
139146
fi
140147
else
141-
#if ! is_writable "${mountFolder}"; then
142148
if [[ ! -w "${mountFolder}" ]] && [[ "$(stat -c %U ${mountFolder})" != "neo4j" ]]; then
143-
#echo >&2 "Consider unsetting SECURE_FILE_PERMISSIONS environment variable, to enable docker to write to ${mountFolder}."
144149
print_permissions_advice_and_fail "${mountFolder}"
145150
fi
146151
fi
@@ -182,6 +187,7 @@ function load_plugin_from_github
182187
local _plugins_dir="/plugins"
183188
fi
184189
local _versions_json_url="$(jq --raw-output "with_entries( select(.key==\"${_plugin_name}\") ) | to_entries[] | .value.versions" /startup/neo4jlabs-plugins.json )"
190+
debug_msg "Will read ${_plugin_name} versions.json from ${_versions_json_url}"
185191
# Using the same name for the plugin irrespective of version ensures we don't end up with different versions of the same plugin
186192
local _destination="${_plugins_dir}/${_plugin_name}.jar"
187193
local _neo4j_version="$(neo4j --version | cut -d' ' -f2)"
@@ -205,30 +211,34 @@ function load_plugin_from_github
205211

206212
function apply_plugin_default_configuration
207213
{
208-
# Set the correct Load a plugin at runtime. The provided github repository must have a versions.json on the master branch with the
209-
# correct format.
210-
local _plugin_name="${1}" #e.g. apoc, graph-algorithms, graph-ql
211-
local _reference_conf="${2}" # used to determine if we can override properties
212-
local _neo4j_conf="${NEO4J_HOME}/conf/neo4j.conf"
213-
214-
local _property _value
215-
echo "Applying default values for plugin ${_plugin_name} to neo4j.conf"
216-
for _entry in $(jq --compact-output --raw-output "with_entries( select(.key==\"${_plugin_name}\") ) | to_entries[] | .value.properties | to_entries[]" /startup/neo4jlabs-plugins.json); do
217-
_property="$(jq --raw-output '.key' <<< "${_entry}")"
218-
_value="$(jq --raw-output '.value' <<< "${_entry}")"
219-
220-
# the first grep strips out comments
221-
if grep -o "^[^#]*" "${_reference_conf}" | grep -q --fixed-strings "${_property}=" ; then
222-
# property is already set in the user provided config. In this case we don't override what has been set explicitly by the user.
223-
echo "Skipping ${_property} for plugin ${_plugin_name} because it is already set"
224-
else
225-
if grep -o "^[^#]*" "${_neo4j_conf}" | grep -q --fixed-strings "${_property}=" ; then
226-
sed --in-place "s/${_property}=/&${_value},/" "${_neo4j_conf}"
227-
else
228-
echo "${_property}=${_value}" >> "${_neo4j_conf}"
229-
fi
230-
fi
231-
done
214+
# Set the correct Load a plugin at runtime. The provided github repository must have a versions.json on the master branch with the
215+
# correct format.
216+
local _plugin_name="${1}" #e.g. apoc, graph-algorithms, graph-ql
217+
local _reference_conf="${2}" # used to determine if we can override properties
218+
local _neo4j_conf="${NEO4J_HOME}/conf/neo4j.conf"
219+
220+
local _property _value
221+
echo "Applying default values for plugin ${_plugin_name} to neo4j.conf"
222+
for _entry in $(jq --compact-output --raw-output "with_entries( select(.key==\"${_plugin_name}\") ) | to_entries[] | .value.properties | to_entries[]" /startup/neo4jlabs-plugins.json); do
223+
_property="$(jq --raw-output '.key' <<< "${_entry}")"
224+
_value="$(jq --raw-output '.value' <<< "${_entry}")"
225+
debug_msg "${_plugin_name} requires setting ${_property}=${_value}"
226+
227+
# the first grep strips out comments
228+
if grep -o "^[^#]*" "${_reference_conf}" | grep -q --fixed-strings "${_property}=" ; then
229+
# property is already set in the user provided config. In this case we don't override what has been set explicitly by the user.
230+
echo "Skipping ${_property} for plugin ${_plugin_name} because it is already set."
231+
echo "You may need to add ${_value} to the ${_property} setting in your configuration file."
232+
else
233+
if grep -o "^[^#]*" "${_neo4j_conf}" | grep -q --fixed-strings "${_property}=" ; then
234+
sed --in-place "s/${_property}=/&${_value},/" "${_neo4j_conf}"
235+
debug_msg "${_property} was already in the configuration file, so ${_value} was added to it."
236+
else
237+
echo "${_property}=${_value}" >> "${_neo4j_conf}"
238+
debug_msg "${_property}=${_value} has been added to the configuration file."
239+
fi
240+
fi
241+
done
232242
}
233243

234244
function install_neo4j_labs_plugins
@@ -239,10 +249,13 @@ function install_neo4j_labs_plugins
239249
for plugin_name in $(echo "${NEO4JLABS_PLUGINS}" | jq --raw-output '.[]'); do
240250
local _location="$(jq --raw-output "with_entries( select(.key==\"${plugin_name}\") ) | to_entries[] | .value.location" /startup/neo4jlabs-plugins.json )"
241251
if [ "${_location}" != "null" -a -n "$(shopt -s nullglob; echo ${_location})" ]; then
252+
debug_msg "$plugin_name is already in the container at ${_location}"
242253
load_plugin_from_location "${plugin_name}" "${_location}"
243254
else
255+
debug_msg "$plugin_name must be downloaded."
244256
load_plugin_from_github "${plugin_name}"
245257
fi
258+
debug_msg "Applying plugin specific configurations"
246259
apply_plugin_default_configuration "${plugin_name}" "${_old_config}"
247260
done
248261
rm "${_old_config}"
@@ -253,11 +266,11 @@ function add_docker_default_to_conf
253266
# docker defaults should NOT overwrite values already in the conf file
254267
local _setting="${1}"
255268
local _value="${2}"
256-
local _neo4j_home="${3}"
257269

258-
if ! grep -q "^${_setting}=" "${_neo4j_home}"/conf/neo4j.conf
270+
if ! grep -q "^${_setting}=" "${NEO4J_HOME}"/conf/neo4j.conf
259271
then
260-
echo -e "\n"${_setting}=${_value} >> "${_neo4j_home}"/conf/neo4j.conf
272+
debug_msg "Appended ${_setting}=${_value} to ${NEO4J_HOME}/conf/neo4j.conf"
273+
echo -e "\n"${_setting}=${_value} >> "${NEO4J_HOME}"/conf/neo4j.conf
261274
fi
262275
}
263276

@@ -266,14 +279,15 @@ function add_env_setting_to_conf
266279
# settings from environment variables should overwrite values already in the conf
267280
local _setting=${1}
268281
local _value=${2}
269-
local _neo4j_home=${3}
270282

271-
if grep -q -F "${_setting}=" "${_neo4j_home}"/conf/neo4j.conf; then
283+
if grep -q -F "${_setting}=" "${NEO4J_HOME}"/conf/neo4j.conf; then
272284
# Remove any lines containing the setting already
273-
sed --in-place "/^${_setting}=.*/d" "${_neo4j_home}"/conf/neo4j.conf
285+
debug_msg "Removing existing setting for ${_setting}"
286+
sed --in-place "/^${_setting}=.*/d" "${NEO4J_HOME}"/conf/neo4j.conf
274287
fi
275288
# Then always append setting to file
276-
echo "${_setting}=${_value}" >> "${_neo4j_home}"/conf/neo4j.conf
289+
debug_msg "Appended ${_setting}=${_value} to ${NEO4J_HOME}/conf/neo4j.conf"
290+
echo "${_setting}=${_value}" >> "${NEO4J_HOME}"/conf/neo4j.conf
277291
}
278292

279293
function set_initial_password
@@ -283,11 +297,13 @@ function set_initial_password
283297
# set the neo4j initial password only if you run the database server
284298
if [ "${cmd}" == "neo4j" ]; then
285299
if [ "${_neo4j_auth:-}" == "none" ]; then
286-
add_env_setting_to_conf "dbms.security.auth_enabled" "false" "${NEO4J_HOME}"
300+
debug_msg "Authentication is requested to be unset"
301+
add_env_setting_to_conf "dbms.security.auth_enabled" "false"
287302
elif [[ "${_neo4j_auth:-}" =~ ^([^/]+)\/([^/]+)/?([tT][rR][uU][eE])?$ ]]; then
288303
admin_user="${BASH_REMATCH[1]}"
289304
password="${BASH_REMATCH[2]}"
290305
do_reset="${BASH_REMATCH[3]}"
306+
debug_msg "NEO4J_AUTH has been parsed as user \"${admin_user}\", password \"${password}\", do_reset \"${do_reset}\""
291307

292308
if [ "${password}" == "neo4j" ]; then
293309
echo >&2 "Invalid value for password. It cannot be 'neo4j', which is the default."
@@ -302,16 +318,28 @@ function set_initial_password
302318
# running set-initial-password as root will create subfolders to /data as root, causing startup fail when neo4j can't read or write the /data/dbms folder
303319
# creating the folder first will avoid that
304320
mkdir -p /data/dbms
321+
debug_msg "Making sure /data/dbms is owned by ${userid}:${groupid}"
305322
chown "${userid}":"${groupid}" /data/dbms
306323
fi
307324

308-
# Will exit with error if users already exist (and print a message explaining that)
309-
# we probably don't want the message though, since it throws an error message on restarting the container.
325+
local extra_args=()
310326
if [ "${do_reset}" == "true" ]; then
311-
${neo4j_admin_cmd} set-initial-password "${password}" --require-password-change $(expand_commands_optionally) 2>/dev/null || true
327+
extra_args+=("--require-password-change")
328+
fi
329+
if [ "${EXTENDED_CONF+"yes"}" == "yes" ]; then
330+
extra_args+=("--expand-commands")
331+
fi
332+
debug_msg "Setting initial password"
333+
debug_msg "${neo4j_admin_cmd} set-initial-password ${password} ${extra_args[*]}"
334+
if debugging_enabled; then
335+
# don't suppress any output or errors in debugging mode
336+
${neo4j_admin_cmd} set-initial-password "${password}" "${extra_args[@]}"
312337
else
313-
${neo4j_admin_cmd} set-initial-password "${password}" $(expand_commands_optionally) 2>/dev/null || true
338+
# Will exit with error if users already exist (and print a message explaining that)
339+
# we probably don't want the message though, since it throws an error message on restarting the container.
340+
${neo4j_admin_cmd} set-initial-password "${password}" "${extra_args[@]}" 2>/dev/null || true
314341
fi
342+
315343
elif [ -n "${_neo4j_auth:-}" ]; then
316344
echo "$_neo4j_auth is invalid"
317345
echo >&2 "Invalid value for NEO4J_AUTH: '${_neo4j_auth}'"
@@ -320,6 +348,9 @@ function set_initial_password
320348
fi
321349
}
322350

351+
# ==== CODE STARTS ====
352+
debug_msg "DEBUGGING ENABLED"
353+
323354
# If we're running as root, then run as the neo4j user. Otherwise
324355
# docker is running with --user and we simply use that user. Note
325356
# that su-exec, despite its name, does not replicate the functionality
@@ -330,12 +361,14 @@ if running_as_root; then
330361
groups=($(id -G neo4j))
331362
exec_cmd="exec gosu neo4j:neo4j"
332363
neo4j_admin_cmd="gosu neo4j:neo4j neo4j-admin"
364+
debug_msg "Running as root user inside neo4j image"
333365
else
334366
userid="$(id -u)"
335367
groupid="$(id -g)"
336368
groups=($(id -G))
337369
exec_cmd="exec"
338370
neo4j_admin_cmd="neo4j-admin"
371+
debug_msg "Running as user ${userid}:${groupid} inside neo4j image"
339372
fi
340373
readonly userid
341374
readonly groupid
@@ -346,9 +379,11 @@ readonly neo4j_admin_cmd
346379

347380
# Need to chown the home directory
348381
if running_as_root; then
382+
debug_msg "chowning ${NEO4J_HOME} recursively to ${userid}":"${groupid}"
349383
chown -R "${userid}":"${groupid}" "${NEO4J_HOME}"
350384
chmod 700 "${NEO4J_HOME}"
351385
find "${NEO4J_HOME}" -mindepth 1 -maxdepth 1 -type d -exec chmod -R 700 {} \;
386+
debug_msg "Setting all files in ${NEO4J_HOME}/conf to permissions 600"
352387
find "${NEO4J_HOME}"/conf -type f -exec chmod -R 600 {} \;
353388
fi
354389

@@ -403,6 +438,7 @@ if [ "${NEO4J_EDITION}" == "enterprise" ];
403438
then
404439
: ${NEO4J_causal__clustering_expected__core__cluster__size:=${NEO4J_causalClustering_expectedCoreClusterSize:-}}
405440
: ${NEO4J_causal__clustering_initial__discovery__members:=${NEO4J_causalClustering_initialDiscoveryMembers:-}}
441+
debug_msg "Copying contents of /conf to ${NEO4J_HOME}/conf/*"
406442
: ${NEO4J_causal__clustering_discovery__advertised__address:=${NEO4J_causalClustering_discoveryAdvertisedAddress:-}}
407443
: ${NEO4J_causal__clustering_transaction__advertised__address:=${NEO4J_causalClustering_transactionAdvertisedAddress:-}}
408444
: ${NEO4J_causal__clustering_raft__advertised__address:=${NEO4J_causalClustering_raftAdvertisedAddress:-}}
@@ -427,6 +463,7 @@ unset NEO4J_dbms_txLog_rotation_retentionPolicy NEO4J_UDC_SOURCE \
427463
if [ -d /conf ]; then
428464
check_mounted_folder_readable "/conf"
429465
rm -rf "${NEO4J_HOME}"/conf/*
466+
debug_msg "Copying contents of /conf to ${NEO4J_HOME}/conf/*"
430467
find /conf -type f -exec cp --preserve=ownership,mode {} "${NEO4J_HOME}"/conf \;
431468
fi
432469

@@ -438,7 +475,8 @@ fi
438475

439476
if [ -d /plugins ]; then
440477
if [[ -n "${NEO4JLABS_PLUGINS:-}" ]]; then
441-
# We need write permissions
478+
# We need write permissions to write the required plugins to /plugins
479+
debug_msg "Extra plugins were requested. Ensuring the mounted /plugins folder has the required write permissions."
442480
check_mounted_folder_writable_with_chown "/plugins"
443481
fi
444482
check_mounted_folder_readable "/plugins"
@@ -487,43 +525,47 @@ fi
487525
## == DOCKER SPECIFIC DEFAULT CONFIGURATIONS ===
488526
## these should not override *any* configurations set by the user
489527

490-
add_docker_default_to_conf "dbms.tx_log.rotation.retention_policy" "100M size" "${NEO4J_HOME}"
491-
add_docker_default_to_conf "dbms.memory.pagecache.size" "512M" "${NEO4J_HOME}"
492-
add_docker_default_to_conf "dbms.default_listen_address" "0.0.0.0" "${NEO4J_HOME}"
528+
debug_msg "Setting docker specific configuration overrides"
529+
add_docker_default_to_conf "dbms.tx_log.rotation.retention_policy" "100M size"
530+
add_docker_default_to_conf "dbms.memory.pagecache.size" "512M"
531+
add_docker_default_to_conf "dbms.default_listen_address" "0.0.0.0"
493532
# set enterprise only docker defaults
494533
if [ "${NEO4J_EDITION}" == "enterprise" ];
495534
then
496-
add_docker_default_to_conf "causal_clustering.discovery_advertised_address" "$(hostname):5000" "${NEO4J_HOME}"
497-
add_docker_default_to_conf "causal_clustering.transaction_advertised_address" "$(hostname):6000" "${NEO4J_HOME}"
498-
add_docker_default_to_conf "causal_clustering.raft_advertised_address" "$(hostname):7000" "${NEO4J_HOME}"
535+
debug_msg "Setting docker specific Enterprise Edition overrides"
536+
add_docker_default_to_conf "causal_clustering.discovery_advertised_address" "$(hostname):5000"
537+
add_docker_default_to_conf "causal_clustering.transaction_advertised_address" "$(hostname):6000"
538+
add_docker_default_to_conf "causal_clustering.raft_advertised_address" "$(hostname):7000"
499539
fi
500540

501541
## == ENVIRONMENT VARIABLE CONFIGURATIONS ===
502542
## these override BOTH defaults and any existing values in the neo4j.conf file
503543

504-
# save NEO4J_HOME and NEO4J_AUTH to temp variables that don't begin with NEO4J_ so they don't get added to the conf
505-
temp_neo4j_home="${NEO4J_HOME}"
506-
temp_neo4j_auth="${NEO4J_AUTH:-}"
544+
# these are docker control envs that have the NEO4J_ prefix but we don't want to add to the config.
545+
not_configs=("NEO4J_ACCEPT_LICENSE_AGREEMENT" "NEO4J_AUTH" "NEO4J_DEBUG" "NEO4J_EDITION" \
546+
"NEO4J_HOME" "NEO4J_PLUGINS" "NEO4J_SHA256" "NEO4J_TARBALL")
547+
548+
debug_msg "Applying configuration settings that have been set using environment variables."
507549
# list env variables with prefix NEO4J_ and create settings from them
508-
unset NEO4J_AUTH NEO4J_SHA256 NEO4J_TARBALL NEO4J_EDITION NEO4J_ACCEPT_LICENSE_AGREEMENT NEO4J_HOME
509550
for i in $( set | grep ^NEO4J_ | awk -F'=' '{print $1}' | sort -rn ); do
551+
if containsElement "$i" "${not_configs[@]}"; then
552+
continue
553+
fi
510554
setting=$(echo "${i}" | sed 's|^NEO4J_||' | sed 's|_|.|g' | sed 's|\.\.|_|g')
511555
value=$(echo "${!i}")
512556
# Don't allow settings with no value or settings that start with a number (neo4j converts settings to env variables and you cannot have an env variable that starts with a number)
513557
if [[ -n ${value} ]]; then
514558
if [[ ! "${setting}" =~ ^[0-9]+.*$ ]]; then
515-
add_env_setting_to_conf "${setting}" "${value}" "${temp_neo4j_home}"
559+
add_env_setting_to_conf "${setting}" "${value}"
516560
else
517561
echo >&2 "WARNING: ${setting} not written to conf file because settings that start with a number are not permitted"
518562
fi
519563
fi
520564
done
521-
export NEO4J_HOME="${temp_neo4j_home}"
522-
unset temp_neo4j_home
523565

524566
# ==== SET PASSWORD AND PLUGINS ====
525567

526-
set_initial_password "${temp_neo4j_auth}"
568+
set_initial_password "${NEO4J_AUTH:-}"
527569

528570

529571
if [[ ! -z "${NEO4JLABS_PLUGINS:-}" ]]; then
@@ -550,16 +592,19 @@ fi
550592
# the command is something like: `java ...[lots of java options]... neo4j.mainClass ...[some neo4j options]...`
551593
function get_neo4j_run_cmd {
552594

553-
local extraArgs=()
595+
local extra_args=()
554596

555597
if [ "${EXTENDED_CONF+"yes"}" == "yes" ]; then
556-
extraArgs+=("--expand-commands")
598+
extra_args+=("--expand-commands")
599+
fi
600+
if debugging_enabled ; then
601+
extra_args+=("--verbose")
557602
fi
558603

559604
if running_as_root; then
560-
gosu neo4j:neo4j neo4j console --dry-run "${extraArgs[@]}"
605+
gosu neo4j:neo4j neo4j console --dry-run "${extra_args[@]}"
561606
else
562-
neo4j console --dry-run "${extraArgs[@]}"
607+
neo4j console --dry-run "${extra_args[@]}"
563608
fi
564609
}
565610

@@ -569,7 +614,9 @@ function get_neo4j_run_cmd {
569614
if [ "${cmd}" == "neo4j" ]; then
570615
# separate declaration and use of get_neo4j_run_cmd so that error codes are correctly surfaced
571616
neo4j_console_cmd="$(get_neo4j_run_cmd)"
617+
debug_msg "${exec_cmd} ${neo4j_console_cmd}"
572618
eval ${exec_cmd} ${neo4j_console_cmd?:No Neo4j command was generated}
573619
else
620+
debug_msg "${exec_cmd}" "$@"
574621
${exec_cmd} "$@"
575622
fi

0 commit comments

Comments
 (0)