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,33 +0,0 @@
BUILDENV_GIT_URL=https://github.com/tuxbox-neutrino/buildenv.git
BUILDENV_VERSION=3.2.4
BUILDENV_PREFIX=buildenv
TB_BUILD_TIME=
DISPLAY=:0
ENABLE_UI_TOOLS=false
GIT_EMAIL=${USER}@localhost
GIT_USER=${USER}
HISTFILE=/home/${USER}/tuxbox/.data/.bash_history
HISTFILE_NAME=.bash_history
HOST_PREFIX=tuxbox
LANGUAGE=de_DE.UTF-8
LC_ALL=de_DE.UTF-8
LOCALE_LANG=de_DE.UTF-8
LOCAL_HOSTNAME=localhost
NVIDIA_VISIBLE_DEVICES=all
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
QT_QUICK_BACKEND=software
QT_XCB_GL_INTEGRATION=xcb_egl
START_PATH=/home/${USER}/tuxbox/buildenv
TERM=xterm-256color
TZ=Europe/Berlin
USER=${USER}
USER_DIR=/home/${USER}
USER_GROUP=${USER}
USER_GROUP_ID=1000
USER_ID=1000
USER_PASSWORD=${USER}
USER_VOLUME_WORKDIR=/home/${USER}/tuxbox
USER_VOLUME_DATADIR=/home/${USER}/tuxbox/.data
TB_VERSION=
XDG_CONFIG_HOME=/home
XDG_RUNTIME_DIR=/tmp/runtime-root

View File

@@ -1,25 +0,0 @@
from googletrans import Translator
def translate_readme(input_text, target_lang):
translator = Translator()
translated = translator.translate(input_text, dest=target_lang)
translated_text = translated.text
# add hint for automatically translation
translated_text = f"Note: This is an automatically translated file. Original content from [here](https://github.com/tuxbox-neutrino/docker-buildenv/blob/master/README-de.md):\n\n{translated_text}"
# Use this workaround, because translater breaks some links and anchors
translated_text = translated_text.replace("[Build Image](#Build Image)", "[Build Image](#build-image)")
translated_text = translated_text.replace("devtool -reference.html", "devtool-reference.html")
translated_text = translated_text.replace("dev-manual -common-tasks.html", "dev-manual-common-tasks.html")
translated_text = translated_text.replace("Clone #1-Init-Script", "#1-clone-init-script")
return translated_text
if __name__ == "__main__":
input_text = open("README-de.md", "r").read()
target_lang = "en" # target language is english
translated_text = translate_readme(input_text, target_lang)
with open("README-en.md", "w") as outfile:
outfile.write(translated_text)

View File

@@ -1,11 +1,17 @@
name: Translate README name: Translate README and tag repository
on: on:
push: push:
branches: branches:
- master - master
paths: paths:
- 'README-de.md' - 'README_de.md'
- 'create-env.sh'
- 'docker-compose-wrapper'
- 'docker-compose.yml'
- 'Dockerfile'
paths-ignore:
- '.github/**'
permissions: permissions:
contents: write contents: write
@@ -16,27 +22,66 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v2 uses: actions/setup-python@v3
with: with:
python-version: 3.x python-version: 3.x
- name: Install dependencies - name: Install translate dependencies
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install --upgrade googletrans==3.1.0a0 pip install --upgrade googletrans==3.1.0a0
curl -o translate-md.py https://raw.githubusercontent.com/dbt1/translate-md/refs/heads/master/translate-md.py
chmod 755 translate-md.py
curl -o translate-md-config.json https://raw.githubusercontent.com/dbt1/translate-md/refs/heads/master/translate-md-config.json.sample
- name: Verify translate-md.py download
run: |
if [ ! -f translate-md.py ]; then
echo "translate-md.py was not downloaded!"
exit 1
fi
- name: Translate README - name: Translate README
run: | run: |
python .github/scripts/translate.py cp README_de.md template.md
python translate-md.py --template-md template.md --output-dir . --prefix README_ --main-doc README.md -c translate-md-config.json -s de
rm template.md
- name: Prepare Git user data
run: |
git config --global user.email "dbt@novatux.de"
git config --global user.name "Thilo Graf"
- name: Commit and push translated README - name: Commit and push translated README
run: | run: |
git config --global user.email "actions@github.com" git add README*.md
git config --global user.name "GitHub Actions"
git add README-en.md
git commit -m "readme: Automatically translated README" git commit -m "readme: Automatically translated README"
git push git push
- name: Install tagit dependencies
run: |
pip install GitPython
curl -o tagit.py https://raw.githubusercontent.com/dbt1/tagit/master/tagit.py
curl -o tagit-config.json https://raw.githubusercontent.com/dbt1/tagit/master/tagit-config.json
chmod +x tagit.py
- name: Verify tagit.py download
run: |
if [ ! -f tagit.py ]; then
echo "tagit.py was not downloaded!"
exit 1
fi
- name: Tagging
run: |
python tagit.py -f Makefile
- name: Commit and push version and tag changes
run: |
git add Makefile
git commit -m "tagging: Automatically updated tags [skip ci]" || echo "No changes to commit"
git push
git push --tags

3
.gitignore vendored
View File

@@ -3,5 +3,6 @@
.gitconfig .gitconfig
.directory .directory
init.sh
*-swp *-swp
env_backups

View File

