pgadmin4/pkg/linux/build-functions.sh

256 lines
11 KiB
Bash
Raw Normal View History

2022-08-10 05:34:40 -05:00
# shellcheck shell=bash
_setup_env() {
echo "Setting up the environment..."
2022-08-10 05:34:40 -05:00
WD=$(cd "$(dirname "$1")" && pwd)
SOURCEDIR=$(realpath "${WD}/../..")
BUILDROOT=$(realpath "${WD}/../../$2-build")
DESKTOPROOT=${BUILDROOT}/desktop
METAROOT=${BUILDROOT}/meta
SERVERROOT=${BUILDROOT}/server
WEBROOT=${BUILDROOT}/web
DISTROOT=$(realpath "${WD}/../../dist")
APP_RELEASE=$(grep "^APP_RELEASE" web/version.py | cut -d"=" -f2 | sed 's/ //g')
APP_REVISION=$(grep "^APP_REVISION" web/version.py | cut -d"=" -f2 | sed 's/ //g')
APP_NAME=$(grep "^APP_NAME" web/branding.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //' | sed 's/ //g' | tr '[:upper:]' '[:lower:]')
APP_LONG_VERSION=${APP_RELEASE}.${APP_REVISION}
APP_SUFFIX=$(grep "^APP_SUFFIX" web/version.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g")
2022-08-10 09:54:51 -05:00
if [ -n "${APP_SUFFIX}" ]; then
APP_LONG_VERSION=${APP_LONG_VERSION}-${APP_SUFFIX}
fi
# Setting up the correct Python version for Ubuntu 18 and EL-8, which have
# new Python versions installed parallel to the old ones.
OS_VERSION=$(grep "^VERSION_ID=" /etc/os-release | awk -F "=" '{ print $2 }' | sed 's/"//g' | awk -F "." '{ print $1 }')
SYSTEM_PYTHON_PATH='/usr/bin/python3'
PYTHON_BINARY=$("${SYSTEM_PYTHON_PATH}" -c "import sys; print('python%d.%.d' % (sys.version_info.major, sys.version_info.minor))")
PYTHON_BINARY_WITHOUT_DOTS='python3'
if [ "$2" == 'redhat' ] && [ "${OS_VERSION}" == "8" ]; then
SYSTEM_PYTHON_PATH='/usr/bin/python3.9'
PYTHON_BINARY='python3.9'
PYTHON_BINARY_WITHOUT_DOTS='python39'
fi
}
_cleanup() {
echo "Cleaning up the old environment and app..."
2022-08-10 05:34:40 -05:00
if test -f "${SOURCEDIR}/runtime/pgAdmin4"; then
rm -rf "${SOURCEDIR}/runtime/pgAdmin4"
fi
2022-08-10 05:34:40 -05:00
if test -d "${BUILDROOT}"; then
rm -rf "${BUILDROOT}"
fi
2022-08-10 05:34:40 -05:00
rm -f "${DISTROOT}/pgadmin4"*".$1"
}
_setup_dirs() {
echo "Creating output directories..."
2022-08-10 05:34:40 -05:00
test -d "${BUILDROOT}" || mkdir "${BUILDROOT}"
test -d "${DESKTOPROOT}" || mkdir "${DESKTOPROOT}"
test -d "${METAROOT}" || mkdir "${METAROOT}"
test -d "${SERVERROOT}" || mkdir "${SERVERROOT}"
test -d "${WEBROOT}" || mkdir "${WEBROOT}"
test -d "${DISTROOT}" || mkdir "${DISTROOT}"
}
_create_python_virtualenv() {
echo "Creating the virtual environment..."
2022-08-10 05:34:40 -05:00
cd "${SERVERROOT}" || exit
# Create the required directories
mkdir -p "usr/${APP_NAME}"
2022-08-10 05:34:40 -05:00
cd "usr/${APP_NAME}" || exit
# Create the blank venv
"${SYSTEM_PYTHON_PATH}" -m venv venv
2022-08-10 05:34:40 -05:00
# shellcheck disable=SC1091
. venv/bin/activate
# Make sure we have the wheel package present, as well as the latest pip
pip3 install --upgrade pip
pip3 install setuptools
pip3 install wheel
# Install the requirements
pip3 install --no-cache-dir --no-binary psycopg -r "${SOURCEDIR}/requirements.txt"
# Fixup the paths in the venv activation scripts
sed -i 's/VIRTUAL_ENV=.*/VIRTUAL_ENV="\/usr\/pgadmin4\/venv"/g' venv/bin/activate
sed -i 's/setenv VIRTUAL_ENV .*/setenv VIRTUAL_ENV "\/usr\/pgadmin4\/venv"/g' venv/bin/activate.csh
sed -i 's/set -gx VIRTUAL_ENV .*/set -gx VIRTUAL_ENV "\/usr\/pgadmin4\/venv"/g' venv/bin/activate.fish
# Remove __pycache__
find . -name "__pycache__" -type d -print0 | xargs -0 rm -rf
# Fixup hash bangs
sed -i 's/#!.*\/python3/#\!\/usr\/pgadmin4\/venv\/bin\/python3/g' venv/bin/*
# Figure out some paths for use when completing the venv
# Use "python3" here as we want the venv path
DIR_PYMODULES_PATH=$(python3 -c "from sysconfig import get_path; print(get_path('platstdlib'))")
# Use {SYSTEM_PYTHON_PATH} here as we want the system path
2022-08-10 05:34:40 -05:00
if [ "$1" == "debian" ]; then
PYSYSLIB_PATH=$("${SYSTEM_PYTHON_PATH}" -c "import sys; print('%s/lib/python%d.%.d' % (sys.prefix, sys.version_info.major, sys.version_info.minor))")
else
PYSYSLIB_PATH=$("${SYSTEM_PYTHON_PATH}" -c "import sys; print('%s/lib64/python%d.%.d' % (sys.prefix, sys.version_info.major, sys.version_info.minor))")
fi
# Symlink in the rest of the Python libs. This is required because the runtime
# will clear PYTHONHOME for safety, which has the side-effect of preventing
# it from finding modules that are not explicitly included in the venv
2022-08-10 05:34:40 -05:00
cd "${DIR_PYMODULES_PATH}" || exit
# Files
2022-08-10 05:34:40 -05:00
for FULLPATH in "${PYSYSLIB_PATH}"/*.py; do
FILE=${FULLPATH##*/}
2022-08-10 05:34:40 -05:00
if [ ! -e "${FILE}" ]; then
ln -s "${FULLPATH}" "${FILE}"
fi
done
# Paths
2022-08-10 05:34:40 -05:00
for FULLPATH in "${PYSYSLIB_PATH}"/*/; do
FULLPATH=${FULLPATH%*/}
FILE=${FULLPATH##*/}
2022-08-10 05:34:40 -05:00
if [ ! -e "${FILE}" ]; then
ln -s "${FULLPATH}" "${FILE}"
fi
done
# Remove tests
2022-08-10 05:34:40 -05:00
cd site-packages || exit
find . -name "test" -type d -print0 | xargs -0 rm -rf
find . -name "tests" -type d -print0 | xargs -0 rm -rf
# Link the python<version> directory to python so that the private environment path is found by the application.
2022-08-10 05:34:40 -05:00
if test -d "${DIR_PYMODULES_PATH}"; then
2022-08-10 09:54:51 -05:00
ln -s "$(basename "${DIR_PYMODULES_PATH}")" "${DIR_PYMODULES_PATH}/../python"
fi
}
_build_runtime() {
echo "Assembling the desktop runtime..."
# Get a fresh copy of electron.
ELECTRON_ARCH="x64"
if [ "$(uname -m)" == "arm64" ]; then
ELECTRON_ARCH="arm64"
fi
ELECTRON_VERSION=$(yarn info electron | grep latest | awk -F "'" '{ print $2}')
2022-08-10 05:34:40 -05:00
pushd "${BUILDROOT}" > /dev/null || exit
while true;do
wget "https://github.com/electron/electron/releases/download/v${ELECTRON_VERSION}/electron-v${ELECTRON_VERSION}-linux-${ELECTRON_ARCH}.zip" && break
rm "electron-v${ELECTRON_VERSION}-linux-${ELECTRON_ARCH}.zip"
done
unzip "electron-v${ELECTRON_VERSION}-linux-${ELECTRON_ARCH}.zip" -d "electron-v${ELECTRON_VERSION}-linux-${ELECTRON_ARCH}"
2022-08-10 05:34:40 -05:00
popd > /dev/null || exit
# Copy electron into the staging directory
mkdir -p "${DESKTOPROOT}/usr/${APP_NAME}/bin"
# Change the permission for others and group the same as the owner
chmod -R og=u "${BUILDROOT}/electron-v${ELECTRON_VERSION}-linux-${ELECTRON_ARCH}"/*
# Explicitly remove write permissions for others and group
chmod -R og-w "${BUILDROOT}/electron-v${ELECTRON_VERSION}-linux-${ELECTRON_ARCH}"/*
BUNDLEDIR="${DESKTOPROOT}/usr/${APP_NAME}/bin"
# WGET:
cp -r "${BUILDROOT}/electron-v${ELECTRON_VERSION}-linux-${ELECTRON_ARCH}"/* "${BUNDLEDIR}"
# WGET END
mv "${BUNDLEDIR}/electron" "${BUNDLEDIR}/${APP_NAME}"
mkdir -p "${BUNDLEDIR}/resources/app"
cp -r "${SOURCEDIR}/runtime/assets" "${BUNDLEDIR}/resources/app/assets"
cp -r "${SOURCEDIR}/runtime/src" "${BUNDLEDIR}/resources/app/src"
cp "${SOURCEDIR}/runtime/package.json" "${BUNDLEDIR}/resources/app"
yarn --cwd "${BUNDLEDIR}/resources/app" install --production=true
# Create the icon
mkdir -p "${DESKTOPROOT}/usr/share/icons/hicolor/128x128/apps/"
cp "${SOURCEDIR}/pkg/linux/pgadmin4-128x128.png" "${DESKTOPROOT}/usr/share/icons/hicolor/128x128/apps/${APP_NAME}.png"
mkdir -p "${DESKTOPROOT}/usr/share/icons/hicolor/64x64/apps/"
cp "${SOURCEDIR}/pkg/linux/pgadmin4-64x64.png" "${DESKTOPROOT}/usr/share/icons/hicolor/64x64/apps/${APP_NAME}.png"
mkdir -p "${DESKTOPROOT}/usr/share/icons/hicolor/48x48/apps/"
cp "${SOURCEDIR}/pkg/linux/pgadmin4-48x48.png" "${DESKTOPROOT}/usr/share/icons/hicolor/48x48/apps/${APP_NAME}.png"
mkdir -p "${DESKTOPROOT}/usr/share/icons/hicolor/32x32/apps/"
cp "${SOURCEDIR}/pkg/linux/pgadmin4-32x32.png" "${DESKTOPROOT}/usr/share/icons/hicolor/32x32/apps/${APP_NAME}.png"
mkdir -p "${DESKTOPROOT}/usr/share/icons/hicolor/16x16/apps/"
cp "${SOURCEDIR}/pkg/linux/pgadmin4-16x16.png" "${DESKTOPROOT}/usr/share/icons/hicolor/16x16/apps/${APP_NAME}.png"
mkdir -p "${DESKTOPROOT}/usr/share/applications"
cp "${SOURCEDIR}/pkg/linux/pgadmin4.desktop" "${DESKTOPROOT}/usr/share/applications"
}
_build_docs() {
echo "Building the documentation..."
cd "${SERVERROOT}" && mkdir -p "usr/${APP_NAME}/share/docs/en_US/html"
2022-08-10 05:34:40 -05:00
cd "${SOURCEDIR}/docs/en_US" || exit
python3 build_code_snippet.py
SYS_PYTHONPATH=$("${SYSTEM_PYTHON_PATH}" -c "import sys; print(':'.join([p for p in sys.path if p]))")
2022-08-10 10:43:48 -05:00
# shellcheck disable=SC2153
PYTHONPATH=$PYTHONPATH:${SYS_PYTHONPATH} python3 -msphinx . "${SERVERROOT}/usr/${APP_NAME}/share/docs/en_US/html"
}
_copy_code() {
echo "Copying the server code..."
OS_VERSION=$(grep "^VERSION_ID=" /etc/os-release | awk -F "=" '{ print $2 }' | sed 's/"//g' | awk -F "." '{ print $1 }')
if [ "$1" == 'redhat' ] && [ "${OS_VERSION}" == "8" ]; then
echo "Setting file permission through umask..."
umask u+rwx,go+rx,go-w
fi
# Remove any TCL-related files that may cause us problems
find "${SERVERROOT}/usr/${APP_NAME}/venv/" -name "_tkinter*" -print0 | xargs -0 rm -rf
2022-08-10 05:34:40 -05:00
pushd "${SOURCEDIR}/web" > /dev/null || exit
yarn install
yarn run bundle
2022-08-10 05:34:40 -05:00
popd > /dev/null || exit
# copy the web directory to the bundle as it is required by runtime
cp -r "${SOURCEDIR}/web" "${SERVERROOT}/usr/${APP_NAME}/web/"
cp "${SOURCEDIR}/pkg/linux/config_distro.py" "${SERVERROOT}/usr/${APP_NAME}/web/"
2022-08-10 05:34:40 -05:00
cd "${SERVERROOT}/usr/${APP_NAME}/web/" || exit
rm -f pgadmin4.db config_local.*
rm -rf jest.config.js babel.* package.json node_modules/ regression/ tools/ pgadmin/static/js/generated/.cache
find . -name "tests" -type d -print0 | xargs -0 rm -rf
find . -name "feature_tests" -type d -print0 | xargs -0 rm -rf
find . -name "__pycache__" -type d -print0 | xargs -0 rm -rf
# License files
cp "${SOURCEDIR}/LICENSE" "${SERVERROOT}/usr/${APP_NAME}/"
cp "${SOURCEDIR}/DEPENDENCIES" "${SERVERROOT}/usr/${APP_NAME}/"
# Web setup script
mkdir -p "${WEBROOT}/usr/${APP_NAME}/bin/"
cp "${SOURCEDIR}/pkg/linux/setup-web.sh" "${WEBROOT}/usr/${APP_NAME}/bin/"
# Ensure our venv will use the correct Python interpreter, even if the
# user has configured an alternative default.
# DO THIS LAST!
2022-08-10 05:34:40 -05:00
cd "${SERVERROOT}/usr/${APP_NAME}/venv/bin" || exit
PYTHON_INTERPRETER=$("${SYSTEM_PYTHON_PATH}" -c "import os, sys; print(os.path.realpath(sys.executable))")
PYTHON_VERSION=$("${SYSTEM_PYTHON_PATH}" -c "import sys; print('%d.%d' % (sys.version_info.major, sys.version_info.minor))")
rm python && ln -s python3 python
2022-08-10 05:34:40 -05:00
rm "python${PYTHON_VERSION}" && ln -s python3 "python${PYTHON_VERSION}"
rm python3 && ln -s "${PYTHON_INTERPRETER}" python3
}
_generate_sbom() {
echo "Generating SBOMs..."
# Note that we don't generate an SBOM for the Meta package as it doesn't contain any files.
syft "${SERVERROOT}/" -o cyclonedx-json > "${SERVERROOT}/usr/${APP_NAME}/sbom-server.json"
syft "${DESKTOPROOT}/" -o cyclonedx-json > "${DESKTOPROOT}/usr/${APP_NAME}/sbom-desktop.json"
syft "${WEBROOT}/" -o cyclonedx-json > "${WEBROOT}/usr/${APP_NAME}/sbom-web.json"
}