#!/usr/bin/env bash # shellcheck disable=SC1090,SC2004 podmanRunEasy () { sourcePlugin "podmanRun/podmanRunWrapper" ######################## ####### DEFAULTS ####### ######################## # Can be overridden using environment variables [[ -z $_image ]] && _image="fedora:latest" [[ -z $_mode ]] && _mode="ephemeral" [[ -z $_workdir ]] && _workdir="$PWD" _smartDefaults () { echo "" ### UNDER CONSTRUCTION ### # I would like to handle some options automatically to reduce the number of configuration # options necessary to run podman and also make it easy for users to define defaults based # on file extension, command, shebang, etc # check the basename for defaults #[[ -z $COMMAND_DEF ]] \ # && COMMAND_BASENAME="${COMMAND_ARR[0]##*/}" \ # && _set_defaults "${COMMAND_BASENAME}" # check the extension for defaults #[[ -z $COMMAND_DEF ]] \ # && COMMAND_EXT="${COMMAND_BASENAME##*.}" \ # && _set_defaults "${COMMAND_EXT}" # add defaults to the string #if [[ -n $COMMAND_DEF ]]; then # [[ -z $_silent ]] && echo "Loaded command defaults, executing with \"${COMMAND_DEF}\"" # COMMAND_STR="${COMMAND_DEF} ${COMMAND_STR}" #else # [[ -z $_silent ]] && echo "Could not find command defaults from name or extension" # [[ -z $_silent ]] && echo "Executing script directly" #fi } ######################## ###### FUNCTIONS ####### ######################## _printHelpAndExit () { cat <<-'EOF' USAGE podmanRunEasy [-m _mode] [-w PATH] [-d PATH] [-i _image] [--userfix] [--mkexec] [--help] [--silent] [--debug] [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 --mode, -m MODE MODE can be any of the following: 1. ephemeral 2. persistent 3. recreate-persistent 4. remove-persistent --workdir, -w PATH The directory in the container where we execute the COMMANDS Default: The present working directory --maskdir, -d PATH Hide this directory from the host OS, store contents in the container only --image, -i IMAGE IMAGE used to create the container Default: fedora:latest --mkexec, -x Makes the first argument of COMMANDS executable --name, -n CONTAINER_NAME This will form the base of the container name and should be unique to each project Default: Container name will be set based on a concatenation of the image and commands --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 --silent, -s Don't output anything from this program (container output will still be passed to stdout if -it option is used instead of -d, see `man podman run` for more information) --help, -h Print this help message and exit (overrides --silent) EOF # Exit using passed exit code [[ -z $1 ]] && exit 0 || exit "$1" } _parseInput () { [[ -n $_debug ]] && echo "$@" # Unset array variable when reparsing array unset _array # Parse input and set switches using getopt if _input=$(getopt -o +m:w:d:i:a:n:xh -l mode:,workdir:,maskdir:,image:,array:,name:,mkexec,silent,debug,help -- "$@"); then eval set -- "$_input" while true; do case "$1" in --mode|-m) shift _mode="$1" ;; --workdir|-w) shift _workdir="$1" ;; --maskdir|-d) shift _maskdir="$1" ;; --image|-i) shift _image="$1" ;; --name|-n) shift _name="$1" ;; --array|-a) shift _array="$1" break ;; --mkexec|-x) _mkexec="true" ;; --silent) _silent="true" ;; --debug) _debug="true" echo "Debugging on!" ;; --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)) # create array declare -ga _pre_commands_array _pre_commands_array=("$@") [[ -n $_debug ]] && echo "_pre_commands_array:" "${_pre_commands_array[@]}" # Sanitize mode numbers [[ "$_mode" == "1" ]] && _mode="ephemeral" [[ "$_mode" == "2" ]] && _mode="persistent" [[ "$_mode" == "3" ]] && _mode="recreate-persistent" [[ "$_mode" == "4" ]] && _mode="remove-persistent" # build the podman options array declare -ga _pre_options_array _pre_options_array+=("-it") #[[ "$_mode" == "ephemeral" ]] && _pre_options_array+=("--rm") _pre_options_array+=("-v" "${_workdir}:${_workdir}:Z") _pre_options_array+=("-w" "${_workdir}") _pre_options_array+=("--userns=keep-id") # Fix user permission problems by default [[ -n $_maskdir ]] && _pre_options_array+=("-v" "${_maskdir}") [[ -n $_debug ]] && echo "_pre_options_array:" "${_pre_options_array[@]}" } _makeExec () { # make executable if [[ -n $_mkexec ]]; then # assume script/program is the first argument in the command and break on whitespace _program="${_pre_commands_array[0]}" # make executable on the host chmod +x "${_program}" # make executable in the container #COMMAND="chmod 755 ${_program} && $COMMAND" fi } _sanityChecks () { # If missing, create workdir if ! [[ -d "$_workdir" ]]; then [[ -z $_silent ]] && echo "--workdir does not exist!" [[ -z $_silent ]] && echo "Creating ${_workdir} now..." mkdir -p "${_workdir}" fi # Grant container SELinux access to the _workdir fixPermissions "${_workdir}" } _runPodmanRunWrapper() { _makeExec local _prw_array _prw_array=("-m" "${_mode}" "--optionsarray" "_pre_options_array" "-i" "${_image}" "-n" "${_name}" "--commandsarray" "_pre_commands_array") [[ -n $_debug ]] && _prw_array+=("--debug") [[ -n $_silent ]] && _prw_array+=("--silent") if [[ -n $_debug ]]; then echo -n "PRE->PRW argument array: " printf '"%s" ' "${_prw_array[@]}" echo "" fi podmanRunWrapper -a _prw_array } ######################### ####### EXECUTE ######### ######################### _execute () { # Get input _parseInput "$@" # Call podman-run-wrapper _runPodmanRunWrapper } # Allow this function to be executed directly _execute "$@" } # 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 podmanRunEasy "$@" fi