@@ -1,196 +1,174 @@
## Use the official Debian 11 image based up debian:bullseye-slim as a base # Dockerfile for Debian-based Tuxbox build environment
FROM dbt1/debian-tuxbox-base:v1.6 FROM dbt1/debian-tuxbox-base:v1.6
### Args ## Build arguments from docker-compose ##
ARG PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Internal information
ARG DOCKER_BUILDENV_VERSION=${DOCKER_BUILDENV_VERSION}
ARG DOCKER_BUILDENV_GIT_URL=$DOCKER_BUILDENV_GIT_URL
# URL to buildenv sources and where to install
ARG BUILDENV_GIT_URL=${BUILDENV_GIT_URL} ARG BUILDENV_GIT_URL=${BUILDENV_GIT_URL}
ARG BUILDENV_VERSION=${BUILDENV_VERSION}
ARG BUILDENV_PREFIX=${BUILDENV_PREFIX} ARG BUILDENV_PREFIX=${BUILDENV_PREFIX}
ARG TB_BUILD_TIME=${TB_BUILD_TIME}
# User and group
ARG USER_NAME=${USER_NAME}
ARG USER_ID=${USER_ID}
ARG USER_GROUP=${USER_GROUP}
ARG USER_GROUP_ID=${USER_GROUP_ID}
ARG USER_PASSWORD=${USER_PASSWORD}
ARG USER_DIR=${USER_DIR}
# More build args
ARG DISPLAY=${DISPLAY} ARG DISPLAY=${DISPLAY}
ARG ENABLE_UI_TOOLS=false ARG ENABLE_UI_TOOLS=${ENABLE_UI_TOOLS}
ARG GIT_EMAIL=${GIT_EMAIL} ARG GIT_EMAIL=${GIT_EMAIL}
ARG GIT_USER=${GIT_USER} ARG GIT_USER=${GIT_USER}
ARG USER_GROUP_ID=${USER_GROUP_ID} ARG HISTFILE_NAME=${HISTFILE_NAME}
ARG HISTFILE=${HISTFILE} ARG HISTFILE=${HISTFILE}
ARG HOST_PREFIX=${HOST_PREFIX} ARG BUILDENV_INSTALL_PREFIX=${BUILDENV_INSTALL_PREFIX}
ARG LOCALE_LANG=${LOCALE_LANG}
ARG LOCAL_HOSTNAME=${LOCAL_HOSTNAME} ARG LOCAL_HOSTNAME=${LOCAL_HOSTNAME}
ARG LOCALE_LANG=${LOCALE_LANG}
ARG TZ=${TZ}
ARG TERM=${TERM}
ARG NVIDIA_VISIBLE_DEVICES=${NVIDIA_VISIBLE_DEVICES} ARG NVIDIA_VISIBLE_DEVICES=${NVIDIA_VISIBLE_DEVICES}
ARG QT_QUICK_BACKEND=${QT_QUICK_BACKEND} ARG QT_QUICK_BACKEND=${QT_QUICK_BACKEND}
ARG QT_XCB_GL_INTEGRATION=${QT_XCB_GL_INTEGRATION} ARG QT_XCB_GL_INTEGRATION=${QT_XCB_GL_INTEGRATION}
ARG USER_VOLUME_WORKDIR=${USER_VOLUME_WORKDIR}
ARG USER_VOLUME_DATADIR=${USER_VOLUME_DATADIR}
ARG START_PATH=${START_PATH} ARG START_PATH=${START_PATH}
ARG TERM=${TERM} ARG WWW_DOCDIR=${WWW_DOCDIR}
ARG TZ=${TZ} ARG EXPLORER_ENABLE=${EXPLORER_ENABLE}
ARG USER=${USER} ARG EXPLORER_GIT_URL=${EXPLORER_GIT_URL}
ARG USER_DIR=${USER_DIR}
ARG USER_GROUP=${USER_GROUP}
ARG USER_ID=${USER_ID}
ARG USER_PASSWORD=${USER_PASSWORD}
ARG USER_VOLUME_WORKDIR=${USER_DIR}/${HOST_PREFIX}
ARG TB_VERSION=${TB_VERSION}
ARG XDG_CONFIG_HOME=${XDG_CONFIG_HOME} ARG XDG_CONFIG_HOME=${XDG_CONFIG_HOME}
ARG XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR} ARG XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR}
## Add the user with default password # Convert ARG to ENV for runtime usage
ENV DOCKER_BUILDENV_VERSION=${DOCKER_BUILDENV_VERSION}
ENV DISPLAY=${DISPLAY}
ENV DOCKER_BUILDENV_GIT_URL=$DOCKER_BUILDENV_GIT_URL
ENV BUILDENV_GIT_URL=$BUILDENV_GIT_URL
ENV ENABLE_UI_TOOLS=${ENABLE_UI_TOOLS}
ENV GIT_EMAIL=${GIT_EMAIL}
ENV GIT_USER=${GIT_USER}
ENV HISTFILE_NAME=${HISTFILE_NAME}
ENV HISTFILE=${HISTFILE}
ENV BUILDENV_INSTALL_PREFIX=${BUILDENV_INSTALL_PREFIX}
ENV LOCAL_HOSTNAME=${LOCAL_HOSTNAME}
ENV LOCALE_LANG=${LOCALE_LANG}
ENV TZ=${TZ}
ENV TERM=${TERM}
ENV NVIDIA_VISIBLE_DEVICES=${NVIDIA_VISIBLE_DEVICES}
ENV QT_QUICK_BACKEND=${QT_QUICK_BACKEND}
ENV QT_XCB_GL_INTEGRATION=${QT_XCB_GL_INTEGRATION}
ENV USER=${USER_NAME}
ENV USER_ID=${USER_ID}
ENV USER_GROUP=${USER_GROUP}
ENV USER_GROUP_ID=${USER_GROUP_ID}
ENV USER_PASSWORD=${USER_PASSWORD}
ENV USER_DIR=${USER_DIR}
ENV USER_VOLUME_WORKDIR=${USER_VOLUME_WORKDIR}
ENV USER_VOLUME_DATADIR=${USER_VOLUME_DATADIR}
ENV START_PATH=${START_PATH}
ENV WWW_DOCDIR=${WWW_DOCDIR}
ENV EXPLORER_ENABLE=${EXPLORER_ENABLE}
ENV EXPLORER_GIT_URL=${EXPLORER_GIT_URL}
ENV XDG_CONFIG_HOME=${XDG_CONFIG_HOME}
ENV XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR}
# Create user and group
RUN groupadd -g "${USER_GROUP_ID}" "${USER_GROUP}" && \ RUN groupadd -g "${USER_GROUP_ID}" "${USER_GROUP}" && \
useradd -m -u "${USER_ID}" -g "${USER_GROUP_ID}" -s /bin/bash "${USER}" && \ useradd -m -u "${USER_ID}" -g "${USER_GROUP_ID}" -s /bin/bash "${USER}" && \
echo "${USER}:${USER_PASSWORD}" | chpasswd echo "${USER}:${USER_PASSWORD}" | chpasswd
## Set the desired Locale # Set Locale
RUN locale-gen ${LOCALE_LANG} && \ RUN sed -i "/${LOCALE_LANG}/s/^# //g" /etc/locale.gen && \
dpkg-reconfigure --frontend=noninteractive locales && \ locale-gen ${LOCALE_LANG} && \
update-locale LANG=${LOCALE_LANG} update-locale LANG="${LOCALE_LANG}"
### Some labels # Install UI tools (if enabled)
LABEL maintainer="Thilo Graf <dbt@novatux.de>" \ RUN if [ "${ENABLE_UI_TOOLS}" = "true" ]; then \
maintainer.org="tuxbox-neutrino" \
maintainer.org.uri="https://tuxbox-neutrino.org" \
com.tuxbox-neutrino.project.repo.type="git" \
com.tuxbox-neutrino.project.repo.uri="https://github.com/dbt1/docker-tuxbox-build" \
com.tuxbox-neutrino.project.repo.issues="https://github.com/dbt1/docker-tuxbox-build/issues" \
com.tuxbox-neutrino.app.docker-tuxbox-build.version="${TB_VERSION}" \
# Open container labels
org.opencontainers.image.created="${TB_BUILD_TIME}" \
org.opencontainers.image.description="Debian based" \
org.opencontainers.image.vendor="tuxbox-neutrino" \
org.opencontainers.image.source="https://github.com/dbt1/docker-tuxbox-build" \
# Artifact hub annotations
io.artifacthub.package.readme-url="https://github.com/dbt1/docker-tuxbox-build/blob/master/README.md" \
io.artifacthub.package.logo-url="https://avatars.githubusercontent.com/u/22789022?s=200&v=4"
### ui package experimental atm
RUN if [ "$ENABLE_UI_TOOLS" = "true" ]; then \
apt-get update && apt-get install -y --no-install-recommends \ apt-get update && apt-get install -y --no-install-recommends \
breeze-icon-theme \ breeze-icon-theme \
meld \ meld \
dbus \ dbus \
kdevelop; \ kdevelop; \
fi fi
## avoid dbus warn messages ## avoid dbus warn messages
ENV NO_AT_BRIDGE=1 ENV NO_AT_BRIDGE=1
## Create some basic directories and permissions for X-Server ## Create some basic directories and permissions for X-Server
RUN mkdir -p $XDG_RUNTIME_DIR && chown -R root:root $XDG_RUNTIME_DIR && chmod 0700 $XDG_RUNTIME_DIR RUN mkdir -p "${XDG_RUNTIME_DIR}" && chown -R root:root "${XDG_RUNTIME_DIR}" && chmod 0700 "${XDG_RUNTIME_DIR}"
## Copy welcome message ## Copy welcome message
ENV BANNER_FILE=/etc/welcome.txt ENV BANNER_FILE=/etc/welcome.txt
COPY terminal-splash.txt /etc/terminal-splash.txt COPY files/terminal-splash.txt /etc/terminal-splash.txt
RUN cat /etc/terminal-splash.txt > ${BANNER_FILE} && \ RUN cat /etc/terminal-splash.txt > ${BANNER_FILE} && \
echo "--------------------------------------------------------------" >> ${BANNER_FILE} && \ echo "--------------------------------------------------------------" >> ${BANNER_FILE} && \
echo "Tuxbox-Builder Version: ${TB_VERSION}" >> ${BANNER_FILE} && \ echo "Tuxbox docker-buildenv: v${DOCKER_BUILDENV_VERSION}" >> ${BANNER_FILE} && \
echo "--------------------------------------------------------------" >> ${BANNER_FILE} echo "--------------------------------------------------------------" >> ${BANNER_FILE}
### ssh stuff # ssh service setup
ENV SSHD_RUN_SERVICE_DIR="/etc/service/sshd" ENV SSHD_RUN_SERVICE_DIR="/etc/service/sshd"
ENV SSHD_RUN="${SSHD_RUN_SERVICE_DIR}/run" ENV SSHD_RUN="${SSHD_RUN_SERVICE_DIR}/run"
RUN mkdir /var/run/sshd && \ RUN mkdir -p /var/run/sshd && \
ssh-keygen -A && \ ssh-keygen -A && \
mkdir -p ${SSHD_RUN_SERVICE_DIR} && \ mkdir -p "${SSHD_RUN_SERVICE_DIR}" && \
echo '#!/bin/sh' > ${SSHD_RUN} && \ echo '#!/bin/sh' > "${SSHD_RUN}" && \
echo 'exec /usr/sbin/sshd -D' >> ${SSHD_RUN} && \ echo 'exec /usr/sbin/sshd -D' >> "${SSHD_RUN}" && \
chmod 755 ${SSHD_RUN} chmod 755 "${SSHD_RUN}"
### Set timzone # Set timezone
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN ln -snf /usr/share/zoneinfo/"${TZ}" /etc/localtime && echo "${TZ}" > /etc/timezone
## Lighttpd setup and create the runit service for lighttpd # Lighttpd setup
ENV LIGHTTPD_RUN="/etc/service/lighttpd/run" RUN apt update && apt install -y php-cgi php-cli php-common php-fpm php-mbstring && \
lighty-enable-mod fastcgi && \
lighty-enable-mod fastcgi-php && \
mkdir -p /run/lighttpd && \
chown -R www-data:www-data /run/lighttpd && \
chmod -R 755 /run/lighttpd
ENV LIGHTTPD_SERVICE_RUN="/etc/service/lighttpd/run"
ENV LIGHTTPD_CONFIG_PATH="/config/lighttpd" ENV LIGHTTPD_CONFIG_PATH="/config/lighttpd"
ENV LIGHTTPD_STD_CONFIG_FILE="${LIGHTTPD_CONFIG_PATH}/lighttpd.conf" ENV LIGHTTPD_STD_CONFIG_FILE="${LIGHTTPD_CONFIG_PATH}/lighttpd.conf"
ENV LIGHTTPD_ERROR_DOC="404.html"
RUN mkdir -p /etc/service/lighttpd && \ RUN mkdir -p /etc/service/lighttpd && \
echo '#!/bin/sh' > ${LIGHTTPD_RUN} && \ echo '#!/bin/sh' > "${LIGHTTPD_SERVICE_RUN}" && \
echo "if [ ! -d ${LIGHTTPD_CONFIG_PATH} ]; then" >> ${LIGHTTPD_RUN} && \ echo "if [ ! -d ${LIGHTTPD_CONFIG_PATH} ]; then" >> "${LIGHTTPD_SERVICE_RUN}" && \
echo " mkdir -p ${LIGHTTPD_CONFIG_PATH}" >> ${LIGHTTPD_RUN} && \ echo " mkdir -p ${LIGHTTPD_CONFIG_PATH}" >> "${LIGHTTPD_SERVICE_RUN}" && \
echo "fi" >> ${LIGHTTPD_RUN} && \ echo "fi" >> "${LIGHTTPD_SERVICE_RUN}" && \
echo "" >> ${LIGHTTPD_RUN} && \ echo "" >> "${LIGHTTPD_SERVICE_RUN}" && \
echo "if [ ! -f ${LIGHTTPD_STD_CONFIG_FILE} ]; then" >> ${LIGHTTPD_RUN} && \ echo "if [ ! -f ${LIGHTTPD_STD_CONFIG_FILE} ]; then" >> "${LIGHTTPD_SERVICE_RUN}" && \
echo " cp /etc/lighttpd/lighttpd.conf ${LIGHTTPD_STD_CONFIG_FILE}" >> ${LIGHTTPD_RUN} && \ echo " cp /etc/lighttpd/lighttpd.conf ${LIGHTTPD_STD_CONFIG_FILE}" >> "${LIGHTTPD_SERVICE_RUN}" && \
echo " echo 'dir-listing.activate = \"enable\"' >> ${LIGHTTPD_STD_CONFIG_FILE}" >> ${LIGHTTPD_RUN} && \ echo " echo 'dir-listing.activate = \"enable\"' >> ${LIGHTTPD_STD_CONFIG_FILE}" >> "${LIGHTTPD_SERVICE_RUN}" && \
echo " sed -i 's|/var/www/html|${USER_VOLUME_WORKDIR}/${BUILDENV_PREFIX}/dist|' ${LIGHTTPD_STD_CONFIG_FILE}" >> ${LIGHTTPD_RUN} && \ echo " echo 'server.follow-symlink = \"enable\"' >> ${LIGHTTPD_STD_CONFIG_FILE}" >> "${LIGHTTPD_SERVICE_RUN}" && \
echo "fi" >> ${LIGHTTPD_RUN} && \ echo " echo 'server.error-handler-404 = \"/${LIGHTTPD_ERROR_DOC}\"' >> ${LIGHTTPD_STD_CONFIG_FILE}" >> "${LIGHTTPD_SERVICE_RUN}" && \
echo "" >> ${LIGHTTPD_RUN} && \ echo " sed -i 's|/var/www/html|${WWW_DOCDIR}|g' ${LIGHTTPD_STD_CONFIG_FILE}" >> "${LIGHTTPD_SERVICE_RUN}" && \
echo "exec lighttpd -D -f ${LIGHTTPD_STD_CONFIG_FILE}" >> ${LIGHTTPD_RUN} && \ echo "fi" >> "${LIGHTTPD_SERVICE_RUN}" && \
chmod 755 ${LIGHTTPD_RUN} echo "" >> "${LIGHTTPD_SERVICE_RUN}" && \
echo "exec lighttpd -D -f ${LIGHTTPD_STD_CONFIG_FILE}" >> "${LIGHTTPD_SERVICE_RUN}" && \
usermod -aG www-data "${USER}" && \
chmod 755 "${LIGHTTPD_SERVICE_RUN}"
### Start generate content of start script ### # Copy helper scripts
COPY files/show-env.sh /usr/local/bin/show-env.sh
# Set the location of the init script and copy the init script from your project into the image
ENV CONTAINER_INIT_SCRIPT="/usr/local/bin/init.sh" ENV CONTAINER_INIT_SCRIPT="/usr/local/bin/init.sh"
RUN echo "#!/bin/bash" > ${CONTAINER_INIT_SCRIPT} && \ COPY files/init.sh ${CONTAINER_INIT_SCRIPT}
echo "echo 'Initialize tuxbox-builder container...'" >> ${CONTAINER_INIT_SCRIPT} && \ RUN chmod +x ${CONTAINER_INIT_SCRIPT}
echo "chown -R ${USER}:${USER_GROUP} ${USER_DIR} ${USER_VOLUME_DATADIR}" >> ${CONTAINER_INIT_SCRIPT} && \ COPY files/.bashrc ${USER_DIR}/.bashrc
echo "usermod -aG sudo $USER" >> ${CONTAINER_INIT_SCRIPT}
## prepare git config # Cleanup
RUN mkdir -p ${XDG_CONFIG_HOME}/git && \ RUN apt-get autoremove -y && apt-get autoclean -y && apt-get clean -y && \
echo "echo -e '[user]\\n\\temail = ${GIT_EMAIL}\\n\\tname = ${GIT_USER}' > ${XDG_CONFIG_HOME}/git/config" >> ${CONTAINER_INIT_SCRIPT} && \
echo "chown -R ${USER}:${USER_GROUP} ${XDG_CONFIG_HOME}/git" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo " >> ${CONTAINER_INIT_SCRIPT}
## Prepare buildenv script
RUN echo "if [ ! -d ${START_PATH}/.git ]; then" >> ${CONTAINER_INIT_SCRIPT} && \
echo " echo Cloning buildenv Repository from ${BUILDENV_GIT_URL}" >> ${CONTAINER_INIT_SCRIPT} && \
echo " git clone ${BUILDENV_GIT_URL} /tmp/${BUILDENV_PREFIX}" >> ${CONTAINER_INIT_SCRIPT} && \
echo " rsync -a /tmp/${BUILDENV_PREFIX} ${USER_VOLUME_WORKDIR}/" >> ${CONTAINER_INIT_SCRIPT} && \
echo " rm -rf ${USER_DIR}/${BUILDENV_PREFIX}/tmp" >> ${CONTAINER_INIT_SCRIPT} && \
echo "else" >> ${CONTAINER_INIT_SCRIPT} && \
echo " echo 'Repository [${START_PATH}] already exists. Not touched!'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "fi" >> ${CONTAINER_INIT_SCRIPT} && \
echo "chown -R ${USER}:${USER_GROUP} ${USER_VOLUME_WORKDIR}" >> ${CONTAINER_INIT_SCRIPT}
## prepare profile
ENV BASH_RC_FILE=${USER_DIR}/.bashrc
COPY .bashrc ${BASH_RC_FILE}
RUN echo "sed -i 's|@START_PATH@|'"${START_PATH}"'|' ${BASH_RC_FILE}" >> ${CONTAINER_INIT_SCRIPT} && \
echo "sed -i 's|@VERSION@|'"${TB_VERSION}"'|' ${BASH_RC_FILE}" >> ${CONTAINER_INIT_SCRIPT} && \
echo "sed -i 's|@HISTFILE@|'"${HISTFILE}"'|' ${BASH_RC_FILE}" >> ${CONTAINER_INIT_SCRIPT}
## prepare ssh config
RUN echo "mkdir -p ${USER_DIR}/.ssh" >> ${CONTAINER_INIT_SCRIPT}
## show env info
RUN echo "echo " >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo Environment:" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo BUILDENV_VERSION='${BUILDENV_VERSION}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo HOST_PREFIX='${HOST_PREFIX}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo BUILDENV_PREFIX='${BUILDENV_PREFIX}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo BUILDENV_GIT_URL='${BUILDENV_GIT_URL}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo TZ='${TZ}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo USER='${USER}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo USER_GROUP='${USER_GROUP}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo USER_ID='${USER_ID}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo USER_GROUP_ID='${USER_GROUP_ID}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo USER_DIR='${HOME}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo USER_PASSWORD=******" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo HISTFILE='${HISTFILE}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo GIT_USER='${GIT_USER}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo GIT_EMAIL='${GIT_EMAIL}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo PATH='${PATH}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo LOCALE_LANG='${LOCALE_LANG}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo START_PATH='${START_PATH}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo TB_VERSION='${TB_VERSION}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo TB_BUILD_TIME='${TB_BUILD_TIME}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo DISPLAY='${DISPLAY}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo ENABLE_UI_TOOLS='${ENABLE_UI_TOOLS} NOTE: Experimental only!'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo LOCAL_HOSTNAME='${LOCAL_HOSTNAME}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo HOSTNAME='$HOSTNAME'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo XDG_RUNTIME_DIR='${XDG_RUNTIME_DIR}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo XDG_CONFIG_HOME='${XDG_CONFIG_HOME}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo QT_QUICK_BACKEND='${QT_QUICK_BACKEND}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo QT_XCB_GL_INTEGRATION='${QT_XCB_GL_INTEGRATION}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo NVIDIA_VISIBLE_DEVICES='${NVIDIA_VISIBLE_DEVICES}'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "echo " >> ${CONTAINER_INIT_SCRIPT}
## start services
RUN echo "echo 'Ready...'" >> ${CONTAINER_INIT_SCRIPT} && \
echo "exec runsvdir -P /etc/service" >> ${CONTAINER_INIT_SCRIPT}
### END generate content of start script ###
# clean up
RUN apt-get autoremove -y && apt-get autoclean && apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
## make start script executable # Make init script executable
RUN chmod 755 "${CONTAINER_INIT_SCRIPT}" RUN chmod 755 "${CONTAINER_INIT_SCRIPT}"
# Start container with init script # Start container with init script
ENTRYPOINT ["bash", "-c", "${CONTAINER_INIT_SCRIPT}"] ENTRYPOINT ["bash", "-c", "exec ${CONTAINER_INIT_SCRIPT:-/usr/local/bin/init.sh}"]
CMD ["D"]
# Add HEALTHCHECK
HEALTHCHECK --interval=5s --timeout=5s --start-period=1s --retries=10 \
CMD [ -f /tmp/container_ready ] || exit 1

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" ENV_FILE=".env"
BACKUP_DIR="env_backups"
EXIT_USER_CANCEL=70
BUILDENV_VERSION="3.2.4" # ------------------------------------------------------------------------------
TB_VERSION="latest" # Prompt functions
TB_BUILD_TIME=$(date '+%Y-%m-%d %H:%M:%S') # ------------------------------------------------------------------------------
USER=$(whoami)
USER_ID=$(id -u) # Prompt the user with a message and default value
USER_GROUP_ID=$(id -g) function prompt {
USER_DIR="${HOME}" local PROMPT_MESSAGE=$1
HOST_PREFIX=tuxbox local DEFAULT_VALUE=$2
BUILDENV_PREFIX="buildenv" local PAD_WIDTH=${3:-20}
LOCAL_HOSTNAME=$(hostname)
ENABLE_UI_TOOLS="false" # Build the prompt with color logic
USER_VOLUME_BINDIR="${USER_DIR}/bin" local PROMPT_WITH_COLOR
USER_VOLUME_WORKDIR="${USER_DIR}/${HOST_PREFIX}" PROMPT_WITH_COLOR=$(prompt_color "$PROMPT_MESSAGE" "$DEFAULT_VALUE" "$PAD_WIDTH")
USER_VOLUME_WORKBINDIR="${USER_VOLUME_WORKDIR}/bin"
# 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_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_NAME=".bash_history"
HISTFILE="${USER_VOLUME_DATADIR}/${HISTFILE_NAME}" HISTFILE="${USER_VOLUME_DATADIR}/${HISTFILE_NAME}"
# Set default values for GIT_EMAIL, GIT_USER # ------------------------------------------------------------------------------
GIT_EMAIL="${USER}@${HOSTNAME}" # Write the final .env file
GIT_USER="$(grep "${USER}" /etc/passwd | cut -d: -f5 | sed 's/,//g')" # ------------------------------------------------------------------------------
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 DOCKER_BUILDENV_GIT_URL=${DOCKER_BUILDENV_GIT_URL}
if git --version &>/dev/null; then DOCKER_BUILDENV_VERSION=${DOCKER_BUILDENV_VERSION}
# 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 BUILDENV_GIT_URL=${BUILDENV_GIT_URL}
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
# 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_PREFIX=${BUILDENV_PREFIX} 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} DISPLAY=${DISPLAY}
ENABLE_UI_TOOLS=${ENABLE_UI_TOOLS} ENABLE_UI_TOOLS=${ENABLE_UI_TOOLS}
GIT_EMAIL=${GIT_EMAIL} GIT_EMAIL=${GIT_EMAIL}
GIT_USER=${GIT_USER} GIT_USER=${GIT_USER}
HISTFILE=${HISTFILE}
HISTFILE_NAME=${HISTFILE_NAME} HISTFILE_NAME=${HISTFILE_NAME}
HOST_PREFIX=${HOST_PREFIX} HISTFILE=${HISTFILE}
LANGUAGE=${LANG} BUILDENV_INSTALL_PREFIX=${BUILDENV_INSTALL_PREFIX}
LC_ALL=${LANG}
LOCALE_LANG=${LANG}
LOCAL_HOSTNAME=${LOCAL_HOSTNAME} LOCAL_HOSTNAME=${LOCAL_HOSTNAME}
NVIDIA_VISIBLE_DEVICES=all LOCALE_LANG=${LOCALE_LANG}
QT_QUICK_BACKEND=software TZ=${TZ}
QT_XCB_GL_INTEGRATION=xcb_egl
START_PATH=${USER_VOLUME_WORKDIR}/${BUILDENV_PREFIX}
TERM=${TERM} TERM=${TERM}
TZ=$(cat /etc/timezone) NVIDIA_VISIBLE_DEVICES=${NVIDIA_VISIBLE_DEVICES}
USER=${USER} QT_QUICK_BACKEND=${QT_QUICK_BACKEND}
QT_XCB_GL_INTEGRATION=${QT_XCB_GL_INTEGRATION}
USER_DIR=${USER_DIR} 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_WORKDIR=${USER_VOLUME_WORKDIR}
USER_VOLUME_DATADIR=${USER_VOLUME_DATADIR} USER_VOLUME_DATADIR=${USER_VOLUME_DATADIR}
USER_VOLUME_BINDIR=${USER_VOLUME_BINDIR} USER_VOLUME_BINDIR=${USER_VOLUME_BINDIR}
USER_VOLUME_WORKBINDIR=${USER_VOLUME_WORKBINDIR} START_PATH=${START_PATH}
TB_VERSION=${TB_VERSION} WWW_DOCDIR=${WWW_DOCDIR}
XDG_CONFIG_HOME=/home EXPLORER_ENABLE=${EXPLORER_ENABLE}
XDG_RUNTIME_DIR=/tmp/runtime-root EXPLORER_GIT_URL=${EXPLORER_GIT_URL}
XDG_CONFIG_HOME=${XDG_CONFIG_HOME}
XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR}
EOF EOF
# validate echo -e ""
echo ".env-file successfully created with:" echo -e "$ENV_FILE file was successfully created (or overwritten)."
cat $ENV_FILE

