Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker /etc/cont.init.d/ scripts for installation of Jython and the Helper Libraries for openHAB Scripted Automation #215

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 199 additions & 0 deletions Docker/cont-init.d/10-jsr223-jython
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
#!/bin/bash

## Jython Version
# The Jython verion to install when using the default download location.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verion

version

#
# For example:
# JYTHON_VERSION="2.7.1"
#
# Leave empty to use the default version (2.7.0)
JYTHON_VERSION=


## Additional Python Modules
# List of additional python module(s) that need to be installed.
#
# NOTE: Due to bugs in the Jython 2.7.0 and 2.7.1 installer, pip is only installed when
# using a Debian based image on x86 architecture. When using an Alpine based image or
# when using ARM (e.g. Raspberry Pi) architecture pip will not be installed and this
# parameter is ignored.
#
# For example:
# PYPI_MODULES="requests python-dateutil"
#
# Leave empty when no additional python module need to be installed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

python module

Python modules

PYPI_MODULES=


## Jython Installer Download Location
# The location from where to download the Jython Installer.
#
# For example:
# JYTHON_INSTALLER_URI=http://www.example.com/jython-installer-2.7.0.jar
#
# Or file location inside the container:
# JYTHON_INSTALLER_URI=/openhab/jython-installer/jython-installer-2.7.0.jar
#
# Leave empty to use the default location.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the default location? Maybe move the definition to here?

JYTHON_INSTALLER_URI=


## Jython Installer Options
# Specifiy the command line options that will be used when running the jython-installer.jar.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specifiy

Specify

#
# For example:
# JYTHON_INSTALLER_OPTIONS="-t standard -e demo doc src ensurepip"
#
# Leave empty to use the default options.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the default options? Maybe move the definition to here?

JYTHON_INSTALLER_OPTIONS=



####################################################################################
# End of configuration
####################################################################################

IFS=" "
set +e

function beginswith() { case $2 in "$1"*) true;; *) false;; esac; }
function contains() { case $2 in *"$1"*) true;; *) false;; esac; }

function check_addons_config() {
# Check if the Next Generation Rule Engine is enabled
MISC_LINE=$(grep '^[[:space:]]\?misc' $1)
if [ $? -eq 0 ]; then
# ensure we have ruleengine enabled
if [[ ${MISC_LINE} == *"ruleengine"* ]]; then
return 0
fi
fi

return 1
}

function check_next_generation_rule_engine() {

if check_addons_config "${OPENHAB_CONF}/services/addons.cfg"; then
echo "New rule engine is already enabled in the addons.cfg."
elif check_addons_config "$OPENHAB_USERDATA/config/org/openhab/addons.config"; then
echo "New rule engine is already enabled in the addons.config."
else
echo "Please enable the Next Generation Rule Engine."
echo "See https://www.openhab.org/docs/configuration/rules-ng.html"
fi
}

function cleanup_compiled_classes() {
# Clears Jython's compiled classes
if [ -d "${OPENHAB_CONF}/automation/lib/python" ]; then
find "${OPENHAB_CONF}/automation/lib/python" -name '*\$py.class' -delete
fi
if [ -d "${JYTHON_HOME}/Lib" ]; then
find "${JYTHON_HOME}/Lib" -name '*\$py.class' -delete
fi
}

function create_directory() {
local DIRECTORY=$1
if [ ! -d "${DIRECTORY}" ]; then
mkdir -p "${DIRECTORY}"
if [ $? -ne 0 ]; then
echo "ERROR: Could not create directory ${DIRECTORY}."
exit 1
fi
else
echo "Directory ${DIRECTORY} already exists."
fi
}

function download_jython_libraries() {
# Download or copy Jython installer
if [ -z "${JYTHON_INSTALLER_URI}" ]; then
JYTHON_INSTALLER_URI=${JYTHON_DEFAULT_INSTALLER_URI}
fi

if beginswith http "${JYTHON_INSTALLER_URI}"; then
wget -nv -O /tmp/jython-installer.jar "${JYTHON_INSTALLER_URI}"
if [ $? -ne 0 ]; then
echo "ERROR: Failed to download the helper libraries form ${JYTHON_INSTALLER_URI}"
exit 1
fi
else
cp "${JYTHON_INSTALLER_URI}" /tmp/jython-installer.jar
if [ $? -ne 0 ]; then
echo "ERROR: Failed to copy the helper libraries form ${JYTHON_INSTALLER_URI} to /tmp/jython-installer.jar"
exit 1
fi
fi
}

function install_additional_python_modules() {
if [ ! -z "${PYPI_MODULES}" ]; then
if is_pip_installed; then
"${JYTHON_HOME}/bin/jython" -m pip install ${PYPI_MODULES}
chown -R openhab:openhab "${JYTHON_HOME}/Lib"
if [ $? -ne 0 ]; then
echo "ERROR: Failed to install additional python packages."
exit 1
fi
else
echo "ERROR: Cannot install additional Python modules because pip is not installed."
fi
fi
}

