1ae96c5eeSMichael Walsh#!/bin/bash 2ae96c5eeSMichael Walsh 3410b1787SMichael Walsh# This script is a wrapper for programs that may have alternate versions (e.g. python2, python3). This 4410b1787SMichael Walsh# wrapper allows the user to influence the selection of the program version by setting the <program 5410b1787SMichael Walsh# name>_VERSION (e.g. PYTHON_VERSION, ROBOT_VERSION, etc.) environment variable. 6ae96c5eeSMichael Walsh 7410b1787SMichael Walsh# Users would be expected to create a link with the base name of the program that points to this file. 8ae96c5eeSMichael Walsh 9ae96c5eeSMichael Walsh# Example: 10ae96c5eeSMichael Walsh# cd openbmc-test-automation/bin 11ae96c5eeSMichael Walsh# ln -s select_version python 12ae96c5eeSMichael Walsh 13410b1787SMichael Walsh# The PATH variable should contain the expanded path to openbmc-test-automation/bin. 14ae96c5eeSMichael Walsh 15410b1787SMichael Walsh# If <program name>_VERSION is blank or not set, then the program version will be whatever the system 16410b1787SMichael Walsh# default program version is. If <program name>_VERSION is set to a value, then that value will be appended 17410b1787SMichael Walsh# to the name of the program (e.g. if PYTHON_VERSION = "3", then python3 will be used.). If <program 18410b1787SMichael Walsh# name>_VERSION is set to some value that does not correspond to a valid program version for the given 19410b1787SMichael Walsh# system, this program will fail. 20ae96c5eeSMichael Walsh 21ae96c5eeSMichael Walsh 22ae96c5eeSMichael Walsh# Make sure program_name is set. 23ae96c5eeSMichael Walshprogram_name="${0##*/}" 24ae96c5eeSMichael Walshprogram_uppercase_name=${program_name^^} 25ae96c5eeSMichael Walsh 26ae96c5eeSMichael Walsh 27*90dfee36SPatrick Williamsfunction get_target_program_path() { 28ae96c5eeSMichael Walsh local target_program_path_var="${1:-target_program_path}" ; shift 29ae96c5eeSMichael Walsh 30410b1787SMichael Walsh # Get the full path to the "real" program and assign it to the variable named in target_program_path_var. 31ae96c5eeSMichael Walsh 32ae96c5eeSMichael Walsh # Description of argument(s): 33410b1787SMichael Walsh # target_program_path_var The name of the variable to receive the result. 34ae96c5eeSMichael Walsh 35ae96c5eeSMichael Walsh # Example result: 36ae96c5eeSMichael Walsh 37ae96c5eeSMichael Walsh # /usr/bin/python3 38ae96c5eeSMichael Walsh 39ae96c5eeSMichael Walsh local version_var_name 40ae96c5eeSMichael Walsh local alternate_program_name 41ae96c5eeSMichael Walsh local base_program_path 42ae96c5eeSMichael Walsh local base_program_name 43ae96c5eeSMichael Walsh local candidate 44ae96c5eeSMichael Walsh local candidates 45ae96c5eeSMichael Walsh local base_file_path 46ae96c5eeSMichael Walsh 47ae96c5eeSMichael Walsh # The typical use of this program would be to create a link to it like this: 48ae96c5eeSMichael Walsh # ln -s select_version python 49410b1787SMichael Walsh # That being the case, get the name of this actual program (rather than the name of the link to it). 50ae96c5eeSMichael Walsh base_program_path=$(readlink -f "${0}") 51ae96c5eeSMichael Walsh base_program_name=${base_program_path##*/} 52ae96c5eeSMichael Walsh 532bcd654fSMichael Walsh if [ "${program_name}" == "${base_program_name}" ] ; then 542bcd654fSMichael Walsh { 552bcd654fSMichael Walsh echo -n "**ERROR** ${base_program_name} should never be called directly." 562bcd654fSMichael Walsh echo " Only links to ${base_program_name} should be called." 572bcd654fSMichael Walsh } >&2 582bcd654fSMichael Walsh exit 1 592bcd654fSMichael Walsh fi 602bcd654fSMichael Walsh 61ae96c5eeSMichael Walsh # Compose the version_var_name value (e.g. PYTHON_VERSION). 62ae96c5eeSMichael Walsh version_var_name=${program_uppercase_name}_VERSION 63ae96c5eeSMichael Walsh # Compose the alternate_program_name (e.g. python3). 64ae96c5eeSMichael Walsh alternate_program_name=${program_name}${!version_var_name} 65ae96c5eeSMichael Walsh 66410b1787SMichael Walsh # Now use the "type" built-in to search the PATH variable for a list of target program candidates. 67ae96c5eeSMichael Walsh candidates=$(type -ap ${alternate_program_name}) 68ae96c5eeSMichael Walsh 69ae96c5eeSMichael Walsh # Example candidates: 70ae96c5eeSMichael Walsh # /home/robot/openbmc-test-automation/bin/python 71ae96c5eeSMichael Walsh # /usr/bin/python 72ae96c5eeSMichael Walsh 73ae96c5eeSMichael Walsh # In this example, the first candidate is actually a link to 74410b1787SMichael Walsh # /home/robot/openbmc-test-automation/bin/select_version. As such it will be rejected. 75ae96c5eeSMichael Walsh 76ae96c5eeSMichael Walsh for candidate in ${candidates} 77ae96c5eeSMichael Walsh do 78ae96c5eeSMichael Walsh if [ -L "${candidate}" ] ; then 79410b1787SMichael Walsh # The candidate is a link so we need to see if it's a link to this program file. 80ae96c5eeSMichael Walsh base_file_path=$(readlink "${candidate}") 81ae96c5eeSMichael Walsh [ "${base_file_path}" == "${base_program_name}" ] && continue 82ae96c5eeSMichael Walsh fi 83ae96c5eeSMichael Walsh 84410b1787SMichael Walsh # The candidate is NOT a link so it qualifies as the desired target program path. 85ae96c5eeSMichael Walsh eval ${target_program_path_var}=\"\${candidate}\" 86ae96c5eeSMichael Walsh return 87ae96c5eeSMichael Walsh 88ae96c5eeSMichael Walsh done 89ae96c5eeSMichael Walsh 90ae96c5eeSMichael Walsh} 91ae96c5eeSMichael Walsh 92ae96c5eeSMichael Walsh 93ae96c5eeSMichael Walsh# Main 94ae96c5eeSMichael Walsh 95ae96c5eeSMichael Walshget_target_program_path target_program_path 96ae96c5eeSMichael Walsh 97ae96c5eeSMichael Walsh# Compose program path var name (e.g. PYTHON_PGM_PATH). 98ae96c5eeSMichael Walshpgm_path_var_name=${program_uppercase_name}_PGM_PATH 99410b1787SMichael Walsh# Set and export pgm_path_var_name (e.g. PYTHON_PGM_PATH=/usr/bin/python3). This value can be used by 100410b1787SMichael Walsh# child programs for debug. 101ae96c5eeSMichael Walsheval export ${pgm_path_var_name}=${target_program_path} 102ae96c5eeSMichael Walsh 103ae96c5eeSMichael Walshif [ "${1}" == "--print_only" ] ; then 104ae96c5eeSMichael Walsh echo "${target_program_path}" 105ae96c5eeSMichael Walshelse 106a6076076SMichael Walsh # Use exec in order to replace this process with the target process. 107a6076076SMichael Walsh exec ${target_program_path} "${@}" 108ae96c5eeSMichael Walshfi 109ae96c5eeSMichael Walsh 110