View File

@@ -1,16 +1,28 @@
#!/bin/bash #!/bin/bash
# Path to script that will be executed before starts docker-compose # Path to script that will be executed before starting docker-compose
ENV_SCRIPT="./create-env.sh" ENV_SCRIPT="./create-env.sh"
# Define exit codes as constants
EXIT_USER_CANCEL=70
# Check script # Check script
if [ -x "$ENV_SCRIPT" ]; then if [ -x "$ENV_SCRIPT" ]; then
echo "executing $ENV_SCRIPT..." echo "Executing $ENV_SCRIPT..."
$ENV_SCRIPT "$ENV_SCRIPT"
EXIT_CODE=$?
if [ $EXIT_CODE -eq $EXIT_USER_CANCEL ]; then
echo "create-env.sh was canceled by the user."
exit $EXIT_USER_CANCEL
elif [ $EXIT_CODE -ne 0 ]; then
echo "create-env.sh failed with exit code $EXIT_CODE."
exit $EXIT_CODE
fi
else else
echo "Error: $ENV_SCRIPT not found or not executable." echo "Error: $ENV_SCRIPT not found or not executable."
exit 1 exit 1
fi fi
# Execute docker-compose with all parameters an sub commannds # Execute docker-compose with all parameters and subcommands
docker-compose "$@" docker-compose "$@"

