Browse Source

[multi-python] scripts to simplify the selection of python version

1. `tools/scripts/hue.sh` is the wrapper script to call the hue script,
   that is currently in `build/env/bin/hue` but could be in various
   locations depending on python version in use.
2. `tools/scripts/python/python_helper.sh` contains helper functions
  - `find_latest_python` returns the latest py version (3.11, 3.9, 3.8)
  - `latest_venv_bin_path` returns the path to the env/bin of the latest
    python, relative to the top-level hue directory.
3. `tools/scripts/python/hue_py_shebang.sh` is a helper script that
   is supposed to be used in the shebang line of python scripts in Hue.
   I can direct the python script to the correct python to be used.
4. `HUE_PYTHON_VERSION` environment variable can be set to override the
   automatic selection of latest available python.
Amit Srivastava 7 months ago
parent
commit
3cfba0ba32
3 changed files with 191 additions and 0 deletions
  1. 59 0
      tools/scripts/hue.sh
  2. 29 0
      tools/scripts/python/hue_py_shebang.sh
  3. 103 0
      tools/scripts/python/python_helper.sh

+ 59 - 0
tools/scripts/hue.sh

@@ -0,0 +1,59 @@
+#!/bin/bash
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# wrapper script to identify the latest python and pass the execution
+# to the corresponding hue script in the `build` directory.
+
+set -ex
+
+# Time marker for both stderr and stdout
+date; date 1>&2
+
+export SCRIPT_DIR=`dirname $0`
+export HUE_HOME_DIR=$(dirname $(dirname "$SCRIPT_DIR"))
+
+source $SCRIPT_DIR/python/python_helper.sh
+
+function stop_previous_hueprocs() {
+  for p in $(cat /tmp/hue_${HUE_PORT}.pid); do
+    if [[ $p -eq $(ps -p $p -ho pid=) ]]; then
+      kill -9 $p
+    fi
+  done
+}
+
+PYTHON_BIN="${HUE_HOME_DIR}/$(latest_venv_bin_path)/python"
+HUE="${HUE_HOME_DIR}/$(latest_venv_bin_path)/hue"
+HUE_LOGLISTENER="${HUE_HOME_DIR}/desktop/core/src/desktop/loglistener.py"
+
+if [[ "dumpdata" == "$1" ]]; then
+  umask 037
+  "$HUE" "$1" --indent 2 > "$2"
+elif [[ "syncdb" == "$1" ]]; then
+  run_syncdb_and_migrate_subcommands
+elif [[ "ldaptest" == "$1" ]]; then
+  "$HUE" "$1"
+elif [[ "runcpserver" == "$1" ]]; then
+  exec "$HUE" "runcpserver"
+elif [[ "rungunicornserver" == "$1" ]]; then
+  stop_previous_hueprocs
+  exec "$PYTHON_BIN" "$HUE_LOGLISTENER" &
+  echo $! > /tmp/hue_${HUE_PORT}.pid
+  exec "$HUE" "rungunicornserver"
+else
+  exec "$HUE" "$@"
+fi

+ 29 - 0
tools/scripts/python/hue_py_shebang.sh

@@ -0,0 +1,29 @@
+#!/bin/bash
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This script is supposed to be used in the shebang line of python scripts
+# It will choose the correct python version and corresponding build dir
+set -ex
+
+SCRIPT_DIR=`dirname $0`
+export HUE_HOME_DIR=$(dirname $(dirname $(dirname "$SCRIPT_DIR")))
+
+source $SCRIPT_DIR/python_helper.sh
+
+PYTHON_BIN="${HUE_HOME_DIR}/$(latest_venv_bin_path)/python"
+
+exec "$PYTHON_BIN" "$@"

+ 103 - 0
tools/scripts/python/python_helper.sh

@@ -0,0 +1,103 @@
+#!/bin/bash
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Some helper functions to find the latest python bin and venv path
+set -ex
+
+# Find the latest Python binary in build/env/bin
+LATEST_PYTHON=$(find "$HUE_HOME_DIR/build/env/bin" -name "python3*" -exec basename {} \; | sort -V | tail -n 1)
+
+# Extract version from the latest python binary (e.g., python3.11 → 3.11)
+LATEST_PYTHON_VERSION=$(echo "$LATEST_PYTHON" | grep -oP '\d+\.\d+')
+
+# Find all supported python versions from build/venvs and include latest version
+readarray -t SUPPORTED_VERSIONS < <(
+  (
+    find "$HUE_HOME_DIR/build/venvs" -mindepth 1 -maxdepth 1 -type d -exec basename {} \; | grep -oP '\d+\.\d+';
+    echo "$LATEST_PYTHON_VERSION"
+  ) | sort -Vr | uniq
+)
+
+# Create array of supported versions
+SUPPORTED_PYTHON_VERSIONS=("${SUPPORTED_VERSIONS[@]}")
+
+python_bin_path() {
+  # Searches for the provided python version in various locations on the node
+  PYTHON_VERSION="$1"
+  PYTHON_VERSION_NO_DOT="${PYTHON_VERSION//./}"
+
+  # First check in PATH if it exists
+  if [ -n "$PATH" ]; then
+    IFS=: read -ra PATH_DIRS <<< "$PATH"
+    for DIR in "${PATH_DIRS[@]}"; do
+      # Skip cm-agent/bin directories
+      if [[ "$DIR" == *"cm-agent/bin"* ]]; then
+        continue
+      fi
+      PY_PATH="$DIR/python$PYTHON_VERSION"
+      if [[ -x "$PY_PATH" ]]; then
+        echo "$PY_PATH"
+        return 0
+      fi
+    done
+  fi
+
+  # Fall back to hardcoded directories
+  SEARCH_DIRS=("/usr/local/bin" "/bin" "/usr/bin" "/opt/rh/rh-${PYTHON_VERSION_NO_DOT}/root/usr/bin")
+  for DIR in "${SEARCH_DIRS[@]}"; do
+    PY_PATH="$DIR/python$PYTHON_VERSION"
+    if [[ -x "$PY_PATH" ]]; then
+      echo "$PY_PATH"
+      return 0
+    fi
+  done
+  return 1
+}
+
+find_latest_python() {
+  # returns the latest py version, e.g., 3.11, 3.9 or 3.8
+  for PYTHON_VERSION in "${SUPPORTED_PYTHON_VERSIONS[@]}"; do
+    if python_bin_path "$PYTHON_VERSION" > /dev/null; then
+      echo "$PYTHON_VERSION"
+      return 0
+    fi
+  done
+
+  echo "No supported Python versions found in expected locations."
+  return 1
+}
+
+latest_venv_bin_path() {
+  # returns the path to the env/bin of the latest python,
+  # relative to the top-level hue directory.
+  local version
+  if [ -n "$HUE_PYTHON_VERSION" ]; then
+    version=$(echo "$HUE_PYTHON_VERSION" | grep -oP '\d+\.\d+')
+  else
+    version="$(find_latest_python)"
+  fi
+
+  if [ -z "$version" ]; then
+    return 1  # Return error if no version provided/found
+  fi
+
+  if [ "$version" = "$LATEST_PYTHON_VERSION" ]; then
+    echo "build/env/bin"
+  else
+    echo "build/venvs/python${version}/bin"
+  fi
+}