refactor: major overhaul and cleanup of the build environment

- Removed `.env.sample` and improved `.env` handling
- Deleted `translate.py` and replaced it with `translate-md.py`
- Refactored `readme.yml` to enhance translation and tagging workflow
- Updated `.gitignore` with new exclusions
- Major restructuring of `Dockerfile`, including improved ENV variables and layout
- Extended `create-env.sh` with interactive prompts and validation
- Improved error handling and structure in `docker-compose-wrapper`
- Expanded `docker-compose.yml` with new environment variables and network settings
- Moved and updated `init.sh`, `.bashrc`, and other files to `files/` directory
- Added new scripts: `show-env.sh` for better diagnostics and `terminal-splash.txt` for enhanced display

These changes optimize the build environment for improved stability and flexibility.
This commit is contained in:
2025-02-11 18:20:58 +01:00
parent f823e7e8ee
commit 7ab5a410d3
12 changed files with 818 additions and 371 deletions

View File

@@ -1,106 +1,330 @@
#!/bin/bash
#!/usr/bin/env bash
#
# create_env.sh - Automatically create the .env file for Docker Compose
# Creates a .env file with user and system settings.
# If a .env file already exists, the user is asked
# if a backup should be created and the file overwritten.
# Path to.env-Datei
set -e # Stop on error
# Prints an error message and exits
function error_exit {
echo "$1" >&2
exit 1
}
# ------------------------------------------------------------------------------
# Global constants
# ------------------------------------------------------------------------------
ENV_FILE=".env"
BACKUP_DIR="env_backups"
EXIT_USER_CANCEL=70
BUILDENV_VERSION="3.2.4"
TB_VERSION="latest"
TB_BUILD_TIME=$(date '+%Y-%m-%d %H:%M:%S')
USER=$(whoami)
USER_ID=$(id -u)
USER_GROUP_ID=$(id -g)
USER_DIR="${HOME}"
HOST_PREFIX=tuxbox
BUILDENV_PREFIX="buildenv"
LOCAL_HOSTNAME=$(hostname)
ENABLE_UI_TOOLS="false"
USER_VOLUME_BINDIR="${USER_DIR}/bin"
USER_VOLUME_WORKDIR="${USER_DIR}/${HOST_PREFIX}"
USER_VOLUME_WORKBINDIR="${USER_VOLUME_WORKDIR}/bin"
# ------------------------------------------------------------------------------
# Prompt functions
# ------------------------------------------------------------------------------
# Prompt the user with a message and default value
function prompt {
local PROMPT_MESSAGE=$1
local DEFAULT_VALUE=$2
local PAD_WIDTH=${3:-20}
# Build the prompt with color logic
local PROMPT_WITH_COLOR
PROMPT_WITH_COLOR=$(prompt_color "$PROMPT_MESSAGE" "$DEFAULT_VALUE" "$PAD_WIDTH")
# Read user input and use default if empty
read -p "$(echo -e "$PROMPT_WITH_COLOR")" INPUT
INPUT="${INPUT:-$DEFAULT_VALUE}"
echo "$INPUT"
}
# Return a color-coded prompt based on whether the current default deviates from the original default
function prompt_color {
local PROMPT_MESSAGE=$1
local DEFAULT_VALUE=$2
local PAD_WIDTH=${3:-20}
local GREEN="\033[0;32m"
local YELLOW="\033[0;33m"
local RESET="\033[0m"
# Retrieve the original value from a variable named ORIG_<PROMPT_MESSAGE>
local ORIG_VAR="ORIG_${PROMPT_MESSAGE}"
local ORIG_VALUE="${!ORIG_VAR}"
local COLOR="$GREEN"
if [[ -n "$ORIG_VALUE" && "$DEFAULT_VALUE" != "$ORIG_VALUE" ]]; then
COLOR="$YELLOW"
fi
local ADJUSTED_WIDTH=$((PAD_WIDTH + 3))
local PROMPT_WITH_COLOR
PROMPT_WITH_COLOR=$(printf "%-*s %s%s%s: " \
$ADJUSTED_WIDTH \
"$PROMPT_MESSAGE" \
"$COLOR" \
"$DEFAULT_VALUE" \
"$RESET")
echo "$PROMPT_WITH_COLOR"
}
# Prompt for mandatory input (e.g. passwords), input is hidden
function prompt_mandatory {
local PROMPT_MESSAGE=$1
local PAD_WIDTH=${2:-20}
local INPUT=""
while [ -z "$INPUT" ]; do
local PROMPT_WITH_COLOR
PROMPT_WITH_COLOR=$(printf "%-*s: " $PAD_WIDTH "$PROMPT_MESSAGE")
read -s -p "$(echo -e "$PROMPT_WITH_COLOR")" INPUT
echo # newline after hidden input
if [ -z "$INPUT" ]; then
echo "The field $PROMPT_MESSAGE may not be empty. Please enter again."
fi
done
echo "$INPUT"
}
# Prompt the user with specific options and return the response in lowercase
function prompt_user() {
local prompt_message="$1"
local options="$2"
local default_response="$3"
read -p "$prompt_message ($options): " RESPONSE
RESPONSE=${RESPONSE,,} # Convert to lowercase
echo "${RESPONSE:-$default_response}"
}
# ------------------------------------------------------------------------------
# Function to edit an existing .env file (create a backup and load its values)
# ------------------------------------------------------------------------------
function edit_env_file() {
# Create backup
mkdir -p "$BACKUP_DIR"
local TIMESTAMP
TIMESTAMP=$(date +"%Y%m%d-%H%M%S")
local BACKUP_FILE="${BACKUP_DIR}/.env.backup-${TIMESTAMP}"
cp "$ENV_FILE" "$BACKUP_FILE" || error_exit "Error creating backup copy."
echo "Backup copy created under $BACKUP_FILE."
# Read existing .env and export variables
echo "Reading existing .env to use its values as defaults..."
while IFS='=' read -r key value || [[ -n "$key" ]]; do
# Skip empty lines and comments
[[ -z "$key" || "$key" =~ ^# ]] && continue
# Remove surrounding quotes if any
value=${value#\"}
value=${value%\"}
value=${value#\'}
value=${value%\'}
export "$key=$value"
done < "$ENV_FILE"
}
# ------------------------------------------------------------------------------
# Function to handle user cancellation
# ------------------------------------------------------------------------------
function cancel_operation() {
echo "Operation cancelled by user."
exit "$EXIT_USER_CANCEL"
}
# ------------------------------------------------------------------------------
# Main Logic
# ------------------------------------------------------------------------------
if [ -f "$ENV_FILE" ]; then
RESPONSE=$(prompt_user "Edit: ${ENV_FILE} type <e> | Hold: type <enter> or <u> | Cancel: type <c>" "Edit/Use/Cancel" "use")
case "$RESPONSE" in
edit|e)
edit_env_file
;;
use|u)
echo "Existing ${ENV_FILE} file will be used (unchanged)."
exit 0
;;
cancel|c)
cancel_operation
;;
*)
echo "Unknown input - existing ${ENV_FILE} will be used (unchanged)."
exit 0
;;
esac
else
echo "No ${ENV_FILE} file found."
RESPONSE=$(prompt_user "Create new: ${ENV_FILE} type <e> | Cancel: type <c>" "Edit/Cancel" "edit")
case "$RESPONSE" in
edit|e)
echo "Proceeding to create a new ${ENV_FILE} file..."
;;
cancel|c)
cancel_operation
;;
*)
echo "Unknown input - proceeding to create a new ${ENV_FILE} file."
;;
esac
fi
# ------------------------------------------------------------------------------
# Internal use: Retrieve git info
# ------------------------------------------------------------------------------
DOCKER_BUILDENV_GIT_URL="$(git config --get remote.origin.url)"
DOCKER_BUILDENV_VERSION="$(git -C "$(pwd)" describe --tags --long | sed -e 's/-g[0-9a-f]\{7,\}$//' -e 's/-\([0-9]\+\)$/.\1/')"
# ------------------------------------------------------------------------------
# Original defaults used for prompts (for color comparison and fallback)
# ------------------------------------------------------------------------------
ORIG_USER_NAME="$(whoami)"
ORIG_USER_ID="$(id -u)"
ORIG_USER_GROUP="$(id -gn)"
ORIG_USER_GROUP_ID="$(id -g)"
ORIG_DEFAULT_PASSWORD="tuxpwd"
if command -v git &>/dev/null; then
ORIG_GIT_EMAIL=$(git config --global user.email || true)
ORIG_GIT_USER=$(git config --global user.name || true)
fi
ORIG_GIT_EMAIL=${ORIG_GIT_EMAIL:-"${USER}@${HOSTNAME}"}
ORIG_GIT_USER=${ORIG_GIT_USER:-$(getent passwd "${USER}" | cut -d: -f5 | cut -d, -f1)}
ORIG_BUILDENV_GIT_URL="https://github.com/tuxbox-neutrino/buildenv.git"
ORIG_BUILDENV_PREFIX="buildenv"
# Additional defaults
ORIG_DISPLAY="${DISPLAY:-:0}"
ORIG_ENABLE_UI_TOOLS="false"
ORIG_BUILDENV_INSTALL_PREFIX="tuxbox"
ORIG_LOCAL_HOSTNAME="${HOSTNAME}"
ORIG_LOCALE_LANG="${LANG:-en_US.UTF-8}"
ORIG_TZ="$(cat /etc/timezone 2>/dev/null || echo 'UTC')"
ORIG_TERM="${TERM:-xterm}"
ORIG_NVIDIA_VISIBLE_DEVICES="all"
ORIG_QT_QUICK_BACKEND="software"
ORIG_QT_XCB_GL_INTEGRATION="xcb_egl"
ORIG_USER_DIR="${HOME}"
ORIG_EXPLORER_ENABLE="false"
ORIG_EXPLORER_GIT_URL="https://github.com/dbt1/tuxbox-explorer.git"
ORIG_XDG_CONFIG_HOME="${ORIG_USER_DIR}/.config"
ORIG_XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR}"
# ------------------------------------------------------------------------------
# Prompt the user for various settings using defaults (either from existing .env or original)
# ------------------------------------------------------------------------------
echo -e "Global user data"
USER_NAME=$(prompt "USER_NAME" "${USER_NAME:-$ORIG_USER_NAME}")
USER_DIR=$(prompt "USER_DIR" "${USER_DIR:-$ORIG_USER_DIR}")
USER_ID=$(prompt "USER_ID" "${USER_ID:-$ORIG_USER_ID}")
USER_GROUP=$(prompt "USER_GROUP" "${USER_GROUP:-$ORIG_USER_GROUP}")
USER_GROUP_ID=$(prompt "USER_GROUP_ID" "${USER_GROUP_ID:-$ORIG_USER_GROUP_ID}")
echo -e ""
echo -e "Set or use this default user password, NOTE: Please change it if you run the container at first time!"
USER_PASSWORD=$(prompt "USER_PASSWORD" "${USER_PASSWORD:-$ORIG_DEFAULT_PASSWORD}")
# Alternatively, you could use prompt_mandatory for hidden password input:
# USER_PASSWORD=$(prompt_mandatory "USER_PASSWORD" 20)
echo -e ""
echo -e "Add some default git user data."
GIT_EMAIL=$(prompt "GIT_EMAIL" "${GIT_EMAIL:-$ORIG_GIT_EMAIL}")
GIT_USER=$(prompt "GIT_USER" "${GIT_USER:-$ORIG_GIT_USER}")
echo -e ""
echo -e "Clone URL for buildenv sources."
BUILDENV_GIT_URL=$(prompt "BUILDENV_GIT_URL" "${BUILDENV_GIT_URL:-$ORIG_BUILDENV_GIT_URL}")
echo -e ""
echo -e "htdoc content for file explorer, allows userfriendly navigation through deploed results"
EXPLORER_ENABLE=$(prompt "EXPLORER_ENABLE" "${EXPLORER_ENABLE:-$ORIG_EXPLORER_ENABLE}")
EXPLORER_GIT_URL=$(prompt "EXPLORER_GIT_URL" "${EXPLORER_GIT_URL:-$ORIG_EXPLORER_GIT_URL}")
echo -e ""
echo -e "Prefix where to install all buildenv stuff within user dir (default: $ORIG_BUILDENV_INSTALL_PREFIX)"
BUILDENV_INSTALL_PREFIX=$(prompt "BUILDENV_INSTALL_PREFIX" "${BUILDENV_INSTALL_PREFIX:-$ORIG_BUILDENV_INSTALL_PREFIX}")
echo -e ""
echo -e "Prefix for buildenv sources (default: $ORIG_BUILDENV_PREFIX)"
BUILDENV_PREFIX=$(prompt "BUILDENV_PREFIX" "${BUILDENV_PREFIX:-$ORIG_BUILDENV_PREFIX}")
echo -e ""
echo -e "UI-related settings."
DISPLAY=$(prompt "DISPLAY" "${DISPLAY:-$ORIG_DISPLAY}")
ENABLE_UI_TOOLS=$(prompt "ENABLE_UI_TOOLS" "${ENABLE_UI_TOOLS:-$ORIG_ENABLE_UI_TOOLS}")
NVIDIA_VISIBLE_DEVICES=$(prompt "NVIDIA_VISIBLE_DEVICES" "${NVIDIA_VISIBLE_DEVICES:-$ORIG_NVIDIA_VISIBLE_DEVICES}")
QT_QUICK_BACKEND=$(prompt "QT_QUICK_BACKEND" "${QT_QUICK_BACKEND:-$ORIG_QT_QUICK_BACKEND}")
QT_XCB_GL_INTEGRATION=$(prompt "QT_XCB_GL_INTEGRATION" "${QT_XCB_GL_INTEGRATION:-$ORIG_QT_XCB_GL_INTEGRATION}")
echo -e ""
echo -e "System variables."
LOCAL_HOSTNAME=$(prompt "LOCAL_HOSTNAME" "${LOCAL_HOSTNAME:-$ORIG_LOCAL_HOSTNAME}")
LOCALE_LANG=$(prompt "LOCALE_LANG" "${LOCALE_LANG:-$ORIG_LOCALE_LANG}")
TZ=$(prompt "TZ" "${TZ:-$ORIG_TZ}")
TERM=$(prompt "TERM" "${TERM:-$ORIG_TERM}")
XDG_CONFIG_HOME=$(prompt "XDG_CONFIG_HOME" "${XDG_CONFIG_HOME:-$ORIG_XDG_CONFIG_HOME}")
XDG_RUNTIME_DIR=$(prompt "XDG_RUNTIME_DIR" "${XDG_RUNTIME_DIR:-$ORIG_XDG_RUNTIME_DIR}")
# Derived variables based on the above
USER_VOLUME_WORKDIR="${USER_DIR}/${BUILDENV_INSTALL_PREFIX}"
USER_VOLUME_DATADIR="${USER_VOLUME_WORKDIR}/.data"
USER_VOLUME_BINDIR="${USER_DIR}/bin"
START_PATH="${USER_VOLUME_WORKDIR}/${BUILDENV_PREFIX}"
WWW_DOCDIR="${USER_VOLUME_WORKDIR}/htdoc"
# Setup history file location
HISTFILE_NAME=".bash_history"
HISTFILE="${USER_VOLUME_DATADIR}/${HISTFILE_NAME}"
# Set default values for GIT_EMAIL, GIT_USER
GIT_EMAIL="${USER}@${HOSTNAME}"
GIT_USER="$(grep "${USER}" /etc/passwd | cut -d: -f5 | sed 's/,//g')"
# ------------------------------------------------------------------------------
# Write the final .env file
# ------------------------------------------------------------------------------
cat <<EOF > "$ENV_FILE"
# Auto-generated $ENV_FILE file for docker-buildenv
# Do not change manually! Run $0 to generate $ENV_FILE!
# Check if git is installed
if git --version &>/dev/null; then
# Git is installed, try to get global values
GLOBAL_EMAIL=$(git config --global user.email)
if [ -z "$GLOBAL_EMAIL" ]; then
GLOBAL_EMAIL=$GIT_EMAIL
fi
GLOBAL_USER=$(git config --global user.name)
if [ -z "$GLOBAL_USER" ]; then
GLOBAL_USER=$GIT_USER
fi
# Check if inside a Git repository
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
# Try to get local values if globals are not set
[ -z "$GLOBAL_EMAIL" ] && GIT_EMAIL=$(git config --local user.email) || GIT_EMAIL=$GLOBAL_EMAIL
[ -z "$GLOBAL_USER" ] && GIT_USER=$(git config --local user.name) || GIT_USER=$GLOBAL_USER
DOCKER_BUILDENV_GIT_URL=${DOCKER_BUILDENV_GIT_URL}
DOCKER_BUILDENV_VERSION=${DOCKER_BUILDENV_VERSION}
# Get version info
last_tag=$(git describe --tags --abbrev=0 2>/dev/null)
last_commit_id=$(git rev-parse --short HEAD)
current_branch=$(git rev-parse --abbrev-ref HEAD)
if [ -z "$last_tag" ]; then
commit_count=$(git rev-list --count HEAD)
TB_VERSION="git+${commit_count}-${last_commit_id}-${current_branch}"
else
commit_count=$(git rev-list --count ${last_tag}..HEAD)
TB_VERSION="${last_tag}.${commit_count}-${current_branch}"
fi
else
# Not inside a Git repo, use global values if available
GIT_EMAIL=${GLOBAL_EMAIL:-$GIT_EMAIL}
GIT_USER=${GLOBAL_USER:-$GIT_USER}
fi
else
echo "Git is not installed, using default values."
fi
# Create environment variables and write into .env
cat <<EOF >$ENV_FILE
BUILDENV_GIT_URL=https://github.com/tuxbox-neutrino/buildenv.git
BUILDENV_VERSION=${BUILDENV_VERSION}
BUILDENV_GIT_URL=${BUILDENV_GIT_URL}
BUILDENV_PREFIX=${BUILDENV_PREFIX}
TB_BUILD_TIME=${TB_BUILD_TIME}
USER_NAME=${USER_NAME}
USER_ID=${USER_ID}
USER_GROUP=${USER_GROUP}
USER_GROUP_ID=${USER_GROUP_ID}
USER_PASSWORD=${USER_PASSWORD}
DISPLAY=${DISPLAY}
ENABLE_UI_TOOLS=${ENABLE_UI_TOOLS}
GIT_EMAIL=${GIT_EMAIL}
GIT_USER=${GIT_USER}
HISTFILE=${HISTFILE}
HISTFILE_NAME=${HISTFILE_NAME}
HOST_PREFIX=${HOST_PREFIX}
LANGUAGE=${LANG}
LC_ALL=${LANG}
LOCALE_LANG=${LANG}
HISTFILE=${HISTFILE}
BUILDENV_INSTALL_PREFIX=${BUILDENV_INSTALL_PREFIX}
LOCAL_HOSTNAME=${LOCAL_HOSTNAME}
NVIDIA_VISIBLE_DEVICES=all
QT_QUICK_BACKEND=software
QT_XCB_GL_INTEGRATION=xcb_egl
START_PATH=${USER_VOLUME_WORKDIR}/${BUILDENV_PREFIX}
LOCALE_LANG=${LOCALE_LANG}
TZ=${TZ}
TERM=${TERM}
TZ=$(cat /etc/timezone)
USER=${USER}
NVIDIA_VISIBLE_DEVICES=${NVIDIA_VISIBLE_DEVICES}
QT_QUICK_BACKEND=${QT_QUICK_BACKEND}
QT_XCB_GL_INTEGRATION=${QT_XCB_GL_INTEGRATION}
USER_DIR=${USER_DIR}
USER_GROUP=${USER}
USER_GROUP_ID=${USER_GROUP_ID}
USER_ID=${USER_ID}
USER_PASSWORD=${USER}
USER_VOLUME_WORKDIR=${USER_VOLUME_WORKDIR}
USER_VOLUME_DATADIR=${USER_VOLUME_DATADIR}
USER_VOLUME_BINDIR=${USER_VOLUME_BINDIR}
USER_VOLUME_WORKBINDIR=${USER_VOLUME_WORKBINDIR}
TB_VERSION=${TB_VERSION}
XDG_CONFIG_HOME=/home
XDG_RUNTIME_DIR=/tmp/runtime-root
START_PATH=${START_PATH}
WWW_DOCDIR=${WWW_DOCDIR}
EXPLORER_ENABLE=${EXPLORER_ENABLE}
EXPLORER_GIT_URL=${EXPLORER_GIT_URL}
XDG_CONFIG_HOME=${XDG_CONFIG_HOME}
XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR}
EOF
# validate
echo ".env-file successfully created with:"
cat $ENV_FILE
echo -e ""
echo -e "$ENV_FILE file was successfully created (or overwritten)."