View File

@@ -1,86 +1,118 @@
services: services:
tuxbox-build: tuxbox-build:
container_name: tuxbox-build container_name: tuxbox-build
image: tuxbox-build
environment:
- PATH=${USER_VOLUME_WORKBINDIR}:${USER_VOLUME_BINDIR}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
env_file:
- .env
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
args: args:
- BUILDENV_GIT_URL=${BUILDENV_GIT_URL} DOCKER_BUILDENV_VERSION: ${DOCKER_BUILDENV_VERSION}
- BUILDENV_PREFIX=${BUILDENV_PREFIX} DOCKER_BUILDENV_GIT_URL: $DOCKER_BUILDENV_GIT_URL
- BUILDENV_VERSION=${BUILDENV_VERSION}
- DISPLAY=${DISPLAY}
- ENABLE_UI_TOOLS=false
- GIT_EMAIL=${GIT_EMAIL}
- GIT_USER=${GIT_USER}
- HISTFILE=${USER_VOLUME_DATADIR}/${HISTFILE_NAME}
- HISTFILE_NAME=${HISTFILE_NAME}
- HOST_PREFIX=${HOST_PREFIX}
- LOCALE_LANG=${LOCALE_LANG}
- LOCAL_HOSTNAME=${LOCAL_HOSTNAME}
- NVIDIA_VISIBLE_DEVICES=${NVIDIA_VISIBLE_DEVICES}
- QT_QUICK_BACKEND=${QT_QUICK_BACKEND}
- QT_XCB_GL_INTEGRATION=${QT_XCB_GL_INTEGRATION}
- START_PATH=${START_PATH}
- TB_BUILD_TIME=${TB_BUILD_TIME}
- TB_VERSION=${TB_VERSION}
- TERM=${TERM}
- TZ=${TZ}
- USER=${USER}
- USER_DIR=${USER_DIR}
- USER_GROUP=${USER_GROUP}
- USER_GROUP_ID=${USER_GROUP_ID}
- USER_ID=${USER_ID}
- USER_PASSWORD=${USER_PASSWORD}
- USER_VOLUME_WORKDIR=${USER_DIR}/${HOST_PREFIX}
- USER_VOLUME_DATADIR=${USER_VOLUME_DATADIR}
- XDG_CONFIG_HOME=${XDG_CONFIG_HOME}
- XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR}
PATH: "${USER_VOLUME_WORKDIR}/bin:${USER_VOLUME_BINDIR}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
BUILDENV_GIT_URL: ${BUILDENV_GIT_URL}
BUILDENV_PREFIX: ${BUILDENV_PREFIX}
# Host user and group
USER_NAME: ${USER_NAME}
USER_ID: ${USER_ID}
USER_GROUP: ${USER_GROUP}
USER_GROUP_ID: ${USER_GROUP_ID}
USER_PASSWORD: ${USER_PASSWORD}
USER_DIR: ${USER_DIR}
# More Build-Args
DISPLAY: ${DISPLAY}
ENABLE_UI_TOOLS: ${ENABLE_UI_TOOLS}
GIT_EMAIL: ${GIT_EMAIL}
GIT_USER: ${GIT_USER}
HISTFILE_NAME: ${HISTFILE_NAME}
HISTFILE: ${HISTFILE}
BUILDENV_INSTALL_PREFIX: ${BUILDENV_INSTALL_PREFIX}
LOCAL_HOSTNAME: ${LOCAL_HOSTNAME}
LOCALE_LANG: ${LOCALE_LANG}
TZ: ${TZ}
TERM: ${TERM}
NVIDIA_VISIBLE_DEVICES: ${NVIDIA_VISIBLE_DEVICES}
QT_QUICK_BACKEND: ${QT_QUICK_BACKEND}
QT_XCB_GL_INTEGRATION: ${QT_XCB_GL_INTEGRATION}
USER_VOLUME_WORKDIR: ${USER_VOLUME_WORKDIR}
USER_VOLUME_DATADIR: ${USER_VOLUME_DATADIR}
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}
image: tuxbox-build
environment:
DOCKER_BUILDENV_VERSION: ${DOCKER_BUILDENV_VERSION}
DOCKER_BUILDENV_GIT_URL: $DOCKER_BUILDENV_GIT_URL
BUILDENV_GIT_URL: ${BUILDENV_GIT_URL}
BUILDENV_PREFIX: ${BUILDENV_PREFIX}
PATH: "${USER_VOLUME_WORKDIR}/bin:${USER_VOLUME_BINDIR}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
DISPLAY: ${DISPLAY}
ENABLE_UI_TOOLS: ${ENABLE_UI_TOOLS}
GIT_EMAIL: ${GIT_EMAIL}
GIT_USER: ${GIT_USER}
HISTFILE_NAME: ${HISTFILE_NAME}
HISTFILE: ${HISTFILE}
BUILDENV_INSTALL_PREFIX: ${BUILDENV_INSTALL_PREFIX}
LOCAL_HOSTNAME: ${LOCAL_HOSTNAME}
LOCALE_LANG: ${LOCALE_LANG}
TZ: ${TZ}
TERM: ${TERM}
NVIDIA_VISIBLE_DEVICES: ${NVIDIA_VISIBLE_DEVICES}
QT_QUICK_BACKEND: ${QT_QUICK_BACKEND}
QT_XCB_GL_INTEGRATION: ${QT_XCB_GL_INTEGRATION}
USER: ${USER_NAME}
USER_ID: ${USER_ID}
USER_GROUP: ${USER_GROUP}
USER_GROUP_ID: ${USER_GROUP_ID}
USER_PASSWORD: ${USER_PASSWORD}
USER_DIR: ${USER_DIR}
USER_VOLUME_WORKDIR: ${USER_VOLUME_WORKDIR}
USER_VOLUME_DATADIR: ${USER_VOLUME_DATADIR}
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}
devices:
- /dev/dri:/dev/dri
ports:
# the host: container ports for web access, used for httpd inside container to get built packages and images via browser, wget, curl, set top boxes etc.
- "8080:80"
# the host: container ports for ssh access of users in its /home
- "222:22"
tty: true
working_dir: /
volumes: volumes:
- ${USER_VOLUME_WORKDIR}:${USER_VOLUME_WORKDIR} - ${USER_VOLUME_WORKDIR}:${USER_VOLUME_WORKDIR}
- ${USER_VOLUME_BINDIR}:${USER_DIR}/bin
- ${USER_VOLUME_DATADIR}:/data
- ${USER_VOLUME_WORKDIR}/.config:/config
- ${USER_VOLUME_WORKDIR}/.config/git/config:${XDG_CONFIG_HOME}/git
- ${USER_DIR}/sstate-cache:${USER_DIR}/sstate-cache - ${USER_DIR}/sstate-cache:${USER_DIR}/sstate-cache
- ${USER_DIR}/Archive:${USER_DIR}/Archive - ${USER_DIR}/Archive:${USER_DIR}/Archive
- ${USER_DIR}/.ccache:${USER_DIR}/.ccache - ${USER_DIR}/.ccache:${USER_DIR}/.ccache
- ${USER_DIR}/sources:${USER_DIR}/sources - ${USER_DIR}/sources:${USER_DIR}/sources
- ${USER_VOLUME_BINDIR}:${USER_DIR}/bin
- ${USER_VOLUME_WORKBINDIR}:${USER_VOLUME_WORKDIR}/bin
- ${USER_DIR}/.ssh:${USER_DIR}/.ssh - ${USER_DIR}/.ssh:${USER_DIR}/.ssh
- ${USER_VOLUME_DATADIR}:/data
- ${USER_VOLUME_WORKDIR}/.config:/config
- ${USER_VOLUME_WORKDIR}/.config/git/config:${XDG_CONFIG_HOME}/git # Optional for UI tools
- /tmp/.X11-unix:/tmp/.X11-unix - /tmp/.X11-unix:/tmp/.X11-unix
- /usr/lib/x86_64-linux-gnu/mesa:/usr/lib/x86_64-linux-gnu/mesa - /usr/lib/x86_64-linux-gnu/mesa:/usr/lib/x86_64-linux-gnu/mesa
networks:
- tuxbox-network devices:
#hostname: ${LOCAL_HOSTNAME} - /dev/dri:/dev/dri # For GPU acceleration if needed
ports:
- "8080:80" # Webserver
- "222:22" # SSH
tty: true
working_dir: /
cap_add: cap_add:
- SYS_ADMIN - SYS_ADMIN
restart: unless-stopped restart: unless-stopped
networks: networks:
tuxbox-network: default:
driver: bridge driver: bridge
volumes:
tuxbox-volumes:
driver: local