function install_jython_libraries() {
create_directory "${JYTHON_HOME}"

if [ -z ${JYTHON_INSTALLER_OPTIONS} ]; then
JYTHON_INSTALLER_OPTIONS=${JYTHON_DEFAULT_INSTALLER_OPTIONS}
if ! is_distro_pip_compatible; then
echo "The distro and/or platform architecture is not compatible with pip!"
echo "Pip will not be installed."
JYTHON_INSTALLER_OPTIONS="${JYTHON_INSTALLER_OPTIONS} ensurepip"
fi
fi

java -jar /tmp/jython-installer.jar -s -d "${JYTHON_HOME}/" ${JYTHON_INSTALLER_OPTIONS}
rm /tmp/jython-installer.jar
chown -R openhab:openhab "${JYTHON_HOME}"
}

function is_distro_pip_compatible() {
if [ "${ARCH}" != "x86_64" ] || contains alpline "${DOCKER_REPO}"; then
return 1
else
return 0
fi
}

function is_pip_installed() {
if [ -e "${JYTHON_HOME}/bin/pip" ]; then
return 0
else
return 1
fi
}


if [ -z ${JYTHON_VERSION} ]; then
JYTHON_VERSION="2.7.0"
fi

JYTHON_DEFAULT_INSTALLER_URI=http://central.maven.org/maven2/org/python/jython-installer/${JYTHON_VERSION}/jython-installer-${JYTHON_VERSION}.jar
JYTHON_DEFAULT_INSTALLER_OPTIONS="-t standard -e demo doc src"

JYTHON_HOME="${OPENHAB_CONF}/automation/jython"
export EXTRA_JAVA_OPTS="${EXTRA_JAVA_OPTS} -Xbootclasspath/a:${JYTHON_HOME}/jython.jar -Dpython.home=${JYTHON_HOME} -Dpython.path=${JYTHON_HOME}/Lib:${OPENHAB_CONF}/automation/lib/python"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

${JYTHON_HOME}/Lib

I don't believe this is necessary, since this directory is added to sys.path... https://jython.readthedocs.io/en/latest/chapter7/#module-search-path-and-loading



if [ ! -d "${JYTHON_HOME}" ]; then
download_jython_libraries
install_jython_libraries
fi

check_next_generation_rule_engine
install_additional_python_modules
cleanup_compiled_classes

188 changes: 188 additions & 0 deletions Docker/cont-init.d/10-openhab-helper-libraries
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
#!/bin/bash -x

OPENHAB_AUTOMATION="${OPENHAB_CONF}/automation"
OPENHAB_HL_AUTOMATION="${OPENHAB_AUTOMATION}/openhab-helper-libraries/Core/automation"
OPENHAB_HL_AUTOMATION_RELATIVE="../../openhab-helper-libraries/Core/automation"
OPENHAB_HL_URL="https://github.com/openhab-scripters/openhab-helper-libraries/archive/master.zip"

declare -A LANGUAGES=( ["groovy"]="groovy" ["javascript"]="js" ["python"]="py" )

function verify_directory_structure() {
# before making any changes let's first verify that we can make the required changes
verify_directory "${OPENHAB_AUTOMATION}"
for SUBDIR in jsr223 lib; do
verify_directory "${OPENHAB_AUTOMATION}/${SUBDIR}"
for LANGUAGE in "${!LANGUAGES[@]}"; do
verify_directory "${OPENHAB_AUTOMATION}/${SUBDIR}/$LANGUAGE/community"
verify_directory "${OPENHAB_AUTOMATION}/${SUBDIR}/$LANGUAGE/personal"

verify_symlink "${OPENHAB_AUTOMATION}/${SUBDIR}/${LANGUAGE}" "core" "${OPENHAB_HL_AUTOMATION_RELATIVE}/${SUBDIR}/${LANGUAGE}/core"
done
done
}

function create_directory_structure() {
create_directory "${OPENHAB_AUTOMATION}"
for SUBDIR in jsr223 lib; do
create_directory "${OPENHAB_AUTOMATION}/${SUBDIR}"
for LANGUAGE in "${!LANGUAGES[@]}"; do
create_directory "${OPENHAB_AUTOMATION}/${SUBDIR}/$LANGUAGE/community"
chmod g+w "${OPENHAB_AUTOMATION}/${SUBDIR}/$LANGUAGE/community"
create_directory "${OPENHAB_AUTOMATION}/${SUBDIR}/$LANGUAGE/personal"
chmod g+w "${OPENHAB_AUTOMATION}/${SUBDIR}/$LANGUAGE/personal"

create_symlink "${OPENHAB_AUTOMATION}/${SUBDIR}/${LANGUAGE}" "core" "${OPENHAB_HL_AUTOMATION_RELATIVE}/${SUBDIR}/${LANGUAGE}/core"
done
done
}

function verify_directory() {
local DIRECTORY=$1
if [ -L "${DIRECTORY}" ]; then
echo "ERROR: Cannot create directory ${DIRECTORY}. A symlink with that link name already exists."
exit 1
elif [ -f "${DIRECTORY}" ]; then
echo "ERROR: Cannot create directory ${DIRECTORY}. A file with that name already exists."
exit 1
fi
}

