#!/bin/bash # # ===== dckr ===== # # Copyright 2020 Jan Heuermann (https://www.jotaen.net) # # 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. # ini_path=~/.dckr ini_contents=() flag_help=0 flag_verbose=0 flag_list=0 flag_describe=0 flag_readonly="" all_section_names=() section_name="" section_exists=0 additional_args=() additional_cmd=() config_image=() config_args=() config_cmd=() parse_and_load() { PATTERN_ENTRY='^[[:space:]]*(image|args|cmd)[[:space:]]*=[[:space:]]*(.*)' PATTERN_SECTION='^[[:space:]]*\[[[:space:]]*([a-zA-Z0-9:._-]+)[[:space:]]*\]' section="" for line in "${ini_contents[@]}"; do if [[ "$line" =~ ^[[:space:]]*\;.* ]] || [[ "$line" =~ ^[[:space:]]*$ ]]; then continue fi if [[ "$line" =~ $PATTERN_SECTION ]]; then section=${BASH_REMATCH[1]} all_section_names+=( $section ) if [[ "$section" == "$1" ]]; then eval section_exists=1 fi continue fi if [[ "$section" != "$1" ]]; then continue fi if [[ "$line" =~ $PATTERN_ENTRY ]]; then key=${BASH_REMATCH[1]} value=${BASH_REMATCH[2]} eval config_$key=\( $value \) else echo "Error: malformed syntax '$line'" exit 1 fi done } while (( ${#@} )); do # Process input if [[ "$section_name" == "" ]]; then # 1. Input meant for this script if [[ "$1" =~ ^-.+ ]]; then # 2. dckr flags case $1 in "-h" | "--help") flag_help=1;; "-v" | "--verbose") flag_verbose=1;; "-ls" | "--list") flag_list=1;; "-d" | "--describe") flag_describe=1;; "-ro" | "--readonly") flag_readonly=":ro";; *) echo "Error: Unrecognized flag $1" exit 1 esac else # 3. Section name section_name=$1 fi else if [[ "$1" != "--" ]]; then # 4.Flags for docker run additional_args+=($1) else # 5. Separator shift 1 # Skip `--` separator additional_cmd="${@}" break # done fi fi shift 1 done if [[ ! -f $ini_path ]]; then echo "Error: no config file found '$ini_path'" exit 1 fi # Read the file and convert to line array IFS=$'\n' && file="$(<$ini_path)" ini_contents=( ${file} ) # Print help if [[ "$flag_help" == 1 ]]; then echo "dckr is a command line utility that makes it quick and convenient" echo "to execute predefined 'docker run' configurations." echo echo "Usage: dckr [OPTIONS] NAME [ARGS] [-- CMD]" echo echo " OPTIONS (See below)" echo " NAME Refers to one specific configuration in ~/.dckr" echo " ARGS Additional arguments that you want to be" echo " passed to 'docker run'" echo " CMD Additional command that you want to pass to the" echo " entrypoint (delimited by a double-dash)" echo echo "Options:" echo " --help -h Print help" echo " --verbose -v Print docker command before executing" echo " --list -ls Enumerate all available configurations" echo " --describe -d Print parameters of a specific configuration" echo " --readonly -ro Mount current directory as readonly" exit 0 fi # Load config into env variables parse_and_load $section_name # Print list of all available configurations if [[ "$flag_list" == 1 ]]; then for s in "${all_section_names[@]}"; do echo $s done exit 0 fi if [[ "$section_name" == "" ]]; then echo "Error: no input argument given" exit 1 fi if [[ "$section_exists" != "1" ]]; then echo "Error: no configuration found for alias '$section_name' in $ini_path" exit 1 fi if [[ "$config_image" == "" ]]; then echo "Error: no image specified for alias '$section_name' in $ini_path" exit 1 fi # Print info about image if [[ "$flag_describe" == 1 ]]; then echo "Image: $config_image" echo "Arguments: ${config_args[@]}" echo "Command: ${config_cmd[@]}" exit 0 fi run=( \ --rm \ --tty \ --interactive \ --workdir=/dckr \ --volume=$(pwd):/dckr$flag_readonly \ "${config_args[@]}" \ "${additional_args[@]}" \ $config_image \ "${config_cmd[@]}" \ "${additional_cmd[@]}" \ ) if [[ "$flag_verbose" == 1 ]]; then echo docker run ${run[@]} echo fi docker run ${run[@]}