View File

@@ -58,11 +58,12 @@ if [ -n "$force_color_prompt" ]; then
fi fi
if [ "$color_prompt" = yes ]; then if [ "$color_prompt" = yes ]; then
PS1='\[\033[01;33m\]\u\[\033[01;33m\]@\[\033[01;33m\]\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' PS1='\[\033[01;33m\]\u\[\033[01;33m\]@@LOCAL_HOSTNAME@\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' PS1='${debian_chroot:+($debian_chroot)}\u@@LOCAL_HOSTNAME@:\w\$ '
fi fi
unset color_prompt force_color_prompt unset color_prompt force_color_prompt
# If this is an xterm set the title to user@host:dir # If this is an xterm set the title to user@host:dir
@@ -116,8 +117,56 @@ fi
cd @START_PATH@ cd @START_PATH@
while IFS= read -r line; do echo -e "$line"; done < /etc/terminal-splash.txt echo -e "--------------------------------------------------------------------"
echo -e "--------------------------------------------------------------" while IFS= read -r line; do
echo -e "Tuxbox-Builder Version: @VERSION@" echo -e "$line"
echo -e "--------------------------------------------------------------" done < /etc/terminal-splash.txt
echo -e "--------------------------------------------------------------------"
echo -e "docker-buildenv: v@DOCKER_BUILDENV_VERSION@\t| @DOCKER_BUILDENV_GIT_URL@"
echo -e "buildenv: $(git -C @START_PATH@ describe --tags --long | sed -e 's/-g[0-9a-f]\{7,\}$//' -e 's/-\([0-9]\+\)$/.\1/')\t| @BUILDENV_GIT_URL@"
if [ -f /etc/os-release ]; then
PRETTY_NAME=$(grep '^PRETTY_NAME=' /etc/os-release | cut -d= -f2 | tr -d '"')
echo -e "OS-Version: $PRETTY_NAME"
fi
echo -e "Kernel-Version: $(uname -r)"
echo -e "Container-Hostname: $(hostname)"
echo -e "Container-IP: $(hostname -I | awk '{print $1}')"
echo -e "--------------------------------------------------------------------"
echo -e "" echo -e ""
convert_locale() {
local input_locale="$1"
echo "${input_locale%.*}:${input_locale%%_*}"
}
export LANG=@LANG@
export LANGUAGE=$(convert_locale $LANG)
export LC_ALL=$LANG
# Set the directory to check
DIR_TO_CHECK=@START_PATH@
# Detect system locale
LOCALE=$(locale | grep LANG= | cut -d= -f2 | cut -d_ -f1)
# Set link based on locale
if [[ "$LOCALE" == "de" ]]; then
LINK="https://github.com/tuxbox-neutrino/buildenv/blob/master/README-de.md#14-init-skript-ausf%C3%BChren"
else
LINK="https://github.com/tuxbox-neutrino/buildenv/blob/master/README-us.md#14-init-script"
fi
# Check for subdirectories starting with 'meta-'
if ! find "$DIR_TO_CHECK" -type d -name "meta-*" | grep -q .; then
# Print bold and user-friendly message if no subdirectory matches
echo -e "--------------------------------------------------------------"
echo -e "\033[1m\033[33mNOTE: Your build environment seems to be uninitialized!\033[0m"
echo -e "--------------------------------------------------------------"
echo -e "\033[1mPlease run the init script to set up your environment.\033[0m"
echo -e ""
echo -e "./init && cd poky-@BUILDENV_VERSION@"
echo -e ""
echo -e "--------------------------------------------------------------"
echo -e "Refer to the instructions here:"
echo -e "\033[4m$LINK\033[0m"
echo -e ""
fi

