diff --git a/client/Dockerfiles/finance/Dockerfile.archlinux.in b/client/Dockerfiles/finance/Dockerfile.archlinux.in
index a33b757..da2dd7e 100644
--- a/client/Dockerfiles/finance/Dockerfile.archlinux.in
+++ b/client/Dockerfiles/finance/Dockerfile.archlinux.in
@@ -59,14 +59,6 @@ RUN pacman -Syu \
root \
--noconfirm --disable-download-timeout
-# Optional userspace
-RUN pacman -Syu \
- calc \
- emacs-nox \
- less \
- nano \
- --noconfirm --disable-download-timeout
-
# PHP mandatory requirements
RUN sed -i \
-e 's:^;extension=bcmath:extension=bcmath:' \
@@ -108,9 +100,6 @@ WORKDIR /home/@DOCKER_FINANCE_USER@
RUN pipx install shyaml
RUN pipx install csvkit
-# Optional userspace (python / ROOT.cern custom metadata analysis)
-RUN pipx install xlsx2csv
-
# Superscript
RUN echo "source \"\${DOCKER_FINANCE_CONTAINER_CONF}/shell/superscript.bash\"" | tee -a ~/.bashrc
diff --git a/client/Dockerfiles/finance/Dockerfile.ubuntu.in b/client/Dockerfiles/finance/Dockerfile.ubuntu.in
index 9b0b493..5683077 100644
--- a/client/Dockerfiles/finance/Dockerfile.ubuntu.in
+++ b/client/Dockerfiles/finance/Dockerfile.ubuntu.in
@@ -66,13 +66,6 @@ RUN cargo install xsv --root /usr
#RUN apt install -y root
#RUN apt install -y botan libcrypto++-dev libsodium-dev googletest libbenchmark-dev
-# Optional userspace
-RUN apt install -y \
- calc \
- emacs-nox \
- mc \
- nano
-
# Give access to builder
RUN gpasswd -a builder wheel
RUN chown root:wheel /usr/local/* && chmod g+rwx /usr/local/*
@@ -101,9 +94,6 @@ WORKDIR /home/@DOCKER_FINANCE_USER@
RUN pipx install shyaml
RUN pipx install csvkit
-# Optional userspace (python)
-#RUN pipx install xlsx2csv
-
# Superscript
RUN echo "source \"\${DOCKER_FINANCE_CONTAINER_CONF}/shell/superscript.bash\"" | tee -a ~/.bash_aliases
diff --git a/client/docker-finance.d/client/Dockerfiles/dev-tools/Dockerfile.dev-tools.in b/client/docker-finance.d/client/Dockerfiles/dev-tools/Dockerfile.dev-tools.in
new file mode 100644
index 0000000..f68e032
--- /dev/null
+++ b/client/docker-finance.d/client/Dockerfiles/dev-tools/Dockerfile.dev-tools.in
@@ -0,0 +1,33 @@
+# docker-finance | modern accounting for the power-user
+#
+# Copyright (C) 2021-2024 Aaron Fiore (Founder, Evergreen Crypto LLC)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+#
+# Custom (optional) Dockerfile - appends to existing Dockerfile
+#
+
+USER root
+
+RUN apt update -y
+
+RUN apt install -y \
+ curl \
+ yq
+
+USER @DOCKER_FINANCE_USER@
+WORKDIR /home/@DOCKER_FINANCE_USER@
+
+# vim: sw=2 sts=2 si ai et
diff --git a/client/docker-finance.d/client/Dockerfiles/finance/Dockerfile.archlinux.in b/client/docker-finance.d/client/Dockerfiles/finance/Dockerfile.archlinux.in
new file mode 100644
index 0000000..ef1bd95
--- /dev/null
+++ b/client/docker-finance.d/client/Dockerfiles/finance/Dockerfile.archlinux.in
@@ -0,0 +1,44 @@
+# docker-finance | modern accounting for the power-user
+#
+# Copyright (C) 2021-2024 Aaron Fiore (Founder, Evergreen Crypto LLC)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+#
+# Custom (optional) Dockerfile - appends to existing Dockerfile
+#
+
+#
+# Optional userspace
+#
+
+USER root
+
+RUN pacman -Syu \
+ calc \
+ emacs-nox \
+ less \
+ nano \
+ --noconfirm --disable-download-timeout
+
+#
+# Optional userspace (python / ROOT.cern custom metadata analysis)
+#
+
+USER @DOCKER_FINANCE_USER@
+WORKDIR /home/@DOCKER_FINANCE_USER@
+
+RUN pipx install xlsx2csv
+
+# vim: sw=2 sts=2 si ai et
diff --git a/client/docker-finance.d/client/Dockerfiles/finance/Dockerfile.ubuntu.in b/client/docker-finance.d/client/Dockerfiles/finance/Dockerfile.ubuntu.in
new file mode 100644
index 0000000..490d1d3
--- /dev/null
+++ b/client/docker-finance.d/client/Dockerfiles/finance/Dockerfile.ubuntu.in
@@ -0,0 +1,45 @@
+# docker-finance | modern accounting for the power-user
+#
+# Copyright (C) 2021-2024 Aaron Fiore (Founder, Evergreen Crypto LLC)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+#
+# Custom (optional) Dockerfile - appends to existing Dockerfile
+#
+
+#
+# Optional userspace
+#
+
+USER root
+
+RUN apt update -y
+
+RUN apt install -y \
+ calc \
+ emacs-nox \
+ mc \
+ nano
+
+#
+# Optional userspace (python)
+#
+
+USER @DOCKER_FINANCE_USER@
+WORKDIR /home/@DOCKER_FINANCE_USER@
+
+RUN pipx install xlsx2csv
+
+# vim: sw=2 sts=2 si ai et
diff --git a/client/src/docker/docker.bash b/client/src/docker/docker.bash
index aa32242..f55eb04 100755
--- a/client/src/docker/docker.bash
+++ b/client/src/docker/docker.bash
@@ -55,7 +55,7 @@ function main()
Environment (all platforms):
gen \e[34;3mGenerate docker-finance environment\e[0m
- edit \e[34;3mEdit existing client-side configuration file [arg]\e[0m
+ edit \e[34;3mEdit existing client-side configurations\e[0m
All platforms:
diff --git a/client/src/docker/lib/internal/lib_docker.bash b/client/src/docker/lib/internal/lib_docker.bash
index 2bdee08..683ed42 100644
--- a/client/src/docker/lib/internal/lib_docker.bash
+++ b/client/src/docker/lib/internal/lib_docker.bash
@@ -53,12 +53,12 @@ fi
function lib_docker::__docker_compose()
{
[ -z "$global_env_file" ] && lib_utils::die_fatal
- [ -z "$global_dockerfile_path" ] && lib_utils::die_fatal
+ [ -z "$global_repo_dockerfiles" ] && lib_utils::die_fatal
[ ! -f "$global_env_file" ] \
&& lib_utils::die_fatal "$global_env_file not found! Run the gen command!"
- pushd "$global_dockerfile_path" 1>/dev/null \
+ pushd "$global_repo_dockerfiles" 1>/dev/null \
|| return $? \
&& docker compose -f docker-compose.yml --env-file "$global_env_file" "$@"
popd 1>/dev/null || return $?
@@ -233,7 +233,7 @@ function lib_docker::__edit()
Configuration type:
- type${global_arg_delim_2}
+ type${global_arg_delim_2}
\e[32mExamples:\e[0m
@@ -243,8 +243,11 @@ function lib_docker::__edit()
\e[37;2m# Edit client/container shell (superscript) \e[0m
$ $global_usage type${global_arg_delim_2}shell
- \e[37;2m# Edit client/container shell (w/ alternate wording) and environment variables\e[0m
- $ $global_usage type${global_arg_delim_2}superscript${global_arg_delim_3}env
+ \e[37;2m# Edit client's custom Dockerfile (appended to final Dockerfile) \e[0m
+ $ $global_usage type${global_arg_delim_2}build
+
+ \e[37;2m# Previous commands with alternate wordings\e[0m
+ $ $global_usage type${global_arg_delim_2}superscript${global_arg_delim_3}dockerfile${global_arg_delim_3}env
"
if [ $# -ne 1 ]; then
@@ -277,7 +280,7 @@ function lib_docker::__edit()
read -ra _read <<<"$_arg_type"
for _type in "${_read[@]}"; do
- if [[ ! "$_type" =~ ^env$|^shell$|^superscript$ ]]; then
+ if [[ ! "$_type" =~ ^env$|^shell$|^superscript$|^build$|^dockerfile$ ]]; then
lib_utils::die_usage "$_usage"
fi
done
@@ -312,6 +315,11 @@ function lib_docker::__edit()
_paths+=("$global_shell_file")
;;
+ build | dockerfile)
+ [ -z "$global_custom_dockerfile" ] && lib_utils::die_fatal
+
+ _paths+=("$global_custom_dockerfile")
+ ;;
esac
done
diff --git a/client/src/docker/lib/internal/lib_gen.bash b/client/src/docker/lib/internal/lib_gen.bash
index 6ba7813..1916f94 100644
--- a/client/src/docker/lib/internal/lib_gen.bash
+++ b/client/src/docker/lib/internal/lib_gen.bash
@@ -62,10 +62,28 @@ function lib_gen::gen()
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)"
+ # Custom Dockerfile (to be appended to final Dockerfile)
+ local _image
+ case "$global_platform" in
+ archlinux | ubuntu)
+ _image+="finance"
+ ;;
+ dev-tools)
+ _image+="dev-tools"
+ ;;
+ *)
+ lib_utils::die_fatal "unsupported platform"
+ ;;
+ esac
+ declare -gr global_repo_dockerfile="${global_repo_conf_dir}/client/Dockerfiles/${_image}/Dockerfile.${global_platform}.in"
+ [ ! -f "$global_repo_dockerfile" ] \
+ && lib_utils::die_fatal "Missing environment defaults! ($global_repo_dockerfile)"
+
#
# If empty environment, bootstrap with defaults
#
@@ -79,8 +97,8 @@ function lib_gen::gen()
&& lib_utils::die_fatal "Defaults not generated! (${global_repo_env_file})"
[ -z "$DOCKER_FINANCE_USER" ] && lib_utils::die_fatal
- global_env_filename="${DOCKER_FINANCE_USER}@$(uname -n)"
- declare -gr global_env_filename
+ global_conf_filename="${DOCKER_FINANCE_USER}@$(uname -n)"
+ declare -gr global_conf_filename
lib_gen::__set_client_globals
@@ -91,8 +109,8 @@ function lib_gen::gen()
[ -z "$global_platform" ] && lib_utils::die_fatal
[ -z "$global_tag" ] && lib_utils::die_fatal
- local -r _env_dir="${DOCKER_FINANCE_CLIENT_CONF}/client/env/$(uname -s)-$(uname -m)/${global_platform}/${global_tag}"
- local -r _env_file="${_env_dir}/${global_env_filename}"
+ 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}"
if [ -f "$_env_file" ]; then
if [ -s "$_env_file" ]; then
@@ -128,16 +146,21 @@ function lib_gen::__set_client_globals()
lib_utils::print_debug "Setting client globals"
# Appending all client-side conf paths
- local _client_path_tag
- _client_path_tag="$(uname -s)-$(uname -m)/${global_platform}/${global_tag}"
+ local _client_tag_path
+ _client_tag_path="${DOCKER_FINANCE_CLIENT_CONF}/client/$(uname -s)-$(uname -m)/${global_platform}/${global_tag}"
# Client-side environment file (if available)
- local _client_env_dir="${DOCKER_FINANCE_CLIENT_CONF}/client/env/${_client_path_tag}"
-
+ local _client_env_dir="${_client_tag_path}/env"
[ ! -d "$_client_env_dir" ] && mkdir -p "$_client_env_dir"
- global_env_file="${_client_env_dir}/${global_env_filename}"
+ 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"
+ [ ! -d "$_client_dockerfile_dir" ] && mkdir -p "$_client_dockerfile_dir"
+ global_custom_dockerfile="${_client_dockerfile_dir}/${global_conf_filename}"
+ lib_utils::print_debug "global_custom_dockerfile=${global_custom_dockerfile}"
+
# NOTE:
#
# Client env tag format is avoided because:
@@ -230,7 +253,11 @@ function lib_gen::__gen_client()
{
lib_utils::print_debug "Generating client"
- # Backup existing client-side environment file
+ #
+ # Client-side environment file
+ #
+
+ # Backup existing file
if [ -f "$global_env_file" ]; then
lib_utils::print_custom " \e[32m│\e[0m\n"
lib_utils::print_custom " \e[32m├─\e[34;1m Client-side environment found, backup then generate new one? [Y/n] \e[0m"
@@ -256,6 +283,38 @@ function lib_gen::__gen_client()
# Get/Set new (edited) environment variables
lib_gen::__read_env "$global_env_file"
lib_gen::__set_client_globals
+
+ #
+ # Custom (optional) Dockerfile
+ #
+
+ # Backup existing custom Dockerfile
+ if [ -f "$global_custom_dockerfile" ]; then
+ lib_utils::print_custom " \e[32m│\e[0m\n"
+ lib_utils::print_custom " \e[32m├─\e[34;1m Custom (optional) Dockerfile found, backup then generate new one? [Y/n] \e[0m"
+
+ read -p "" _read
+ local _confirm="${_read:-y}"
+ if [[ "$_confirm" == [yY] ]]; then
+ cp -a "$global_custom_dockerfile" "${global_custom_dockerfile}_${global_suffix}" \
+ || lib_utils::die_fatal
+ fi
+ else
+ lib_utils::print_custom " \e[32m│\e[0m\n"
+ lib_utils::print_custom " \e[32m├─\e[34;1m Generating new custom (optional) Dockerfile\e[0m\n"
+
+ if [ ! -f "$global_custom_dockerfile" ]; then
+ lib_utils::print_debug "$global_repo_dockerfile"
+ lib_utils::print_debug "$global_custom_dockerfile"
+
+ cp -a "$global_repo_dockerfile" "$global_custom_dockerfile"
+ fi
+ fi
+
+ lib_utils::print_custom " \e[32m│ └─\e[34m Edit (new) custom Dockerfile now? [Y/n] \e[0m"
+ read -p "" _read
+ local _confirm="${_read:-y}"
+ [[ "$_confirm" == [yY] ]] && $EDITOR "$global_custom_dockerfile"
}
function lib_gen::__gen_container()
diff --git a/client/src/docker/lib/lib_docker.bash b/client/src/docker/lib/lib_docker.bash
index 08dfc1a..52616bd 100644
--- a/client/src/docker/lib/lib_docker.bash
+++ b/client/src/docker/lib/lib_docker.bash
@@ -109,15 +109,18 @@ function lib_docker::docker()
# Setup remaining client/container globals
lib_gen::gen || return $?
+ # TODO: all following docker related should be internal
+
+ # Docker-related files
[ -z "$global_repo_client" ] && lib_utils::die_fatal
- declare -g global_dockerfile_path="${global_repo_client}/Dockerfiles/"
+ declare -g global_repo_dockerfiles="${global_repo_client}/Dockerfiles/"
case "$global_platform" in
archlinux | ubuntu)
- global_dockerfile_path+="finance"
+ global_repo_dockerfiles+="finance"
;;
dev-tools)
- global_dockerfile_path+="dev-tools"
+ global_repo_dockerfiles+="dev-tools"
;;
*)
lib_utils::die_fatal "platform was not previously checked"
@@ -131,7 +134,7 @@ function lib_docker::docker()
[ -z "$global_env_file" ] && lib_utils::die_fatal
[ -z "$global_shell_file" ] && lib_utils::die_fatal
- local _path="${global_dockerfile_path}/docker-compose.yml"
+ local _path="${global_repo_dockerfiles}/docker-compose.yml"
lib_utils::print_debug "Generating '${_path}'"
sed \
@@ -148,7 +151,7 @@ function lib_docker::docker()
[ -z "$DOCKER_FINANCE_GID" ] && lib_utils::die_fatal
[ -z "$DOCKER_FINANCE_USER" ] && lib_utils::die_fatal
- local _path="${global_dockerfile_path}/Dockerfile"
+ local _path="${global_repo_dockerfiles}/Dockerfile"
lib_utils::print_debug "Generating '${_path}'"
sed \
@@ -157,6 +160,19 @@ function lib_docker::docker()
-e "s:@DOCKER_FINANCE_USER@:${DOCKER_FINANCE_USER}:g" \
"${_path}.${global_platform}.in" >"$_path" || return $?
+ # Append end-user's custom Dockerfile to final Dockerfile
+ [ -z "$global_custom_dockerfile" ] && lib_utils::die_fatal
+
+ if [[ ! -f "$global_custom_dockerfile" ]]; then
+ lib_utils::print_debug "'${global_custom_dockerfile}' not found, skipping"
+ return 0
+ fi
+
+ lib_utils::print_debug "Appending '${global_custom_dockerfile}' to '${_path}'"
+ sed \
+ -e "s:@DOCKER_FINANCE_USER@:${DOCKER_FINANCE_USER}:g" \
+ "$global_custom_dockerfile" >>"$_path" || return $?
+
return 0
}