hue.sh 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. #!/bin/bash
  2. # Licensed to Cloudera, Inc. under one
  3. # or more contributor license agreements. See the NOTICE file
  4. # distributed with this work for additional information
  5. # regarding copyright ownership. Cloudera, Inc. licenses this file
  6. # to you under the Apache License, Version 2.0 (the
  7. # "License"); you may not use this file except in compliance
  8. # with the License. You may obtain a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing, software
  13. # distributed under the License is distributed on an "AS IS" BASIS,
  14. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. # See the License for the specific language governing permissions and
  16. # limitations under the License.
  17. # wrapper script to identify the latest python and pass the execution
  18. # to the corresponding hue script in the `build` directory.
  19. set -ex
  20. # Time marker for both stderr and stdout
  21. date; date 1>&2
  22. export SCRIPT_DIR=`dirname $0`
  23. export HUE_HOME_DIR=$(dirname $(dirname "$SCRIPT_DIR"))
  24. source $SCRIPT_DIR/python/python_helper.sh
  25. PYTHON_BIN="${VENV_BIN_PATH}/python"
  26. HUE="${VENV_BIN_PATH}/hue"
  27. HUE_LOGLISTENER="${HUE_HOME_DIR}/desktop/core/src/desktop/loglistener.py"
  28. echo "Hue Environment Variables:" 1>&2
  29. env 1>&2
  30. function set_path() {
  31. etpath=$(dirname $2)
  32. if [ "$1" == "PYTHONPATH" ]; then
  33. if [ -z ${PYTHONPATH:+x} ]; then
  34. export PYTHONPATH=$etpath
  35. else
  36. export PYTHONPATH=$PYTHONPATH:$etpath
  37. fi
  38. elif [ "$1" == "LD_LIBRARY_PATH" ]; then
  39. if [ -z ${LD_LIBRARY_PATH:+x} ]; then
  40. export LD_LIBRARY_PATH=$etpath
  41. else
  42. export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$etpath
  43. fi
  44. elif [ "$1" == "PATH" ]; then
  45. if [ -z ${PATH:+x} ]; then
  46. export PATH=$etpath
  47. else
  48. export PATH=$PATH:$etpath
  49. fi
  50. fi
  51. }
  52. # This function sets the ENVIRONMENT variable, it has 3 args
  53. # 1. target file, 2. environment variable name
  54. # 3. list of possible places where target can be found
  55. # It iterates over list and tries matching list item and target
  56. # on the filesystem.
  57. function set_env_var() {
  58. target=$1
  59. shift
  60. setvar=$1
  61. shift
  62. search=("$@")
  63. targetpath=""
  64. # Dont use "echo" in the function as last line returns value
  65. for spath in ${search[@]}; do
  66. tpath=""
  67. if echo x"$target" | grep '*' > /dev/null || \
  68. echo x"$spath" | grep '*' > /dev/null; then
  69. # sort with newone first
  70. glob_path=$(ls -1td $spath/$target 2>/dev/null|head -1)
  71. if [ -z ${glob_path:+x} ]; then
  72. tpath=""
  73. else
  74. tpath=$glob_path
  75. fi
  76. else
  77. if [ -e "$spath/$target" ]; then
  78. tpath="$spath/$target"
  79. fi
  80. fi
  81. if [ "$tpath" != "" ]; then
  82. targetpath=$tpath
  83. set_path $setvar $targetpath
  84. break
  85. fi
  86. done
  87. echo $targetpath
  88. }
  89. add_postgres_to_pythonpath_for_version() {
  90. local version="${1:-$SELECTED_PYTHON_VERSION}" # Use first arg if provided, otherwise use SELECTED_PYTHON_VERSION
  91. # If postgres engine is detected in *.ini files then check for proper psycopg2 version.
  92. if grep -q '^\s*engine\s*=\s*postgres\+' *.ini; then
  93. list=("/usr/lib*" "/usr/local/lib/python${version}/*-packages" \
  94. "/usr/lib64/python${version}/*-packages" \
  95. "/opt/rh/rh-postgresql*/root/usr/lib64" \
  96. "/usr/pgsql-*/lib" \
  97. )
  98. set_env_var "libpq.so" "LD_LIBRARY_PATH" "${list[@]}"
  99. list=("/usr/bin" "/opt/rh/rh-python${version//./}/root/usr/local/lib64/python${version}/site-packages" \
  100. "/usr/local/lib/python${version}/*-packages" \
  101. "/usr/lib64/python${version}/*-packages" \
  102. )
  103. set_env_var "psycopg2" "PYTHONPATH" "${list[@]}"
  104. fi
  105. }
  106. add_mysql_to_pythonpath_for_version() {
  107. local version="${1:-$SELECTED_PYTHON_VERSION}" # Use first arg if provided, otherwise use SELECTED_PYTHON_VERSION
  108. # If mysql engine is detected in *.ini files then check for proper MySQL-python version.
  109. if grep -q '^\s*engine\s*=\s*mysql\+' *.ini; then
  110. if [ -z ${LD_LIBRARY_PATH:+x} ]; then
  111. list=("/usr/lib*" "/usr/local/lib/python${version}/*-packages" \
  112. "/usr/lib64/python${version}/*-packages" \
  113. "/opt/rh/rh-mysql*/root/usr/lib64" \
  114. "/usr/lib64/mysql" \
  115. )
  116. set_env_var "libmysqlclient.so" "LD_LIBRARY_PATH" "${list[@]}"
  117. else
  118. echo "LD_LIBRARY_PATH is taken from safety valve, $LD_LIBRARY_PATH"
  119. fi
  120. if [ -z ${PYTHONPATH:+x} ]; then
  121. # If we've included a MySQL-python for this platform, override on PYTHONPATH
  122. list=("/usr/bin" "/opt/rh/rh-python${version//./}/root/usr/local/lib64/python${version}/site-packages" \
  123. "/usr/local/lib/python${version}/*-packages" \
  124. "/usr/lib64/python${version}/*-packages" \
  125. )
  126. set_env_var "MySQLdb" "PYTHONPATH" "${list[@]}"
  127. else
  128. echo "PYTHONPATH is taken from safety valve, $PYTHONPATH"
  129. fi
  130. fi
  131. }
  132. add_postgres_to_pythonpath_for_version "$SELECTED_PYTHON_VERSION"
  133. add_mysql_to_pythonpath_for_version "$SELECTED_PYTHON_VERSION"
  134. function stop_previous_hueprocs() {
  135. for p in $(cat /tmp/hue_${HUE_PORT}.pid); do
  136. if [[ $p -eq $(ps -p $p -ho pid=) ]]; then
  137. kill -9 $p
  138. fi
  139. done
  140. rm -f /tmp/hue_${HUE_PORT}.pid
  141. }
  142. # Executes Django database migrations with retry logic to handle
  143. # concurrent migration attempts from multiple hosts.
  144. function run_syncdb_and_migrate_subcommands() {
  145. # Run the initial command first, but allow it to fail gracefully
  146. echo "INFO: Running --fake-initial to sync history for legacy databases..."
  147. if ! $HUE migrate --fake-initial --noinput; then
  148. echo "WARN: --fake-initial failed, but continuing with regular migration..."
  149. fi
  150. # Now, attempt the main migration in a retry loop.
  151. local max_attempts=3
  152. local delay_seconds=5
  153. for ((attempt=1; attempt<=max_attempts; attempt++)); do
  154. echo "INFO: Applying migrations (Attempt $attempt of $max_attempts)..."
  155. # If the migrate command succeeds, we're done.
  156. if $HUE migrate --noinput; then
  157. echo "INFO: Migration successful."
  158. return 0
  159. fi
  160. # If we've not reached the max attempts, wait and retry.
  161. if [ $attempt -lt $max_attempts ]; then
  162. echo "WARN: Migration failed, likely due to a temporary lock. Retrying in $delay_seconds seconds..."
  163. sleep $delay_seconds
  164. fi
  165. done
  166. # If the loop finishes, all attempts have failed.
  167. echo "ERROR: All migration attempts failed after $max_attempts tries." >&2
  168. exit 1
  169. }
  170. if [[ "$1" == "kt_renewer" ]]; then
  171. # The Kerberos ticket renewer needs to know where kinit is.
  172. if [ -d /usr/kerberos/bin ]; then
  173. export PATH=/usr/kerberos/bin:$PATH
  174. fi
  175. KINIT_PATH=`which kinit`
  176. KINIT_PATH=${KINIT_PATH-/usr/bin/kinit}
  177. perl -pi -e "s#\{\{KINIT_PATH}}#$KINIT_PATH#g" $HUE_CONF_DIR/*.ini
  178. fi
  179. if [[ "dumpdata" == "$1" ]]; then
  180. umask 037
  181. "$HUE" "$1" --indent 2 > "$2"
  182. elif [[ "syncdb" == "$1" ]]; then
  183. run_syncdb_and_migrate_subcommands
  184. elif [[ "ldaptest" == "$1" ]]; then
  185. "$HUE" "$1"
  186. elif [[ "runcpserver" == "$1" ]]; then
  187. run_syncdb_and_migrate_subcommands
  188. exec "$HUE" "runcpserver"
  189. elif [[ "rungunicornserver" == "$1" ]]; then
  190. stop_previous_hueprocs
  191. sleep 5 # wait to handle some unknown concurrency issue that can kill loglistener process
  192. nohup "$PYTHON_BIN" "$HUE_LOGLISTENER" &
  193. echo "Log Listener Status: $?" >&2
  194. jobs -l >&2
  195. echo $! > /tmp/hue_${HUE_PORT}.pid
  196. run_syncdb_and_migrate_subcommands
  197. exec "$HUE" "rungunicornserver"
  198. else
  199. exec "$HUE" "$@"
  200. fi