120
files/init.sh Executable file
View File

@@ -0,0 +1,120 @@
#!/bin/bash
# Initialize tuxbox-builder container...
echo 'Initialize tuxbox-builder container...'
# Define a dedicated user group
GROUP_NAME="${USER_GROUP:-$USER}"
# Ensure the group exists, create it if necessary
if ! getent group "$GROUP_NAME" > /dev/null; then
echo "Group $GROUP_NAME does not exist. Creating..."
groupadd "$GROUP_NAME"
fi
# Ensure the user exists, create it if necessary
if ! id "$USER" &>/dev/null; then
echo "User $USER does not exist. Creating..."
useradd -m -s /bin/bash -g "$GROUP_NAME" -G www-data "$USER"
else
usermod -aG "$GROUP_NAME" "$USER"
usermod -aG www-data "$USER"
fi
# Prepare global Git configuration
mkdir -p "${XDG_CONFIG_HOME:-$USER_DIR/.config}/git"
echo 'Setting up global Git configuration...'
echo -e "[user]\n\temail = ${GIT_EMAIL}\n\tname = ${GIT_USER}" > "${XDG_CONFIG_HOME}/git/config"
chown -R "$USER":"$GROUP_NAME" "${XDG_CONFIG_HOME}/git"
# Prepare SSH configuration
mkdir -p "${USER_DIR}/.ssh"
# Optimize chown: Only change ownership if incorrect
for dir in "$USER_VOLUME_WORKDIR" "$WWW_DOCDIR"; do
if [ -d "$dir" ]; then
current_owner=$(stat -c "%U:%G" "$dir")
if [ "$current_owner" != "$USER:$GROUP_NAME" ]; then
echo "Updating ownership for $dir..."
chown -R "$USER":"$GROUP_NAME" "$dir"
fi
fi
done
# Optimize chmod: Only change permissions if incorrect
for dir in "$USER_VOLUME_WORKDIR" "$WWW_DOCDIR"; do
if [ -d "$dir" ]; then
if find "$dir" -not -perm -g+rw | grep . > /dev/null 2>&1; then
echo "Updating permissions for $dir..."
chmod -R g+rw "$dir"
fi
fi
done
echo "User $USER is set up with group $GROUP_NAME and www-data for shared access."
# Prepare build environment
if [ ! -d "${USER_VOLUME_WORKDIR}/${BUILDENV_PREFIX}/.git" ]; then
if cd "${USER_VOLUME_WORKDIR}"; then
echo "Cloning build environment repository..."
git clone "${BUILDENV_GIT_URL}" "${BUILDENV_PREFIX}"
else
echo "Error: Could not change directory to ${USER_VOLUME_WORKDIR}" >&2
exit 1
fi
else
echo "Repository [${USER_VOLUME_WORKDIR}/${BUILDENV_PREFIX}] already exists. Not modified!"
fi
chown -R "$USER":"$GROUP_NAME" "$USER_VOLUME_WORKDIR"
# Detect the build environment version
BUILDENV_DISTRO_VERSION=$(grep 'DEFAULT_IMAGE_VERSION=' "${START_PATH}/init.sh" | cut -d'=' -f2 | tr -d '"')
echo "Detected DISTRO_VERSION = $BUILDENV_DISTRO_VERSION within ${START_PATH}"
# Prepare web server content if enabled
if [ "${EXPLORER_ENABLE}" != "false" ]; then
if [ ! -d "${WWW_DOCDIR}/.git" ]; then
echo 'Cloning File Explorer web content repository...'
git clone "${EXPLORER_GIT_URL}" "${WWW_DOCDIR}"
fi
# Download default configuration file if it does not exist
if [ ! -f "${WWW_DOCDIR}/config/config.php" ]; then
echo "[${WWW_DOCDIR}/config/config.php] does not exist. Downloading..."
curl -o "${WWW_DOCDIR}/config/config.php" "https://raw.githubusercontent.com/dbt1/support/master/docker-buildenv/config-sample.php"
else
echo "Repository [${WWW_DOCDIR}] already exists and configured. Not modified!"
fi
# Find the build directory based on detected distro version
BUILD_DIR=$(find "${START_PATH}" -type d -path "*-${BUILDENV_DISTRO_VERSION}/build" ! -path "*-${BUILDENV_DISTRO_VERSION}/build/*" 2>/dev/null)
if [ -n "$BUILD_DIR" ]; then
sed -i "s|#@FILES_DIRECTORY@|\\\$FILES_DIRECTORY = '$BUILD_DIR'|g" "${WWW_DOCDIR}/config/config.php"
fi
chown -R "$USER":"$GROUP_NAME" "$WWW_DOCDIR"
else
echo "EXPLORER_ENABLE is disabled. Skipping web server setup."
fi
# Prepare user profile with environment variables
echo 'Configuring user profile...'
BASH_RC_FILE="${USER_DIR}/.bashrc"
sed -i "s|@START_PATH@|${START_PATH}|g" "$BASH_RC_FILE"
sed -i "s|@BUILDENV_GIT_URL@|${BUILDENV_GIT_URL}|g" "$BASH_RC_FILE"
sed -i "s|@DOCKER_BUILDENV_VERSION@|${DOCKER_BUILDENV_VERSION}|g" "$BASH_RC_FILE"
sed -i "s|@HISTFILE@|${HISTFILE}|g" "$BASH_RC_FILE"
sed -i "s|@LANG@|${LOCALE_LANG}|g" "$BASH_RC_FILE"
sed -i "s|@BUILDENV_VERSION@|${BUILDENV_DISTRO_VERSION}|g" "$BASH_RC_FILE"
sed -i "s|@DOCKER_BUILDENV_GIT_URL@|${DOCKER_BUILDENV_GIT_URL}|g" "$BASH_RC_FILE"
sed -i "s|@LOCAL_HOSTNAME@|${LOCAL_HOSTNAME}|g" "$BASH_RC_FILE"
chown "$USER":"$GROUP_NAME" "$BASH_RC_FILE"
# Mark container as ready
touch /tmp/container_ready
echo "Container setup complete. Ready to start services..."
echo "Enjoy...!"
# Start services using runsvdir
exec runsvdir -P /etc/service

