From d7e519314698859923a621513abc973f6577fb09 Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Mon, 3 Feb 2025 13:57:13 +0000 Subject: [PATCH 01/11] [python] - issue #1172 - add version switching mechanism using update-alternatives --- src/python/install.sh | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/python/install.sh b/src/python/install.sh index b3311c7c6..171ccf857 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -766,6 +766,12 @@ esac check_packages ${REQUIRED_PKGS} +# Function to get the major version from a SemVer string +get_major_version() { + local version="$1" + echo "$version" | cut -d '.' -f 1 +} + # Install Python from source if needed if [ "${PYTHON_VERSION}" != "none" ]; then if ! cat /etc/group | grep -e "^python:" > /dev/null 2>&1; then @@ -777,15 +783,28 @@ if [ "${PYTHON_VERSION}" != "none" ]; then install_python ${PYTHON_VERSION} + PYTHON_VER=${PYTHON_VERSION} + find_version_from_git_tags PYTHON_VER "https://github.com/python/cpython" + major_version=$(get_major_version ${PYTHON_VER}) + IFS="," + read -a additional_versions <<< "$ADDITIONAL_VERSIONS" + # update-alternatives --install ${PYTHON_INSTALL_PATH}${major_version} python${major_version} ${PYTHON_INSTALL_PATH}/${PYTHON_VER} $((${#additional_versions[@]}+1)) + # update-alternatives --install ${PYTHON_INSTALL_PATH}/${PYTHON_VER}/bin/python${major_version} python${major_version} ${PYTHON_INSTALL_PATH}/${PYTHON_VER} $((${#additional_versions[@]}+1)) + update-alternatives --install ${CURRENT_PATH}/bin/python${PYTHON_VERSION} python${major_version} ${PYTHON_INSTALL_PATH}/${PYTHON_VER} $((${#additional_versions[@]}+1)) + update-alternatives --set python${major_version} ${PYTHON_INSTALL_PATH}/${PYTHON_VER} + # Additional python versions to be installed but not be set as default. if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then OLD_INSTALL_PATH="${INSTALL_PATH}" OLDIFS=$IFS IFS="," read -a additional_versions <<< "$ADDITIONAL_VERSIONS" - for version in "${additional_versions[@]}"; do + for i in "${!additional_versions[@]}"; do + version=${additional_versions[$i]} OVERRIDE_DEFAULT_VERSION="false" install_python $version + major_version=$(get_major_version ${version}) + update-alternatives --install ${PYTHON_INSTALL_PATH}/${VERSION}/bin/python${VERSION} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} $((${i}+1)) done INSTALL_PATH="${OLD_INSTALL_PATH}" IFS=$OLDIFS From 685efc8a06d847e86ff66d88eaf58671d5cae44d Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Mon, 3 Feb 2025 14:01:36 +0000 Subject: [PATCH 02/11] removed commented code --- src/python/install.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/python/install.sh b/src/python/install.sh index 171ccf857..e756b60be 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -788,8 +788,6 @@ if [ "${PYTHON_VERSION}" != "none" ]; then major_version=$(get_major_version ${PYTHON_VER}) IFS="," read -a additional_versions <<< "$ADDITIONAL_VERSIONS" - # update-alternatives --install ${PYTHON_INSTALL_PATH}${major_version} python${major_version} ${PYTHON_INSTALL_PATH}/${PYTHON_VER} $((${#additional_versions[@]}+1)) - # update-alternatives --install ${PYTHON_INSTALL_PATH}/${PYTHON_VER}/bin/python${major_version} python${major_version} ${PYTHON_INSTALL_PATH}/${PYTHON_VER} $((${#additional_versions[@]}+1)) update-alternatives --install ${CURRENT_PATH}/bin/python${PYTHON_VERSION} python${major_version} ${PYTHON_INSTALL_PATH}/${PYTHON_VER} $((${#additional_versions[@]}+1)) update-alternatives --set python${major_version} ${PYTHON_INSTALL_PATH}/${PYTHON_VER} From 816a44436625fcc3b6911123905d03b27e520fc2 Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Mon, 10 Feb 2025 05:33:39 +0000 Subject: [PATCH 03/11] [python] - update-alternatives addition for ease in switching of python versions - complete --- src/python/install.sh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/python/install.sh b/src/python/install.sh index e756b60be..2265d4f8c 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -785,11 +785,6 @@ if [ "${PYTHON_VERSION}" != "none" ]; then PYTHON_VER=${PYTHON_VERSION} find_version_from_git_tags PYTHON_VER "https://github.com/python/cpython" - major_version=$(get_major_version ${PYTHON_VER}) - IFS="," - read -a additional_versions <<< "$ADDITIONAL_VERSIONS" - update-alternatives --install ${CURRENT_PATH}/bin/python${PYTHON_VERSION} python${major_version} ${PYTHON_INSTALL_PATH}/${PYTHON_VER} $((${#additional_versions[@]}+1)) - update-alternatives --set python${major_version} ${PYTHON_INSTALL_PATH}/${PYTHON_VER} # Additional python versions to be installed but not be set as default. if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then @@ -802,8 +797,10 @@ if [ "${PYTHON_VERSION}" != "none" ]; then OVERRIDE_DEFAULT_VERSION="false" install_python $version major_version=$(get_major_version ${version}) - update-alternatives --install ${PYTHON_INSTALL_PATH}/${VERSION}/bin/python${VERSION} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} $((${i}+1)) + update-alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} 100 done + update-alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${PYTHON_VER} 100 + update-alternatives --set python${major_version} ${PYTHON_INSTALL_PATH}/${PYTHON_VER} INSTALL_PATH="${OLD_INSTALL_PATH}" IFS=$OLDIFS fi From c2da50b64c9a15d00ff8c27e71f5dfd14ac89751 Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Mon, 10 Feb 2025 05:41:26 +0000 Subject: [PATCH 04/11] changes for passing of other tests !! --- src/python/install.sh | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/python/install.sh b/src/python/install.sh index 2265d4f8c..b5fdc383b 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -778,13 +778,11 @@ if [ "${PYTHON_VERSION}" != "none" ]; then groupadd -r python fi usermod -a -G python "${USERNAME}" - CURRENT_PATH="${PYTHON_INSTALL_PATH}/current" - install_python ${PYTHON_VERSION} - - PYTHON_VER=${PYTHON_VERSION} - find_version_from_git_tags PYTHON_VER "https://github.com/python/cpython" + major_version=$(get_major_version ${VERSION}) + update-alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} 100 + update-alternatives --set python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} # Additional python versions to be installed but not be set as default. if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then @@ -796,11 +794,8 @@ if [ "${PYTHON_VERSION}" != "none" ]; then version=${additional_versions[$i]} OVERRIDE_DEFAULT_VERSION="false" install_python $version - major_version=$(get_major_version ${version}) update-alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} 100 done - update-alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${PYTHON_VER} 100 - update-alternatives --set python${major_version} ${PYTHON_INSTALL_PATH}/${PYTHON_VER} INSTALL_PATH="${OLD_INSTALL_PATH}" IFS=$OLDIFS fi From dd6f8c3e3f63d0ea405b7cf535b8ce9e4d53eb4e Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Mon, 10 Feb 2025 05:50:01 +0000 Subject: [PATCH 05/11] change for better positioning of code --- src/python/install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/python/install.sh b/src/python/install.sh index b5fdc383b..5cfb4f3c6 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -780,9 +780,6 @@ if [ "${PYTHON_VERSION}" != "none" ]; then usermod -a -G python "${USERNAME}" CURRENT_PATH="${PYTHON_INSTALL_PATH}/current" install_python ${PYTHON_VERSION} - major_version=$(get_major_version ${VERSION}) - update-alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} 100 - update-alternatives --set python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} # Additional python versions to be installed but not be set as default. if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then @@ -790,11 +787,14 @@ if [ "${PYTHON_VERSION}" != "none" ]; then OLDIFS=$IFS IFS="," read -a additional_versions <<< "$ADDITIONAL_VERSIONS" + major_version=$(get_major_version ${VERSION}) + update-alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} $((${#additional_versions[@]}+1)) + update-alternatives --set python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} for i in "${!additional_versions[@]}"; do version=${additional_versions[$i]} OVERRIDE_DEFAULT_VERSION="false" install_python $version - update-alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} 100 + update-alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} $((${i}+1)) done INSTALL_PATH="${OLD_INSTALL_PATH}" IFS=$OLDIFS From d60d526212c068408d0230e3230ca8950e0c190c Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Mon, 10 Feb 2025 08:21:15 +0000 Subject: [PATCH 06/11] Added test case scenario for Update-Alternatives check --- ...update-alternatives_switchable_versions.sh | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 test/python/update-alternatives_switchable_versions.sh diff --git a/test/python/update-alternatives_switchable_versions.sh b/test/python/update-alternatives_switchable_versions.sh new file mode 100644 index 000000000..612c5be4e --- /dev/null +++ b/test/python/update-alternatives_switchable_versions.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "python version 3.11 installed as default" bash -c "python --version | grep 3.11" +check "python3 version 3.11 installed as default" bash -c "python3 --version | grep 3.11" +check "python version 3.10.5 installed" bash -c "ls -l /usr/local/python | grep 3.10.5" +check "python version 3.8 installed" bash -c "ls -l /usr/local/python | grep 3.8" +check "python version 3.9.13 installed" bash -c "ls -l /usr/local/python | grep 3.9.13" + +# Check paths in settings +check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python" +check "current symlink works" /usr/local/python/current/bin/python --version + +# check update-alternatives command + +check_version_switch() { + PYTHON_ALTERNATIVES=$(update-alternatives --query python3 | grep -E 'Alternative:|Priority:') + AVAILABLE_VERSIONS=() + INDEX=1 + + echo "Available Python versions:" + while read -r alt && read -r pri; do + PATH=${alt#Alternative: } # Extract only the path + PRIORITY=${pri#Priority: } # Extract only the priority number + AVAILABLE_VERSIONS+=("$PATH") + echo "$INDEX) $PATH (Priority: $PRIORITY)" + ((INDEX++)) + done <<< "${PYTHON_ALTERNATIVES}" + + echo -e "\n" + + # Ensure at least 4 alternatives exist + if [ "${#AVAILABLE_VERSIONS[@]}" -lt 4 ]; then + echo "Error: Less than 4 Python versions registered in update-alternatives." + exit 1 + fi + + for CHOICE in {1..4}; do + SELECTED_VERSION="${AVAILABLE_VERSIONS[$((CHOICE - 1))]}" + echo "Switching to: ${SELECTED_VERSION}" + /usr/bin/update-alternatives --set python3 ${SELECTED_VERSION} + + # Verify the switch + echo "Python version after switch:" + /usr/local/python/current/bin/python3 --version + + /bin/sleep 2 + + echo -e "\n" + done + echo -e "Update-Alternatives --display: \n" + /usr/bin/update-alternatives --display python3 +} + +check "Version Switch With Update_Alternatives" check_version_switch \ No newline at end of file From 31a32746e238ef2a0f14b0e7a23b6b61c796aa20 Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Mon, 10 Feb 2025 09:44:02 +0000 Subject: [PATCH 07/11] added scenario for testing --- test/python/scenarios.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/python/scenarios.json b/test/python/scenarios.json index be37869df..b3051d143 100644 --- a/test/python/scenarios.json +++ b/test/python/scenarios.json @@ -255,5 +255,15 @@ "enableShared": true } } + }, + "update-alternatives_switchable_versions": { + "image": "ubuntu:focal", + "features": { + "python": { + "version": "3.11", + "installTools": true, + "additionalVersions": "3.8,3.9.13,3.10.5" + } + } } } \ No newline at end of file From ab9b1c83d5dc5b9cb12b42463583e00cfd74a094 Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Tue, 11 Feb 2025 00:18:43 +0000 Subject: [PATCH 08/11] [alternatives] - added option for fedora, centos & rhel --- src/python/install.sh | 19 +++- .../alternatives_switchable_versions.sh | 89 +++++++++++++++++++ test/python/scenarios.json | 10 +++ ...update-alternatives_switchable_versions.sh | 54 ++++++++--- 4 files changed, 157 insertions(+), 15 deletions(-) create mode 100644 test/python/alternatives_switchable_versions.sh diff --git a/src/python/install.sh b/src/python/install.sh index 5cfb4f3c6..fec8937a0 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -788,13 +788,26 @@ if [ "${PYTHON_VERSION}" != "none" ]; then IFS="," read -a additional_versions <<< "$ADDITIONAL_VERSIONS" major_version=$(get_major_version ${VERSION}) - update-alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} $((${#additional_versions[@]}+1)) - update-alternatives --set python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} + if type apt-get > /dev/null 2>&1; then + # Debian/Ubuntu: Use update-alternatives + update-alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} $((${#additional_versions[@]}+1)) + update-alternatives --set python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} + elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then + # Fedora/RHEL/CentOS: Use alternatives + alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} $((${#additional_versions[@]}+1)) + alternatives --set python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} + fi for i in "${!additional_versions[@]}"; do version=${additional_versions[$i]} OVERRIDE_DEFAULT_VERSION="false" install_python $version - update-alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} $((${i}+1)) + if type apt-get > /dev/null 2>&1; then + # Debian/Ubuntu: Use update-alternatives + update-alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} $((${i}+1)) + elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then + # Fedora/RHEL/CentOS: Use alternatives + alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} $((${i}+1)) + fi done INSTALL_PATH="${OLD_INSTALL_PATH}" IFS=$OLDIFS diff --git a/test/python/alternatives_switchable_versions.sh b/test/python/alternatives_switchable_versions.sh new file mode 100644 index 000000000..5c8821088 --- /dev/null +++ b/test/python/alternatives_switchable_versions.sh @@ -0,0 +1,89 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "python version 3.11 installed as default" bash -c "python --version | grep 3.11" +check "python3 version 3.11 installed as default" bash -c "python3 --version | grep 3.11" +check "python version 3.10.5 installed" bash -c "ls -l /usr/local/python | grep 3.10.5" +check "python version 3.8 installed" bash -c "ls -l /usr/local/python | grep 3.8" +check "python version 3.9.13 installed" bash -c "ls -l /usr/local/python | grep 3.9.13" + +# Check paths in settings +check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python" +check "current symlink works" /usr/local/python/current/bin/python --version + +# check alternatives command +check_version_switch() { + if type apt-get > /dev/null 2>&1; then + PYTHON_ALTERNATIVES=$(update-alternatives --query python3 | grep -E 'Alternative:|Priority:') + STYLE="debian" + elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then + PYTHON_ALTERNATIVES=$(alternatives --display python3 | grep " - priority") + STYLE="fedora" + else + echo "No supported package manager found." + exit 1 + fi + AVAILABLE_VERSIONS=() + INDEX=1 + + echo "Available Python versions:" + if [ "$STYLE" = "debian" ]; then + while read -r alt && read -r pri; do + PATH=${alt#Alternative: } # Extract only the path + PRIORITY=${pri#Priority: } # Extract only the priority number + AVAILABLE_VERSIONS+=("$PATH") + echo "$INDEX) $PATH (Priority: $PRIORITY)" + ((INDEX++)) + done <<< "${PYTHON_ALTERNATIVES}" + elif [ "$STYLE" = "fedora" ]; then + # Fedora/RHEL output: one line per alternative in the format: + # /usr/local/python/3.11.11 - priority 4 + while IFS= read -r line; do + # Split using " - priority " as a delimiter. + SELECTED_PATH=$(echo "$line" | awk -F' - priority ' '{print $1}' | xargs) + PRIORITY_VALUE=$(echo "$line" | awk -F' - priority ' '{print $2}' | xargs) + AVAILABLE_VERSIONS+=("$SELECTED_PATH") + echo "$INDEX) $SELECTED_PATH (Priority: $PRIORITY_VALUE)" + ((INDEX++)) + done <<< "${PYTHON_ALTERNATIVES}" + fi + + echo -e "\n" + + # Ensure at least 4 alternatives exist + if [ "${#AVAILABLE_VERSIONS[@]}" -lt 4 ]; then + echo "Error: Less than 4 Python versions registered in update-alternatives." + exit 1 + fi + + for CHOICE in {1..4}; do + SELECTED_VERSION="${AVAILABLE_VERSIONS[$((CHOICE - 1))]}" + echo "Switching to: ${SELECTED_VERSION}" + if type apt-get > /dev/null 2>&1; then + /usr/bin/update-alternatives --set python3 ${SELECTED_VERSION} + elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then + /usr/sbin/alternatives --set python3 ${SELECTED_VERSION} + fi + + # Verify the switch + echo "Python version after switch:" + /usr/local/python/current/bin/python3 --version + + /bin/sleep 2 + + echo -e "\n" + done + echo -e "Update-Alternatives --display: \n" + if type apt-get > /dev/null 2>&1; then + /usr/bin/update-alternatives --display python3 + elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then + /usr/sbin/alternatives --display python3 + fi + +} + +check "Version Switch With Update_Alternatives" check_version_switch \ No newline at end of file diff --git a/test/python/scenarios.json b/test/python/scenarios.json index b3051d143..335fd36c8 100644 --- a/test/python/scenarios.json +++ b/test/python/scenarios.json @@ -265,5 +265,15 @@ "additionalVersions": "3.8,3.9.13,3.10.5" } } + }, + "alternatives_switchable_versions": { + "image": "fedora", + "features": { + "python": { + "version": "3.11", + "installTools": true, + "additionalVersions": "3.8,3.9.13,3.10.5" + } + } } } \ No newline at end of file diff --git a/test/python/update-alternatives_switchable_versions.sh b/test/python/update-alternatives_switchable_versions.sh index 612c5be4e..5c8821088 100644 --- a/test/python/update-alternatives_switchable_versions.sh +++ b/test/python/update-alternatives_switchable_versions.sh @@ -15,21 +15,42 @@ check "python version 3.9.13 installed" bash -c "ls -l /usr/local/python | gre check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python" check "current symlink works" /usr/local/python/current/bin/python --version -# check update-alternatives command - +# check alternatives command check_version_switch() { - PYTHON_ALTERNATIVES=$(update-alternatives --query python3 | grep -E 'Alternative:|Priority:') + if type apt-get > /dev/null 2>&1; then + PYTHON_ALTERNATIVES=$(update-alternatives --query python3 | grep -E 'Alternative:|Priority:') + STYLE="debian" + elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then + PYTHON_ALTERNATIVES=$(alternatives --display python3 | grep " - priority") + STYLE="fedora" + else + echo "No supported package manager found." + exit 1 + fi AVAILABLE_VERSIONS=() INDEX=1 echo "Available Python versions:" - while read -r alt && read -r pri; do - PATH=${alt#Alternative: } # Extract only the path - PRIORITY=${pri#Priority: } # Extract only the priority number - AVAILABLE_VERSIONS+=("$PATH") - echo "$INDEX) $PATH (Priority: $PRIORITY)" - ((INDEX++)) - done <<< "${PYTHON_ALTERNATIVES}" + if [ "$STYLE" = "debian" ]; then + while read -r alt && read -r pri; do + PATH=${alt#Alternative: } # Extract only the path + PRIORITY=${pri#Priority: } # Extract only the priority number + AVAILABLE_VERSIONS+=("$PATH") + echo "$INDEX) $PATH (Priority: $PRIORITY)" + ((INDEX++)) + done <<< "${PYTHON_ALTERNATIVES}" + elif [ "$STYLE" = "fedora" ]; then + # Fedora/RHEL output: one line per alternative in the format: + # /usr/local/python/3.11.11 - priority 4 + while IFS= read -r line; do + # Split using " - priority " as a delimiter. + SELECTED_PATH=$(echo "$line" | awk -F' - priority ' '{print $1}' | xargs) + PRIORITY_VALUE=$(echo "$line" | awk -F' - priority ' '{print $2}' | xargs) + AVAILABLE_VERSIONS+=("$SELECTED_PATH") + echo "$INDEX) $SELECTED_PATH (Priority: $PRIORITY_VALUE)" + ((INDEX++)) + done <<< "${PYTHON_ALTERNATIVES}" + fi echo -e "\n" @@ -42,7 +63,11 @@ check_version_switch() { for CHOICE in {1..4}; do SELECTED_VERSION="${AVAILABLE_VERSIONS[$((CHOICE - 1))]}" echo "Switching to: ${SELECTED_VERSION}" - /usr/bin/update-alternatives --set python3 ${SELECTED_VERSION} + if type apt-get > /dev/null 2>&1; then + /usr/bin/update-alternatives --set python3 ${SELECTED_VERSION} + elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then + /usr/sbin/alternatives --set python3 ${SELECTED_VERSION} + fi # Verify the switch echo "Python version after switch:" @@ -53,7 +78,12 @@ check_version_switch() { echo -e "\n" done echo -e "Update-Alternatives --display: \n" - /usr/bin/update-alternatives --display python3 + if type apt-get > /dev/null 2>&1; then + /usr/bin/update-alternatives --display python3 + elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then + /usr/sbin/alternatives --display python3 + fi + } check "Version Switch With Update_Alternatives" check_version_switch \ No newline at end of file From f00d4a7940b36b2b79278bb49124a73f0291ba66 Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Tue, 11 Feb 2025 00:34:03 +0000 Subject: [PATCH 09/11] changed file name --- test/python/scenarios.json | 2 +- ...e_versions.sh => update_alternatives_switchable_versions.sh} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename test/python/{update-alternatives_switchable_versions.sh => update_alternatives_switchable_versions.sh} (100%) diff --git a/test/python/scenarios.json b/test/python/scenarios.json index 335fd36c8..9dc37e16c 100644 --- a/test/python/scenarios.json +++ b/test/python/scenarios.json @@ -256,7 +256,7 @@ } } }, - "update-alternatives_switchable_versions": { + "update_alternatives_switchable_versions": { "image": "ubuntu:focal", "features": { "python": { diff --git a/test/python/update-alternatives_switchable_versions.sh b/test/python/update_alternatives_switchable_versions.sh similarity index 100% rename from test/python/update-alternatives_switchable_versions.sh rename to test/python/update_alternatives_switchable_versions.sh From 1ca2d2660edde010f897198cd34f2593c4b3da94 Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Tue, 11 Feb 2025 04:12:29 +0000 Subject: [PATCH 10/11] changes for update-alternatives test case proper functioning --- ...update_alternatives_switchable_versions.sh | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/test/python/update_alternatives_switchable_versions.sh b/test/python/update_alternatives_switchable_versions.sh index 5c8821088..aa2b914dd 100644 --- a/test/python/update_alternatives_switchable_versions.sh +++ b/test/python/update_alternatives_switchable_versions.sh @@ -31,28 +31,27 @@ check_version_switch() { INDEX=1 echo "Available Python versions:" - if [ "$STYLE" = "debian" ]; then + if [ "${STYLE}" = "debian" ]; then while read -r alt && read -r pri; do PATH=${alt#Alternative: } # Extract only the path PRIORITY=${pri#Priority: } # Extract only the priority number - AVAILABLE_VERSIONS+=("$PATH") + AVAILABLE_VERSIONS+=("${PATH}") echo "$INDEX) $PATH (Priority: $PRIORITY)" ((INDEX++)) done <<< "${PYTHON_ALTERNATIVES}" - elif [ "$STYLE" = "fedora" ]; then + elif [ "${STYLE}" = "fedora" ]; then # Fedora/RHEL output: one line per alternative in the format: - # /usr/local/python/3.11.11 - priority 4 while IFS= read -r line; do # Split using " - priority " as a delimiter. - SELECTED_PATH=$(echo "$line" | awk -F' - priority ' '{print $1}' | xargs) + PATH=$(echo "$line" | awk -F' - priority ' '{print $1}' | xargs) PRIORITY_VALUE=$(echo "$line" | awk -F' - priority ' '{print $2}' | xargs) - AVAILABLE_VERSIONS+=("$SELECTED_PATH") - echo "$INDEX) $SELECTED_PATH (Priority: $PRIORITY_VALUE)" + AVAILABLE_VERSIONS+=("$PATH") + echo "$INDEX) $PATH (Priority: $PRIORITY_VALUE)" ((INDEX++)) done <<< "${PYTHON_ALTERNATIVES}" fi - echo -e "\n" + echo -e "\n Available Versions: ${#AVAILABLE_VERSIONS[@]}" # Ensure at least 4 alternatives exist if [ "${#AVAILABLE_VERSIONS[@]}" -lt 4 ]; then @@ -60,21 +59,20 @@ check_version_switch() { exit 1 fi + export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + for CHOICE in {1..4}; do SELECTED_VERSION="${AVAILABLE_VERSIONS[$((CHOICE - 1))]}" echo "Switching to: ${SELECTED_VERSION}" - if type apt-get > /dev/null 2>&1; then + if command -v apt-get > /dev/null 2>&1; then /usr/bin/update-alternatives --set python3 ${SELECTED_VERSION} - elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then + elif command -v dnf > /dev/null 2>&1 || command -v yum > /dev/null 2>&1 || command -v microdnf > /dev/null 2>&1; then /usr/sbin/alternatives --set python3 ${SELECTED_VERSION} fi - # Verify the switch echo "Python version after switch:" /usr/local/python/current/bin/python3 --version - /bin/sleep 2 - echo -e "\n" done echo -e "Update-Alternatives --display: \n" From 7692c63169db96bc41e594fd399a3ac2efd1d95a Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Tue, 11 Feb 2025 23:38:16 +0000 Subject: [PATCH 11/11] arrange in asc order for default value retention after testing ends --- .../alternatives_switchable_versions.sh | 50 ++++++++++++------- ...update_alternatives_switchable_versions.sh | 35 +++++++++---- 2 files changed, 57 insertions(+), 28 deletions(-) diff --git a/test/python/alternatives_switchable_versions.sh b/test/python/alternatives_switchable_versions.sh index 5c8821088..a29392c17 100644 --- a/test/python/alternatives_switchable_versions.sh +++ b/test/python/alternatives_switchable_versions.sh @@ -27,54 +27,69 @@ check_version_switch() { echo "No supported package manager found." exit 1 fi + AVAILABLE_VERSIONS=() INDEX=1 - echo "Available Python versions:" - if [ "$STYLE" = "debian" ]; then + if [ "${STYLE}" = "debian" ]; then while read -r alt && read -r pri; do PATH=${alt#Alternative: } # Extract only the path PRIORITY=${pri#Priority: } # Extract only the priority number - AVAILABLE_VERSIONS+=("$PATH") + TEMP_VERSIONS+=("${PRIORITY} ${PATH}") echo "$INDEX) $PATH (Priority: $PRIORITY)" ((INDEX++)) done <<< "${PYTHON_ALTERNATIVES}" - elif [ "$STYLE" = "fedora" ]; then + elif [ "${STYLE}" = "fedora" ]; then + export PATH="/usr/bin:$PATH" # Fedora/RHEL output: one line per alternative in the format: - # /usr/local/python/3.11.11 - priority 4 while IFS= read -r line; do # Split using " - priority " as a delimiter. - SELECTED_PATH=$(echo "$line" | awk -F' - priority ' '{print $1}' | xargs) - PRIORITY_VALUE=$(echo "$line" | awk -F' - priority ' '{print $2}' | xargs) - AVAILABLE_VERSIONS+=("$SELECTED_PATH") - echo "$INDEX) $SELECTED_PATH (Priority: $PRIORITY_VALUE)" + PATH=$(/usr/bin/awk -F' - priority ' '{print $1}' <<< "$line" | /usr/bin/xargs /bin/echo) + PRIORITY=$(/usr/bin/awk -F' - priority ' '{print $2}' <<< "$line" | /usr/bin/xargs /bin/echo) + TEMP_VERSIONS+=("${PRIORITY} ${PATH}") + echo "$INDEX) $PATH (Priority: $PRIORITY_VALUE)" ((INDEX++)) done <<< "${PYTHON_ALTERNATIVES}" fi - echo -e "\n" + export PATH="/usr/bin:$PATH" + # Sort by priority (numerically ascending) + IFS=$'\n' TEMP_VERSIONS=($(sort -n <<<"${TEMP_VERSIONS[*]}")) + unset IFS + + # Populate AVAILABLE_VERSIONS from sorted data + AVAILABLE_VERSIONS=() + INDEX=1 + echo -e "\nAvailable Python versions (Sorted in asc order of priority):" + for ENTRY in "${TEMP_VERSIONS[@]}"; do + PRIORITY=${ENTRY%% *} # Extract priority (first part before space) + PATH=${ENTRY#* } # Extract path (everything after first space) + AVAILABLE_VERSIONS+=("${PATH}") + echo "$INDEX) $PATH (Priority: $PRIORITY)" + ((INDEX++)) + done + echo -e "\nAvailable Versions Count: ${#AVAILABLE_VERSIONS[@]}" # Ensure at least 4 alternatives exist if [ "${#AVAILABLE_VERSIONS[@]}" -lt 4 ]; then echo "Error: Less than 4 Python versions registered in update-alternatives." exit 1 fi - + + export PATH="/usr/bin:$PATH" + echo -e "\nSwitching to different versions using update-alternatives --set command...\n" for CHOICE in {1..4}; do SELECTED_VERSION="${AVAILABLE_VERSIONS[$((CHOICE - 1))]}" echo "Switching to: ${SELECTED_VERSION}" - if type apt-get > /dev/null 2>&1; then + if command -v apt-get > /dev/null 2>&1; then /usr/bin/update-alternatives --set python3 ${SELECTED_VERSION} - elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then + elif command -v dnf > /dev/null 2>&1 || command -v yum > /dev/null 2>&1 || command -v microdnf > /dev/null 2>&1; then /usr/sbin/alternatives --set python3 ${SELECTED_VERSION} fi - # Verify the switch echo "Python version after switch:" /usr/local/python/current/bin/python3 --version - - /bin/sleep 2 - + /bin/sleep 1 echo -e "\n" done echo -e "Update-Alternatives --display: \n" @@ -83,7 +98,6 @@ check_version_switch() { elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then /usr/sbin/alternatives --display python3 fi - } check "Version Switch With Update_Alternatives" check_version_switch \ No newline at end of file diff --git a/test/python/update_alternatives_switchable_versions.sh b/test/python/update_alternatives_switchable_versions.sh index aa2b914dd..07a517332 100644 --- a/test/python/update_alternatives_switchable_versions.sh +++ b/test/python/update_alternatives_switchable_versions.sh @@ -29,38 +29,54 @@ check_version_switch() { fi AVAILABLE_VERSIONS=() INDEX=1 - echo "Available Python versions:" if [ "${STYLE}" = "debian" ]; then while read -r alt && read -r pri; do PATH=${alt#Alternative: } # Extract only the path PRIORITY=${pri#Priority: } # Extract only the priority number - AVAILABLE_VERSIONS+=("${PATH}") + TEMP_VERSIONS+=("${PRIORITY} ${PATH}") echo "$INDEX) $PATH (Priority: $PRIORITY)" ((INDEX++)) done <<< "${PYTHON_ALTERNATIVES}" elif [ "${STYLE}" = "fedora" ]; then + export PATH="/usr/bin:$PATH" # Fedora/RHEL output: one line per alternative in the format: while IFS= read -r line; do # Split using " - priority " as a delimiter. - PATH=$(echo "$line" | awk -F' - priority ' '{print $1}' | xargs) - PRIORITY_VALUE=$(echo "$line" | awk -F' - priority ' '{print $2}' | xargs) - AVAILABLE_VERSIONS+=("$PATH") + PATH=$(/usr/bin/awk -F' - priority ' '{print $1}' <<< "$line" | /usr/bin/xargs /bin/echo) + PRIORITY=$(/usr/bin/awk -F' - priority ' '{print $2}' <<< "$line" | /usr/bin/xargs /bin/echo) + TEMP_VERSIONS+=("${PRIORITY} ${PATH}") echo "$INDEX) $PATH (Priority: $PRIORITY_VALUE)" ((INDEX++)) done <<< "${PYTHON_ALTERNATIVES}" fi - echo -e "\n Available Versions: ${#AVAILABLE_VERSIONS[@]}" + export PATH="/usr/bin:$PATH" + # Sort by priority (numerically ascending) + IFS=$'\n' TEMP_VERSIONS=($(sort -n <<<"${TEMP_VERSIONS[*]}")) + unset IFS + + # Populate AVAILABLE_VERSIONS from sorted data + AVAILABLE_VERSIONS=() + INDEX=1 + echo -e "\nAvailable Python versions (Sorted in asc order of priority):" + for ENTRY in "${TEMP_VERSIONS[@]}"; do + PRIORITY=${ENTRY%% *} # Extract priority (first part before space) + PATH=${ENTRY#* } # Extract path (everything after first space) + AVAILABLE_VERSIONS+=("${PATH}") + echo "$INDEX) $PATH (Priority: $PRIORITY)" + ((INDEX++)) + done + echo -e "\nAvailable Versions Count: ${#AVAILABLE_VERSIONS[@]}\n" # Ensure at least 4 alternatives exist if [ "${#AVAILABLE_VERSIONS[@]}" -lt 4 ]; then echo "Error: Less than 4 Python versions registered in update-alternatives." exit 1 fi - export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - + export PATH="/usr/bin:$PATH" + echo -e "\nSwitching to different versions using update-alternatives --set command...\n" for CHOICE in {1..4}; do SELECTED_VERSION="${AVAILABLE_VERSIONS[$((CHOICE - 1))]}" echo "Switching to: ${SELECTED_VERSION}" @@ -72,7 +88,7 @@ check_version_switch() { # Verify the switch echo "Python version after switch:" /usr/local/python/current/bin/python3 --version - /bin/sleep 2 + /bin/sleep 1 echo -e "\n" done echo -e "Update-Alternatives --display: \n" @@ -81,7 +97,6 @@ check_version_switch() { elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then /usr/sbin/alternatives --display python3 fi - } check "Version Switch With Update_Alternatives" check_version_switch \ No newline at end of file