diff --git a/conf/systemd.service b/conf/systemd.service index 2ecd49c..ccd671c 100644 --- a/conf/systemd.service +++ b/conf/systemd.service @@ -7,7 +7,7 @@ PIDFile=__FINALPATH__/__APP__-pid User=__APP__ Group=__APP__ WorkingDirectory=__FINALPATH__ -ExecStart=__PYTHON_PATH__/gunicorn -c __FINALPATH__/gunicorn.py wsgi:app --pid __FINALPATH__/__APP__-pid +ExecStart=__PYTHON_PATH__/gunicorn -c __FINALPATH__/venv/bin/gunicorn.py wsgi:app --pid __FINALPATH__/__APP__-pid ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID PrivateTmp=true diff --git a/scripts/_common.sh b/scripts/_common.sh index 41eb8bd..bc48e71 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -5,9 +5,7 @@ #================================================= # dependencies used by the app -pkg_dependencies="curl" - -PYTHON_VERSION=3.7.3 +pkg_dependencies="python3-venv python3-dev python3-pip" #================================================= # PERSONAL HELPERS diff --git a/scripts/install b/scripts/install index e208ff9..64f5dc5 100755 --- a/scripts/install +++ b/scripts/install @@ -7,7 +7,6 @@ #================================================= source _common.sh -source ynh_install_python source /usr/share/yunohost/helpers #================================================= @@ -84,7 +83,6 @@ ynh_app_setting_set --app=$app --key=port --value=$port ynh_script_progression --message="Installing dependencies..." --weight=1 ynh_install_app_dependencies $pkg_dependencies -ynh_install_python --python_version=$PYTHON_VERSION #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE @@ -119,10 +117,10 @@ ynh_system_user_create --username=$app --home_dir="$final_path" ynh_script_progression --message="Installing Python dependencies..." pushd $final_path - ynh_use_python - $ynh_pip install --upgrade pip - $ynh_pip install -r requirements.txt - $ynh_pip install gunicorn + python3 -m venv venv + venv/bin/pip install --upgrade pip + venv/bin/pip install -r requirements.txt + venv/bin/pip install gunicorn mkdir -p /var/log/$app chown -R $app:www-data /var/log/$app cat <> wsgi.py @@ -139,7 +137,7 @@ popd ynh_script_progression --message="Configuring a systemd service..." --weight=1 # Create a dedicated systemd config -ynh_add_systemd_config --others_var="python_path" +ynh_add_systemd_config #================================================= # MODIFY A CONFIG FILE diff --git a/scripts/remove b/scripts/remove index feedb2a..73412c9 100755 --- a/scripts/remove +++ b/scripts/remove @@ -7,7 +7,6 @@ #================================================= source _common.sh -source ynh_install_python source /usr/share/yunohost/helpers #================================================= diff --git a/scripts/restore b/scripts/restore index d2502d2..6f48eb9 100755 --- a/scripts/restore +++ b/scripts/restore @@ -8,7 +8,6 @@ # Keep this path for calling _common.sh inside the execution's context of backup and restore scripts source ../settings/scripts/_common.sh -source ../settings/scripts/ynh_install_python source /usr/share/yunohost/helpers #================================================= @@ -75,7 +74,6 @@ ynh_script_progression --message="Reinstalling dependencies..." --weight=1 # Define and install dependencies ynh_install_app_dependencies $pkg_dependencies -ynh_install_python --python_version=$PYTHON_VERSION #================================================= # INSTALL PYTHON DEPENDENCIES @@ -83,10 +81,10 @@ ynh_install_python --python_version=$PYTHON_VERSION ynh_script_progression --message="Installing Python dependencies..." pushd $final_path - ynh_use_python - $ynh_pip install --upgrade pip - $ynh_pip install -r requirements.txt - $ynh_pip install gunicorn + python3 -m venv venv + venv/bin/pip install --upgrade pip + venv/bin/pip install -r requirements.txt + venv/bin/pip install gunicorn mkdir -p /var/log/$app chown -R $app:www-data /var/log/$app popd diff --git a/scripts/upgrade b/scripts/upgrade index c0d3565..32e3dec 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -7,7 +7,6 @@ #================================================= source _common.sh -source ynh_install_python source /usr/share/yunohost/helpers #================================================= @@ -93,7 +92,6 @@ ynh_add_nginx_config ynh_script_progression --message="Upgrading dependencies..." --weight=1 ynh_install_app_dependencies $pkg_dependencies -ynh_install_python --python_version=$PYTHON_VERSION #================================================= # CREATE DEDICATED USER @@ -111,10 +109,10 @@ ynh_system_user_create --username=$app --home_dir="$final_path" ynh_script_progression --message="Installing Python dependencies..." pushd $final_path - ynh_use_python - $ynh_pip install --upgrade pip - $ynh_pip install -r requirements.txt - $ynh_pip install gunicorn + python3 -m venv venv + venv/bin/pip install --upgrade pip + venv/bin/pip install -r requirements.txt + venv/bin/pip install gunicorn mkdir -p /var/log/$app chown -R $app:www-data /var/log/$app cat <> wsgi.py @@ -131,7 +129,7 @@ popd ynh_script_progression --message="Upgrading systemd configuration..." --weight=1 # Create a dedicated systemd config -ynh_add_systemd_config --others_var="python_path" +ynh_add_systemd_config #================================================= # MODIFY A CONFIG FILE diff --git a/scripts/ynh_install_python b/scripts/ynh_install_python deleted file mode 100644 index 9c285c8..0000000 --- a/scripts/ynh_install_python +++ /dev/null @@ -1,282 +0,0 @@ -#!/bin/bash - -ynh_python_try_bash_extension() { - if [ -x src/configure ]; then - src/configure && make -C src || { - ynh_print_info --message="Optional bash extension failed to build, but things will still work normally." - } - fi -} - -pyenv_install_dir="/opt/pyenv" -python_version_path="$pyenv_install_dir/versions" -# PYENV_ROOT is the directory of pyenv, it needs to be loaded as a environment variable. -export PYENV_ROOT="$pyenv_install_dir" - -# Required dependencies -pyenv_dependencies="build-essential libssl1.0-dev|libssl-dev zlib1g-dev libbz2-dev libreadline-dev|libedit-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python-openssl git" - -# Load the version of Python for an app, and set variables. -# -# ynh_use_python has to be used in any app scripts before using Python for the first time. -# This helper will provide alias and variables to use in your scripts. -# -# To use pip or Python, use the alias `ynh_pip` and `ynh_python` -# Those alias will use the correct version installed for the app -# For example: use `ynh_pip install` instead of `pip install` -# -# With `sudo` or `ynh_exec_as`, use instead the fallback variables `$ynh_pip` and `$ynh_python` -# And propagate $PATH to sudo with $ynh_python_load_path -# Exemple: `ynh_exec_as $app $ynh_python_load_path $ynh_pip install` -# -# $PATH contains the path of the requested version of Python. -# However, $PATH is duplicated into $python_path to outlast any manipulation of $PATH -# You can use the variable `$ynh_python_load_path` to quickly load your Python version -# in $PATH for an usage into a separate script. -# Exemple: $ynh_python_load_path $final_path/script_that_use_pip.sh` -# -# -# Finally, to start a Python service with the correct version, 2 solutions -# Either the app is dependent of python or pip, but does not called it directly. -# In such situation, you need to load PATH -# `Environment="__YNH_PYTHON_LOAD_ENV_PATH__"` -# `ExecStart=__FINALPATH__/my_app` -# You will replace __YNH_PYTHON_LOAD_ENV_PATH__ with $ynh_python_load_path -# -# Or Python start the app directly, then you don't need to load the PATH variable -# `ExecStart=__YNH_PYTHON__ my_app run` -# You will replace __YNH_PYTHON__ with $ynh_python -# -# -# one other variable is also available -# - $python_path: The absolute path to Python binaries for the chosen version. -# -# usage: ynh_use_python -# -# Requires YunoHost version 2.7.12 or higher. -ynh_use_python () { - python_version=$(ynh_app_setting_get --app=$app --key=python_version) - - # Get the absolute path of this version of Python - python_path="$python_version_path/$YNH_APP_INSTANCE_NAME/bin" - - # Allow alias to be used into bash script - shopt -s expand_aliases - - # Create an alias for the specific version of Python and a variable as fallback - ynh_python="$python_path/python" - alias ynh_python="$ynh_python" - # And pip - ynh_pip="$python_path/pip" - alias ynh_pip="$ynh_pip" - - # Load the path of this version of Python in $PATH - if [[ :$PATH: != *":$python_path"* ]]; then - PATH="$python_path:$PATH" - fi - # Create an alias to easily load the PATH - ynh_python_load_path="PATH=$PATH" - - # Sets the local application-specific Python version - pushd $final_path - $pyenv_install_dir/bin/pyenv local $python_version - popd -} - -# Install a specific version of Python -# -# ynh_install_python will install the version of Python provided as argument by using pyenv. -# -# This helper creates a /etc/profile.d/pyenv.sh that configures PATH environment for pyenv -# for every LOGIN user, hence your user must have a defined shell (as opposed to /usr/sbin/nologin) -# -# Don't forget to execute python-dependent command in a login environment -# (e.g. sudo --login option) -# When not possible (e.g. in systemd service definition), please use direct path -# to pyenv shims (e.g. $PYENV_ROOT/shims/bundle) -# -# usage: ynh_install_python --python_version=python_version -# | arg: -v, --python_version= - Version of Python to install. -# -# Requires YunoHost version 2.7.12 or higher. -ynh_install_python () { - # Declare an array to define the options of this helper. - local legacy_args=v - local -A args_array=( [v]=python_version= ) - local python_version - # Manage arguments with getopts - ynh_handle_getopts_args "$@" - - # Install required dependencies - ynh_add_app_dependencies --package="$pyenv_dependencies" - - # Load pyenv path in PATH - local CLEAR_PATH="$pyenv_install_dir/bin:$PATH" - - # Remove /usr/local/bin in PATH in case of Python prior installation - PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@') - - # Move an existing Python binary, to avoid to block pyenv - #test -x /usr/bin/python && mv /usr/bin/python /usr/bin/python_pyenv - - # Install or update pyenv - pyenv="$(command -v pyenv $pyenv_install_dir/bin/pyenv | head -1)" - if [ -n "$pyenv" ]; then - ynh_print_info --message="pyenv already seems installed in \`$pyenv'." - pushd "${pyenv%/*/*}" - if git remote -v 2>/dev/null | grep "https://github.com/pyenv/pyenv.git"; then - echo "Trying to update with git..." - git pull -q --tags origin master - cd .. - ynh_python_try_bash_extension - fi - popd - else - ynh_print_info --message="Installing pyenv with git..." - mkdir -p $pyenv_install_dir - pushd $pyenv_install_dir - git init -q - git remote add -f -t master origin https://github.com/pyenv/pyenv.git > /dev/null 2>&1 - git checkout -q -b master origin/master - ynh_python_try_bash_extension - pyenv=$pyenv_install_dir/bin/pyenv - popd - fi - - pyenv_virtualenv="$(command -v "$pyenv_install_dir"/plugins/*/bin/pyenv-virtualenv pyenv-virtualenv | head -1)" - if [ -n "$pyenv_virtualenv" ]; then - ynh_print_info --message="\`pyenv virtualenv' command already available in \`$pyenv_virtualenv'." - pushd "${pyenv_virtualenv%/*/*}" - if git remote -v 2>/dev/null | grep "https://github.com/pyenv/pyenv-virtualenv.git"; then - ynh_print_info --message="Trying to update pyenv-virtualenv with git..." - git pull -q origin master - fi - popd - else - ynh_print_info --message="Installing pyenv-virtualenv with git..." - mkdir -p "${pyenv_install_dir}/plugins" - git clone -q https://github.com/pyenv/pyenv-virtualenv.git "${pyenv_install_dir}/plugins/pyenv-virtualenv" - fi - - pyenv_latest="$(command -v "$pyenv_install_dir"/plugins/*/bin/pyenv-latest pyenv-latest | head -1)" - if [ -n "$pyenv_latest" ]; then - ynh_print_info --message="\`pyenv latest' command already available in \`$pyenv_latest'." - pushd "${pyenv_latest%/*/*}" - if git remote -v 2>/dev/null | grep "https://github.com/momo-lab/xxenv-latest.git"; then - ynh_print_info --message="Trying to update xxenv-latest with git..." - git pull -q origin master - fi - popd - else - ynh_print_info --message="Installing xxenv-latest with git..." - mkdir -p "${pyenv_install_dir}/plugins" - git clone -q https://github.com/momo-lab/xxenv-latest.git "${pyenv_install_dir}/plugins/xxenv-latest" - fi - - # Enable caching - mkdir -p "${pyenv_install_dir}/cache" - - # Create shims directory if needed - mkdir -p "${pyenv_install_dir}/shims" - - # Restore /usr/local/bin in PATH - PATH=$CLEAR_PATH - - # And replace the old Python binary - # test -x /usr/bin/python_pyenv && mv /usr/bin/python_pyenv /usr/bin/python - - # Install the requested version of Python - local final_python_version=$(pyenv latest --print $python_version) - ynh_print_info --message="Installation of Python-$python_version" - pyenv install --skip-existing $final_python_version > /dev/null 2>&1 - - # Store python_version into the config of this app - ynh_app_setting_set --app=$YNH_APP_INSTANCE_NAME --key=python_version --value=$python_version - - # Remove app virtualenv - if `pyenv virtualenvs | grep --quiet "$YNH_APP_INSTANCE_NAME " 1>/dev/null 2>&1` - then - pyenv virtualenv-delete --force $YNH_APP_INSTANCE_NAME - fi - - # Create app virtualenv - pyenv virtualenv --force $python_version $YNH_APP_INSTANCE_NAME - - # Cleanup Python versions - ynh_cleanup_python - - # Set environment for Python users - echo "#pyenv -export PYENV_ROOT=$pyenv_install_dir -export PATH=\"$pyenv_install_dir/bin:$PATH\" -eval \"\$(pyenv init -)\" -#pyenv" > /etc/profile.d/pyenv.sh - - # Load the environment - eval "$(pyenv init -)" -} - -# Remove the version of Python used by the app. -# -# This helper will also cleanup Python versions -# -# usage: ynh_remove_python -ynh_remove_python () { - local python_version=$(ynh_app_setting_get --app=$YNH_APP_INSTANCE_NAME --key=python_version) - - # Load pyenv path in PATH - local CLEAR_PATH="$pyenv_install_dir/bin:$PATH" - - # Remove /usr/local/bin in PATH in case of Python prior installation - PATH=$(echo $CLEAR_PATH | sed 's@/usr/local/bin:@@') - - pyenv virtualenv-delete --force $YNH_APP_INSTANCE_NAME - - # Remove the line for this app - ynh_app_setting_delete --app=$YNH_APP_INSTANCE_NAME --key=python_version - - # Cleanup Python versions - ynh_cleanup_python -} - -# Remove no more needed versions of Python used by the app. -# -# This helper will check what Python version are no more required, -# and uninstall them -# If no app uses Python, pyenv will be also removed. -# -# usage: ynh_cleanup_python -ynh_cleanup_python () { - - # List required Python version - local installed_apps=$(yunohost app list | grep -oP 'id: \K.*$') - local required_python_versions="" - for installed_app in $installed_apps - do - local installed_app_python_version=$(ynh_app_setting_get --app=$installed_app --key="python_version") - if [[ $installed_app_python_version ]] - then - required_python_versions="${installed_app_python_version}\n${required_python_versions}" - fi - done - - # Remove no more needed Python version - local installed_python_versions=$(pyenv versions --bare --skip-aliases | grep -Ev '/') - for installed_python_version in $installed_python_versions - do - if ! `echo ${required_python_versions} | grep "${installed_python_version}" 1>/dev/null 2>&1` - then - ynh_print_info --message="Removing of Python-$installed_python_version" - $pyenv_install_dir/bin/pyenv uninstall --force $installed_python_version - fi - done - - # If none Python version is required - if [[ ! $required_python_versions ]] - then - # Remove pyenv environment configuration - ynh_print_info --message="Removing of pyenv-$pyenv_version" - ynh_secure_remove --file="$pyenv_install_dir" - ynh_secure_remove --file="/etc/profile.d/pyenv.sh" - fi -}