44
files/show-env.sh Executable file
View File

@@ -0,0 +1,44 @@
#!/bin/bash
echo ""
echo "=== Environment Info for Normal Users, 'sshd', and 'root' ==="
echo ""
# Read all users from /etc/passwd
while IFS=: read -r username _ uid gid _ home _; do
# Include normal users (UID >= 1000), 'sshd', and 'root'
if [ "$uid" -ge 1000 ] || [ "$username" == "sshd" ] || [ "$username" == "root" ]; then
echo "User: $username"
echo "USER_ID: $uid"
echo "USER_GROUP: $(getent group $gid | cut -d: -f1)"
echo "USER_GROUP_ID: $gid"
# Git configuration, if available
if [ -f "$home/.gitconfig" ]; then
git_user=$(git config --global --file "$home/.gitconfig" user.name 2>/dev/null)
git_email=$(git config --global --file "$home/.gitconfig" user.email 2>/dev/null)
echo "GIT_USER: ${git_user:-Not configured}"
echo "GIT_EMAIL: ${git_email:-Not configured}"
fi
# Timezone, Locale, PATH, DISPLAY, and TERM
echo "TIMEZONE: $(cat /etc/timezone)"
if [ -d "$home" ]; then
locale_lang=$(LANG=$LANG HOME=$home bash -c 'echo $LANG' 2>/dev/null)
user_path=$(HOME=$home bash -c 'echo $PATH' 2>/dev/null)
display_var=$(HOME=$home bash -c 'echo $DISPLAY' 2>/dev/null)
term_var=$(HOME=$home bash -c 'echo $TERM' 2>/dev/null)
echo "LOCALE_LANG: ${locale_lang:-Not set}"
echo "PATH: ${user_path:-Not set}"
echo "DISPLAY: ${display_var:-Not set}"
echo "TERM: ${term_var:-Not set}"
echo "USER_HOME:"
# Limit tree output to 6 levels, max 3 directories per level
tree -L 6 -d "$home" | awk '{count[$1]++; if (count[$1] <= 3) print}'
fi
echo "-------------"
fi
done < /etc/passwd
echo "=== End of Environment Info ==="