275 lines
8.1 KiB
Bash
Executable File
275 lines
8.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# shellcheck disable=SC1090,SC2004
|
|
|
|
podmanRunWrapper () {
|
|
|
|
########################
|
|
###### FUNCTIONS #######
|
|
########################
|
|
|
|
_printHelpAndExit () {
|
|
|
|
if [[ -z $_debug ]]; then
|
|
cat <<-'EOF'
|
|
USAGE
|
|
Argument mode:
|
|
podman-run-wrapper -m MODE -o OPTIONS -i IMAGE [-n CONTAINER_NAME]
|
|
[--help] [--silent] [--debug] [COMMANDS [ARGS...]]
|
|
|
|
Array mode (bash >= 4.3):
|
|
podman-run-wrapper -a ARRAY
|
|
|
|
EXAMPLE
|
|
podman-run-wrapper -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")
|
|
podman-run-wrapper -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
|
|
4. remove-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
|
|
|
|
--silent, -s
|
|
Only print errors
|
|
|
|
--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:sdh -l mode:,options:,image:,name:,array:,optionsarray:,commandsarray:,selinuxfix,silent,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
|
|
;;
|
|
--silent|-s)
|
|
_silent="1"
|
|
;;
|
|
--debug|-d)
|
|
_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
|
|
[[ -z $_silent ]] && echo "Warning: running container without any commands"
|
|
fi
|
|
fi
|
|
|
|
[[ -n $_debug ]] && echo "_prw_opts_arr:" "${_prw_opts_arr[@]}"
|
|
[[ -n $_debug ]] && echo "_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 "$_cname"; then
|
|
[[ -z $_silent ]] && echo "Removing container: $_cname"
|
|
[[ -n $_debug ]] && echo "podman rm -v -f $_cname"
|
|
podman rm -v -f "$_cname"
|
|
fi
|
|
}
|
|
|
|
|
|
_runContainer () {
|
|
|
|
# Run _remove_container first to not run in existing container
|
|
if podman container exists "${_cname}"; then
|
|
[[ -z $_silent ]] && echo "Reusing container: $_cname"
|
|
[[ -n $_debug ]] && echo podman exec "$_cname" sh -c "${_prw_cmds_arr[@]}"
|
|
podman exec "$_cname" sh -c "${_prw_cmds_arr[@]}"
|
|
exit $?
|
|
else
|
|
[[ -z $_silent ]] && echo "Running in container: $_cname"
|
|
[[ -n $_debug ]] && echo "Command: podman run" "${_prw_opts_arr[@]}" "$_image" sh -c "${_prw_cmds_arr[@]}"
|
|
podman run "${_prw_opts_arr[@]}" "$_image" "${_prw_cmds_arr[@]}"
|
|
exit $?
|
|
fi
|
|
}
|
|
|
|
|
|
#########################
|
|
####### EXECUTE #########
|
|
#########################
|
|
|
|
_execute () {
|
|
|
|
# Get input
|
|
_parseInput "$@"
|
|
|
|
# Set container name
|
|
_addCName
|
|
|
|
# SELinux fix
|
|
[[ -n $_selinux_fix ]] && fixPermissions "$PWD"
|
|
|
|
# Execute podman
|
|
if [[ $_mode == "ephemeral" || $_mode == "recreate-persistent" ]]; then
|
|
_removeContainer
|
|
_runContainer
|
|
elif [[ $_mode == "remove-persistent" ]]; then
|
|
_removeContainer
|
|
elif [[ $_mode == "persistent" ]]; then
|
|
_runContainer
|
|
else
|
|
echo "Unknown mode!"
|
|
_printHelpAndExit 1
|
|
fi
|
|
}
|
|
|
|
# Allow this function to be executed directly
|
|
_execute "$@"
|
|
}
|
|
|
|
# Allow script to be called directly
|
|
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
|
|
# No imported functions
|
|
#source-functions
|
|
podmanRunWrapper "$@"
|
|
fi
|