diff --git a/helpers/helpers.v2.1.d/utils b/helpers/helpers.v2.1.d/utils index 4c611395d..aca976c54 100644 --- a/helpers/helpers.v2.1.d/utils +++ b/helpers/helpers.v2.1.d/utils @@ -377,3 +377,82 @@ ynh_user_get_info() { ynh_user_list() { yunohost user list --output-as json --quiet | jq -r ".users | keys[]" } + +# Spawn a Bash shell with the app environment loaded +# +# usage: ynh_spawn_app_shell "appname" +# +# examples: +# ynh_spawn_app_shell "foobar" <<< 'echo "$USER"' +# ynh_spawn_app_shell "foobar" < /tmp/some_script.bash +# +# The spawned shell will have environment variables loaded and environment files sourced +# from the app's service configuration file (defaults to $app.service, overridable by the packager with `service` setting). +# If the app relies on a specific PHP version, then `php` will be aliased that version. The PHP command will also be appended with the `phpflags` settings. +ynh_spawn_app_shell() { + local app=$1 + + # Force Bash to be used to run this helper + [[ $0 =~ \/?bash$ ]] || ynh_die "Please use Bash as shell" + + # Make sure the app is installed + test -d /etc/yunohost/apps/$app || ynh_die "$app is not an installed app ?!" + + # Make sure the app has its own user + id -u "$app" &>/dev/null || ynh_die "There is no \"$app\" system user" + + # Make sure the app has an install_dir setting + local install_dir=$(ynh_app_setting_get --app=$app --key=install_dir) + [ -n "$install_dir" ] || ynh_die "$app has no install_dir setting (does it use packaging format >=2?)" + + # Load the app's service name, or default to $app + local service=$(ynh_app_setting_get --app=$app --key=service) + [ -z "$service" ] && service=$app; + + # Export HOME variable + export HOME=$install_dir; + + # Load the Environment variables from the app's service + local env_var=$(systemctl show $service.service -p "Environment" --value) + [ -n "$env_var" ] && export $env_var; + + # Force `php` to its intended version + # We use `eval`+`export` since `alias` is not propagated to subshells, even with `export` + local phpversion=$(ynh_app_setting_get --app=$app --key=phpversion) + local phpflags=$(ynh_app_setting_get --app=$app --key=phpflags) + if [ -n "$phpversion" ] + then + eval "php() { php${phpversion} ${phpflags} \"\$@\"; }" + export -f php + fi + + # Source the EnvironmentFiles from the app's service + local env_files=($(systemctl show $service.service -p "EnvironmentFiles" --value)) + if [ ${#env_files[*]} -gt 0 ] + then + # set -/+a enables and disables new variables being automatically exported. Needed when using `source`. + set -a + for file in ${env_files[*]} + do + [[ $file = /* ]] && source $file + done + set +a + fi + + # Activate the Python environment, if it exists + if [ -f $install_dir/venv/bin/activate ] + then + # set -/+a enables and disables new variables being automatically exported. Needed when using `source`. + set -a + source $install_dir/venv/bin/activate + set +a + fi + + # cd into the WorkingDirectory set in the service, or default to the install_dir + local env_dir=$(systemctl show $service.service -p "WorkingDirectory" --value) + [ -z $env_dir ] && env_dir=$install_dir; + cd $env_dir + + # Spawn the app shell + su -s /bin/bash $app +}