Browse Source

Initial commit

bryan 3 years ago
commit
4bb2ba9cbe
4 changed files with 272 additions and 0 deletions
  1. 5 0
      .atom-build.yml
  2. 41 0
      README.md
  3. 223 0
      podmanRun
  4. 3 0
      test.sh

+ 5 - 0
.atom-build.yml

@@ -0,0 +1,5 @@
+cmd: './podmanRun -o "--name=bash_{FILE_ACTIVE_NAME_BASE} -v={FILE_ACTIVE_PATH}:{FILE_ACTIVE_PATH}:z -w={FILE_ACTIVE_PATH} ubuntu:latest" test.sh "hello world!"'
+name: 'Test podmanRun'
+targets:
+  Test podmanRun w/ debug:
+    cmd: './podmanRun --debug -o "--name=bash_{FILE_ACTIVE_NAME_BASE} -v={FILE_ACTIVE_PATH}:{FILE_ACTIVE_PATH}:z -w={FILE_ACTIVE_PATH} ubuntu:latest" test.sh "hello world!"'

+ 41 - 0
README.md

@@ -0,0 +1,41 @@
+```text
+USAGE
+    podmanRun [-m MODE] [-o OPTIONS] [COMMANDS [ARGS]...] [--help] [--debug]
+
+COMMANDS
+    COMMANDS to run in the container
+
+OPTIONS
+    --mode, -m MODE
+        1. recreate (remove container if it already exists and create a new one)
+        2. persistent (reuse existing container if it exists)
+    --options, -o OPTIONS
+        OPTIONS to pass to podman run/exec
+        Can be passed multiple times to concatenate
+        Will be split on whitespace
+        Final option should be the name of the container image
+    --debug, -d
+        Print debugging
+    --help, -h
+        Print this help message and exit
+
+EXAMPLES
+    Note: IDE examples are using Atom Build package placeholders.
+
+    Run an ephemeral PHP webserver container using the current directory as webroot:
+        podmanRun -o "-p=8000:80 --name=php_script -v=$PWD:/var/www/html:z php:7.3-apache"
+
+    Run an ephemeral PHP webserver container using the current directory as webroot using IDE:
+        podmanRun -o "-p=8000:80 --name=php_{FILE_ACTIVE_NAME_BASE} \
+        -v={FILE_ACTIVE_PATH}:/var/www/html:z php:7.3-apache"
+
+    Run an ephemeral bash script:
+        podmanRun -o "--name=bash_script -v=$PWD:$PWD:z -w=$PWD debian:testing" ./script.sh
+
+    Run an ephemeral bash script using IDE:
+        podmanRun -o "--name=bash_{FILE_ACTIVE_NAME_BASE}" \
+                  -o "-v={FILE_ACTIVE_PATH}:{FILE_ACTIVE_PATH}:z"
+                  -o "-w={FILE_ACTIVE_PATH}" \
+                  -o "debian:testing" \
+                  {FILE_ACTIVE} arg1 arg2
+```

+ 223 - 0
podmanRun

