123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- #!/usr/bin/env bash
- # shellcheck disable=SC1090
- toolboxRun () {
- _printHelpAndExit () {
- cat <<-'EOF'
- USAGE
- toolboxRun -c NAME [-i NAME] [-r RELEASE] [--no-sh] [-h] [-s] [-d] [COMMANDS [ARGS...]]
- COMMANDS
- COMMANDS to run in the container (e.g. the current active file, an external
- build script, a program residing in the container, etc.)
- Can be empty (default entrypoint)
- OPTIONS
- --container NAME, -c NAME
- Assign a different NAME to the toolbox container. This is useful for creating multiple
- toolbox containers from the same base image, or for entirely customized containers from
- custom-built base images.
- If the toolbox container NAME already exists, the command passed to toolboxRun will be
- executed in the existing toolbox. If toolbox container NAME does not exist, it will be
- created and the COMMAND will then be run in it.
- --image NAME, -i NAME
- Change the NAME of the base image used to create the toolbox container. This is useful for
- creating containers from custom-built base images.
- --release RELEASE, -r RELEASE
- Create a toolbox container for a different operating system RELEASE than the host.
- --ephemeral
- The toolbox will be removed after the COMMAND is executed
- --recreate
- If the toolbox NAME already exists, it will first be removed and recreated
- --no-sh, -n
- Makes the first argument of COMMANDS executable and runs it directly
- --debug, -d
- Display debugging output
- --array, -a ARRAY
- Read arguments from an existing or new ARRAY (bash >= 4.3)
- This is useful to reduce parsing errors and recommended for build-wrapper plugins
- --help, -h
- Print this help message and exit (overrides --silent)
- EOF
- # Exit using passed exit code
- [[ -z $1 ]] && exit 0 || exit "$1"
- }
- debug () {
- [[ -n $_debug ]] && echo "debug: " "$@"
- }
- _parseInput () {
- debug "${FUNCNAME[0]}" "$@"
- # Unset vars
- unset _array
- # Parse input and set switches using getopt
- if _input=$(getopt -o +c:i:r:nda:h -l container:,image:,release:,ephemeral,recreate,no-sh,debug,array:,help -- "$@"); then
- eval set -- "$_input"
- while true; do
- case "$1" in
- --container|-c)
- shift && _cname="$1"
- ;;
- --image|-i)
- shift && _image=("-i" "$1")
- ;;
- --release|-r)
- shift && _release=("-r" "$1")
- ;;
- --ephemeral)
- _ephemeral="true"
- ;;
- --recreate)
- _recreate="true"
- ;;
- --no-sh|-n)
- _no_sh="true"
- ;;
- --debug|-d)
- _debug="true"
- echo "Debugging on!"
- ;;
- --array|-a)
- shift && _array="$1"
- break
- ;;
- --help|-h)
- _printHelpAndExit 0
- ;;
- --)
- shift
- break
- ;;
- esac
- shift
- done
- else
- echo "Incorrect options provided"
- _printHelpAndExit 1
- fi
- # If array mode, load input array, reparse input, and return
- if [[ -n $_array ]]; then
- checkBashVersion
- local _n_array
- declare -n _n_array="$_array"
- _parseInput "${_n_array[@]}"
- return
- fi
- # Create _pre_commands_array from remaining arguments
- # shift getopt parameters away
- shift $((OPTIND - 1))
- # Assume program name is first argument
- _program="$1"
- # create command array
- declare -ga _cmd_array=("$@")
- }
- _shWrap () {
- debug "${FUNCNAME[0]}"
- if [[ -z $_no_sh ]]; then
- _cmd_array=("sh" "-c" "${_cmd_array[*]}")
- fi
- }
- _toolboxExists () {
- debug "${FUNCNAME[0]}" "$1"
- toolbox list -c | cut -d ' ' -f 3 | grep -w "$1" > /dev/null 2>&1
- }
- _toolboxCreate () {
- debug "${FUNCNAME[0]}" "$1" "${_image[@]}" "${_release[@]}"
- toolbox create -c "$1" "${_image[@]}" "${_release[@]}"
- }
- _toolboxRemove () {
- debug "${FUNCNAME[0]}" "$1"
- toolbox rm -f "$1"
- }
- _toolboxRun () {
- debug "${FUNCNAME[0]}" "$1" "${_cmd_array[@]}"
- toolbox run -c "$1" "${_cmd_array[@]}"
- }
- __main () {
- # Get input
- _parseInput "$@"
- # Make sure the first argument is executable
- chmod +x "$_program"
- # Wrap command with `sh -c` by default
- _shWrap
- # Check if container exists
- if _toolboxExists "$_cname"; then
- if [[ -n $_recreate || -n $_ephemeral ]]; then
- _toolboxRemove "$_cname"
- fi
- else
- _toolboxCreate "$_cname"
- fi
- _toolboxRun "$_cname"
- if [[ -n $_ephemeral ]]; then
- _toolboxRemove "$_cname"
- fi
- }
- # Allow this function to be executed directly
- __main "$@"
- }
- # Allow this file to be executed directly if not being sourced
- if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
- # The following functions are usually handled by build-wrapper
- _getBaseDir () {
- # Get base directory name of where this script resides
- # https://stackoverflow.com/questions/59895/how-to-get-the-source-directory-of-a-bash-script-from-within-the-script-itself#comment54598418_246128
- _basedir=$(dirname "$(readlink -f "$0")")
- }
- _sourceFunctions () {
- # Get the location of this file
- _getBaseDir
- # Go up two directories
- ff="${_basedir%/*/*}/functions"
- # Source functions file
- if [[ -f "$ff" ]]; then
- source "$ff"
- else
- echo "Cannot find functions file: ${ff}"
- fi
- }
- _sourceFunctions
- toolboxRun "$@"
- fi
|