hue.sh 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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. echo "Hue Environment Variables:" 1>&2
  28. env 1>&2
  29. function set_path() {
  30. etpath=$(dirname $2)
  31. if [ "$1" == "PYTHONPATH" ]; then
  32. if [ -z ${PYTHONPATH:+x} ]; then
  33. export PYTHONPATH=$etpath
  34. else
  35. export PYTHONPATH=$PYTHONPATH:$etpath
  36. fi
  37. elif [ "$1" == "LD_LIBRARY_PATH" ]; then
  38. if [ -z ${LD_LIBRARY_PATH:+x} ]; then
  39. export LD_LIBRARY_PATH=$etpath
  40. else
  41. export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$etpath
  42. fi
  43. elif [ "$1" == "PATH" ]; then
  44. if [ -z ${PATH:+x} ]; then
  45. export PATH=$etpath
  46. else
  47. export PATH=$PATH:$etpath
  48. fi
  49. fi
  50. }
  51. # This function sets the ENVIRONMENT variable, it has 3 args
  52. # 1. target file, 2. environment variable name
  53. # 3. list of possible places where target can be found
  54. # It iterates over list and tries matching list item and target
  55. # on the filesystem.
  56. function set_env_var() {
  57. target=$1
  58. shift
  59. setvar=$1
  60. shift
  61. search=("$@")
  62. targetpath=""
  63. # Dont use "echo" in the function as last line returns value
  64. for spath in ${search[@]}; do
  65. tpath=""
  66. if echo x"$target" | grep '*' > /dev/null || \
  67. echo x"$spath" | grep '*' > /dev/null; then
  68. # sort with newone first
  69. glob_path=$(ls -1td $spath/$target 2>/dev/null|head -1)
  70. if [ -z ${glob_path:+x} ]; then
  71. tpath=""
  72. else
  73. tpath=$glob_path
  74. fi
  75. else
  76. if [ -e "$spath/$target" ]; then
  77. tpath="$spath/$target"
  78. fi
  79. fi
  80. if [ "$tpath" != "" ]; then
  81. targetpath=$tpath
  82. set_path $setvar $targetpath
  83. break
  84. fi
  85. done
  86. echo $targetpath
  87. }
  88. add_postgres_to_pythonpath_for_version() {
  89. local version="${1:-$SELECTED_PYTHON_VERSION}" # Use first arg if provided, otherwise use SELECTED_PYTHON_VERSION
  90. # If postgres engine is detected in *.ini files then check for proper psycopg2 version.
  91. if grep -q '^\s*engine\s*=\s*postgres\+' *.ini; then
  92. list=("/usr/lib*" "/usr/local/lib/python${version}/*-packages" \
  93. "/usr/lib64/python${version}/*-packages" \
  94. "/opt/rh/rh-postgresql*/root/usr/lib64" \
  95. "/usr/pgsql-*/lib" \
  96. )
  97. set_env_var "libpq.so" "LD_LIBRARY_PATH" "${list[@]}"
  98. list=("/usr/bin" "/opt/rh/rh-python${version//./}/root/usr/local/lib64/python${version}/site-packages" \
  99. "/usr/local/lib/python${version}/*-packages" \
  100. "/usr/lib64/python${version}/*-packages" \
  101. )
  102. set_env_var "psycopg2" "PYTHONPATH" "${list[@]}"
  103. fi
  104. }
  105. add_mysql_to_pythonpath_for_version() {
  106. local version="${1:-$SELECTED_PYTHON_VERSION}" # Use first arg if provided, otherwise use SELECTED_PYTHON_VERSION
  107. # If mysql engine is detected in *.ini files then check for proper MySQL-python version.
  108. if grep -q '^\s*engine\s*=\s*mysql\+' *.ini; then
  109. if [ -z ${LD_LIBRARY_PATH:+x} ]; then
  110. list=("/usr/lib*" "/usr/local/lib/python${version}/*-packages" \
  111. "/usr/lib64/python${version}/*-packages" \
  112. "/opt/rh/rh-mysql*/root/usr/lib64" \
  113. "/usr/lib64/mysql" \
  114. )
  115. set_env_var "libmysqlclient.so" "LD_LIBRARY_PATH" "${list[@]}"
  116. else
  117. echo "LD_LIBRARY_PATH is taken from safety valve, $LD_LIBRARY_PATH"
  118. fi
  119. if [ -z ${PYTHONPATH:+x} ]; then
  120. # If we've included a MySQL-python for this platform, override on PYTHONPATH
  121. list=("/usr/bin" "/opt/rh/rh-python${version//./}/root/usr/local/lib64/python${version}/site-packages" \
  122. "/usr/local/lib/python${version}/*-packages" \
  123. "/usr/lib64/python${version}/*-packages" \
  124. )
  125. set_env_var "MySQLdb" "PYTHONPATH" "${list[@]}"
  126. else
  127. echo "PYTHONPATH is taken from safety valve, $PYTHONPATH"
  128. fi
  129. fi
  130. }
  131. add_postgres_to_pythonpath_for_version "$SELECTED_PYTHON_VERSION"
  132. add_mysql_to_pythonpath_for_version "$SELECTED_PYTHON_VERSION"
  133. # Executes Django database migrations with retry logic to handle
  134. # concurrent migration attempts from multiple hosts.
  135. function run_syncdb_and_migrate_subcommands() {
  136. # Run the initial command first, but allow it to fail gracefully
  137. echo "INFO: Running --fake-initial to sync history for legacy databases..."
  138. if ! $HUE migrate --fake-initial --noinput; then
  139. echo "WARN: --fake-initial failed, but continuing with regular migration..."
  140. fi
  141. # Now, attempt the main migration in a retry loop.
  142. local max_attempts=3
  143. local delay_seconds=5
  144. for ((attempt=1; attempt<=max_attempts; attempt++)); do
  145. echo "INFO: Applying migrations (Attempt $attempt of $max_attempts)..."
  146. # If the migrate command succeeds, we're done.
  147. if $HUE migrate --noinput; then
  148. echo "INFO: Migration successful."
  149. return 0
  150. fi
  151. # If we've not reached the max attempts, wait and retry.
  152. if [ $attempt -lt $max_attempts ]; then
  153. echo "WARN: Migration failed, likely due to a temporary lock. Retrying in $delay_seconds seconds..."
  154. sleep $delay_seconds
  155. fi
  156. done
  157. # If the loop finishes, all attempts have failed.
  158. echo "ERROR: All migration attempts failed after $max_attempts tries." >&2
  159. exit 1
  160. }
  161. if [[ "$1" == "kt_renewer" ]]; then
  162. # The Kerberos ticket renewer needs to know where kinit is.
  163. if [ -d /usr/kerberos/bin ]; then
  164. export PATH=/usr/kerberos/bin:$PATH
  165. fi
  166. KINIT_PATH=`which kinit`
  167. KINIT_PATH=${KINIT_PATH-/usr/bin/kinit}
  168. perl -pi -e "s#\{\{KINIT_PATH}}#$KINIT_PATH#g" $HUE_CONF_DIR/*.ini
  169. fi
  170. if [[ "dumpdata" == "$1" ]]; then
  171. umask 037
  172. "$HUE" "$1" --indent 2 > "$2"
  173. elif [[ "syncdb" == "$1" ]]; then
  174. run_syncdb_and_migrate_subcommands
  175. elif [[ "ldaptest" == "$1" ]]; then
  176. "$HUE" "$1"
  177. elif [[ "runcpserver" == "$1" ]]; then
  178. run_syncdb_and_migrate_subcommands
  179. exec "$HUE" "runcpserver"
  180. elif [[ "rungunicornserver" == "$1" ]]; then
  181. run_syncdb_and_migrate_subcommands
  182. exec "$HUE" "rungunicornserver"
  183. else
  184. exec "$HUE" "$@"
  185. fi