diff --git a/client/src/docker/docker.bash b/client/src/docker/docker.bash index 0d49e56..5f66882 100755 --- a/client/src/docker/docker.bash +++ b/client/src/docker/docker.bash @@ -21,7 +21,12 @@ # Implementation # -source "$(dirname "$(realpath -s $0)")/src/docker/lib/lib_docker.bash" || exit 1 +if [ -z "$DOCKER_FINANCE_CLIENT_REPO" ]; then + declare -gx DOCKER_FINANCE_CLIENT_REPO + DOCKER_FINANCE_CLIENT_REPO="$(dirname "$(realpath -s $0)" | rev | cut -d'/' -f2- | rev)" +fi + +source "${DOCKER_FINANCE_CLIENT_REPO}/client/src/docker/lib/lib_docker.bash" || exit 1 # # Execute @@ -32,6 +37,7 @@ function main() [ -z "$global_basename" ] && lib_utils::die_fatal [ -z "$global_arg_delim_1" ] && lib_utils::die_fatal [ -z "$global_arg_delim_2" ] && lib_utils::die_fatal + [ -z "$global_arg_delim_3" ] && lib_utils::die_fatal local _usage=" \e[32mDescription:\e[0m @@ -93,7 +99,7 @@ function main() $ alias docker-finance=\"$0 archlinux${global_arg_delim_1}${USER}:latest\" \e[37;2m# Generate environment and build default image\e[0m - $ docker-finance gen && docker-finance build type=default + $ docker-finance gen && docker-finance build type${global_arg_delim_2}default \e[37;2m# Bring up container, open shell (type 'exit' to leave)\e[0m $ docker-finance up @@ -106,7 +112,7 @@ function main() \e[37;2m# Spawn a container with given command (removed after command finishes)\e[0m \e[37;2m# NOTE: incredibly useful when used with your host's crontab\e[0m - $ docker-finance run 'finance family/alice fetch all=price' + $ docker-finance run 'finance family/alice fetch all${global_arg_delim_2}price' \e[37;2m# Bring down running container (stop and remove container & network)\e[0m $ docker-finance down @@ -115,29 +121,29 @@ function main() $ docker-finance backup && docker-finance rm && docker-finance build \e[37;2m# Print current version of 'docker-finance' and client/container ('finance') dependencies\e[0m - $ docker-finance version + $ docker-finance version type${global_arg_delim_2}all \e[37;2m#\e[0m \e[37;2m# Dev-tools platform\e[0m \e[37;2m#\e[0m \e[37;2m# Setup an alias for dev-tools\e[0m - $ alias docker-finance_dev-tools=\"$0 dev-tools${global_arg_delim_1}${USER}:latest\" + $ alias dev-tools=\"$0 dev-tools${global_arg_delim_1}${USER}:latest\" \e[37;2m# Generate environment and build default image\e[0m - $ docker-finance_dev-tools gen && docker-finance_dev-tools build type=default + $ dev-tools gen && docker-finance_dev-tools build type${global_arg_delim_2}default \e[37;2m# Spawn a container with given command (removed after command finishes)\e[0m - $ docker-finance_dev-tools run 'shellcheck --version' + $ dev-tools run 'shellcheck --version' \e[37;2m# Lint entire docker-finance source\e[0m - $ docker-finance_dev-tools linter type=bash,php,c++ + $ dev-tools linter type${global_arg_delim_2}bash${global_arg_delim_3}php${global_arg_delim_3}c++ \e[37;2m# Generate Doxygen for docker-finance source\e[0m - $ docker-finance_dev-tools doxygen gen + $ dev-tools doxygen gen \e[37;2m# Print current version of 'docker-finance' and client/container ('dev-tools') dependencies\e[0m - $ docker-finance_dev-tools version + $ dev-tools version type${global_arg_delim_2}all " # diff --git a/client/src/docker/lib/internal/dev-tools/lib_doxygen.bash b/client/src/docker/lib/internal/dev-tools/lib_doxygen.bash index 73d0f7b..7482a69 100644 --- a/client/src/docker/lib/internal/dev-tools/lib_doxygen.bash +++ b/client/src/docker/lib/internal/dev-tools/lib_doxygen.bash @@ -17,12 +17,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +[ -z "$DOCKER_FINANCE_CLIENT_REPO" ] && exit 1 + # # "Libraries" # -source "$(dirname "$(realpath -s $0)")/src/docker/lib/internal/lib_docker.bash" || exit 1 -source "$(dirname "$(realpath -s $0)")/../container/src/finance/lib/internal/lib_utils.bash" || exit 1 +source "${DOCKER_FINANCE_CLIENT_REPO}/client/src/docker/lib/internal/lib_docker.bash" || exit 1 +source "${DOCKER_FINANCE_CLIENT_REPO}/container/src/finance/lib/internal/lib_utils.bash" || exit 1 # # Implementation diff --git a/client/src/docker/lib/internal/dev-tools/lib_license.bash b/client/src/docker/lib/internal/dev-tools/lib_license.bash index da48f51..01dd527 100644 --- a/client/src/docker/lib/internal/dev-tools/lib_license.bash +++ b/client/src/docker/lib/internal/dev-tools/lib_license.bash @@ -17,11 +17,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +[ -z "$DOCKER_FINANCE_CLIENT_REPO" ] && exit 1 + # # "Libraries" # -source "$(dirname "$(realpath -s $0)")/../container/src/finance/lib/internal/lib_utils.bash" || exit 1 +source "${DOCKER_FINANCE_CLIENT_REPO}/container/src/finance/lib/internal/lib_utils.bash" || exit 1 # # Implementation diff --git a/client/src/docker/lib/internal/dev-tools/lib_linter.bash b/client/src/docker/lib/internal/dev-tools/lib_linter.bash index 87bed26..f704010 100644 --- a/client/src/docker/lib/internal/dev-tools/lib_linter.bash +++ b/client/src/docker/lib/internal/dev-tools/lib_linter.bash @@ -17,12 +17,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +[ -z "$DOCKER_FINANCE_CLIENT_REPO" ] && exit 1 + # # "Libraries" # -source "$(dirname "$(realpath -s $0)")/src/docker/lib/internal/lib_docker.bash" || exit 1 -source "$(dirname "$(realpath -s $0)")/../container/src/finance/lib/internal/lib_utils.bash" || exit 1 +source "${DOCKER_FINANCE_CLIENT_REPO}/client/src/docker/lib/internal/lib_docker.bash" || exit 1 +source "${DOCKER_FINANCE_CLIENT_REPO}/container/src/finance/lib/internal/lib_utils.bash" || exit 1 # # Implementation diff --git a/client/src/docker/lib/internal/lib_docker.bash b/client/src/docker/lib/internal/lib_docker.bash index b6bb5b8..1214ecd 100644 --- a/client/src/docker/lib/internal/lib_docker.bash +++ b/client/src/docker/lib/internal/lib_docker.bash @@ -17,12 +17,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +[ -z "$DOCKER_FINANCE_CLIENT_REPO" ] && exit 1 + # # "Libraries" # # Utilities (a container library (but container is never exposed to client code)) -source "$(dirname "$(realpath -s $0)")/../container/src/finance/lib/internal/lib_utils.bash" || exit 1 +source "${DOCKER_FINANCE_CLIENT_REPO}/container/src/finance/lib/internal/lib_utils.bash" || exit 1 # # Implementation diff --git a/client/src/docker/lib/internal/lib_gen.bash b/client/src/docker/lib/internal/lib_gen.bash index 8f331b0..7005d07 100644 --- a/client/src/docker/lib/internal/lib_gen.bash +++ b/client/src/docker/lib/internal/lib_gen.bash @@ -17,11 +17,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +[ -z "$DOCKER_FINANCE_CLIENT_REPO" ] && exit 1 + # # "Libraries" # -source "$(dirname "$(realpath -s $0)")/../container/src/finance/lib/internal/lib_utils.bash" || exit 1 +source "${DOCKER_FINANCE_CLIENT_REPO}/container/src/finance/lib/internal/lib_utils.bash" || exit 1 # # Implementation @@ -51,87 +53,69 @@ fi # # "Constructor" for environment generation # -# Sets client-side environment with defaults or use existing environment +# 1. Sets client-side environment with defaults or use existing environment +# 2. If configured, resets to alternative environment configuration after bootstrap # # NOTE: some bootstrapped defaults are ignored by environment file (as seen below) # -# TODO: further refactoring; make clearer transient env vars versus persistent env vars function lib_gen::gen() { - lib_utils::print_debug "Constructing environment" + [ -z "$DOCKER_FINANCE_CLIENT_REPO" ] && lib_utils::die_fatal + # NOTE: global_* *MUST* be reset after sourcing new env file + + # # Generate `docker-finance` version - global_repo_manifest="$(dirname "$(realpath -s $0)")/docker-finance.yaml" - declare -gr global_repo_manifest + # + + global_repo_manifest="${DOCKER_FINANCE_CLIENT_REPO}/client/docker-finance.yaml" + declare -g global_repo_manifest global_client_version="$(grep '^version: ' $global_repo_manifest | sed -e 's/version: "//' -e 's/"//g')" # shellcheck disable=SC2034 # used during env gen - declare -gr global_client_version - - # Repository-provided (not user-defined) default environment - global_repo_conf_dir="$(dirname "$(realpath -s $0)")/docker-finance.d" - declare -gr global_repo_conf_dir - - # Environment - declare -gr global_repo_env_file="${global_repo_conf_dir}/client/env/gen.bash" - [ ! -f "$global_repo_env_file" ] \ - && lib_utils::die_fatal "Missing environment defaults! ($global_repo_env_file)" + declare -g global_client_version # - # Dockerfiles + # If empty environment: + # + # 1. Poke at possible (default) location of end-user environment file + # a. If found, point to new location and read/reset from there + # + # 2. If file not found, bootstrap with defaults # - # Set image type - [ -z "$global_platform" ] && lib_utils::die_fatal - case "$global_platform" in - archlinux | ubuntu) - global_platform_image="finance" - ;; - dev-tools) - global_platform_image="dev-tools" - ;; - *) - lib_utils::die_fatal "unsupported platform" - ;; - esac - declare -gr global_platform_image + # Environment (end-user) + global_conf_filename="${USER}@$(uname -n)" + declare -g global_conf_filename - # Base location of Docker-related files (.in and final out files) - global_repo_dockerfiles="$(dirname "$(realpath -s $0)")/Dockerfiles/${global_platform_image}" - # shellcheck disable=SC2034 # used in lib_docker - declare -gr global_repo_dockerfiles + # Environment (end-user) tag dir (not full path) + [ -z "$global_tag" ] && lib_utils::die_fatal + global_tag_dir="client/$(uname -s)-$(uname -m)/${global_platform}/${global_tag}" + declare -g global_tag_dir - # Base custom end-user .in Dockerfile (to be appended to final Dockerfile after installation) - declare -gr global_repo_custom_dockerfile="${global_repo_conf_dir}/client/Dockerfiles/${global_platform_image}/Dockerfile.${global_platform}.in" - [ ! -f "$global_repo_custom_dockerfile" ] \ - && lib_utils::die_fatal "Missing default custom Dockerfile '${global_repo_custom_dockerfile}'" + local _env_dir="/home/${USER}/.config/docker-finance.d/${global_tag_dir}/env" # NOTE: keep aligned with gen.bash + local _env_file="${_env_dir}/${global_conf_filename}" - # - # If empty environment, bootstrap with defaults - # + # shellcheck source=/dev/null + [ -f "$_env_file" ] && source "$_env_file" if [ -z "$DOCKER_FINANCE_CLIENT_CONF" ]; then # shellcheck source=/dev/null - source "$global_repo_env_file" + source "${DOCKER_FINANCE_CLIENT_REPO}/client/docker-finance.d/client/env/gen.bash" fi [ -z "$DOCKER_FINANCE_CLIENT_CONF" ] \ && lib_utils::die_fatal "Defaults not generated! (${global_repo_env_file})" - [ -z "$DOCKER_FINANCE_USER" ] && lib_utils::die_fatal - global_conf_filename="${DOCKER_FINANCE_USER}@$(uname -n)" - declare -gr global_conf_filename - lib_gen::__set_client_globals # # Reset environment with user-provided (user-defined) existing file (if available) # - [ -z "$global_tag" ] && lib_utils::die_fatal - local -r _env_dir="${DOCKER_FINANCE_CLIENT_CONF}/client/$(uname -s)-$(uname -m)/${global_platform}/${global_tag}/env" - local -r _env_file="${_env_dir}/${global_conf_filename}" + _env_dir="${DOCKER_FINANCE_CLIENT_CONF}/${global_tag_dir}/env" + _env_file="${_env_dir}/${global_conf_filename}" if [ -f "$_env_file" ]; then if [ -s "$_env_file" ]; then @@ -165,22 +149,93 @@ function lib_gen::gen() function lib_gen::__set_client_globals() { - lib_utils::print_debug "Setting client globals" + lib_utils::print_debug "Setting (or resetting) client globals" - # Appending all client-side conf paths - local _client_tag_path - _client_tag_path="${DOCKER_FINANCE_CLIENT_CONF}/client/$(uname -s)-$(uname -m)/${global_platform}/${global_tag}" + # + # Repository env + # - # Client-side environment file (if available) - local _client_env_dir="${_client_tag_path}/env" + [ -z "$DOCKER_FINANCE_CLIENT_REPO" ] && lib_utils::die_fatal + + # Generate `docker-finance` version + global_repo_manifest="${DOCKER_FINANCE_CLIENT_REPO}/client/docker-finance.yaml" + declare -g global_repo_manifest + lib_utils::print_debug "global_repo_manifest=${global_repo_manifest}" + + global_client_version="$(grep '^version: ' $global_repo_manifest | sed -e 's/version: "//' -e 's/"//g')" + # shellcheck disable=SC2034 # used during env gen + declare -g global_client_version + lib_utils::print_debug "global_client_version=${global_client_version}" + + # This does not reset when reading env; export again + export DOCKER_FINANCE_VERSION="$global_client_version" + lib_utils::print_debug "DOCKER_FINANCE_VERSION=${DOCKER_FINANCE_VERSION}" + + # Repository-provided (not user-defined) default environment + global_repo_conf_dir="${DOCKER_FINANCE_CLIENT_REPO}/client/docker-finance.d" + declare -g global_repo_conf_dir + lib_utils::print_debug "global_repo_conf_dir=${global_repo_conf_dir}" + + # Environment (repo) + declare -g global_repo_env_file="${global_repo_conf_dir}/client/env/gen.bash" + [ ! -f "$global_repo_env_file" ] \ + && lib_utils::die_fatal "Missing environment defaults! ($global_repo_env_file)" + lib_utils::print_debug "global_repo_env_file=${global_repo_env_file}" + + # + # Repository env (Dockerfiles) + # + + # Set image type + [ -z "$global_platform" ] && lib_utils::die_fatal + case "$global_platform" in + archlinux | ubuntu) + global_platform_image="finance" + ;; + dev-tools) + global_platform_image="dev-tools" + ;; + *) + lib_utils::die_fatal "unsupported platform" + ;; + esac + declare -g global_platform_image + lib_utils::print_debug "global_platform_image=${global_platform_image}" + + # Base location of Docker-related files (.in and final out files) + global_repo_dockerfiles="${DOCKER_FINANCE_CLIENT_REPO}/client/Dockerfiles/${global_platform_image}" + # shellcheck disable=SC2034 # used in lib_docker + declare -g global_repo_dockerfiles + lib_utils::print_debug "global_repo_dockerfiles=${global_repo_dockerfiles}" + + # Base custom end-user .in Dockerfile (to be appended to final Dockerfile after installation) + declare -g global_repo_custom_dockerfile="${global_repo_conf_dir}/client/Dockerfiles/${global_platform_image}/Dockerfile.${global_platform}.in" + [ ! -f "$global_repo_custom_dockerfile" ] \ + && lib_utils::die_fatal "Missing default custom Dockerfile '${global_repo_custom_dockerfile}'" + lib_utils::print_debug "global_repo_custom_dockerfile=${global_repo_custom_dockerfile}" + + # + # Client-side env + # + + [ -z "$global_tag_dir" ] && lib_utils::die_fatal + + # Environment (end-user) format + [ -z "$DOCKER_FINANCE_USER" ] && lib_utils::die_fatal + global_conf_filename="${DOCKER_FINANCE_USER}@$(uname -n)" + declare -g global_conf_filename + lib_utils::print_debug "global_conf_filename=${global_conf_filename}" + + # Environment file (if available) + local _client_env_dir="${DOCKER_FINANCE_CLIENT_CONF}/${global_tag_dir}/env" [ ! -d "$_client_env_dir" ] && mkdir -p "$_client_env_dir" global_env_file="${_client_env_dir}/${global_conf_filename}" lib_utils::print_debug "global_env_file=${global_env_file}" - # Client-side custom Dockerfile (if available) - local _client_dockerfile_dir="${_client_tag_path}/Dockerfiles" + # Custom Dockerfile (if available) + local _client_dockerfile_dir="${global_tag_dir}/Dockerfiles" [ ! -d "$_client_dockerfile_dir" ] && mkdir -p "$_client_dockerfile_dir" - global_custom_dockerfile="${_client_dockerfile_dir}/${global_conf_filename}" + global_custom_dockerfile="${DOCKER_FINANCE_CLIENT_CONF}/${_client_dockerfile_dir}/${global_conf_filename}" lib_utils::print_debug "global_custom_dockerfile=${global_custom_dockerfile}" # NOTE: @@ -198,7 +253,6 @@ function lib_gen::__set_client_globals() lib_utils::print_debug "global_shell_file=${global_shell_file}" # Client view of client portion of repository - [ -z "$DOCKER_FINANCE_CLIENT_REPO" ] && lib_utils::die_fatal global_repo_client="${DOCKER_FINANCE_CLIENT_REPO}/client" [ ! -d "$global_repo_client" ] && lib_utils::die_fatal "Repository '${global_repo_client}' not found!" lib_utils::print_debug "global_repo_client=${global_repo_client}" @@ -215,11 +269,22 @@ function lib_gen::__set_client_globals() function lib_gen::__read_env() { + local _file="$1" + + # Get environment + local _env=() + while read _line; do + _env+=("$_line") + done < <(printenv | grep -Eo "^DOCKER_FINANCE[^=]+") + # Reset environment - unset "$(printenv | grep -Eo "^DOCKER_FINANCE[^=]+")" + for _line in "${_env[@]}"; do + lib_utils::print_debug "Unsetting $_line" + unset "$_line" + done # Set, if a script that generates env - if [[ "$(head -n1 $1)" =~ (bin|env|sh|bash) ]]; then + if [[ "$(head -n1 $_file)" =~ (bin|env|sh|bash) ]]; then # shellcheck source=/dev/null source "$global_repo_env_file" return $? @@ -237,7 +302,7 @@ function lib_gen::__read_env() export "${_line?}" # SC2163 lib_utils::print_debug "$_line" fi - done <"$1" + done <"$_file" } # @@ -299,7 +364,10 @@ function lib_gen::__gen_client() || lib_utils::die_fatal # Get/Set with repository defaults + lib_utils::print_debug "Reading $global_repo_env_file" lib_gen::__read_env "$global_repo_env_file" + + lib_utils::print_debug "Writing $global_env_file" lib_gen::__write_env "$global_env_file" fi fi diff --git a/client/src/docker/lib/lib_docker.bash b/client/src/docker/lib/lib_docker.bash index ad91bd7..2a5dce3 100644 --- a/client/src/docker/lib/lib_docker.bash +++ b/client/src/docker/lib/lib_docker.bash @@ -17,23 +17,25 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +[ -z "$DOCKER_FINANCE_CLIENT_REPO" ] && exit 1 + # # "Libraries" # # Docker impl -source "$(dirname "$(realpath -s $0)")/src/docker/lib/internal/lib_docker.bash" || exit 1 +source "${DOCKER_FINANCE_CLIENT_REPO}/client/src/docker/lib/internal/lib_docker.bash" || exit 1 # Environment generation -source "$(dirname "$(realpath -s $0)")/src/docker/lib/internal/lib_gen.bash" || exit 1 +source "${DOCKER_FINANCE_CLIENT_REPO}/client/src/docker/lib/internal/lib_gen.bash" || exit 1 # Development tools -source "$(dirname "$(realpath -s $0)")/src/docker/lib/internal/dev-tools/lib_doxygen.bash" || exit 1 -source "$(dirname "$(realpath -s $0)")/src/docker/lib/internal/dev-tools/lib_license.bash" || exit 1 -source "$(dirname "$(realpath -s $0)")/src/docker/lib/internal/dev-tools/lib_linter.bash" || exit 1 +source "${DOCKER_FINANCE_CLIENT_REPO}/client/src/docker/lib/internal/dev-tools/lib_doxygen.bash" || exit 1 +source "${DOCKER_FINANCE_CLIENT_REPO}/client/src/docker/lib/internal/dev-tools/lib_license.bash" || exit 1 +source "${DOCKER_FINANCE_CLIENT_REPO}/client/src/docker/lib/internal/dev-tools/lib_linter.bash" || exit 1 # Utilities (a container library (but container is never exposed to client code)) -source "$(dirname "$(realpath -s $0)")/../container/src/finance/lib/internal/lib_utils.bash" || exit 1 +source "${DOCKER_FINANCE_CLIENT_REPO}/container/src/finance/lib/internal/lib_utils.bash" || exit 1 # # Implementation