123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- #!/usr/bin/env bash
- # shellcheck disable=SC1090,SC2004
- podmanRunWrapper() {
- ########################
- ###### FUNCTIONS #######
- ########################
- _printHelpAndExit() {
- if [[ -z $_debug ]]; then
- cat <<-'EOF'
- USAGE
- Argument mode:
- podmanRunWrapper -m MODE -o OPTIONS -i IMAGE [-n CONTAINER_NAME] [--help]
- [--debug] [COMMANDS [ARGS...]]
- Array mode (bash >= 4.3):
- podmanRunWrapper -a ARRAY
- EXAMPLE
- podmanRunWrapper -m ephemeral -o "-it -v $PWD:$PWD -w $PWD" -i "php:latest" -c "php ./script.php"
- ARRAY=( "-m" "ephemeral" "-o" "--rm -it -v $PWD:$PWD -w $PWD" "-i" "php:latest" "-c" "php ./script.php")
- podmanRunWrapper -a ARRAY
- 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 (run default container entrypoint)
- OPTIONS
- --mode, -m MODE
- MODE can be any of the following:
- 1. ephemeral
- 2. persistent
- 3. recreate-persistent
- --options, -o OPTIONS
- OPTIONS to pass directly to `podman run` or `podman exec` depending on the mode or
- container state
- --image, -i IMAGE
- IMAGE used to create the container
- --array, -a ARRAY
- Read arguments array named ARRAY (bash >= 4.3)
- This is useful to reduce parsing errors and recommended for build-wrapper plugins
- --optionsarray OPTIONS_ARRAY
- Read podman options from array named OPTIONS_ARRAY (bash >= 4.3)
- This is useful to reduce parsing errors and recommended for build-wrapper plugins
- --commandsarray COMMANDS_ARRAY
- Read container commands from array named COMMANDS_ARRAY (bash >= 4.3)
- This is useful to reduce parsing errors and recommended for build-wrapper plugins
- --name, -n CONTAINER_NAME
- Use the CONTAINER_NAME base to name containers (should be unique to each project)
- Default: Container name will be set based on a concatenation of the image and commands
- --selinuxfix
- A temporary hack to grant SELinux write access on $PWD until a better fix is found
- --debug, -d
- Print debugging
- --help, -h
- Print this help message and exit
- EOF
- fi
- # Exit using passed exit code
- [[ -z $1 ]] && exit 0 || exit "$1"
- }
- # Parse input
- _parseInput() {
- unset _mode _cmds_arr _opts_arr _options _prw_opts_arr _image _name _array _selinux_fix
- # Use getopt to print help
- if INPUT=$(getopt -o +m:o:i:x:n:a:dh -l mode:,options:,image:,name:,array:,optionsarray:,commandsarray:,selinuxfix,debug,help -- "$@"); then
- eval set -- "$INPUT"
- while true; do
- case "$1" in
- --mode|-m)
- shift
- _mode="$1"
- ;;
- --options|-o)
- shift
- _options+=("$1")
- ;;
- --image|-i)
- shift
- _image="$1"
- ;;
- --name|-n)
- shift
- _name="$1"
- ;;
- --array|-a)
- shift
- _array="$1"
- ;;
- --optionsarray)
- shift
- _opts_arr="$1"
- ;;
- --commandsarray)
- shift
- _cmds_arr="$1"
- ;;
- --selinuxfix)
- _selinux_fix="1"
- ;;
- --help|-h)
- _printHelpAndExit 0
- ;;
- --debug|-d)
- export _debug="1"
- echo "Debugging on!"
- ;;
- --)
- shift
- break
- ;;
- esac
- shift
- done
- else
- echo "Incorrect options provided!"
- _printHelpAndExit 1
- fi
- # If array mode, load and parse input array
- if [[ -n $_array ]]; then
- checkBashVersion
- local _n_array
- declare -n _n_array="$_array"
- _parseInput "${_n_array[@]}"
- return
- fi
- # Parse podman options from --optionsarray
- if [[ -n $_opts_arr ]]; then
- # namerefs are awesome
- declare -gn _prw_opts_arr="$_opts_arr"
- # If no array given, parse input from options
- elif [[ ${#_options[@]} -ge 1 ]]; then
- declare -ga _prw_opts_arr=("${_options[@]}")
- else
- echo "Must provide --options or the name of an existing --optionsarray"
- _printHelpAndExit 1
- fi
- # Parse commands
- if [[ -n $_cmds_arr ]]; then
- declare -gn _prw_cmds_arr="$_cmds_arr"
- else
- # Create COMMANDS array from remaining arguments
- # shift getopt parameters away
- shift $((OPTIND - 1))
- # create array
- declare -ga _prw_cmds_arr
- _prw_cmds_arr=("$@")
- if [[ ${#_prw_cmds_arr[@]} -lt 1 ]]; then
- debug "Running container without any commands"
- fi
- fi
- debug "_prw_opts_arr:" "${_prw_opts_arr[@]}"
- debug "_prw_cmds_arr:" "${_prw_cmds_arr[@]}"
- }
- _addCName() {
- # autogenerate _name if missing
- [[ -z $_name ]] && _name="${_image}${_prw_cmds_arr[*]}"
- # sanitize container name
- _name="${_name//_/}" && _name="${_name// /}" && \
- _name="${_name//[^a-zA-Z0-9_]/}" && _name="${_name,,}"
- # append flag
- if [[ "$_mode" == "ephemeral" ]]; then
- _cname="prw-e-$_name"
- else
- _cname="prw-p-$_name"
- fi
- _prw_opts_arr+=("--name" "$_cname")
- }
- _removeContainer() {
- if podman container exists "$1"; then
- debug "podman rm -v -f $1"
- podman rm -v -f "$1"
- fi
- }
- _runContainer() {
- # Run _remove_container first to not run in existing container
- if podman container exists "$1"; then
- debug podman exec "$1" sh -c "${_prw_cmds_arr[@]}"
- podman exec "$1" sh -c "${_prw_cmds_arr[@]}"
- exit $?
- else
- debug "Command: podman run" "${_prw_opts_arr[@]}" "$_image" sh -c "${_prw_cmds_arr[@]}"
- podman run "${_prw_opts_arr[@]}" "$_image" "${_prw_cmds_arr[@]}"
- exit $?
- fi
- }
- #########################
- ####### EXECUTE #########
- #########################
- __main() {
- # Get input
- _parseInput "$@"
- # Set container name
- _addCName
- # SELinux fix
- [[ -n $_selinux_fix ]] && fixPermissions "$PWD"
- # Execute podman
- if [[ "$_mode" =~ ^(ephemeral|recreate-persistent)$ ]]; then
- _removeContainer "$_cname"
- fi
- _runContainer "$_cname"
- }
- # Allow this function to be executed directly
- __main "$@"
- exit $?
- }
- # Allow script to be called directly
- if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
- _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
- podmanRunWrapper "$@"
- fi
|