podmanRunEasy 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. #!/usr/bin/env bash
  2. # shellcheck disable=SC1090,SC2004
  3. podmanRunEasy () {
  4. sourcePlugin "podmanRun/podmanRunWrapper"
  5. ########################
  6. ####### DEFAULTS #######
  7. ########################
  8. # Can be overridden using environment variables
  9. [[ -z $_image ]] && _image="fedora:latest"
  10. [[ -z $_mode ]] && _mode="ephemeral"
  11. [[ -z $_workdir ]] && _workdir="$PWD"
  12. _smartDefaults () {
  13. echo ""
  14. ### UNDER CONSTRUCTION ###
  15. # I would like to handle some options automatically to reduce the number of configuration
  16. # options necessary to run podman and also make it easy for users to define defaults based
  17. # on file extension, command, shebang, etc
  18. # check the basename for defaults
  19. #[[ -z $COMMAND_DEF ]] \
  20. # && COMMAND_BASENAME="${COMMAND_ARR[0]##*/}" \
  21. # && _set_defaults "${COMMAND_BASENAME}"
  22. # check the extension for defaults
  23. #[[ -z $COMMAND_DEF ]] \
  24. # && COMMAND_EXT="${COMMAND_BASENAME##*.}" \
  25. # && _set_defaults "${COMMAND_EXT}"
  26. # add defaults to the string
  27. #if [[ -n $COMMAND_DEF ]]; then
  28. # [[ -z $_silent ]] && echo "Loaded command defaults, executing with \"${COMMAND_DEF}\""
  29. # COMMAND_STR="${COMMAND_DEF} ${COMMAND_STR}"
  30. #else
  31. # [[ -z $_silent ]] && echo "Could not find command defaults from name or extension"
  32. # [[ -z $_silent ]] && echo "Executing script directly"
  33. #fi
  34. }
  35. ########################
  36. ###### FUNCTIONS #######
  37. ########################
  38. _printHelpAndExit () {
  39. cat <<-'EOF'
  40. USAGE
  41. podmanRunEasy [-m _mode] [-w PATH] [-d PATH] [-i _image] [--userfix] [--mkexec] [--help]
  42. [--silent] [--debug] [COMMANDS [ARGS...]]
  43. COMMANDS
  44. COMMANDS to run in the container (e.g. the current active file, an external
  45. build script, a program residing in the container, etc.)
  46. Can be empty (default entrypoint)
  47. OPTIONS
  48. --mode, -m MODE
  49. MODE can be any of the following:
  50. 1. ephemeral
  51. 2. persistent
  52. 3. recreate-persistent
  53. 4. remove-persistent
  54. --workdir, -w PATH
  55. The directory in the container where we execute the COMMANDS
  56. Default: The present working directory
  57. --maskdir, -d PATH
  58. Hide this directory from the host OS, store contents in the container only
  59. --image, -i IMAGE
  60. IMAGE used to create the container
  61. Default: fedora:latest
  62. --mkexec, -x
  63. Makes the first argument of COMMANDS executable
  64. --name, -n CONTAINER_NAME
  65. This will form the base of the container name and should be unique to each project
  66. Default: Container name will be set based on a concatenation of the image and commands
  67. --array, -a ARRAY
  68. Read arguments from an existing or new ARRAY (bash >= 4.3)
  69. This is useful to reduce parsing errors and recommended for build-wrapper plugins
  70. --silent, -s
  71. Don't output anything from this program (container output will still be passed to stdout
  72. if -it option is used instead of -d, see `man podman run` for more information)
  73. --help, -h
  74. Print this help message and exit (overrides --silent)
  75. EOF
  76. # Exit using passed exit code
  77. [[ -z $1 ]] && exit 0 || exit "$1"
  78. }
  79. _parseInput () {
  80. [[ -n $_debug ]] && echo "$@"
  81. # Unset array variable when reparsing array
  82. unset _array
  83. # Parse input and set switches using getopt
  84. if _input=$(getopt -o +m:w:d:i:a:n:xh -l mode:,workdir:,maskdir:,image:,array:,name:,mkexec,silent,debug,help -- "$@"); then
  85. eval set -- "$_input"
  86. while true; do
  87. case "$1" in
  88. --mode|-m)
  89. shift
  90. _mode="$1"
  91. ;;
  92. --workdir|-w)
  93. shift
  94. _workdir="$1"
  95. ;;
  96. --maskdir|-d)
  97. shift
  98. _maskdir="$1"
  99. ;;
  100. --image|-i)
  101. shift
  102. _image="$1"
  103. ;;
  104. --name|-n)
  105. shift
  106. _name="$1"
  107. ;;
  108. --array|-a)
  109. shift
  110. _array="$1"
  111. break
  112. ;;
  113. --mkexec|-x)
  114. _mkexec="true"
  115. ;;
  116. --silent)
  117. _silent="true"
  118. ;;
  119. --debug)
  120. _debug="true"
  121. echo "Debugging on!"
  122. ;;
  123. --help|-h)
  124. _printHelpAndExit 0
  125. ;;
  126. --)
  127. shift
  128. break
  129. ;;
  130. esac
  131. shift
  132. done
  133. else
  134. echo "Incorrect options provided"
  135. _printHelpAndExit 1
  136. fi
  137. # If array mode, load input array, reparse input, and return
  138. if [[ -n $_array ]]; then
  139. checkBashVersion
  140. local _n_array
  141. declare -n _n_array="$_array"
  142. _parseInput "${_n_array[@]}"
  143. return
  144. fi
  145. # Create _pre_commands_array from remaining arguments
  146. # shift getopt parameters away
  147. shift $((OPTIND - 1))
  148. # create array
  149. declare -ga _pre_commands_array
  150. _pre_commands_array=("$@")
  151. [[ -n $_debug ]] && echo "_pre_commands_array:" "${_pre_commands_array[@]}"
  152. # Sanitize mode numbers
  153. [[ "$_mode" == "1" ]] && _mode="ephemeral"
  154. [[ "$_mode" == "2" ]] && _mode="persistent"
  155. [[ "$_mode" == "3" ]] && _mode="recreate-persistent"
  156. [[ "$_mode" == "4" ]] && _mode="remove-persistent"
  157. # build the podman options array
  158. declare -ga _pre_options_array
  159. _pre_options_array+=("-it")
  160. #[[ "$_mode" == "ephemeral" ]] && _pre_options_array+=("--rm")
  161. _pre_options_array+=("-v" "${_workdir}:${_workdir}:Z")
  162. _pre_options_array+=("-w" "${_workdir}")
  163. _pre_options_array+=("--userns=keep-id") # Fix user permission problems by default
  164. [[ -n $_maskdir ]] && _pre_options_array+=("-v" "${_maskdir}")
  165. [[ -n $_debug ]] && echo "_pre_options_array:" "${_pre_options_array[@]}"
  166. }
  167. _makeExec () {
  168. # make executable
  169. if [[ -n $_mkexec ]]; then
  170. # assume script/program is the first argument in the command and break on whitespace
  171. _program="${_pre_commands_array[0]}"
  172. # make executable on the host
  173. chmod +x "${_program}"
  174. # make executable in the container
  175. #COMMAND="chmod 755 ${_program} && $COMMAND"
  176. fi
  177. }
  178. _sanityChecks () {
  179. # If missing, create workdir
  180. if ! [[ -d "$_workdir" ]]; then
  181. [[ -z $_silent ]] && echo "--workdir does not exist!"
  182. [[ -z $_silent ]] && echo "Creating ${_workdir} now..."
  183. mkdir -p "${_workdir}"
  184. fi
  185. # Grant container SELinux access to the _workdir
  186. fixPermissions "${_workdir}"
  187. }
  188. _runPodmanRunWrapper() {
  189. _makeExec
  190. local _prw_array
  191. _prw_array=("-m" "${_mode}" "--optionsarray" "_pre_options_array" "-i" "${_image}" "-n" "${_name}" "--commandsarray" "_pre_commands_array")
  192. [[ -n $_debug ]] && _prw_array+=("--debug")
  193. [[ -n $_silent ]] && _prw_array+=("--silent")
  194. if [[ -n $_debug ]]; then
  195. echo -n "PRE->PRW argument array: "
  196. printf '"%s" ' "${_prw_array[@]}"
  197. echo ""
  198. fi
  199. podmanRunWrapper -a _prw_array
  200. }
  201. #########################
  202. ####### EXECUTE #########
  203. #########################
  204. _execute () {
  205. # Get input
  206. _parseInput "$@"
  207. # Call podman-run-wrapper
  208. _runPodmanRunWrapper
  209. }
  210. # Allow this function to be executed directly
  211. _execute "$@"
  212. }
  213. # Allow this file to be executed directly if not being sourced
  214. if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
  215. # The following functions are usually handled by build-wrapper
  216. _getBaseDir () {
  217. # Get base directory name of where this script resides
  218. # https://stackoverflow.com/questions/59895/how-to-get-the-source-directory-of-a-bash-script-from-within-the-script-itself#comment54598418_246128
  219. _basedir=$(dirname "$(readlink -f "$0")")
  220. }
  221. _sourceFunctions () {
  222. # Get the location of this file
  223. _getBaseDir
  224. # Go up two directories
  225. ff="${_basedir%/*/*}/functions"
  226. # Source functions file
  227. if [[ -f "$ff" ]]; then
  228. source "$ff"
  229. else
  230. echo "Cannot find functions file: ${ff}"
  231. fi
  232. }
  233. _sourceFunctions
  234. podmanRunEasy "$@"
  235. fi