@@ -0,0 +1,223 @@
+#!/usr/bin/env bash
+# shellcheck disable=SC1090,SC2004
+#
+# This script/function is a wrapper for podman run/exec that will automatically handle container
+# creation, removal, and reuse
+#
+# MIT License
+# Copyright (c) 2020 Bryan Roessler
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+podmanRun() {
+
+    _printHelpAndExit() {
+
+        if [[ -z $_debug ]]; then
+            cat <<-'EOF'
+USAGE
+    podmanRun [-m MODE] [-o OPTIONS] [COMMANDS [ARGS]...] [--help] [--debug]
+
+COMMANDS
+    COMMANDS to run in the container
+
+OPTIONS
+    --mode, -m MODE
+        1. recreate (remove container if it already exists and create a new one)
+        2. persistent (reuse existing container if it exists)
+    --options, -o OPTIONS
+        OPTIONS to pass to podman run/exec
+        Can be passed multiple times to concatenate
+        Will be split on whitespace
+        Final option should be the name of the container image
+    --debug, -d
+        Print debugging
+    --help, -h
+        Print this help message and exit
+
+EXAMPLES
+    Note: IDE examples are using Atom Build package placeholders.
+
+    Run an ephemeral PHP webserver container using the current directory as webroot:
+        podmanRun -o "-p=8000:80 --name=php_script -v=$PWD:/var/www/html:z php:7.3-apache"
+
+    Run an ephemeral PHP webserver container using the current directory as webroot using IDE:
+        podmanRun -o "-p=8000:80 --name=php_{FILE_ACTIVE_NAME_BASE} \
+        -v={FILE_ACTIVE_PATH}:/var/www/html:z php:7.3-apache"
+
+    Run an ephemeral bash script:
+        podmanRun -o "--name=bash_script -v=$PWD:$PWD:z -w=$PWD debian:testing" ./script.sh
+
+    Run an ephemeral bash script using IDE:
+        podmanRun -o "--name=bash_{FILE_ACTIVE_NAME_BASE}" \
+                  -o "-v={FILE_ACTIVE_PATH}:{FILE_ACTIVE_PATH}:z"
+                  -o "-w={FILE_ACTIVE_PATH}" \
+                  -o "debian:testing" \
+                  {FILE_ACTIVE} arg1 arg2
+EOF
+        fi
+
+        # Exit using passed exit code
+        [[ -z $1 ]] && exit 0 || exit "$1"
+    }
+
+
+    # Parse input
+    _parseInput() {
+
+        declare -g _mode _debug
+        declare -ga  _opts_arr _cmds_arr
+        local INPUT
+
+        # Use getopt to print help
+        if INPUT=$(getopt -o +m:o:dh -l mode:,options:,debug,help -- "$@"); then
+            eval set -- "$INPUT"
+            while true; do
+                case "$1" in
+                    --mode|-m)
+                        shift
+                        _mode="$1"
+                        ;;
+                    --options|-o)
+                        shift
+                        #
+                        _opts_arr+=("$1")
+                        ;;
+                    --help|-h)
+                        _printHelpAndExit 0
+                        ;;
+                    --debug|-d)
+                        _debug="1"
+                        echo "Debugging on!"
+                        ;;
+                    --)
+                        shift
+                        break
+                        ;;
+                esac
+                shift
+            done
+        else
+            err "Incorrect options provided!"
+            _printHelpAndExit 1
+        fi
+
+        # Load remaining arguments into the commands array
+        shift $((OPTIND - 1))
+        _cmds_arr=("$@")
+
+        # Set default mode
+        [[ -z $_mode ]] && _mode="recreate"
+        # Allow mode numbers
+        [[ "$_mode" == "1" ]] && _mode="recreate"
+        [[ "$_mode" == "2" ]] && _mode="persistent"
+        # Sanity check
+        [[ ! "$_mode" =~ ^(recreate|persistent)$ ]] && err "Bad --mode" && _printHelpAndExit 1
+
+        # Split options on whitespace
+        # This assumes that podman options are properly formatted
+        # https://unix.stackexchange.com/a/519917/382539
+        readarray -td' ' _opts_arr < <(printf '%s' "${_opts_arr[*]}")
+
+        debug "_opts_arr:" "${_opts_arr[@]}"
+        debug "_cmds_arr:" "${_cmds_arr[@]}"
+    }
+
+
+    debug() { [[ -n $_debug ]] && echo "debug: " "$@"; }
+    err() { echo "error: $*" >&2; }
+
+
+    _setContainerName() {
+
+        debug "${FUNCNAME[0]}"
+
+        export _cname
+        local index _name
+
+        # Get user-specified container name by parsing the options array for --name
+        for ((index=0; index <= ${#_opts_arr[@]}; index++)); do
+            if [[ "${_opts_arr[index]}" == "--name" ]]; then
+                _name="${_opts_arr[index+1]}"
+            elif [[ "${_opts_arr[index]}" =~ ^--name ]]; then
+                _name="${_opts_arr[index]}"
+                _name="${_name#--name=}"
+            fi
+        done
+
+        _sanitize() {
+            local i="$*"; i="${i// /}" && i="${i//[^a-zA-Z0-9_]/}" && i="${i,,}"; echo "$i" ;
+        }
+
+        # If no --name is specified, then generate one using the opts and cmds arrays
+        if [[ -z $_name ]]; then
+            _cname="$(_sanitize "${_opts_arr[*]}${_cmds_arr[*]}")"
+        else
+            _cname="$(_sanitize "$_name")"
+            [[ "$_name" != "$_cname" ]] && err "You must provide a valid --name" && exit 1
+        fi
+
+        debug "_cname: $_cname"
+    }
+
+
+    _containerExists() { debug "${FUNCNAME[0]} $1"; podman container exists "$1"; }
+
+    _removeContainer() { debug "${FUNCNAME[0]} $1"; _containerExists "$1" && podman rm -vf "$1"; }
+
+    _runContainer() {
+
+        debug "${FUNCNAME[0]} $1"
+
+        if _containerExists "$1"; then
+            debug "podman exec $1 sh -c" "${_cmds_arr[@]}"
+            podman exec "$1" "${_cmds_arr[@]}"
+        else
+            debug "podman run" "${_opts_arr[@]}" "${_cmds_arr[@]}"
+            podman run "${_opts_arr[@]}" "${_cmds_arr[@]}"
+        fi
+    }
+
+
+    __main() {
+
+        # Get input
+        _parseInput "$@"
+
+        # Set _cname (container name)
+        _setContainerName
+
+        # Remove container if necessary
+        [[ "$_mode" == "recreate" ]] && _containerExists "$_cname" && _removeContainer "$_cname"
+
+        # Run or execute container
+        _runContainer "$_cname"
+
+        # Cleanup more reliably
+        [[ "$_mode" == "recreate" ]] && _containerExists "$_cname" && _removeContainer "$_cname"
+    }
+
+    # Allow this function to be executed directly
+    __main "$@"
+    exit $?
+}
+
+# Allow script to be called directly
+if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
+    podmanRun "$@"
+fi

+ 3 - 0
test.sh

@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+echo "$@"