diff --git a/.github/workflows/build_pull_request.yml b/.github/workflows/build_pull_request.yml index 4636b92..93dbb61 100644 --- a/.github/workflows/build_pull_request.yml +++ b/.github/workflows/build_pull_request.yml @@ -18,6 +18,31 @@ jobs: with: dockerfile: Dockerfile + lint_shell_scripts: + name: Lint shell scripts + runs-on: ubuntu-latest + steps: + - + name: Checkout github repository + uses: actions/checkout@v6 + - + name: Install shell lint tools + run: | + sudo apt-get update + sudo apt-get install -y shellcheck shfmt + - + name: Run shellcheck + run: | + set -euo pipefail + mapfile -t scripts < <(git ls-files '*.sh') + shellcheck --severity style "${scripts[@]}" + - + name: Run shfmt + run: | + set -euo pipefail + mapfile -t scripts < <(git ls-files '*.sh') + shfmt -d -i 2 -ci "${scripts[@]}" + check_build: runs-on: ubuntu-latest env: diff --git a/Dockerfile b/Dockerfile index 0f8680f..2737b0b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,123 +23,17 @@ COPY --from=comp /usr/bin/composer /usr/bin/composer # Update and install required debian packages ENV DEBIAN_FRONTEND=noninteractive -SHELL ["/bin/bash", "-o", "pipefail", "-c"] -# hadolint ignore=DL3008 # 'Pin versions in apt get install' -RUN < /etc/apache2/conf-available/remoteip.conf <//' -EORUN - -# Get and customize librebooking ARG APP_GH_REF ARG APP_GH_ADD_SHA=false +# hadolint ignore=DL3008 # 'Pin versions in apt get install' +COPY setup.sh /usr/local/bin/setup.sh RUN < /var/www/html/config/version-suffix.txt - else - echo "ERROR determining the LB_SHORT_SHA value from TARBALL_FILENAME ${TARBALL_FILENAME}" >&2 - exit 1 - fi -fi -if [ -f /var/www/html/composer.json ]; then - sed \ - -i /var/www/html/composer.json \ - -e "s:\(.*\)nickdnk/graph-sdk\(.*\)7.0\(.*\):\1joelbutcher/facebook-graph-sdk\26.1\3:" - composer install -fi -sed \ - -i /var/www/html/database_schema/create-user.sql \ - -e "s:^DROP USER ':DROP USER IF EXISTS ':g" \ - -e "s:booked_user:schedule_user:g" \ - -e "s:localhost:%:g" -if ! [ -d /var/www/html/tpl_c ]; then - mkdir /var/www/html/tpl_c -fi -mkdir /var/www/html/Web/uploads/reservation -EORUN - -RUN <&2 "error: both $var and $fileVar are set (but are exclusive)" - exit 1 + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 fi if [ -n "${varValue}" ]; then - export "$var"="${varValue}" + export "$var"="${varValue}" elif [ -n "${fileVarValue}" ]; then - export "$var"="$(cat "${fileVarValue}")" + export "$var"="$(cat "${fileVarValue}")" elif [ -n "${def}" ]; then - export "$var"="$def" + export "$var"="$def" fi unset "$fileVar" } @@ -36,10 +39,10 @@ LB_LOGGING_SQL=${LB_LOGGING_SQL:-${DFT_LOGGING_SQL}} APP_PATH=${APP_PATH:-${DFT_APP_PATH}} # Set the php timezone file -if [ -f /usr/share/zoneinfo/${LB_DEFAULT_TIMEZONE} ]; then +if [ -f /usr/share/zoneinfo/"${LB_DEFAULT_TIMEZONE}" ]; then INI_FILE="/usr/local/etc/php/conf.d/librebooking.ini" - echo "[Date]" >> ${INI_FILE} - echo "date.timezone=\"${LB_DEFAULT_TIMEZONE}\"" >> ${INI_FILE} + echo "[Date]" >>${INI_FILE} + echo "date.timezone=\"${LB_DEFAULT_TIMEZONE}\"" >>${INI_FILE} fi # Link the configuration file diff --git a/bin/entrypoint.sh b/bin/entrypoint.sh index 94efdfd..e63f2e9 100644 --- a/bin/entrypoint.sh +++ b/bin/entrypoint.sh @@ -1,4 +1,5 @@ #!/bin/bash +# vim: set expandtab ts=2 sw=2 ai : set -ex @@ -12,25 +13,27 @@ file_env() { local var="$1" local fileVar="${var}_FILE" local def="${2:-}" - local varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//") - local fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//") + local varValue + varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//") + local fileVarValue + fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//") if [ -n "${varValue}" ] && [ -n "${fileVarValue}" ]; then - echo >&2 "error: both $var and $fileVar are set (but are exclusive)" - exit 1 + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 fi if [ -n "${varValue}" ]; then - export "$var"="${varValue}" + export "$var"="${varValue}" elif [ -n "${fileVarValue}" ]; then - export "$var"="$(cat "${fileVarValue}")" + export "$var"="$(cat "${fileVarValue}")" elif [ -n "${def}" ]; then - export "$var"="$def" + export "$var"="$def" fi unset "$fileVar" } # Exit if incompatible mount (images prior to V2) if [ "$(mount | grep /var/www/html)" = "/var/www/html" ]; then - echo "The volume must be mapped to container directory /config" >2 + echo "The volume must be mapped to container directory /config" >&2 exit 1 fi @@ -46,8 +49,8 @@ APP_PATH=${APP_PATH:-${DFT_APP_PATH}} # If volume was used with images older than v2, then archive useless files pushd /config if [ -d Web ]; then - mkdir archive - mv $(ls --ignore=archive) archive + mkdir -p archive + find . -mindepth 1 -maxdepth 1 ! -name archive -exec mv -t archive -- {} + if [ -f archive/config/config.php ]; then cp archive/config/config.php config.php fi @@ -79,21 +82,21 @@ sed \ -e "s:\(\['logging'\]\['sql'\].*\) '.*':\1 '${LB_LOGGING_SQL}':" # Create the plugins configuration file inside the volume -for source in $(find /var/www/html/plugins -type f -name "*dist*"); do - target=$(echo "${source}" | sed -e "s/.dist//") - if ! [ -f "/config/$(basename ${target})" ]; then - cp --no-clobber "${source}" "/config/$(basename ${target})" +while IFS= read -r -d '' source; do + target=${source//.dist/} + if ! [ -f "/config/$(basename "${target}")" ]; then + cp --no-clobber "${source}" "/config/$(basename "${target}")" fi - if ! [ -f ${target} ]; then - ln -s "/config/$(basename ${target})" "${target}" + if ! [ -f "${target}" ]; then + ln -s "/config/$(basename "${target}")" "${target}" fi -done +done < <(find /var/www/html/plugins -type f -name "*dist*" -print0) # Set the php timezone file -if [ -f /usr/share/zoneinfo/${LB_DEFAULT_TIMEZONE} ]; then +if [ -f /usr/share/zoneinfo/"${LB_DEFAULT_TIMEZONE}" ]; then INI_FILE="/usr/local/etc/php/conf.d/librebooking.ini" - echo "[Date]" >> ${INI_FILE} - echo "date.timezone=\"${LB_DEFAULT_TIMEZONE}\"" >> ${INI_FILE} + echo "[Date]" >>${INI_FILE} + echo "date.timezone=\"${LB_DEFAULT_TIMEZONE}\"" >>${INI_FILE} fi # Missing log directory @@ -102,7 +105,7 @@ if ! [ -d "${LB_LOGGING_FOLDER}" ]; then fi # A URL path prefix was set -if ! [ -z "${APP_PATH}" ]; then +if [ -n "${APP_PATH}" ]; then ## Set server document root 1 directory up sed \ -i /etc/apache2/sites-enabled/000-default.conf \ @@ -115,16 +118,16 @@ if ! [ -z "${APP_PATH}" ]; then ## Adapt the .htaccess file sed \ - -i /var/www/${APP_PATH}/.htaccess \ + -i /var/www/"${APP_PATH}"/.htaccess \ -e "s:\(RewriteCond .*\)/Web/:\1\.\*/Web/:" \ -e "s:\(RewriteRule .*\) /Web/:\1 /${APP_PATH}/Web/:" fi # Send log files to /dev/stdout as background jobs touch "${LB_LOGGING_FOLDER}/app.log" -tail --follow "${LB_LOGGING_FOLDER}/app.log" >> /dev/stdout & +tail --follow "${LB_LOGGING_FOLDER}/app.log" >>/dev/stdout & touch "${LB_LOGGING_FOLDER}/sql.log" -tail --follow "${LB_LOGGING_FOLDER}/sql.log" >> /dev/stdout & +tail --follow "${LB_LOGGING_FOLDER}/sql.log" >>/dev/stdout & # Switch to the apache server exec "$@" diff --git a/setup.sh b/setup.sh new file mode 100644 index 0000000..2fab56e --- /dev/null +++ b/setup.sh @@ -0,0 +1,114 @@ +#!/bin/bash +# vim: set expandtab ts=2 sw=2 ai : + +set -e +set -u +set -o pipefail +trap 'echo "Exit status $? at line $LINENO from: $BASH_COMMAND"' ERR + +PS4='+ ${BASH_SOURCE:-}:${FUNCNAME[0]:-}:L${LINENO:-}: ' +set -x + +apt-get update +apt-get upgrade --yes +apt-get install --yes --no-install-recommends \ + cron \ + git \ + libjpeg-dev \ + libldap-dev \ + libpng-dev \ + libfreetype6-dev \ + unzip +apt-get clean +rm -rf /var/lib/apt/lists/* + +# Customize the http & php environment +cp "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" +cat >/etc/apache2/conf-available/remoteip.conf <//' + +set -xeuo pipefail +LB_TARBALL_URL="https://api.github.com/repos/LibreBooking/librebooking/tarball/${APP_GH_REF}" +curl \ + --fail \ + --silent \ + --location "${LB_TARBALL_URL}" | + tar --extract --gzip --directory=/var/www/html --strip-components=1 +if [ "${APP_GH_ADD_SHA}" = "true" ]; then + LB_SHORT_SHA="" + # TARBALL_FILENAME will be like the result of a `git describe` For + # example: 'LibreBooking-librebooking-v4.1.0-126-g6cc8a4c.tar.gz' where + # 'g6cc8a4c' is the short SHA prefixed with 'g'. So the short SHA is + # '6cc8a4c' + TARBALL_FILENAME=$( + curl \ + --head \ + --fail \ + --silent \ + --show-error \ + --location "${LB_TARBALL_URL}" | + sed -nE 's/.*filename="?([^";]+)"?.*/\1/p' + ) + LB_SHORT_SHA=$(echo "${TARBALL_FILENAME}" | sed -E 's/.*-g([0-9a-f]+)\.tar\.gz/\1/') + if [ -n "${LB_SHORT_SHA}" ]; then + printf '%s\n' "${LB_SHORT_SHA}" >/var/www/html/config/version-suffix.txt + else + echo "ERROR determining the LB_SHORT_SHA value from TARBALL_FILENAME ${TARBALL_FILENAME}" >&2 + exit 1 + fi +fi +if [ -f /var/www/html/composer.json ]; then + sed \ + -i /var/www/html/composer.json \ + -e "s:\(.*\)nickdnk/graph-sdk\(.*\)7.0\(.*\):\1joelbutcher/facebook-graph-sdk\26.1\3:" + composer install +fi +sed \ + -i /var/www/html/database_schema/create-user.sql \ + -e "s:^DROP USER ':DROP USER IF EXISTS ':g" \ + -e "s:booked_user:schedule_user:g" \ + -e "s:localhost:%:g" +if ! [ -d /var/www/html/tpl_c ]; then + mkdir /var/www/html/tpl_c +fi +mkdir /var/www/html/Web/uploads/reservation + +chown www-data:root \ + /var/www/html/config \ + /var/www/html/tpl_c \ + /var/www/html/Web/uploads/images \ + /var/www/html/Web/uploads/reservation \ + /usr/local/etc/php/conf.d/librebooking.ini +chmod g+rwx \ + /var/www/html/config \ + /var/www/html/tpl_c \ + /var/www/html/Web/uploads/images \ + /var/www/html/Web/uploads/reservation \ + /usr/local/etc/php/conf.d/librebooking.ini +chown --recursive www-data:root \ + /var/www/html/plugins +chmod --recursive g+rwx \ + /var/www/html/plugins