blob: baa1536c941acc96f11e066db77d242203cec8cb [file] [log] [blame]
#!/usr/bin/env bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
###############################################################################
###############################################################################
# OFBiz initialisation script for use as the entry point in a docker container.
#
# Triggers the loading of data and configuration of various OFBiz properties before
# executing the command given as arguments to the script.
#
#
# Behaviour controlled by environment variables:
#
# OFBIZ_SKIP_INIT
# Any non-empty value will cause this script to skip any initialisation steps.
# Default: <empty>
#
# OFBIZ_ADMIN_USER
# The username of the OFBIZ admin user.
# Default: admin
#
# OFBIZ_ADMIN_PASSWORD
# The password of the OFBIZ admin user.
# Default: ofbiz
#
# OFBIZ_DATA_LOAD
# Determine what type of data loading is required.
# Default: seed
# Values:
# - none: No data loading is performed.
# - seed: Seed data is loaded.
# - demo: Demo data is loaded.
#
# OFBIZ_HOST
# Specify the hostname used to access OFBiz.
# Used to populate the host-headers-allowed property in framework/security/config/security.properties.
# Default: default value of host-headers-allowed from framework/security/config/security.properties.
#
# OFBIZ_CONTENT_URL_PREFIX
# Used to set the content.url.prefix.secure and content.url.prefix.standard properties in
# framework/webapp/config/url.properties.
# Default: <empty>
#
# OFBIZ_ENABLE_AJP_PORT
# Enable the AJP (Apache JServe Protocol) port to allow communication with OFBiz via a reverse proxy.
# Enabled when this environment variable contains a non-empty value.
# Default value: <empty>
#
# OFBIZ_SKIP_DB_DRIVER_DOWNLOAD
# When connecting to databases other than the OFBiz embedded Derby database a suitable driver will be needed.
# This script will attempt to download a suitable driver unless the OFBIZ_SKIP_DB_DRIVER_DOWNLOAD contains a non-empty
# value.
#
# OFBIZ_POSTGRES_HOST
# Sets the name of the PostgreSQL database host.
# If OFBIZ_POSTGRES_HOST is non-empty, then the following OFBIZ_POSTGRES_* environment variables are used to configure
# access to PostgreSQL databases.
# OFBIZ_POSTGRES_OFBIZ_DB Default: ofbiz
# OFBIZ_POSTGRES_OFBIZ_USER Default: ofbiz
# OFBIZ_POSTGRES_OFBIZ_PASSWORD Default: ofbiz
# OFBIZ_POSTGRES_OLAP_DB Default: ofbizolap
# OFBIZ_POSTGRES_OLAP_USER Default: ofbizolap
# OFBIZ_POSTGRES_OLAP_PASSWORD Default: ofbizolap
# OFBIZ_POSTGRES_TENANT_DB Default: ofbiztenant
# OFBIZ_POSTGRES_TENANT_USER Default: ofbiztenant
# OFBIZ_POSTGRES_TENANT_PASSWORD Default: ofbiztenant
#
# OFBIZ_DISABLE_COMPONENTS
# Prevents loading of ofbiz-components.
# Contains a comma separated list of relative paths from the ofbiz sources directory to the ofbiz-component.xml files
# that should be prevented from loading.
# Default: plugins/birt/ofbiz-component.xml
#
# Hooks are executed at the various stages of the initialisation process by executing scripts in the following
# directories. Scripts must be executable and have the .sh extension:
#
# /docker-entrypoint-hooks/before-config-applied.d
# Executed before any changes are applied to the OFBiz configuration files.
#
# /docker-entrypoint-hooks/after-config-applied.d
# Executed after any changes are applied to the OFBiz configuration files.
#
# /docker-entrypoint-hooks/before-data-load.d
# Executed before any data loading is about to be performed. Only executed if data loading is required.
# Example usage would be to alter the data to be loaded.
#
# /docker-entrypoint-hooks/additional-data.d
# Any data files (.xml files) in this directory are loaded after seed/demo data.
#
# /docker-entrypoint-hooks/after-data-load.d
# Executed after any data loading has been performed. Only executed if data loading was required.
#
###############################################################################
set -x
set -e
trap shutdown_ofbiz SIGTERM SIGINT
CONTAINER_STATE_DIR="/ofbiz/runtime/container_state"
CONTAINER_DATA_LOADED="$CONTAINER_STATE_DIR/data_loaded"
CONTAINER_ADMIN_LOADED="$CONTAINER_STATE_DIR/admin_loaded"
CONTAINER_CONFIG_APPLIED="$CONTAINER_STATE_DIR/config_applied"
CONTAINER_DB_CONFIG_APPLIED="$CONTAINER_STATE_DIR/db_config_applied"
POSTGRES_DRIVER_URL="https://jdbc.postgresql.org/download/postgresql-42.5.4.jar"
###############################################################################
# Validate and apply defaults to any environment variables used by this script.
# See script header for environment variable descriptions.
ofbiz_setup_env() {
case "$OFBIZ_DATA_LOAD" in
none | seed | demo) ;;
*)
OFBIZ_DATA_LOAD="seed"
;;
esac
OFBIZ_ADMIN_USER=${OFBIZ_ADMIN_USER:-admin}
OFBIZ_ADMIN_PASSWORD=${OFBIZ_ADMIN_PASSWORD:-ofbiz}
OFBIZ_POSTGRES_OFBIZ_DB=${OFBIZ_POSTGRES_OFBIZ_DB:-ofbiz}
OFBIZ_POSTGRES_OFBIZ_USER=${OFBIZ_POSTGRES_OFBIZ_USER:-ofbiz}
OFBIZ_POSTGRES_OFBIZ_PASSWORD=${OFBIZ_POSTGRES_OFBIZ_PASSWORD:-ofbiz}
OFBIZ_POSTGRES_OLAP_DB=${OFBIZ_POSTGRES_OLAP_DB:-ofbizolap}
OFBIZ_POSTGRES_OLAP_USER=${OFBIZ_POSTGRES_OLAP_USER:-ofbizolap}
OFBIZ_POSTGRES_OLAP_PASSWORD=${OFBIZ_POSTGRES_OLAP_PASSWORD:-ofbizolap}
OFBIZ_POSTGRES_TENANT_DB=${OFBIZ_POSTGRES_TENANT_DB:-ofbiztenant}
OFBIZ_POSTGRES_TENANT_USER=${OFBIZ_POSTGRES_TENANT_USER:-ofbiztenant}
OFBIZ_POSTGRES_TENANT_PASSWORD=${OFBIZ_POSTGRES_TENANT_PASSWORD:-ofbiztenant}
OFBIZ_DISABLE_COMPONENTS=${OFBIZ_DISABLE_COMPONENTS-plugins/birt/ofbiz-component.xml}
}
###############################################################################
# Create the runtime container state directory used to track which initialisation
# steps have been run for the container.
# This directory should be hosted on a volume that persists for the life of the container.
create_ofbiz_runtime_directories() {
if [ ! -d "$CONTAINER_STATE_DIR" ]; then
mkdir --parents "$CONTAINER_STATE_DIR"
fi
}
###############################################################################
# Execute the shell scripts at the paths passed to this function.
# Args:
# 1: Name of the hook stage being executed. Used for logging.
# 2+: Variable number of paths to the shell scripts to be executed.
# Only scripts with the .sh extension are executed.
# Scripts will be sourced if they are not executable.
run_init_hooks() {
local hookStage="$1"
shift
local filePath
for filePath; do
case "$filePath" in
*.sh)
if [ -x "$filePath" ]; then
printf '%s: running %s\n' "$hookStage" "$filePath"
"$filePath"
else
printf '%s: sourcing %s\n' "$hookStage" "$filePath"
. "$filePath"
fi
;;
*)
printf '%s: Not a script. Ignoring %s\n' "$hookStage" "$filePath"
;;
esac
done
}
###############################################################################
# If required, load data into OFBiz.
load_data() {
if [ ! -f "$CONTAINER_DATA_LOADED" ]; then
run_init_hooks before-data-load /docker-entrypoint-hooks/before-data-load.d/*
case "$OFBIZ_DATA_LOAD" in
none) ;;
seed)
/ofbiz/bin/ofbiz --load-data readers=seed,seed-initial
;;
demo)
/ofbiz/bin/ofbiz --load-data
# Demo data includes the admin user so indicate that the user is already loaded.
touch "$CONTAINER_ADMIN_LOADED"
;;
esac
# Load any additional data files provided.
if [ -z $(find /docker-entrypoint-hooks/additional-data.d/ -prune -empty) ]; then
/ofbiz/bin/ofbiz --load-data dir=/docker-entrypoint-hooks/additional-data.d
fi
touch "$CONTAINER_DATA_LOADED"
run_init_hooks after-data-load /docker-entrypoint-hooks/after-data-load.d/*
fi
}
###############################################################################
# Create and load the password hash for the admin user.
load_admin_user() {
if [ ! -f "$CONTAINER_ADMIN_LOADED" ]; then
TMPFILE=$(mktemp)
# Concatenate a random salt and the admin password.
SALT=$(tr --delete --complement A-Za-z0-9 </dev/urandom | head --bytes=16)
SALT_AND_PASSWORD="${SALT}${OFBIZ_ADMIN_PASSWORD}"
# Take a SHA-1 hash of the combined salt and password and strip off any additional output form the sha1sum utility.
SHA1SUM_ASCII_HEX=$(printf "$SALT_AND_PASSWORD" | sha1sum | cut --delimiter=' ' --fields=1 --zero-terminated | tr --delete '\000')
# Convert the ASCII Hex representation of the hash to raw bytes by inserting escape sequences and running
# through the printf command. Encode the result as URL base 64 and remove padding.
SHA1SUM_ESCAPED_STRING=$(printf "$SHA1SUM_ASCII_HEX" | sed -e 's/\(..\)\.\?/\\x\1/g')
SHA1SUM_BASE64=$(printf "$SHA1SUM_ESCAPED_STRING" | basenc --base64url --wrap=0 | tr --delete '=')
# Concatenate the hash type, salt and hash as the encoded password value.
ENCODED_PASSWORD_HASH="\$SHA\$${SALT}\$${SHA1SUM_BASE64}"
# Populate the login data template
sed "s/@userLoginId@/$OFBIZ_ADMIN_USER/g; s/currentPassword=\".*\"/currentPassword=\"$ENCODED_PASSWORD_HASH\"/g;" framework/resources/templates/AdminUserLoginData.xml >"$TMPFILE"
# Load data from the populated template.
/ofbiz/bin/ofbiz --load-data "file=$TMPFILE"
rm "$TMPFILE"
touch "$CONTAINER_ADMIN_LOADED"
fi
}
###############################################################################
# Modify the given ofbiz-component configuration XML file to set the root
# component's 'enabled' attribute to false.
# $1 - Path to the XML file to be modified.
disable_component() {
XML_FILE="/ofbiz/$1"
if [ -f "$XML_FILE" ]; then
TMPFILE=$(mktemp)
xsltproc /ofbiz/disable-component.xslt "$XML_FILE" > "$TMPFILE"
mv "$TMPFILE" "$XML_FILE"
else
echo "Cannot find ofbiz-component configuration file. Not disabling component: $XML_FILE"
fi
}
###############################################################################
# Modify the given ofbiz-component configuration XML files to set their root
# components' 'enabled' attribute to false.
# $1 - Comma separated list of paths to configuration XML files to be modified.
disable_components() {
COMMA_SEPARATED_PATHS="$1"
if [ -n "$COMMA_SEPARATED_PATHS" ]; then
# Split the comma separated paths into separate arguments.
IFS=,
set "$COMMA_SEPARATED_PATHS"
while [ -n "$1" ]; do
disable_component "$1"
shift
done
fi
}
###############################################################################
# Apply any configuration changes required.
# Changed property files need to be placed in /ofbiz/config so they appear earlier
# in the classpath and override the build-time copies of the properties in ofbiz.jar.
apply_configuration() {
if [ ! -f "$CONTAINER_CONFIG_APPLIED" ]; then
run_init_hooks before-config-applied /docker-entrypoint-hooks/before-config-applied.d/*
if [ -n "$OFBIZ_ENABLE_AJP_PORT" ]; then
# Configure tomcat to listen for AJP connections on all interfaces within the container.
sed --in-place \
'/<property name="ajp-connector" value="connector">/ a <property name="address" value="0.0.0.0"/>' \
/ofbiz/framework/catalina/ofbiz-component.xml
fi
if [ -n "$OFBIZ_HOST" ]; then
sed "s/host-headers-allowed=.*/host-headers-allowed=${OFBIZ_HOST}/" \
framework/security/config/security.properties >config/security.properties
fi
if [ -n "$OFBIZ_CONTENT_URL_PREFIX" ]; then
sed \
--expression="s#content.url.prefix.secure=.*#content.url.prefix.secure=${OFBIZ_CONTENT_URL_PREFIX}#;" \
--expression="s#content.url.prefix.standard=.*#content.url.prefix.standard=${OFBIZ_CONTENT_URL_PREFIX}#;" \
framework/webapp/config/url.properties >config/url.properties
fi
if [ -n "$OFBIZ_DISABLE_COMPONENTS" ]; then
disable_component "$OFBIZ_DISABLE_COMPONENTS"
fi
touch "$CONTAINER_CONFIG_APPLIED"
run_init_hooks after-config-applied /docker-entrypoint-hooks/after-config-applied.d/*
fi
}
###############################################################################
# Set up the connection to the OFBiz database.
configure_database() {
if [ ! -f "$CONTAINER_DB_CONFIG_APPLIED" ]; then
if [ -n "$OFBIZ_POSTGRES_HOST" ]; then
sed \
--expression="s/@HOST@/$OFBIZ_POSTGRES_HOST/;" \
--expression="s/@OFBIZ_DB@/$OFBIZ_POSTGRES_OFBIZ_DB/;" \
--expression="s/@OFBIZ_USERNAME@/$OFBIZ_POSTGRES_OFBIZ_USER/;" \
--expression="s/@OFBIZ_PASSWORD@/$OFBIZ_POSTGRES_OFBIZ_PASSWORD/;" \
--expression="s/@OLAP_DB@/$OFBIZ_POSTGRES_OLAP_DB/;" \
--expression="s/@OLAP_USERNAME@/$OFBIZ_POSTGRES_OLAP_USER/;" \
--expression="s/@OLAP_PASSWORD@/$OFBIZ_POSTGRES_OLAP_PASSWORD/;" \
--expression="s/@TENANT_DB@/$OFBIZ_POSTGRES_TENANT_DB/;" \
--expression="s/@TENANT_USERNAME@/$OFBIZ_POSTGRES_TENANT_USER/;" \
--expression="s/@TENANT_PASSWORD@/$OFBIZ_POSTGRES_TENANT_PASSWORD/;" \
templates/postgres-entityengine.xml > config/entityengine.xml
if [ -z "$OFBIZ_SKIP_DB_DRIVER_DOWNLOAD" ]; then
echo "Retrieving PostgreSQL driver from $POSTGRES_DRIVER_URL"
wget --verbose --directory-prefix=lib-extra "$POSTGRES_DRIVER_URL"
fi
fi
touch "$CONTAINER_DB_CONFIG_APPLIED"
fi
}
###############################################################################
# Send a shutdown signal to OFBiz
shutdown_ofbiz() {
/ofbiz/send_ofbiz_stop_signal.sh
}
_main() {
if [ -z "$OFBIZ_SKIP_INIT" ]; then
ofbiz_setup_env
create_ofbiz_runtime_directories
configure_database
apply_configuration
load_data
load_admin_user
fi
unset OFBIZ_SKIP_INIT
unset OFBIZ_ADMIN_USER
unset OFBIZ_ADMIN_PASSWORD
unset OFBIZ_DATA_LOAD
unset OFBIZ_ENABLE_AJP_PORT
unset OFBIZ_HOST
unset OFBIZ_CONTENT_URL_PREFIX
unset OFBIZ_POSTGRES_OFBIZ_DB
unset OFBIZ_POSTGRES_OFBIZ_USER
unset OFBIZ_POSTGRES_OFBIZ_PASSWORD
unset OFBIZ_POSTGRES_OLAP_DB
unset OFBIZ_POSTGRES_OLAP_USER
unset OFBIZ_POSTGRES_OLAP_PASSWORD
unset OFBIZ_POSTGRES_TENANT_DB
unset OFBIZ_POSTGRES_TENANT_USER
unset OFBIZ_POSTGRES_TENANT_PASSWORD
# Continue loading OFBiz.
exec "$@"
}
_main "$@"