function create_directory() {
local DIRECTORY=$1
if [ ! -d "${DIRECTORY}" ]; then
mkdir -p "${DIRECTORY}"
if [ $? -ne 0 ]; then
echo "ERROR: Could not create directory ${DIRECTORY}."
exit 1
fi
else
echo "Directory ${DIRECTORY} already exists."
fi
}

function verify_symlink() {
local LINK_DIR=$1
local LINK_NAME=$2
local TARGET=$3
if [ -d ${LINK_DIR} ]; then
cd "${LINK_DIR}"
if [ -L "${LINK_NAME}" ]; then
local LINK_TARGET="$(readlink ${LINK_NAME})"
if [ "${LINK_TARGET}" != "${TARGET}" ]; then
echo "ERROR: A symlink with ${LINK_NAME} already exists pointing to a different target."
exit 1
fi
elif [ -e "${LINK_NAME}" ]; then
echo "ERROR: File or directory with name ${LINK_NAME} already exists."
exit 1
fi
fi
}

function create_symlink() {
local LINK_DIR=$1
local LINK_NAME=$2
local TARGET=$3
cd "${LINK_DIR}"
if [ ! -L "${LINK_NAME}" ]; then
ln -rs "${TARGET}" "${LINK_NAME}"
if [ $? -ne 0 ]; then
echo "ERROR: Could not create symlink ${LINK_NAME} to ${TARGET}."
exit 1
fi
else
echo "Symlink ${LINK_NAME} already exists."
fi
}

function create_initial_configuration() {
for LANGUAGE in "${!LANGUAGES[@]}"; do
if [ ! -f "${OPENHAB_AUTOMATION}/lib/${LANGUAGE}/configuration.${LANGUAGES[$LANGUAGE]}" ]; then
cp "${OPENHAB_HL_AUTOMATION}/lib/${LANGUAGE}/configuration.${LANGUAGES[$LANGUAGE]}.example" "${OPENHAB_AUTOMATION}/lib/${LANGUAGE}/configuration.${LANGUAGES[$LANGUAGE]}"
fi
done

for DIRECTORY in community personal; do
if [ ! -f "${OPENHAB_AUTOMATION}/lib/python/${DIRECTORY}/__init__.py" ]; then
touch "${OPENHAB_AUTOMATION}/lib/python/${DIRECTORY}/__init__.py"
fi
done
}

function download_helper_libraries() {
# Download the Helper Libraries for openHAB Scripted Automation
echo "Downloading openhab-helper-libraries-master archive from Github."
wget -nv -O /tmp/openhab-helper-libraries-master.zip "${OPENHAB_HL_URL}"
if [ $? -ne 0 ]; then
echo "ERROR: Failed to download the helper libraries form Github."
exit 1
fi

unzip -q /tmp/openhab-helper-libraries-master.zip -d /tmp -x \
"openhab-helper-libraries-master/.github/*" \
"openhab-helper-libraries-master/.gitignore" \
"openhab-helper-libraries-master/docs/*" \
"openhab-helper-libraries-master/Docker/*" \
"openhab-helper-libraries-master/Sphinx/*"
if [ $? != 0 ]; then
echo "ERROR: Failed to extract the helper libraries zip file."
exit 1
fi

rm /tmp/openhab-helper-libraries-master.zip
}

function install_helper_libraries() {
mv /tmp/openhab-helper-libraries-master "${OPENHAB_AUTOMATION}/openhab-helper-libraries"
# update ownership
chown -R openhab:openhab "${OPENHAB_AUTOMATION}"
}

function check_addons_config() {
# Check if the Next Generation Rule Engine is enabled
MISC_LINE=$(grep '^[[:space:]]\?misc' $1)
if [ $? -eq 0 ]; then
# ensure we have ruleengine enabled
if [[ ${MISC_LINE} == *"ruleengine"* ]]; then
return 0
fi
fi

return 1
}

function check_next_generation_rule_engine() {

if check_addons_config "${OPENHAB_CONF}/services/addons.cfg"; then
echo "New rule engine is already enabled in the addons.cfg."
elif check_addons_config "$OPENHAB_USERDATA/config/org/openhab/addons.config"; then
echo "New rule engine is already enabled in the addons.config."
else
echo "Please enable the Next Generation Rule Engine."
echo "See https://www.openhab.org/docs/configuration/rules-ng.html"
fi
}


if [ ! -d "${OPENHAB_AUTOMATION}/openhab-helper-libraries" ]; then
CURRENT_DIR=$(pwd)

# verify if installation is possible
verify_directory_structure
download_helper_libraries

# make the required changes and install the libraries
create_directory_structure
install_helper_libraries

# create initial configuration if required
create_initial_configuration

# check if the ng-rule engine is enabled
check_next_generation_rule_engine

cd "${CURRENT_DIR}"
else
echo "Helper Libraries for openHAB Scripted Automation already installed."
fi