blob: d6fca43929fbc30ea89c232fc72227521e2f0516 [file] [log] [blame]
Michael Walshae96c5e2019-05-29 17:19:44 -05001#!/bin/bash
2
Michael Walsh410b1782019-10-22 15:56:18 -05003# This script is a wrapper for programs that may have alternate versions (e.g. python2, python3). This
4# wrapper allows the user to influence the selection of the program version by setting the <program
5# name>_VERSION (e.g. PYTHON_VERSION, ROBOT_VERSION, etc.) environment variable.
Michael Walshae96c5e2019-05-29 17:19:44 -05006
Michael Walsh410b1782019-10-22 15:56:18 -05007# Users would be expected to create a link with the base name of the program that points to this file.
Michael Walshae96c5e2019-05-29 17:19:44 -05008
9# Example:
10# cd openbmc-test-automation/bin
11# ln -s select_version python
12
Michael Walsh410b1782019-10-22 15:56:18 -050013# The PATH variable should contain the expanded path to openbmc-test-automation/bin.
Michael Walshae96c5e2019-05-29 17:19:44 -050014
Michael Walsh410b1782019-10-22 15:56:18 -050015# If <program name>_VERSION is blank or not set, then the program version will be whatever the system
16# default program version is. If <program name>_VERSION is set to a value, then that value will be appended
17# to the name of the program (e.g. if PYTHON_VERSION = "3", then python3 will be used.). If <program
18# name>_VERSION is set to some value that does not correspond to a valid program version for the given
19# system, this program will fail.
Michael Walshae96c5e2019-05-29 17:19:44 -050020
21
22# Make sure program_name is set.
23program_name="${0##*/}"
24program_uppercase_name=${program_name^^}
25
26
27function get_target_program_path {
28 local target_program_path_var="${1:-target_program_path}" ; shift
29
Michael Walsh410b1782019-10-22 15:56:18 -050030 # Get the full path to the "real" program and assign it to the variable named in target_program_path_var.
Michael Walshae96c5e2019-05-29 17:19:44 -050031
32 # Description of argument(s):
Michael Walsh410b1782019-10-22 15:56:18 -050033 # target_program_path_var The name of the variable to receive the result.
Michael Walshae96c5e2019-05-29 17:19:44 -050034
35 # Example result:
36
37 # /usr/bin/python3
38
39 local version_var_name
40 local alternate_program_name
41 local base_program_path
42 local base_program_name
43 local candidate
44 local candidates
45 local base_file_path
46
47 # The typical use of this program would be to create a link to it like this:
48 # ln -s select_version python
Michael Walsh410b1782019-10-22 15:56:18 -050049 # That being the case, get the name of this actual program (rather than the name of the link to it).
Michael Walshae96c5e2019-05-29 17:19:44 -050050 base_program_path=$(readlink -f "${0}")
51 base_program_name=${base_program_path##*/}
52
Michael Walsh2bcd6542019-06-24 14:41:10 -050053 if [ "${program_name}" == "${base_program_name}" ] ; then
54 {
55 echo -n "**ERROR** ${base_program_name} should never be called directly."
56 echo " Only links to ${base_program_name} should be called."
57 } >&2
58 exit 1
59 fi
60
Michael Walshae96c5e2019-05-29 17:19:44 -050061 # Compose the version_var_name value (e.g. PYTHON_VERSION).
62 version_var_name=${program_uppercase_name}_VERSION
63 # Compose the alternate_program_name (e.g. python3).
64 alternate_program_name=${program_name}${!version_var_name}
65
Michael Walsh410b1782019-10-22 15:56:18 -050066 # Now use the "type" built-in to search the PATH variable for a list of target program candidates.
Michael Walshae96c5e2019-05-29 17:19:44 -050067 candidates=$(type -ap ${alternate_program_name})
68
69 # Example candidates:
70 # /home/robot/openbmc-test-automation/bin/python
71 # /usr/bin/python
72
73 # In this example, the first candidate is actually a link to
Michael Walsh410b1782019-10-22 15:56:18 -050074 # /home/robot/openbmc-test-automation/bin/select_version. As such it will be rejected.
Michael Walshae96c5e2019-05-29 17:19:44 -050075
76 for candidate in ${candidates}
77 do
78 if [ -L "${candidate}" ] ; then
Michael Walsh410b1782019-10-22 15:56:18 -050079 # The candidate is a link so we need to see if it's a link to this program file.
Michael Walshae96c5e2019-05-29 17:19:44 -050080 base_file_path=$(readlink "${candidate}")
81 [ "${base_file_path}" == "${base_program_name}" ] && continue
82 fi
83
Michael Walsh410b1782019-10-22 15:56:18 -050084 # The candidate is NOT a link so it qualifies as the desired target program path.
Michael Walshae96c5e2019-05-29 17:19:44 -050085 eval ${target_program_path_var}=\"\${candidate}\"
86 return
87
88 done
89
90}
91
92
93# Main
94
95 get_target_program_path target_program_path
96
97 # Compose program path var name (e.g. PYTHON_PGM_PATH).
98 pgm_path_var_name=${program_uppercase_name}_PGM_PATH
Michael Walsh410b1782019-10-22 15:56:18 -050099 # Set and export pgm_path_var_name (e.g. PYTHON_PGM_PATH=/usr/bin/python3). This value can be used by
100 # child programs for debug.
Michael Walshae96c5e2019-05-29 17:19:44 -0500101 eval export ${pgm_path_var_name}=${target_program_path}
102
103 if [ "${1}" == "--print_only" ] ; then
104 echo "${target_program_path}"
105 else
Michael Walsha6076072019-06-14 13:19:54 -0500106 # Use exec in order to replace this process with the target process.
107 exec ${target_program_path} "${@}"
Michael Walshae96c5e2019-05-29 17:19:44 -0500108 fi
109