Merge branch 'migrate_to_bullseye' into bullseye

This commit is contained in:
Alexandre Aubin 2021-10-13 15:12:56 +02:00
commit 0b4aa81f8c
57 changed files with 2126 additions and 1939 deletions

View file

@ -12,11 +12,9 @@ ynh_wait_dpkg_free() {
local try local try
set +o xtrace # set +x set +o xtrace # set +x
# With seq 1 17, timeout will be almost 30 minutes # With seq 1 17, timeout will be almost 30 minutes
for try in `seq 1 17` for try in $(seq 1 17); do
do
# Check if /var/lib/dpkg/lock is used by another process # Check if /var/lib/dpkg/lock is used by another process
if lsof /var/lib/dpkg/lock > /dev/null if lsof /var/lib/dpkg/lock >/dev/null; then
then
echo "apt is already in use..." echo "apt is already in use..."
# Sleep an exponential time at each round # Sleep an exponential time at each round
sleep $((try * try)) sleep $((try * try))
@ -26,11 +24,9 @@ ynh_wait_dpkg_free() {
local dpkg_dir="/var/lib/dpkg/updates/" local dpkg_dir="/var/lib/dpkg/updates/"
# For each file in $dpkg_dir # For each file in $dpkg_dir
while read dpkg_file <&9 while read dpkg_file <&9; do
do
# Check if the name of this file contains only numbers. # Check if the name of this file contains only numbers.
if echo "$dpkg_file" | grep --perl-regexp --quiet "^[[:digit:]]+$" if echo "$dpkg_file" | grep --perl-regexp --quiet "^[[:digit:]]+$"; then
then
# If so, that a remaining of dpkg. # If so, that a remaining of dpkg.
ynh_print_err "dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem." ynh_print_err "dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem."
set -o xtrace # set -x set -o xtrace # set -x
@ -84,8 +80,7 @@ ynh_package_version() {
# Manage arguments with getopts # Manage arguments with getopts
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
if ynh_package_is_installed "$package" if ynh_package_is_installed "$package"; then
then
dpkg-query --show --showformat='${Version}' "$package" 2>/dev/null dpkg-query --show --showformat='${Version}' "$package" 2>/dev/null
else else
echo '' echo ''
@ -191,12 +186,14 @@ ynh_package_install_from_equivs () {
# Install missing dependencies with ynh_package_install # Install missing dependencies with ynh_package_install
ynh_wait_dpkg_free ynh_wait_dpkg_free
cp "$controlfile" "${TMPDIR}/control" cp "$controlfile" "${TMPDIR}/control"
(cd "$TMPDIR" (
cd "$TMPDIR"
LC_ALL=C equivs-build ./control 2>&1 LC_ALL=C equivs-build ./control 2>&1
LC_ALL=C dpkg --force-depends --install "./${pkgname}_${pkgversion}_all.deb" 2>&1 | tee ./dpkg_log) LC_ALL=C dpkg --force-depends --install "./${pkgname}_${pkgversion}_all.deb" 2>&1 | tee ./dpkg_log
)
ynh_package_install --fix-broken || \ ynh_package_install --fix-broken \
{ # If the installation failed || { # If the installation failed
# (the following is ran inside { } to not start a subshell otherwise ynh_die wouldnt exit the original process) # (the following is ran inside { } to not start a subshell otherwise ynh_die wouldnt exit the original process)
# Parse the list of problematic dependencies from dpkg's log ... # Parse the list of problematic dependencies from dpkg's log ...
# (relevant lines look like: "foo-ynh-deps depends on bar; however:") # (relevant lines look like: "foo-ynh-deps depends on bar; however:")
@ -204,13 +201,16 @@ ynh_package_install_from_equivs () {
# Fake an install of those dependencies to see the errors # Fake an install of those dependencies to see the errors
# The sed command here is, Print only from 'Reading state info' to the end. # The sed command here is, Print only from 'Reading state info' to the end.
[[ -n "$problematic_dependencies" ]] && ynh_package_install $problematic_dependencies --dry-run 2>&1 | sed --quiet '/Reading state info/,$p' | grep -v "fix-broken\|Reading state info" >&2 [[ -n "$problematic_dependencies" ]] && ynh_package_install $problematic_dependencies --dry-run 2>&1 | sed --quiet '/Reading state info/,$p' | grep -v "fix-broken\|Reading state info" >&2
ynh_die --message="Unable to install dependencies"; } ynh_die --message="Unable to install dependencies"
}
[[ -n "$TMPDIR" ]] && rm --recursive --force $TMPDIR # Remove the temp dir. [[ -n "$TMPDIR" ]] && rm --recursive --force $TMPDIR # Remove the temp dir.
# check if the package is actually installed # check if the package is actually installed
ynh_package_is_installed "$pkgname" ynh_package_is_installed "$pkgname"
} }
YNH_INSTALL_APP_DEPENDENCIES_REPLACE="true"
# Define and install dependencies with a equivs control file # Define and install dependencies with a equivs control file
# #
# This helper can/should only be called once per app # This helper can/should only be called once per app
@ -236,8 +236,7 @@ ynh_install_app_dependencies () {
local dep_app=${app//_/-} # Replace all '_' by '-' local dep_app=${app//_/-} # Replace all '_' by '-'
# Handle specific versions # Handle specific versions
if [[ "$dependencies" =~ [\<=\>] ]] if [[ "$dependencies" =~ [\<=\>] ]]; then
then
# Replace version specifications by relationships syntax # Replace version specifications by relationships syntax
# https://www.debian.org/doc/debian-policy/ch-relationships.html # https://www.debian.org/doc/debian-policy/ch-relationships.html
# Sed clarification # Sed clarification
@ -249,22 +248,57 @@ ynh_install_app_dependencies () {
dependencies="$(echo "$dependencies" | sed 's/\([^(\<=\>]\)\([\<=\>]\+\)\([^,]\+\)/\1 (\2 \3)/g')" dependencies="$(echo "$dependencies" | sed 's/\([^(\<=\>]\)\([\<=\>]\+\)\([^,]\+\)/\1 (\2 \3)/g')"
fi fi
# Check for specific php dependencies which requires sury
# This grep will for example return "7.4" if dependencies is "foo bar php7.4-pwet php-gni"
# The (?<=php) syntax corresponds to lookbehind ;)
local specific_php_version=$(echo $dependencies | grep -oP '(?<=php)[0-9.]+(?=-|\>)' | sort -u)
# Ignore case where the php version found is the one available in debian vanilla
[[ "$specific_php_version" != "$YNH_DEFAULT_PHP_VERSION" ]] || specific_php_version=""
if [[ -n "$specific_php_version" ]]
then
# Cover a small edge case where a packager could have specified "php7.4-pwet php5-gni" which is confusing
[[ $(echo $specific_php_version | wc -l) -eq 1 ]] \
|| ynh_die --message="Inconsistent php versions in dependencies ... found : $specific_php_version"
dependencies+=", php${specific_php_version}, php${specific_php_version}-fpm, php${specific_php_version}-common"
ynh_add_sury
fi
# The first time we run ynh_install_app_dependencies, we will replace the
# entire control file (This is in particular meant to cover the case of
# upgrade script where ynh_install_app_dependencies is called with this
# expected effect) Otherwise, any subsequent call will add dependencies
# to those already present in the equivs control file.
if [[ $YNH_INSTALL_APP_DEPENDENCIES_REPLACE == "true" ]]
then
YNH_INSTALL_APP_DEPENDENCIES_REPLACE="false"
else
local current_dependencies=""
if ynh_package_is_installed --package="${dep_app}-ynh-deps"
then
current_dependencies="$(dpkg-query --show --showformat='${Depends}' ${dep_app}-ynh-deps) "
current_dependencies=${current_dependencies// | /|}
fi
dependencies="$current_dependencies, $dependencies"
fi
# #
# Epic ugly hack to fix the goddamn dependency nightmare of sury # Epic ugly hack to fix the goddamn dependency nightmare of sury
# Sponsored by the "Djeezusse Fokin Kraiste Why Do Adminsys Has To Be So Fucking Complicated I Should Go Grow Potatoes Instead Of This Shit" collective # Sponsored by the "Djeezusse Fokin Kraiste Why Do Adminsys Has To Be So Fucking Complicated I Should Go Grow Potatoes Instead Of This Shit" collective
# https://github.com/YunoHost/issues/issues/1407 # https://github.com/YunoHost/issues/issues/1407
# #
# If we require to install php dependency # If we require to install php dependency
if echo $dependencies | grep --quiet 'php' if grep --quiet 'php' <<< "$dependencies"; then
then
# And we have packages from sury installed (7.0.33-10+weirdshiftafter instead of 7.0.33-0 on debian) # And we have packages from sury installed (7.0.33-10+weirdshiftafter instead of 7.0.33-0 on debian)
if dpkg --list | grep "php7.0" | grep --quiet --invert-match "7.0.33-0+deb9" if dpkg --list | grep "php7.0" | grep --quiet --invert-match "7.0.33-0+deb9"; then
then
# And sury ain't already in sources.lists # And sury ain't already in sources.lists
if ! grep --recursive --quiet "^ *deb.*sury" /etc/apt/sources.list* if ! grep --recursive --quiet "^ *deb.*sury" /etc/apt/sources.list*; then
then
# Re-add sury # Re-add sury
ynh_install_extra_repo --repo="https://packages.sury.org/php/ $(ynh_get_debian_release) main" --key="https://packages.sury.org/php/apt.gpg" --name=extra_php_version --priority=600 ynh_add_sury
fi fi
fi fi
fi fi
@ -282,14 +316,43 @@ EOF
ynh_package_install_from_equivs /tmp/${dep_app}-ynh-deps.control \ ynh_package_install_from_equivs /tmp/${dep_app}-ynh-deps.control \
|| ynh_die --message="Unable to install dependencies" # Install the fake package and its dependencies || ynh_die --message="Unable to install dependencies" # Install the fake package and its dependencies
rm /tmp/${dep_app}-ynh-deps.control rm /tmp/${dep_app}-ynh-deps.control
ynh_app_setting_set --app=$app --key=apt_dependencies --value="$dependencies" ynh_app_setting_set --app=$app --key=apt_dependencies --value="$dependencies"
if [[ -n "$specific_php_version" ]]
then
# Set the default php version back as the default version for php-cli.
update-alternatives --set php /usr/bin/php$YNH_DEFAULT_PHP_VERSION
# Store phpversion into the config of this app
ynh_app_setting_set --app=$app --key=phpversion --value=$specific_php_version
# Integrate new php-fpm service in yunohost
yunohost service add php${specific_php_version}-fpm --log "/var/log/php${phpversion}-fpm.log"
elif grep --quiet 'php' <<< "$dependencies"; then
# Store phpversion into the config of this app
ynh_app_setting_set --app=$app --key=phpversion --value=$YNH_DEFAULT_PHP_VERSION
fi
} }
# Add sury repository with adequate pin strategy
#
# [internal]
#
# usage: ynh_add_sury
#
ynh_add_sury() {
# Add an extra repository for those packages
ynh_install_extra_repo --repo="https://packages.sury.org/php/ $(ynh_get_debian_release) main" --key="https://packages.sury.org/php/apt.gpg" --name=extra_php_version --priority=600
}
# Add dependencies to install with ynh_install_app_dependencies # Add dependencies to install with ynh_install_app_dependencies
# #
# usage: ynh_add_app_dependencies --package=phpversion [--replace] # usage: ynh_add_app_dependencies --package=phpversion [--replace]
# | arg: -p, --package= - Packages to add as dependencies for the app. # | arg: -p, --package= - Packages to add as dependencies for the app.
# | arg: -r, --replace - Replace dependencies instead of adding to existing ones.
# #
# Requires YunoHost version 3.8.1 or higher. # Requires YunoHost version 3.8.1 or higher.
ynh_add_app_dependencies() { ynh_add_app_dependencies() {
@ -297,24 +360,11 @@ ynh_add_app_dependencies () {
local legacy_args=pr local legacy_args=pr
local -A args_array=([p]=package= [r]=replace) local -A args_array=([p]=package= [r]=replace)
local package local package
local replace
# Manage arguments with getopts # Manage arguments with getopts
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
replace=${replace:-0}
local current_dependencies="" ynh_print_warn --message="Packagers: ynh_add_app_dependencies is deprecated and is now only an alias to ynh_install_app_dependencies"
if [ $replace -eq 0 ] ynh_install_app_dependencies "${package}"
then
local dep_app=${app//_/-} # Replace all '_' by '-'
if ynh_package_is_installed --package="${dep_app}-ynh-deps"
then
current_dependencies="$(dpkg-query --show --showformat='${Depends}' ${dep_app}-ynh-deps) "
fi
current_dependencies=${current_dependencies// | /|}
fi
ynh_install_app_dependencies "${current_dependencies}${package}"
} }
# Remove fake package and its dependencies # Remove fake package and its dependencies
@ -326,7 +376,24 @@ ynh_add_app_dependencies () {
# Requires YunoHost version 2.6.4 or higher. # Requires YunoHost version 2.6.4 or higher.
ynh_remove_app_dependencies() { ynh_remove_app_dependencies() {
local dep_app=${app//_/-} # Replace all '_' by '-' local dep_app=${app//_/-} # Replace all '_' by '-'
local current_dependencies=""
if ynh_package_is_installed --package="${dep_app}-ynh-deps"; then
current_dependencies="$(dpkg-query --show --showformat='${Depends}' ${dep_app}-ynh-deps) "
current_dependencies=${current_dependencies// | /|}
fi
ynh_package_autopurge ${dep_app}-ynh-deps # Remove the fake package and its dependencies if they not still used. ynh_package_autopurge ${dep_app}-ynh-deps # Remove the fake package and its dependencies if they not still used.
# Check if this app used a specific php version ... in which case we check
# if the corresponding php-fpm is still there. Otherwise, we remove the
# service from yunohost as well
local specific_php_version=$(echo $current_dependencies | tr '-' ' ' | grep -o -E "\<php[0-9.]+\>" | sed 's/php//g' | sort | uniq)
[[ "$specific_php_version" != "$YNH_DEFAULT_PHP_VERSION" ]] || specific_php_version=""
if [[ -n "$specific_php_version" ]] && ! ynh_package_is_installed --package="php${specific_php_version}-fpm"; then
yunohost service remove php${specific_php_version}-fpm
fi
} }
# Install packages from an extra repository properly. # Install packages from an extra repository properly.
@ -352,15 +419,14 @@ ynh_install_extra_app_dependencies () {
key=${key:-} key=${key:-}
# Set a key only if asked # Set a key only if asked
if [ -n "$key" ] if [ -n "$key" ]; then
then
key="--key=$key" key="--key=$key"
fi fi
# Add an extra repository for those packages # Add an extra repository for those packages
ynh_install_extra_repo --repo="$repo" $key --priority=995 --name=$name ynh_install_extra_repo --repo="$repo" $key --priority=995 --name=$name
# Install requested dependencies from this extra repository. # Install requested dependencies from this extra repository.
ynh_add_app_dependencies --package="$package" ynh_install_app_dependencies "$package"
# Remove this extra repository after packages are installed # Remove this extra repository after packages are installed
ynh_remove_extra_repo --name=$app ynh_remove_extra_repo --name=$app
@ -394,8 +460,7 @@ ynh_install_extra_repo () {
key=${key:-} key=${key:-}
priority=${priority:-} priority=${priority:-}
if [ $append -eq 1 ] if [ $append -eq 1 ]; then
then
append="--append" append="--append"
wget_append="tee --append" wget_append="tee --append"
else else
@ -424,15 +489,13 @@ ynh_install_extra_repo () {
local pin="${uri#*://}" local pin="${uri#*://}"
pin="${pin%%/*}" pin="${pin%%/*}"
# Set a priority only if asked # Set a priority only if asked
if [ -n "$priority" ] if [ -n "$priority" ]; then
then
priority="--priority=$priority" priority="--priority=$priority"
fi fi
ynh_pin_repo --package="*" --pin="origin \"$pin\"" $priority --name="$name" $append ynh_pin_repo --package="*" --pin="origin \"$pin\"" $priority --name="$name" $append
# Get the public key for the repo # Get the public key for the repo
if [ -n "$key" ] if [ -n "$key" ]; then
then
mkdir --parents "/etc/apt/trusted.gpg.d" mkdir --parents "/etc/apt/trusted.gpg.d"
# Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget) # Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget)
wget --timeout 900 --quiet "$key" --output-document=- | gpg --dearmor | $wget_append /etc/apt/trusted.gpg.d/$name.gpg >/dev/null wget --timeout 900 --quiet "$key" --output-document=- | gpg --dearmor | $wget_append /etc/apt/trusted.gpg.d/$name.gpg >/dev/null
@ -499,8 +562,7 @@ ynh_add_repo () {
name="${name:-$app}" name="${name:-$app}"
append=${append:-0} append=${append:-0}
if [ $append -eq 1 ] if [ $append -eq 1 ]; then
then
append="tee --append" append="tee --append"
else else
append="tee" append="tee"
@ -542,8 +604,7 @@ ynh_pin_repo () {
name="${name:-$app}" name="${name:-$app}"
append=${append:-0} append=${append:-0}
if [ $append -eq 1 ] if [ $append -eq 1 ]; then
then
append="tee --append" append="tee --append"
else else
append="tee" append="tee"

View file

@ -82,10 +82,8 @@ ynh_backup() {
# If backing up core only (used by ynh_backup_before_upgrade), # If backing up core only (used by ynh_backup_before_upgrade),
# don't backup big data items # don't backup big data items
if [ $is_big -eq 1 ] && ( [ ${do_not_backup_data:-0} -eq 1 ] || [ $BACKUP_CORE_ONLY -eq 1 ] ) if [ $is_big -eq 1 ] && ([ ${do_not_backup_data:-0} -eq 1 ] || [ $BACKUP_CORE_ONLY -eq 1 ]); then
then if [ $BACKUP_CORE_ONLY -eq 1 ]; then
if [ $BACKUP_CORE_ONLY -eq 1 ]
then
ynh_print_info --message="$src_path will not be saved, because 'BACKUP_CORE_ONLY' is set." ynh_print_info --message="$src_path will not be saved, because 'BACKUP_CORE_ONLY' is set."
else else
ynh_print_info --message="$src_path will not be saved, because 'do_not_backup_data' is set." ynh_print_info --message="$src_path will not be saved, because 'do_not_backup_data' is set."
@ -97,14 +95,11 @@ ynh_backup() {
# Format correctly source and destination paths # Format correctly source and destination paths
# ============================================================================== # ==============================================================================
# Be sure the source path is not empty # Be sure the source path is not empty
if [ ! -e "$src_path" ] if [ ! -e "$src_path" ]; then
then
ynh_print_warn --message="Source path '${src_path}' does not exist" ynh_print_warn --message="Source path '${src_path}' does not exist"
if [ "$not_mandatory" == "0" ] if [ "$not_mandatory" == "0" ]; then
then
# This is a temporary fix for fail2ban config files missing after the migration to stretch. # This is a temporary fix for fail2ban config files missing after the migration to stretch.
if echo "${src_path}" | grep --quiet "/etc/fail2ban" if echo "${src_path}" | grep --quiet "/etc/fail2ban"; then
then
touch "${src_path}" touch "${src_path}"
ynh_print_info --message="The missing file will be replaced by a dummy one for the backup !!!" ynh_print_info --message="The missing file will be replaced by a dummy one for the backup !!!"
else else
@ -122,13 +117,11 @@ ynh_backup() {
# If there is no destination path, initialize it with the source path # If there is no destination path, initialize it with the source path
# relative to "/". # relative to "/".
# eg: src_path=/etc/yunohost -> dest_path=etc/yunohost # eg: src_path=/etc/yunohost -> dest_path=etc/yunohost
if [[ -z "$dest_path" ]] if [[ -z "$dest_path" ]]; then
then
dest_path="${src_path#/}" dest_path="${src_path#/}"
else else
if [[ "${dest_path:0:1}" == "/" ]] if [[ "${dest_path:0:1}" == "/" ]]; then
then
# If the destination path is an absolute path, transform it as a path # If the destination path is an absolute path, transform it as a path
# relative to the current working directory ($YNH_CWD) # relative to the current working directory ($YNH_CWD)
@ -152,8 +145,7 @@ ynh_backup() {
fi fi
# Check if dest_path already exists in tmp archive # Check if dest_path already exists in tmp archive
if [[ -e "${dest_path}" ]] if [[ -e "${dest_path}" ]]; then
then
ynh_print_err --message="Destination path '${dest_path}' already exist" ynh_print_err --message="Destination path '${dest_path}' already exist"
return 1 return 1
fi fi
@ -190,9 +182,8 @@ ynh_restore () {
REL_DIR="${REL_DIR%/}/" REL_DIR="${REL_DIR%/}/"
# For each destination path begining by $REL_DIR # For each destination path begining by $REL_DIR
cat ${YNH_BACKUP_CSV} | tr --delete $'\r' | grep --only-matching --no-filename --perl-regexp "^\".*\",\"$REL_DIR.*\"$" | \ cat ${YNH_BACKUP_CSV} | tr --delete $'\r' | grep --only-matching --no-filename --perl-regexp "^\".*\",\"$REL_DIR.*\"$" \
while read line | while read line; do
do
local ORIGIN_PATH=$(echo "$line" | grep --only-matching --no-filename --perl-regexp "^\"\K.*(?=\",\".*\"$)") local ORIGIN_PATH=$(echo "$line" | grep --only-matching --no-filename --perl-regexp "^\"\K.*(?=\",\".*\"$)")
local ARCHIVE_PATH=$(echo "$line" | grep --only-matching --no-filename --perl-regexp "^\".*\",\"$REL_DIR\K.*(?=\"$)") local ARCHIVE_PATH=$(echo "$line" | grep --only-matching --no-filename --perl-regexp "^\".*\",\"$REL_DIR\K.*(?=\"$)")
ynh_restore_file --origin_path="$ARCHIVE_PATH" --dest_path="$ORIGIN_PATH" ynh_restore_file --origin_path="$ARCHIVE_PATH" --dest_path="$ORIGIN_PATH"
@ -260,10 +251,8 @@ ynh_restore_file () {
local archive_path="$YNH_CWD${origin_path}" local archive_path="$YNH_CWD${origin_path}"
# If archive_path doesn't exist, search for a corresponding path in CSV # If archive_path doesn't exist, search for a corresponding path in CSV
if [ ! -d "$archive_path" ] && [ ! -f "$archive_path" ] && [ ! -L "$archive_path" ] if [ ! -d "$archive_path" ] && [ ! -f "$archive_path" ] && [ ! -L "$archive_path" ]; then
then if [ "$not_mandatory" == "0" ]; then
if [ "$not_mandatory" == "0" ]
then
archive_path="$YNH_BACKUP_DIR/$(_get_archive_path \"$origin_path\")" archive_path="$YNH_BACKUP_DIR/$(_get_archive_path \"$origin_path\")"
else else
return 0 return 0
@ -271,11 +260,9 @@ ynh_restore_file () {
fi fi
# Move the old directory if it already exists # Move the old directory if it already exists
if [[ -e "${dest_path}" ]] if [[ -e "${dest_path}" ]]; then
then
# Check if the file/dir size is less than 500 Mo # Check if the file/dir size is less than 500 Mo
if [[ $(du --summarize --bytes ${dest_path} | cut --delimiter="/" --fields=1) -le "500000000" ]] if [[ $(du --summarize --bytes ${dest_path} | cut --delimiter="/" --fields=1) -le "500000000" ]]; then
then
local backup_file="/home/yunohost.conf/backup/${dest_path}.backup.$(date '+%Y%m%d.%H%M%S')" local backup_file="/home/yunohost.conf/backup/${dest_path}.backup.$(date '+%Y%m%d.%H%M%S')"
mkdir --parents "$(dirname "$backup_file")" mkdir --parents "$(dirname "$backup_file")"
mv "${dest_path}" "$backup_file" # Move the current file or directory mv "${dest_path}" "$backup_file" # Move the current file or directory
@ -288,10 +275,8 @@ ynh_restore_file () {
mkdir --parents $(dirname "$dest_path") mkdir --parents $(dirname "$dest_path")
# Do a copy if it's just a mounting point # Do a copy if it's just a mounting point
if mountpoint --quiet $YNH_BACKUP_DIR if mountpoint --quiet $YNH_BACKUP_DIR; then
then if [[ -d "${archive_path}" ]]; then
if [[ -d "${archive_path}" ]]
then
archive_path="${archive_path}/." archive_path="${archive_path}/."
mkdir --parents "$dest_path" mkdir --parents "$dest_path"
fi fi
@ -335,8 +320,7 @@ ynh_store_file_checksum () {
ynh_app_setting_set --app=$app --key=$checksum_setting_name --value=$(md5sum "$file" | cut --delimiter=' ' --fields=1) ynh_app_setting_set --app=$app --key=$checksum_setting_name --value=$(md5sum "$file" | cut --delimiter=' ' --fields=1)
# If backup_file_checksum isn't empty, ynh_backup_if_checksum_is_different has made a backup # If backup_file_checksum isn't empty, ynh_backup_if_checksum_is_different has made a backup
if [ -n "${backup_file_checksum-}" ] if [ -n "${backup_file_checksum-}" ]; then
then
# Print the diff between the previous file and the new one. # Print the diff between the previous file and the new one.
# diff return 1 if the files are different, so the || true # diff return 1 if the files are different, so the || true
diff --report-identical-files --unified --color=always $backup_file_checksum $file >&2 || true diff --report-identical-files --unified --color=always $backup_file_checksum $file >&2 || true
@ -367,10 +351,8 @@ ynh_backup_if_checksum_is_different () {
local checksum_value=$(ynh_app_setting_get --app=$app --key=$checksum_setting_name) local checksum_value=$(ynh_app_setting_get --app=$app --key=$checksum_setting_name)
# backup_file_checksum isn't declare as local, so it can be reuse by ynh_store_file_checksum # backup_file_checksum isn't declare as local, so it can be reuse by ynh_store_file_checksum
backup_file_checksum="" backup_file_checksum=""
if [ -n "$checksum_value" ] if [ -n "$checksum_value" ]; then # Proceed only if a value was stored into the app settings
then # Proceed only if a value was stored into the app settings if [ -e $file ] && ! echo "$checksum_value $file" | md5sum --check --status; then # If the checksum is now different
if [ -e $file ] && ! echo "$checksum_value $file" | md5sum --check --status
then # If the checksum is now different
backup_file_checksum="/home/yunohost.conf/backup/$file.backup.$(date '+%Y%m%d.%H%M%S')" backup_file_checksum="/home/yunohost.conf/backup/$file.backup.$(date '+%Y%m%d.%H%M%S')"
mkdir --parents "$(dirname "$backup_file_checksum")" mkdir --parents "$(dirname "$backup_file_checksum")"
cp --archive "$file" "$backup_file_checksum" # Backup the current file cp --archive "$file" "$backup_file_checksum" # Backup the current file
@ -424,8 +406,7 @@ ynh_backup_archive_exists () {
# #
# Requires YunoHost version 2.7.2 or higher. # Requires YunoHost version 2.7.2 or higher.
ynh_backup_before_upgrade() { ynh_backup_before_upgrade() {
if [ ! -e "/etc/yunohost/apps/$app/scripts/backup" ] if [ ! -e "/etc/yunohost/apps/$app/scripts/backup" ]; then
then
ynh_print_warn --message="This app doesn't have any backup script." ynh_print_warn --message="This app doesn't have any backup script."
return return
fi fi
@ -434,11 +415,9 @@ ynh_backup_before_upgrade () {
local app_bck=${app//_/-} # Replace all '_' by '-' local app_bck=${app//_/-} # Replace all '_' by '-'
NO_BACKUP_UPGRADE=${NO_BACKUP_UPGRADE:-0} NO_BACKUP_UPGRADE=${NO_BACKUP_UPGRADE:-0}
if [ "$NO_BACKUP_UPGRADE" -eq 0 ] if [ "$NO_BACKUP_UPGRADE" -eq 0 ]; then
then
# Check if a backup already exists with the prefix 1 # Check if a backup already exists with the prefix 1
if ynh_backup_archive_exists "$app_bck-pre-upgrade1" if ynh_backup_archive_exists "$app_bck-pre-upgrade1"; then
then
# Prefix becomes 2 to preserve the previous backup # Prefix becomes 2 to preserve the previous backup
backup_number=2 backup_number=2
old_backup_number=1 old_backup_number=1
@ -446,11 +425,9 @@ ynh_backup_before_upgrade () {
# Create backup # Create backup
BACKUP_CORE_ONLY=1 yunohost backup create --apps $app --name $app_bck-pre-upgrade$backup_number --debug BACKUP_CORE_ONLY=1 yunohost backup create --apps $app --name $app_bck-pre-upgrade$backup_number --debug
if [ "$?" -eq 0 ] if [ "$?" -eq 0 ]; then
then
# If the backup succeeded, remove the previous backup # If the backup succeeded, remove the previous backup
if ynh_backup_archive_exists "$app_bck-pre-upgrade$old_backup_number" if ynh_backup_archive_exists "$app_bck-pre-upgrade$old_backup_number"; then
then
# Remove the previous backup only if it exists # Remove the previous backup only if it exists
yunohost backup delete $app_bck-pre-upgrade$old_backup_number >/dev/null yunohost backup delete $app_bck-pre-upgrade$old_backup_number >/dev/null
fi fi
@ -482,11 +459,9 @@ ynh_restore_upgradebackup () {
NO_BACKUP_UPGRADE=${NO_BACKUP_UPGRADE:-0} NO_BACKUP_UPGRADE=${NO_BACKUP_UPGRADE:-0}
if [ "$NO_BACKUP_UPGRADE" -eq 0 ] if [ "$NO_BACKUP_UPGRADE" -eq 0 ]; then
then
# Check if an existing backup can be found before removing and restoring the application. # Check if an existing backup can be found before removing and restoring the application.
if ynh_backup_archive_exists "$app_bck-pre-upgrade$backup_number" if ynh_backup_archive_exists "$app_bck-pre-upgrade$backup_number"; then
then
# Remove the application then restore it # Remove the application then restore it
yunohost app remove $app yunohost app remove $app
# Restore the backup # Restore the backup

View file

@ -1,44 +1,35 @@
#!/bin/bash #!/bin/bash
_ynh_app_config_get_one() { _ynh_app_config_get_one() {
local short_setting="$1" local short_setting="$1"
local type="$2" local type="$2"
local bind="$3" local bind="$3"
local getter="get__${short_setting}" local getter="get__${short_setting}"
# Get value from getter if exists # Get value from getter if exists
if type -t $getter 2>/dev/null | grep -q '^function$' 2>/dev/null; if type -t $getter 2>/dev/null | grep -q '^function$' 2>/dev/null; then
then
old[$short_setting]="$($getter)" old[$short_setting]="$($getter)"
formats[${short_setting}]="yaml" formats[${short_setting}]="yaml"
elif [[ "$bind" == *"("* ]] && type -t "get__${bind%%(*}" 2>/dev/null | grep -q '^function$' 2>/dev/null; elif [[ "$bind" == *"("* ]] && type -t "get__${bind%%(*}" 2>/dev/null | grep -q '^function$' 2>/dev/null; then
then
old[$short_setting]="$("get__${bind%%(*}" $short_setting $type $bind)" old[$short_setting]="$("get__${bind%%(*}" $short_setting $type $bind)"
formats[${short_setting}]="yaml" formats[${short_setting}]="yaml"
elif [[ "$bind" == "null" ]] elif [[ "$bind" == "null" ]]; then
then
old[$short_setting]="YNH_NULL" old[$short_setting]="YNH_NULL"
# Get value from app settings or from another file # Get value from app settings or from another file
elif [[ "$type" == "file" ]] elif [[ "$type" == "file" ]]; then
then if [[ "$bind" == "settings" ]]; then
if [[ "$bind" == "settings" ]]
then
ynh_die --message="File '${short_setting}' can't be stored in settings" ynh_die --message="File '${short_setting}' can't be stored in settings"
fi fi
old[$short_setting]="$(ls "$(echo $bind | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)" 2>/dev/null || echo YNH_NULL)" old[$short_setting]="$(ls "$(echo $bind | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)" 2>/dev/null || echo YNH_NULL)"
file_hash[$short_setting]="true" file_hash[$short_setting]="true"
# Get multiline text from settings or from a full file # Get multiline text from settings or from a full file
elif [[ "$type" == "text" ]] elif [[ "$type" == "text" ]]; then
then if [[ "$bind" == "settings" ]]; then
if [[ "$bind" == "settings" ]]
then
old[$short_setting]="$(ynh_app_setting_get $app $short_setting)" old[$short_setting]="$(ynh_app_setting_get $app $short_setting)"
elif [[ "$bind" == *":"* ]] elif [[ "$bind" == *":"* ]]; then
then
ynh_die --message="For technical reasons, multiline text '${short_setting}' can't be stored automatically in a variable file, you have to create custom getter/setter" ynh_die --message="For technical reasons, multiline text '${short_setting}' can't be stored automatically in a variable file, you have to create custom getter/setter"
else else
old[$short_setting]="$(cat $(echo $bind | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/) 2>/dev/null || echo YNH_NULL)" old[$short_setting]="$(cat $(echo $bind | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/) 2>/dev/null || echo YNH_NULL)"
@ -47,19 +38,17 @@ _ynh_app_config_get_one() {
# Get value from a kind of key/value file # Get value from a kind of key/value file
else else
local bind_after="" local bind_after=""
if [[ "$bind" == "settings" ]] if [[ "$bind" == "settings" ]]; then
then
bind=":/etc/yunohost/apps/$app/settings.yml" bind=":/etc/yunohost/apps/$app/settings.yml"
fi fi
local bind_key="$(echo "$bind" | cut -d: -f1)" local bind_key_="$(echo "$bind" | cut -d: -f1)"
bind_key=${bind_key:-$short_setting} bind_key_=${bind_key_:-$short_setting}
if [[ "$bind_key" == *">"* ]]; if [[ "$bind_key_" == *">"* ]]; then
then bind_after="$(echo "${bind_key_}" | cut -d'>' -f1)"
bind_after="$(echo "${bind_key}" | cut -d'>' -f1)" bind_key_="$(echo "${bind_key_}" | cut -d'>' -f2)"
bind_key="$(echo "${bind_key}" | cut -d'>' -f2)"
fi fi
local bind_file="$(echo "$bind" | cut -d: -f2 | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)" local bind_file="$(echo "$bind" | cut -d: -f2 | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)"
old[$short_setting]="$(ynh_read_var_in_file --file="${bind_file}" --key="${bind_key}" --after="${bind_after}")" old[$short_setting]="$(ynh_read_var_in_file --file="${bind_file}" --key="${bind_key_}" --after="${bind_after}")"
fi fi
} }
@ -68,83 +57,71 @@ _ynh_app_config_apply_one() {
local setter="set__${short_setting}" local setter="set__${short_setting}"
local bind="${binds[$short_setting]}" local bind="${binds[$short_setting]}"
local type="${types[$short_setting]}" local type="${types[$short_setting]}"
if [ "${changed[$short_setting]}" == "true" ] if [ "${changed[$short_setting]}" == "true" ]; then
then
# Apply setter if exists # Apply setter if exists
if type -t $setter 2>/dev/null | grep -q '^function$' 2>/dev/null; if type -t $setter 2>/dev/null | grep -q '^function$' 2>/dev/null; then
then
$setter $setter
elif [[ "$bind" == *"("* ]] && type -t "set__${bind%%(*}" 2>/dev/null | grep -q '^function$' 2>/dev/null; elif [[ "$bind" == *"("* ]] && type -t "set__${bind%%(*}" 2>/dev/null | grep -q '^function$' 2>/dev/null; then
then
"set__${bind%%(*}" $short_setting $type $bind "set__${bind%%(*}" $short_setting $type $bind
elif [[ "$bind" == "null" ]] elif [[ "$bind" == "null" ]]; then
then return
continue
# Save in a file # Save in a file
elif [[ "$type" == "file" ]] elif [[ "$type" == "file" ]]; then
then if [[ "$bind" == "settings" ]]; then
if [[ "$bind" == "settings" ]]
then
ynh_die --message="File '${short_setting}' can't be stored in settings" ynh_die --message="File '${short_setting}' can't be stored in settings"
fi fi
local bind_file="$(echo "$bind" | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)" local bind_file="$(echo "$bind" | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)"
if [[ "${!short_setting}" == "" ]] if [[ "${!short_setting}" == "" ]]; then
then
ynh_backup_if_checksum_is_different --file="$bind_file" ynh_backup_if_checksum_is_different --file="$bind_file"
ynh_secure_remove --file="$bind_file" ynh_secure_remove --file="$bind_file"
ynh_delete_file_checksum --file="$bind_file" --update_only ynh_delete_file_checksum --file="$bind_file" --update_only
ynh_print_info --message="File '$bind_file' removed" ynh_print_info --message="File '$bind_file' removed"
else else
ynh_backup_if_checksum_is_different --file="$bind_file" ynh_backup_if_checksum_is_different --file="$bind_file"
if [[ "${!short_setting}" != "$bind_file" ]] if [[ "${!short_setting}" != "$bind_file" ]]; then
then
cp "${!short_setting}" "$bind_file" cp "${!short_setting}" "$bind_file"
fi fi
ynh_store_file_checksum --file="$bind_file" --update_only ynh_store_file_checksum --file="$bind_file" --update_only
ynh_print_info --message="File '$bind_file' overwrited with ${!short_setting}" ynh_print_info --message="File '$bind_file' overwritten with ${!short_setting}"
fi fi
# Save value in app settings # Save value in app settings
elif [[ "$bind" == "settings" ]] elif [[ "$bind" == "settings" ]]; then
then
ynh_app_setting_set --app=$app --key=$short_setting --value="${!short_setting}" ynh_app_setting_set --app=$app --key=$short_setting --value="${!short_setting}"
ynh_print_info --message="Configuration key '$short_setting' edited in app settings" ynh_print_info --message="Configuration key '$short_setting' edited in app settings"
# Save multiline text in a file # Save multiline text in a file
elif [[ "$type" == "text" ]] elif [[ "$type" == "text" ]]; then
then if [[ "$bind" == *":"* ]]; then
if [[ "$bind" == *":"* ]]
then
ynh_die --message="For technical reasons, multiline text '${short_setting}' can't be stored automatically in a variable file, you have to create custom getter/setter" ynh_die --message="For technical reasons, multiline text '${short_setting}' can't be stored automatically in a variable file, you have to create custom getter/setter"
fi fi
local bind_file="$(echo "$bind" | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)" local bind_file="$(echo "$bind" | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)"
ynh_backup_if_checksum_is_different --file="$bind_file" ynh_backup_if_checksum_is_different --file="$bind_file"
echo "${!short_setting}" >"$bind_file" echo "${!short_setting}" >"$bind_file"
ynh_store_file_checksum --file="$bind_file" --update_only ynh_store_file_checksum --file="$bind_file" --update_only
ynh_print_info --message="File '$bind_file' overwrited with the content you provieded in '${short_setting}' question" ynh_print_info --message="File '$bind_file' overwritten with the content provided in question '${short_setting}'"
# Set value into a kind of key/value file # Set value into a kind of key/value file
else else
local bind_after="" local bind_after=""
local bind_key="$(echo "$bind" | cut -d: -f1)" local bind_key_="$(echo "$bind" | cut -d: -f1)"
bind_key=${bind_key:-$short_setting} bind_key_=${bind_key_:-$short_setting}
if [[ "$bind_key" == *">"* ]]; if [[ "$bind_key_" == *">"* ]]; then
then bind_after="$(echo "${bind_key_}" | cut -d'>' -f1)"
bind_after="$(echo "${bind_key}" | cut -d'>' -f1)" bind_key_="$(echo "${bind_key_}" | cut -d'>' -f2)"
bind_key="$(echo "${bind_key}" | cut -d'>' -f2)"
fi fi
local bind_file="$(echo "$bind" | cut -d: -f2 | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)" local bind_file="$(echo "$bind" | cut -d: -f2 | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)"
ynh_backup_if_checksum_is_different --file="$bind_file" ynh_backup_if_checksum_is_different --file="$bind_file"
ynh_write_var_in_file --file="${bind_file}" --key="${bind_key}" --value="${!short_setting}" --after="${bind_after}" ynh_write_var_in_file --file="${bind_file}" --key="${bind_key_}" --value="${!short_setting}" --after="${bind_after}"
ynh_store_file_checksum --file="$bind_file" --update_only ynh_store_file_checksum --file="$bind_file" --update_only
# We stored the info in settings in order to be able to upgrade the app # We stored the info in settings in order to be able to upgrade the app
ynh_app_setting_set --app=$app --key=$short_setting --value="${!short_setting}" ynh_app_setting_set --app=$app --key=$short_setting --value="${!short_setting}"
ynh_print_info --message="Configuration key '$bind_key' edited into $bind_file" ynh_print_info --message="Configuration key '$bind_key_' edited into $bind_file"
fi fi
fi fi
@ -152,7 +129,8 @@ _ynh_app_config_apply_one() {
_ynh_app_config_get() { _ynh_app_config_get() {
# From settings # From settings
local lines local lines
lines=$(python3 << EOL lines=$(
python3 <<EOL
import toml import toml
from collections import OrderedDict from collections import OrderedDict
with open("../config_panel.toml", "r") as f: with open("../config_panel.toml", "r") as f:
@ -173,8 +151,7 @@ for panel_name, panel in loaded_toml.items():
])) ]))
EOL EOL
) )
for line in $lines for line in $lines; do
do
# Split line into short_setting, type and bind # Split line into short_setting, type and bind
IFS=';' read short_setting type bind <<<"$line" IFS=';' read short_setting type bind <<<"$line"
binds[${short_setting}]="$bind" binds[${short_setting}]="$bind"
@ -184,23 +161,18 @@ EOL
ynh_app_config_get_one $short_setting $type $bind ynh_app_config_get_one $short_setting $type $bind
done done
} }
_ynh_app_config_apply() { _ynh_app_config_apply() {
for short_setting in "${!old[@]}" for short_setting in "${!old[@]}"; do
do
ynh_app_config_apply_one $short_setting ynh_app_config_apply_one $short_setting
done done
} }
_ynh_app_config_show() { _ynh_app_config_show() {
for short_setting in "${!old[@]}" for short_setting in "${!old[@]}"; do
do if [[ "${old[$short_setting]}" != YNH_NULL ]]; then
if [[ "${old[$short_setting]}" != YNH_NULL ]] if [[ "${formats[$short_setting]}" == "yaml" ]]; then
then
if [[ "${formats[$short_setting]}" == "yaml" ]]
then
ynh_return "${short_setting}:" ynh_return "${short_setting}:"
ynh_return "$(echo "${old[$short_setting]}" | sed 's/^/ /g')" ynh_return "$(echo "${old[$short_setting]}" | sed 's/^/ /g')"
else else
@ -216,48 +188,39 @@ _ynh_app_config_validate() {
ynh_script_progression --message="Checking what changed in the new configuration..." --weight=1 ynh_script_progression --message="Checking what changed in the new configuration..." --weight=1
local nothing_changed=true local nothing_changed=true
local changes_validated=true local changes_validated=true
for short_setting in "${!old[@]}" for short_setting in "${!old[@]}"; do
do
changed[$short_setting]=false changed[$short_setting]=false
if [ -z ${!short_setting+x} ] if [ -z ${!short_setting+x} ]; then
then
# Assign the var with the old value in order to allows multiple # Assign the var with the old value in order to allows multiple
# args validation # args validation
declare "$short_setting"="${old[$short_setting]}" declare "$short_setting"="${old[$short_setting]}"
continue continue
fi fi
if [ ! -z "${file_hash[${short_setting}]}" ] if [ ! -z "${file_hash[${short_setting}]}" ]; then
then
file_hash[old__$short_setting]="" file_hash[old__$short_setting]=""
file_hash[new__$short_setting]="" file_hash[new__$short_setting]=""
if [ -f "${old[$short_setting]}" ] if [ -f "${old[$short_setting]}" ]; then
then
file_hash[old__$short_setting]=$(sha256sum "${old[$short_setting]}" | cut -d' ' -f1) file_hash[old__$short_setting]=$(sha256sum "${old[$short_setting]}" | cut -d' ' -f1)
if [ -z "${!short_setting}" ] if [ -z "${!short_setting}" ]; then
then
changed[$short_setting]=true changed[$short_setting]=true
nothing_changed=false nothing_changed=false
fi fi
fi fi
if [ -f "${!short_setting}" ] if [ -f "${!short_setting}" ]; then
then
file_hash[new__$short_setting]=$(sha256sum "${!short_setting}" | cut -d' ' -f1) file_hash[new__$short_setting]=$(sha256sum "${!short_setting}" | cut -d' ' -f1)
if [[ "${file_hash[old__$short_setting]}" != "${file_hash[new__$short_setting]}" ]] if [[ "${file_hash[old__$short_setting]}" != "${file_hash[new__$short_setting]}" ]]; then
then
changed[$short_setting]=true changed[$short_setting]=true
nothing_changed=false nothing_changed=false
fi fi
fi fi
else else
if [[ "${!short_setting}" != "${old[$short_setting]}" ]] if [[ "${!short_setting}" != "${old[$short_setting]}" ]]; then
then
changed[$short_setting]=true changed[$short_setting]=true
nothing_changed=false nothing_changed=false
fi fi
fi fi
done done
if [[ "$nothing_changed" == "true" ]] if [[ "$nothing_changed" == "true" ]]; then
then
ynh_print_info --message="Nothing has changed" ynh_print_info --message="Nothing has changed"
exit 0 exit 0
fi fi
@ -265,19 +228,15 @@ _ynh_app_config_validate() {
# Run validation if something is changed # Run validation if something is changed
ynh_script_progression --message="Validating the new configuration..." --weight=1 ynh_script_progression --message="Validating the new configuration..." --weight=1
for short_setting in "${!old[@]}" for short_setting in "${!old[@]}"; do
do
[[ "${changed[$short_setting]}" == "false" ]] && continue [[ "${changed[$short_setting]}" == "false" ]] && continue
local result="" local result=""
if type -t validate__$short_setting | grep -q '^function$' 2>/dev/null; if type -t validate__$short_setting | grep -q '^function$' 2>/dev/null; then
then
result="$(validate__$short_setting)" result="$(validate__$short_setting)"
elif [[ "$bind" == *"("* ]] && type -t "validate__${bind%%(*}" 2>/dev/null | grep -q '^function$' 2>/dev/null; elif [[ "$bind" == *"("* ]] && type -t "validate__${bind%%(*}" 2>/dev/null | grep -q '^function$' 2>/dev/null; then
then
"validate__${bind%%(*}" $short_setting "validate__${bind%%(*}" $short_setting
fi fi
if [ -n "$result" ] if [ -n "$result" ]; then
then
# #
# Return a yaml such as: # Return a yaml such as:
# #
@ -287,8 +246,7 @@ _ynh_app_config_validate() {
# #
# We use changes_validated to know if this is # We use changes_validated to know if this is
# the first validation error # the first validation error
if [[ "$changes_validated" == true ]] if [[ "$changes_validated" == true ]]; then
then
ynh_return "validation_errors:" ynh_return "validation_errors:"
fi fi
ynh_return " ${short_setting}: \"$result\"" ynh_return " ${short_setting}: \"$result\""
@ -298,8 +256,7 @@ _ynh_app_config_validate() {
# If validation failed, exit the script right now (instead of going into apply) # If validation failed, exit the script right now (instead of going into apply)
# Yunohost core will pick up the errors returned via ynh_return previously # Yunohost core will pick up the errors returned via ynh_return previously
if [[ "$changes_validated" == "false" ]] if [[ "$changes_validated" == "false" ]]; then
then
exit 0 exit 0
fi fi
@ -354,4 +311,3 @@ ynh_app_config_run() {
;; ;;
esac esac
} }

View file

@ -76,8 +76,7 @@ ynh_add_fail2ban_config () {
ports=${ports:-http,https} ports=${ports:-http,https}
use_template="${use_template:-0}" use_template="${use_template:-0}"
if [ $use_template -ne 1 ] if [ $use_template -ne 1 ]; then
then
# Usage 1, no template. Build a config file from scratch. # Usage 1, no template. Build a config file from scratch.
test -n "$logpath" || ynh_die --message="ynh_add_fail2ban_config expects a logfile path as first argument and received nothing." test -n "$logpath" || ynh_die --message="ynh_add_fail2ban_config expects a logfile path as first argument and received nothing."
test -n "$failregex" || ynh_die --message="ynh_add_fail2ban_config expects a failure regex as second argument and received nothing." test -n "$failregex" || ynh_die --message="ynh_add_fail2ban_config expects a failure regex as second argument and received nothing."
@ -106,8 +105,7 @@ ignoreregex =
ynh_systemd_action --service_name=fail2ban --action=reload --line_match="(Started|Reloaded) Fail2Ban Service" --log_path=systemd ynh_systemd_action --service_name=fail2ban --action=reload --line_match="(Started|Reloaded) Fail2Ban Service" --log_path=systemd
local fail2ban_error="$(journalctl --no-hostname --unit=fail2ban | tail --lines=50 | grep "WARNING.*$app.*")" local fail2ban_error="$(journalctl --no-hostname --unit=fail2ban | tail --lines=50 | grep "WARNING.*$app.*")"
if [[ -n "$fail2ban_error" ]] if [[ -n "$fail2ban_error" ]]; then
then
ynh_print_err --message="Fail2ban failed to load the jail for $app" ynh_print_err --message="Fail2ban failed to load the jail for $app"
ynh_print_warn --message="${fail2ban_error#*WARNING}" ynh_print_warn --message="${fail2ban_error#*WARNING}"
fi fi

View file

@ -48,8 +48,7 @@
ynh_handle_getopts_args() { ynh_handle_getopts_args() {
# Manage arguments only if there's some provided # Manage arguments only if there's some provided
set +o xtrace # set +x set +o xtrace # set +x
if [ $# -ne 0 ] if [ $# -ne 0 ]; then
then
# Store arguments in an array to keep each argument separated # Store arguments in an array to keep each argument separated
local arguments=("$@") local arguments=("$@")
@ -58,14 +57,12 @@ ynh_handle_getopts_args () {
# ${!args_array[@]} is the list of all option_flags in the array (An option_flag is 'u' in [u]=user, user is a value) # ${!args_array[@]} is the list of all option_flags in the array (An option_flag is 'u' in [u]=user, user is a value)
local getopts_parameters="" local getopts_parameters=""
local option_flag="" local option_flag=""
for option_flag in "${!args_array[@]}" for option_flag in "${!args_array[@]}"; do
do
# Concatenate each option_flags of the array to build the string of arguments for getopts # Concatenate each option_flags of the array to build the string of arguments for getopts
# Will looks like 'abcd' for -a -b -c -d # Will looks like 'abcd' for -a -b -c -d
# If the value of an option_flag finish by =, it's an option with additionnal values. (e.g. --user bob or -u bob) # If the value of an option_flag finish by =, it's an option with additionnal values. (e.g. --user bob or -u bob)
# Check the last character of the value associate to the option_flag # Check the last character of the value associate to the option_flag
if [ "${args_array[$option_flag]: -1}" = "=" ] if [ "${args_array[$option_flag]: -1}" = "=" ]; then
then
# For an option with additionnal values, add a ':' after the letter for getopts. # For an option with additionnal values, add a ':' after the letter for getopts.
getopts_parameters="${getopts_parameters}${option_flag}:" getopts_parameters="${getopts_parameters}${option_flag}:"
else else
@ -74,8 +71,7 @@ ynh_handle_getopts_args () {
# Check each argument given to the function # Check each argument given to the function
local arg="" local arg=""
# ${#arguments[@]} is the size of the array # ${#arguments[@]} is the size of the array
for arg in `seq 0 $(( ${#arguments[@]} - 1 ))` for arg in $(seq 0 $((${#arguments[@]} - 1))); do
do
# Escape options' values starting with -. Otherwise the - will be considered as another option. # Escape options' values starting with -. Otherwise the - will be considered as another option.
arguments[arg]="${arguments[arg]//--${args_array[$option_flag]}-/--${args_array[$option_flag]}\\TOBEREMOVED\\-}" arguments[arg]="${arguments[arg]//--${args_array[$option_flag]}-/--${args_array[$option_flag]}\\TOBEREMOVED\\-}"
# And replace long option (value of the option_flag) by the short option, the option_flag itself # And replace long option (value of the option_flag) by the short option, the option_flag itself
@ -91,8 +87,7 @@ ynh_handle_getopts_args () {
# Use a function here, to use standart arguments $@ and be able to use shift. # Use a function here, to use standart arguments $@ and be able to use shift.
parse_arg() { parse_arg() {
# Read all arguments, until no arguments are left # Read all arguments, until no arguments are left
while [ $# -ne 0 ] while [ $# -ne 0 ]; do
do
# Initialize the index of getopts # Initialize the index of getopts
OPTIND=1 OPTIND=1
# Parse with getopts only if the argument begin by -, that means the argument is an option # Parse with getopts only if the argument begin by -, that means the argument is an option
@ -100,11 +95,9 @@ ynh_handle_getopts_args () {
local parameter="" local parameter=""
getopts ":$getopts_parameters" parameter || true getopts ":$getopts_parameters" parameter || true
if [ "$parameter" = "?" ] if [ "$parameter" = "?" ]; then
then
ynh_die --message="Invalid argument: -${OPTARG:-}" ynh_die --message="Invalid argument: -${OPTARG:-}"
elif [ "$parameter" = ":" ] elif [ "$parameter" = ":" ]; then
then
ynh_die --message="-$OPTARG parameter requires an argument." ynh_die --message="-$OPTARG parameter requires an argument."
else else
local shift_value=1 local shift_value=1
@ -115,8 +108,7 @@ ynh_handle_getopts_args () {
local option_var="${args_array[$parameter]%=}" local option_var="${args_array[$parameter]%=}"
# If this option doesn't take values # If this option doesn't take values
# if there's a '=' at the end of the long option name, this option takes values # if there's a '=' at the end of the long option name, this option takes values
if [ "${args_array[$parameter]: -1}" != "=" ] if [ "${args_array[$parameter]: -1}" != "=" ]; then
then
# 'eval ${option_var}' will use the content of 'option_var' # 'eval ${option_var}' will use the content of 'option_var'
eval ${option_var}=1 eval ${option_var}=1
else else
@ -126,14 +118,12 @@ ynh_handle_getopts_args () {
# If the first argument is longer than 2 characters, # If the first argument is longer than 2 characters,
# There's a value attached to the option, in the same array cell # There's a value attached to the option, in the same array cell
if [ ${#all_args[0]} -gt 2 ] if [ ${#all_args[0]} -gt 2 ]; then
then
# Remove the option and the space, so keep only the value itself. # Remove the option and the space, so keep only the value itself.
all_args[0]="${all_args[0]#-${parameter} }" all_args[0]="${all_args[0]#-${parameter} }"
# At this point, if all_args[0] start with "-", then the argument is not well formed # At this point, if all_args[0] start with "-", then the argument is not well formed
if [ "${all_args[0]:0:1}" == "-" ] if [ "${all_args[0]:0:1}" == "-" ]; then
then
ynh_die --message="Argument \"${all_args[0]}\" not valid! Did you use a single \"-\" instead of two?" ynh_die --message="Argument \"${all_args[0]}\" not valid! Did you use a single \"-\" instead of two?"
fi fi
# Reduce the value of shift, because the option has been removed manually # Reduce the value of shift, because the option has been removed manually
@ -144,23 +134,19 @@ ynh_handle_getopts_args () {
eval ${option_var}="" eval ${option_var}=""
# Then read the array value per value # Then read the array value per value
local i local i
for i in `seq 0 $(( ${#all_args[@]} - 1 ))` for i in $(seq 0 $((${#all_args[@]} - 1))); do
do
# If this argument is an option, end here. # If this argument is an option, end here.
if [ "${all_args[$i]:0:1}" == "-" ] if [ "${all_args[$i]:0:1}" == "-" ]; then
then
# Ignore the first value of the array, which is the option itself # Ignore the first value of the array, which is the option itself
if [ "$i" -ne 0 ]; then if [ "$i" -ne 0 ]; then
break break
fi fi
else else
# Ignore empty parameters # Ignore empty parameters
if [ -n "${all_args[$i]}" ] if [ -n "${all_args[$i]}" ]; then
then
# Else, add this value to this option # Else, add this value to this option
# Each value will be separated by ';' # Each value will be separated by ';'
if [ -n "${!option_var}" ] if [ -n "${!option_var}" ]; then
then
# If there's already another value for this option, add a ; before adding the new value # If there's already another value for this option, add a ; before adding the new value
eval ${option_var}+="\;" eval ${option_var}+="\;"
fi fi
@ -190,22 +176,21 @@ ynh_handle_getopts_args () {
# LEGACY MODE # LEGACY MODE
# Check if there's getopts arguments # Check if there's getopts arguments
if [ "${arguments[0]:0:1}" != "-" ] if [ "${arguments[0]:0:1}" != "-" ]; then
then
# If not, enter in legacy mode and manage the arguments as positionnal ones.. # If not, enter in legacy mode and manage the arguments as positionnal ones..
# Dot not echo, to prevent to go through a helper output. But print only in the log. # Dot not echo, to prevent to go through a helper output. But print only in the log.
set -x; echo "! Helper used in legacy mode !" > /dev/null; set +x set -x
echo "! Helper used in legacy mode !" >/dev/null
set +x
local i local i
for i in `seq 0 $(( ${#arguments[@]} -1 ))` for i in $(seq 0 $((${#arguments[@]} - 1))); do
do
# Try to use legacy_args as a list of option_flag of the array args_array # Try to use legacy_args as a list of option_flag of the array args_array
# Otherwise, fallback to getopts_parameters to get the option_flag. But an associative arrays isn't always sorted in the correct order... # Otherwise, fallback to getopts_parameters to get the option_flag. But an associative arrays isn't always sorted in the correct order...
# Remove all ':' in getopts_parameters # Remove all ':' in getopts_parameters
getopts_parameters=${legacy_args:-${getopts_parameters//:}} getopts_parameters=${legacy_args:-${getopts_parameters//:/}}
# Get the option_flag from getopts_parameters, by using the option_flag according to the position of the argument. # Get the option_flag from getopts_parameters, by using the option_flag according to the position of the argument.
option_flag=${getopts_parameters:$i:1} option_flag=${getopts_parameters:$i:1}
if [ -z "$option_flag" ] if [ -z "$option_flag" ]; then
then
ynh_print_warn --message="Too many arguments ! \"${arguments[$i]}\" will be ignored." ynh_print_warn --message="Too many arguments ! \"${arguments[$i]}\" will be ignored."
continue continue
fi fi

View file

@ -25,41 +25,34 @@ ynh_get_ram () {
free=${free:-0} free=${free:-0}
total=${total:-0} total=${total:-0}
if [ $free -eq $total ] if [ $free -eq $total ]; then
then
ynh_print_warn --message="You have to choose --free or --total when using ynh_get_ram" ynh_print_warn --message="You have to choose --free or --total when using ynh_get_ram"
ram=0 ram=0
# Use the total amount of ram # Use the total amount of ram
elif [ $free -eq 1 ] elif [ $free -eq 1 ]; then
then
local free_ram=$(vmstat --stats --unit M | grep "free memory" | awk '{print $1}') local free_ram=$(vmstat --stats --unit M | grep "free memory" | awk '{print $1}')
local free_swap=$(vmstat --stats --unit M | grep "free swap" | awk '{print $1}') local free_swap=$(vmstat --stats --unit M | grep "free swap" | awk '{print $1}')
local free_ram_swap=$((free_ram + free_swap)) local free_ram_swap=$((free_ram + free_swap))
# Use the total amount of free ram # Use the total amount of free ram
local ram=$free_ram_swap local ram=$free_ram_swap
if [ $ignore_swap -eq 1 ] if [ $ignore_swap -eq 1 ]; then
then
# Use only the amount of free ram # Use only the amount of free ram
ram=$free_ram ram=$free_ram
elif [ $only_swap -eq 1 ] elif [ $only_swap -eq 1 ]; then
then
# Use only the amount of free swap # Use only the amount of free swap
ram=$free_swap ram=$free_swap
fi fi
elif [ $total -eq 1 ] elif [ $total -eq 1 ]; then
then
local total_ram=$(vmstat --stats --unit M | grep "total memory" | awk '{print $1}') local total_ram=$(vmstat --stats --unit M | grep "total memory" | awk '{print $1}')
local total_swap=$(vmstat --stats --unit M | grep "total swap" | awk '{print $1}') local total_swap=$(vmstat --stats --unit M | grep "total swap" | awk '{print $1}')
local total_ram_swap=$((total_ram + total_swap)) local total_ram_swap=$((total_ram + total_swap))
local ram=$total_ram_swap local ram=$total_ram_swap
if [ $ignore_swap -eq 1 ] if [ $ignore_swap -eq 1 ]; then
then
# Use only the amount of free ram # Use only the amount of free ram
ram=$total_ram ram=$total_ram
elif [ $only_swap -eq 1 ] elif [ $only_swap -eq 1 ]; then
then
# Use only the amount of free swap # Use only the amount of free swap
ram=$total_swap ram=$total_swap
fi fi
@ -100,8 +93,7 @@ ynh_require_ram () {
local ram=$(ynh_get_ram $free $total $ignore_swap $only_swap) local ram=$(ynh_get_ram $free $total $ignore_swap $only_swap)
if [ $ram -lt $required ] if [ $ram -lt $required ]; then
then
return 1 return 1
else else
return 0 return 0

View file

@ -38,25 +38,6 @@ ynh_print_info() {
echo "$message" >&$YNH_STDINFO echo "$message" >&$YNH_STDINFO
} }
# Ignore the yunohost-cli log to prevent errors with conditional commands
#
# [internal]
#
# usage: ynh_no_log COMMAND
#
# Simply duplicate the log, execute the yunohost command and replace the log without the result of this command
# It's a very badly hack...
#
# Requires YunoHost version 2.6.4 or higher.
ynh_no_log() {
local ynh_cli_log=/var/log/yunohost/yunohost-cli.log
cp --archive ${ynh_cli_log} ${ynh_cli_log}-move
eval $@
local exit_code=$?
mv ${ynh_cli_log}-move ${ynh_cli_log}
return $exit_code
}
# Main printer, just in case in the future we have to change anything about that. # Main printer, just in case in the future we have to change anything about that.
# #
# [internal] # [internal]
@ -102,78 +83,115 @@ ynh_print_err () {
# Execute a command and print the result as an error # Execute a command and print the result as an error
# #
# usage: ynh_exec_err "your_command [ | other_command ]" # usage: ynh_exec_err your command and args
# | arg: command - command to execute # | arg: command - command to execute
# #
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe. # Note that you should NOT quote the command but only prefix it with ynh_exec_err
#
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
# #
# Requires YunoHost version 3.2.0 or higher. # Requires YunoHost version 3.2.0 or higher.
ynh_exec_err() { ynh_exec_err() {
# Boring legacy handling for when people calls ynh_exec_* wrapping the command in quotes,
# (because in the past eval was used) ...
# we detect this by checking that there's no 2nd arg, and $1 contains a space
if [[ "$#" -eq 1 ]] && [[ "$1" == *" "* ]]
then
ynh_print_err "$(eval $@)" ynh_print_err "$(eval $@)"
else
# Note that "$@" is used and not $@, c.f. https://unix.stackexchange.com/a/129077
ynh_print_err "$("$@")"
fi
} }
# Execute a command and print the result as a warning # Execute a command and print the result as a warning
# #
# usage: ynh_exec_warn "your_command [ | other_command ]" # usage: ynh_exec_warn your command and args
# | arg: command - command to execute # | arg: command - command to execute
# #
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe. # Note that you should NOT quote the command but only prefix it with ynh_exec_warn
#
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
# #
# Requires YunoHost version 3.2.0 or higher. # Requires YunoHost version 3.2.0 or higher.
ynh_exec_warn() { ynh_exec_warn() {
# Boring legacy handling for when people calls ynh_exec_* wrapping the command in quotes,
# (because in the past eval was used) ...
# we detect this by checking that there's no 2nd arg, and $1 contains a space
if [[ "$#" -eq 1 ]] && [[ "$1" == *" "* ]]
then
ynh_print_warn "$(eval $@)" ynh_print_warn "$(eval $@)"
else
# Note that "$@" is used and not $@, c.f. https://unix.stackexchange.com/a/129077
ynh_print_warn "$("$@")"
fi
} }
# Execute a command and force the result to be printed on stdout # Execute a command and force the result to be printed on stdout
# #
# usage: ynh_exec_warn_less "your_command [ | other_command ]" # usage: ynh_exec_warn_less your command and args
# | arg: command - command to execute # | arg: command - command to execute
# #
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe. # Note that you should NOT quote the command but only prefix it with ynh_exec_warn
#
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
# #
# Requires YunoHost version 3.2.0 or higher. # Requires YunoHost version 3.2.0 or higher.
ynh_exec_warn_less() { ynh_exec_warn_less() {
# Boring legacy handling for when people calls ynh_exec_* wrapping the command in quotes,
# (because in the past eval was used) ...
# we detect this by checking that there's no 2nd arg, and $1 contains a space
if [[ "$#" -eq 1 ]] && [[ "$1" == *" "* ]]
then
eval $@ 2>&1 eval $@ 2>&1
else
# Note that "$@" is used and not $@, c.f. https://unix.stackexchange.com/a/129077
"$@" 2>&1
fi
} }
# Execute a command and redirect stdout in /dev/null # Execute a command and redirect stdout in /dev/null
# #
# usage: ynh_exec_quiet "your_command [ | other_command ]" # usage: ynh_exec_quiet your command and args
# | arg: command - command to execute # | arg: command - command to execute
# #
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe. # Note that you should NOT quote the command but only prefix it with ynh_exec_warn
#
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
# #
# Requires YunoHost version 3.2.0 or higher. # Requires YunoHost version 3.2.0 or higher.
ynh_exec_quiet() { ynh_exec_quiet() {
# Boring legacy handling for when people calls ynh_exec_* wrapping the command in quotes,
# (because in the past eval was used) ...
# we detect this by checking that there's no 2nd arg, and $1 contains a space
if [[ "$#" -eq 1 ]] && [[ "$1" == *" "* ]]
then
eval $@ > /dev/null eval $@ > /dev/null
else
# Note that "$@" is used and not $@, c.f. https://unix.stackexchange.com/a/129077
"$@" > /dev/null
fi
} }
# Execute a command and redirect stdout and stderr in /dev/null # Execute a command and redirect stdout and stderr in /dev/null
# #
# usage: ynh_exec_fully_quiet "your_command [ | other_command ]" # usage: ynh_exec_quiet your command and args
# | arg: command - command to execute # | arg: command - command to execute
# #
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe. # Note that you should NOT quote the command but only prefix it with ynh_exec_quiet
#
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
# #
# Requires YunoHost version 3.2.0 or higher. # Requires YunoHost version 3.2.0 or higher.
ynh_exec_fully_quiet() { ynh_exec_fully_quiet() {
# Boring legacy handling for when people calls ynh_exec_* wrapping the command in quotes,
# (because in the past eval was used) ...
# we detect this by checking that there's no 2nd arg, and $1 contains a space
if [[ "$#" -eq 1 ]] && [[ "$1" == *" "* ]]
then
eval $@ > /dev/null 2>&1 eval $@ > /dev/null 2>&1
else
# Note that "$@" is used and not $@, c.f. https://unix.stackexchange.com/a/129077
"$@" > /dev/null 2>&1
fi
} }
# Remove any logs for all the following commands. # Remove any logs for all the following commands.
# #
# usage: ynh_print_OFF # usage: ynh_print_OFF
# #
# [internal]
#
# WARNING: You should be careful with this helper, and never forget to use ynh_print_ON as soon as possible to restore the logging. # WARNING: You should be careful with this helper, and never forget to use ynh_print_ON as soon as possible to restore the logging.
# #
# Requires YunoHost version 3.2.0 or higher. # Requires YunoHost version 3.2.0 or higher.
@ -185,6 +203,8 @@ ynh_print_OFF () {
# #
# usage: ynh_print_ON # usage: ynh_print_ON
# #
# [internal]
#
# Requires YunoHost version 3.2.0 or higher. # Requires YunoHost version 3.2.0 or higher.
ynh_print_ON() { ynh_print_ON() {
exec {BASH_XTRACEFD}>&1 exec {BASH_XTRACEFD}>&1
@ -236,8 +256,7 @@ ynh_script_progression () {
base_time=$(date +%s) base_time=$(date +%s)
# Compute $max_progression (if we didn't already) # Compute $max_progression (if we didn't already)
if [ "$max_progression" = -1 ] if [ "$max_progression" = -1 ]; then
then
# Get the number of occurrences of 'ynh_script_progression' in the script. Except those are commented. # Get the number of occurrences of 'ynh_script_progression' in the script. Except those are commented.
local helper_calls="$(grep --count "^[^#]*ynh_script_progression" $0)" local helper_calls="$(grep --count "^[^#]*ynh_script_progression" $0)"
# Get the number of call with a weight value # Get the number of call with a weight value
@ -249,7 +268,7 @@ ynh_script_progression () {
local weight_valuesB="$(grep --perl-regexp "^[^#]*ynh_script_progression.*-w " $0 | sed 's/.*-w[= ]\([[:digit:]]*\).*/\1/g')" local weight_valuesB="$(grep --perl-regexp "^[^#]*ynh_script_progression.*-w " $0 | sed 's/.*-w[= ]\([[:digit:]]*\).*/\1/g')"
# Each value will be on a different line. # Each value will be on a different line.
# Remove each 'end of line' and replace it by a '+' to sum the values. # Remove each 'end of line' and replace it by a '+' to sum the values.
local weight_values=$(( $(echo "$weight_valuesA" | tr '\n' '+') + $(echo "$weight_valuesB" | tr '\n' '+') 0 )) local weight_values=$(($(echo "$weight_valuesA" "$weight_valuesB" | grep -v -E '^\s*$' | tr '\n' '+' | sed 's/+$/+0/g')))
# max_progression is a total number of calls to this helper. # max_progression is a total number of calls to this helper.
# Less the number of calls with a weight value. # Less the number of calls with a weight value.
@ -263,8 +282,7 @@ ynh_script_progression () {
previous_weight=$weight previous_weight=$weight
# Reduce $increment_progression to the size of the scale # Reduce $increment_progression to the size of the scale
if [ $last -eq 0 ] if [ $last -eq 0 ]; then
then
local effective_progression=$(($increment_progression * $progress_scale / $max_progression)) local effective_progression=$(($increment_progression * $progress_scale / $max_progression))
# If last is specified, fill immediately the progression_bar # If last is specified, fill immediately the progression_bar
else else
@ -274,8 +292,7 @@ ynh_script_progression () {
# Build $progression_bar from progress_string(0,1,2) according to $effective_progression and the weight of the current task # Build $progression_bar from progress_string(0,1,2) according to $effective_progression and the weight of the current task
# expected_progression is the progression expected after the current task # expected_progression is the progression expected after the current task
local expected_progression="$((($increment_progression + $weight) * $progress_scale / $max_progression - $effective_progression))" local expected_progression="$((($increment_progression + $weight) * $progress_scale / $max_progression - $effective_progression))"
if [ $last -eq 1 ] if [ $last -eq 1 ]; then
then
expected_progression=0 expected_progression=0
fi fi
# left_progression is the progression not yet done # left_progression is the progression not yet done
@ -284,8 +301,7 @@ ynh_script_progression () {
local progression_bar="${progress_string2:0:$effective_progression}${progress_string1:0:$expected_progression}${progress_string0:0:$left_progression}" local progression_bar="${progress_string2:0:$effective_progression}${progress_string1:0:$expected_progression}${progress_string0:0:$left_progression}"
local print_exec_time="" local print_exec_time=""
if [ $time -eq 1 ] if [ $time -eq 1 ]; then
then
print_exec_time=" [$(date +%Hh%Mm,%Ss --date="0 + $exec_time sec")]" print_exec_time=" [$(date +%Hh%Mm,%Ss --date="0 + $exec_time sec")]"
fi fi
@ -302,70 +318,3 @@ ynh_script_progression () {
ynh_return() { ynh_return() {
echo "$1" >>"$YNH_STDRETURN" echo "$1" >>"$YNH_STDRETURN"
} }
# Debugger for app packagers
#
# usage: ynh_debug [--message=message] [--trace=1/0]
# | arg: -m, --message= - The text to print
# | arg: -t, --trace= - Turn on or off the trace of the script. Usefull to trace nonly a small part of a script.
#
# Requires YunoHost version 3.5.0 or higher.
ynh_debug () {
# Disable set xtrace for the helper itself, to not pollute the debug log
set +o xtrace # set +x
# Declare an array to define the options of this helper.
local legacy_args=mt
local -A args_array=( [m]=message= [t]=trace= )
local message
local trace
# Manage arguments with getopts
ynh_handle_getopts_args "$@"
# Re-disable xtrace, ynh_handle_getopts_args set it back
set +o xtrace # set +x
message=${message:-}
trace=${trace:-}
if [ -n "$message" ]
then
ynh_print_log "[Debug] ${message}" >&2
fi
if [ "$trace" == "1" ]
then
ynh_debug --message="Enable debugging"
set +o xtrace # set +x
# Get the current file descriptor of xtrace
old_bash_xtracefd=$BASH_XTRACEFD
# Add the current file name and the line number of any command currently running while tracing.
PS4='$(basename ${BASH_SOURCE[0]})-L${LINENO}: '
# Force xtrace to stderr
BASH_XTRACEFD=2
# Force stdout to stderr
exec 1>&2
fi
if [ "$trace" == "0" ]
then
ynh_debug --message="Disable debugging"
set +o xtrace # set +x
# Put xtrace back to its original fild descriptor
BASH_XTRACEFD=$old_bash_xtracefd
# Restore stdout
exec 1>&1
fi
# Renable set xtrace
set -o xtrace # set -x
}
# Execute a command and print the result as debug
#
# usage: ynh_debug_exec "your_command [ | other_command ]"
# | arg: command - command to execute
#
# When using pipes, double quotes are required - otherwise, this helper will run the first command, and the whole output will be sent through the next pipe.
#
# If the command to execute uses double quotes, they have to be escaped or they will be interpreted and removed.
#
# Requires YunoHost version 3.5.0 or higher.
ynh_debug_exec () {
ynh_debug --message="$(eval $@)"
}

View file

@ -30,22 +30,18 @@ ynh_use_logrotate () {
specific_user="${specific_user:-}" specific_user="${specific_user:-}"
# LEGACY CODE - PRE GETOPTS # LEGACY CODE - PRE GETOPTS
if [ $# -gt 0 ] && [ "$1" == "--non-append" ] if [ $# -gt 0 ] && [ "$1" == "--non-append" ]; then
then
nonappend=1 nonappend=1
# Destroy this argument for the next command. # Destroy this argument for the next command.
shift shift
elif [ $# -gt 1 ] && [ "$2" == "--non-append" ] elif [ $# -gt 1 ] && [ "$2" == "--non-append" ]; then
then
nonappend=1 nonappend=1
fi fi
if [ $# -gt 0 ] && [ "$(echo ${1:0:1})" != "-" ] if [ $# -gt 0 ] && [ "$(echo ${1:0:1})" != "-" ]; then
then
# If the given logfile parameter already exists as a file, or if it ends up with ".log", # If the given logfile parameter already exists as a file, or if it ends up with ".log",
# we just want to manage a single file # we just want to manage a single file
if [ -f "$1" ] || [ "$(echo ${1##*.})" == "log" ] if [ -f "$1" ] || [ "$(echo ${1##*.})" == "log" ]; then
then
local logfile=$1 local logfile=$1
# Otherwise we assume we want to manage a directory and all its .log file inside # Otherwise we assume we want to manage a directory and all its .log file inside
else else
@ -58,8 +54,7 @@ ynh_use_logrotate () {
if [ "$nonappend" -eq 1 ]; then if [ "$nonappend" -eq 1 ]; then
customtee="tee" customtee="tee"
fi fi
if [ -n "$logfile" ] if [ -n "$logfile" ]; then
then
if [ ! -f "$1" ] && [ "$(echo ${logfile##*.})" != "log" ]; then # Keep only the extension to check if it's a logfile if [ ! -f "$1" ] && [ "$(echo ${logfile##*.})" != "log" ]; then # Keep only the extension to check if it's a logfile
local logfile="$logfile/*.log" # Else, uses the directory and all logfile into it. local logfile="$logfile/*.log" # Else, uses the directory and all logfile into it.
fi fi
@ -67,8 +62,7 @@ ynh_use_logrotate () {
logfile="/var/log/${app}/*.log" # Without argument, use a defaut directory in /var/log logfile="/var/log/${app}/*.log" # Without argument, use a defaut directory in /var/log
fi fi
local su_directive="" local su_directive=""
if [[ -n $specific_user ]] if [[ -n $specific_user ]]; then
then
su_directive=" # Run logorotate as specific user - group su_directive=" # Run logorotate as specific user - group
su ${specific_user%/*} ${specific_user#*/}" su ${specific_user%/*} ${specific_user#*/}"
fi fi
@ -96,6 +90,11 @@ $logfile {
EOF EOF
mkdir --parents $(dirname "$logfile") # Create the log directory, if not exist mkdir --parents $(dirname "$logfile") # Create the log directory, if not exist
cat ${app}-logrotate | $customtee /etc/logrotate.d/$app >/dev/null # Append this config to the existing config file, or replace the whole config file (depending on $customtee) cat ${app}-logrotate | $customtee /etc/logrotate.d/$app >/dev/null # Append this config to the existing config file, or replace the whole config file (depending on $customtee)
if ynh_user_exists --username="$app"; then
chown $app:$app "$logfile"
chmod o-rwx "$logfile"
fi
} }
# Remove the app's logrotate config. # Remove the app's logrotate config.

View file

@ -22,8 +22,7 @@ ynh_multimedia_build_main_dir() {
mkdir -p "$MEDIA_DIRECTORY/share/eBook" mkdir -p "$MEDIA_DIRECTORY/share/eBook"
## Création des dossiers utilisateurs ## Création des dossiers utilisateurs
for user in $(yunohost user list --output-as json | jq -r '.users | keys[]') for user in $(yunohost user list --output-as json | jq -r '.users | keys[]'); do
do
mkdir -p "$MEDIA_DIRECTORY/$user" mkdir -p "$MEDIA_DIRECTORY/$user"
mkdir -p "$MEDIA_DIRECTORY/$user/Music" mkdir -p "$MEDIA_DIRECTORY/$user/Music"
mkdir -p "$MEDIA_DIRECTORY/$user/Picture" mkdir -p "$MEDIA_DIRECTORY/$user/Picture"

View file

@ -43,8 +43,7 @@ ynh_mysql_execute_as_root() {
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
database="${database:-}" database="${database:-}"
if [ -n "$database" ] if [ -n "$database" ]; then
then
database="--database=$database" database="--database=$database"
fi fi
@ -68,8 +67,7 @@ ynh_mysql_execute_file_as_root() {
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
database="${database:-}" database="${database:-}"
if [ -n "$database" ] if [ -n "$database" ]; then
then
database="--database=$database" database="--database=$database"
fi fi
@ -92,8 +90,7 @@ ynh_mysql_create_db() {
local sql="CREATE DATABASE ${db};" local sql="CREATE DATABASE ${db};"
# grant all privilegies to user # grant all privilegies to user
if [[ $# -gt 1 ]] if [[ $# -gt 1 ]]; then
then
sql+=" GRANT ALL PRIVILEGES ON ${db}.* TO '${2}'@'localhost'" sql+=" GRANT ALL PRIVILEGES ON ${db}.* TO '${2}'@'localhost'"
if [[ -n ${3:-} ]]; then if [[ -n ${3:-} ]]; then
sql+=" IDENTIFIED BY '${3}'" sql+=" IDENTIFIED BY '${3}'"
@ -160,8 +157,7 @@ ynh_mysql_create_user() {
# | ret: 0 if the user exists, 1 otherwise. # | ret: 0 if the user exists, 1 otherwise.
# #
# Requires YunoHost version 2.2.4 or higher. # Requires YunoHost version 2.2.4 or higher.
ynh_mysql_user_exists() ynh_mysql_user_exists() {
{
# Declare an array to define the options of this helper. # Declare an array to define the options of this helper.
local legacy_args=u local legacy_args=u
local -A args_array=([u]=user=) local -A args_array=([u]=user=)
@ -169,8 +165,7 @@ ynh_mysql_user_exists()
# Manage arguments with getopts # Manage arguments with getopts
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
if [[ -z $(ynh_mysql_execute_as_root --sql="SELECT User from mysql.user WHERE User = '$user';") ]] if [[ -z $(ynh_mysql_execute_as_root --sql="SELECT User from mysql.user WHERE User = '$user';") ]]; then
then
return 1 return 1
else else
return 0 return 0

View file

@ -18,8 +18,7 @@ ynh_find_port () {
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
test -n "$port" || ynh_die --message="The argument of ynh_find_port must be a valid port." test -n "$port" || ynh_die --message="The argument of ynh_find_port must be a valid port."
while ! ynh_port_available --port=$port while ! ynh_port_available --port=$port; do
do
port=$((port + 1)) port=$((port + 1))
done done
echo $port echo $port
@ -43,19 +42,16 @@ ynh_port_available () {
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
# Check if the port is free # Check if the port is free
if ss --numeric --listening --tcp --udp | awk '{print$5}' | grep --quiet --extended-regexp ":$port$" if ss --numeric --listening --tcp --udp | awk '{print$5}' | grep --quiet --extended-regexp ":$port$"; then
then
return 1 return 1
# This is to cover (most) case where an app is using a port yet ain't currently using it for some reason (typically service ain't up) # This is to cover (most) case where an app is using a port yet ain't currently using it for some reason (typically service ain't up)
elif grep -q "port: '$port'" /etc/yunohost/apps/*/settings.yml elif grep -q "port: '$port'" /etc/yunohost/apps/*/settings.yml; then
then
return 1 return 1
else else
return 0 return 0
fi fi
} }
# Validate an IP address # Validate an IP address
# #
# [internal] # [internal]
@ -66,8 +62,7 @@ ynh_port_available () {
# example: ynh_validate_ip 4 111.222.333.444 # example: ynh_validate_ip 4 111.222.333.444
# #
# Requires YunoHost version 2.2.4 or higher. # Requires YunoHost version 2.2.4 or higher.
ynh_validate_ip() ynh_validate_ip() {
{
# http://stackoverflow.com/questions/319279/how-to-validate-ip-address-in-python#319298 # http://stackoverflow.com/questions/319279/how-to-validate-ip-address-in-python#319298
# Declare an array to define the options of this helper. # Declare an array to define the options of this helper.
@ -101,8 +96,7 @@ EOF
# example: ynh_validate_ip4 111.222.333.444 # example: ynh_validate_ip4 111.222.333.444
# #
# Requires YunoHost version 2.2.4 or higher. # Requires YunoHost version 2.2.4 or higher.
ynh_validate_ip4() ynh_validate_ip4() {
{
# Declare an array to define the options of this helper. # Declare an array to define the options of this helper.
local legacy_args=i local legacy_args=i
local -A args_array=([i]=ip_address=) local -A args_array=([i]=ip_address=)
@ -113,7 +107,6 @@ ynh_validate_ip4()
ynh_validate_ip --family=4 --ip_address=$ip_address ynh_validate_ip --family=4 --ip_address=$ip_address
} }
# Validate an IPv6 address # Validate an IPv6 address
# #
# usage: ynh_validate_ip6 --ip_address=ip_address # usage: ynh_validate_ip6 --ip_address=ip_address
@ -123,8 +116,7 @@ ynh_validate_ip4()
# example: ynh_validate_ip6 2000:dead:beef::1 # example: ynh_validate_ip6 2000:dead:beef::1
# #
# Requires YunoHost version 2.2.4 or higher. # Requires YunoHost version 2.2.4 or higher.
ynh_validate_ip6() ynh_validate_ip6() {
{
# Declare an array to define the options of this helper. # Declare an array to define the options of this helper.
local legacy_args=i local legacy_args=i
local -A args_array=([i]=ip_address=) local -A args_array=([i]=ip_address=)

View file

@ -20,8 +20,7 @@ ynh_add_nginx_config () {
local finalnginxconf="/etc/nginx/conf.d/$domain.d/$app.conf" local finalnginxconf="/etc/nginx/conf.d/$domain.d/$app.conf"
if [ "${path_url:-}" != "/" ] if [ "${path_url:-}" != "/" ]; then
then
ynh_replace_string --match_string="^#sub_path_only" --replace_string="" --target_file="$YNH_APP_BASEDIR/conf/nginx.conf" ynh_replace_string --match_string="^#sub_path_only" --replace_string="" --target_file="$YNH_APP_BASEDIR/conf/nginx.conf"
else else
ynh_replace_string --match_string="^#root_path_only" --replace_string="" --target_file="$YNH_APP_BASEDIR/conf/nginx.conf" ynh_replace_string --match_string="^#root_path_only" --replace_string="" --target_file="$YNH_APP_BASEDIR/conf/nginx.conf"
@ -29,7 +28,6 @@ ynh_add_nginx_config () {
ynh_add_config --template="$YNH_APP_BASEDIR/conf/nginx.conf" --destination="$finalnginxconf" ynh_add_config --template="$YNH_APP_BASEDIR/conf/nginx.conf" --destination="$finalnginxconf"
ynh_systemd_action --service_name=nginx --action=reload ynh_systemd_action --service_name=nginx --action=reload
} }

View file

@ -21,8 +21,10 @@ SOURCE_SUM=d4da7ea91f680de0c9b5876e097e2a793e8234fcd0f7ca87a0599b925be087a3" > "
# Download and extract n # Download and extract n
ynh_setup_source --dest_dir="$n_install_dir/git" --source_id=n ynh_setup_source --dest_dir="$n_install_dir/git" --source_id=n
# Install n # Install n
(cd "$n_install_dir/git" (
PREFIX=$N_PREFIX make install 2>&1) cd "$n_install_dir/git"
PREFIX=$N_PREFIX make install 2>&1
)
} }
# Load the version of node for an app, and set variables. # Load the version of node for an app, and set variables.
@ -132,11 +134,9 @@ ynh_install_nodejs () {
test -x /usr/bin/npm && mv /usr/bin/npm /usr/bin/npm_n test -x /usr/bin/npm && mv /usr/bin/npm /usr/bin/npm_n
# If n is not previously setup, install it # If n is not previously setup, install it
if ! $n_install_dir/bin/n --version > /dev/null 2>&1 if ! $n_install_dir/bin/n --version >/dev/null 2>&1; then
then
ynh_install_n ynh_install_n
elif dpkg --compare-versions "$($n_install_dir/bin/n --version)" lt $n_version elif dpkg --compare-versions "$($n_install_dir/bin/n --version)" lt $n_version; then
then
ynh_install_n ynh_install_n
fi fi
@ -152,8 +152,7 @@ ynh_install_nodejs () {
# Install the requested version of nodejs # Install the requested version of nodejs
uname=$(uname --machine) uname=$(uname --machine)
if [[ $uname =~ aarch64 || $uname =~ arm64 ]] if [[ $uname =~ aarch64 || $uname =~ arm64 ]]; then
then
n $nodejs_version --arch=arm64 n $nodejs_version --arch=arm64
else else
n $nodejs_version n $nodejs_version
@ -164,8 +163,7 @@ ynh_install_nodejs () {
real_nodejs_version=$(basename $real_nodejs_version) real_nodejs_version=$(basename $real_nodejs_version)
# Create a symbolic link for this major version if the file doesn't already exist # Create a symbolic link for this major version if the file doesn't already exist
if [ ! -e "$node_version_path/$nodejs_version" ] if [ ! -e "$node_version_path/$nodejs_version" ]; then
then
ln --symbolic --force --no-target-directory $node_version_path/$real_nodejs_version $node_version_path/$nodejs_version ln --symbolic --force --no-target-directory $node_version_path/$real_nodejs_version $node_version_path/$nodejs_version
fi fi
@ -197,14 +195,12 @@ ynh_remove_nodejs () {
sed --in-place "/$YNH_APP_INSTANCE_NAME:$nodejs_version/d" "$n_install_dir/ynh_app_version" sed --in-place "/$YNH_APP_INSTANCE_NAME:$nodejs_version/d" "$n_install_dir/ynh_app_version"
# If no other app uses this version of nodejs, remove it. # If no other app uses this version of nodejs, remove it.
if ! grep --quiet "$nodejs_version" "$n_install_dir/ynh_app_version" if ! grep --quiet "$nodejs_version" "$n_install_dir/ynh_app_version"; then
then
$n_install_dir/bin/n rm $nodejs_version $n_install_dir/bin/n rm $nodejs_version
fi fi
# If no other app uses n, remove n # If no other app uses n, remove n
if [ ! -s "$n_install_dir/ynh_app_version" ] if [ ! -s "$n_install_dir/ynh_app_version" ]; then
then
ynh_secure_remove --file="$n_install_dir" ynh_secure_remove --file="$n_install_dir"
ynh_secure_remove --file="/usr/local/n" ynh_secure_remove --file="/usr/local/n"
sed --in-place "/N_PREFIX/d" /root/.bashrc sed --in-place "/N_PREFIX/d" /root/.bashrc

View file

@ -84,13 +84,11 @@ ynh_permission_create() {
show_tile=${show_tile:-} show_tile=${show_tile:-}
protected=${protected:-} protected=${protected:-}
if [[ -n $url ]] if [[ -n $url ]]; then
then
url=",url='$url'" url=",url='$url'"
fi fi
if [[ -n $additional_urls ]] if [[ -n $additional_urls ]]; then
then
# Convert a list from getopts to python list # Convert a list from getopts to python list
# Note that getopts separate the args with ';' # Note that getopts separate the args with ';'
# By example: # By example:
@ -100,18 +98,15 @@ ynh_permission_create() {
additional_urls=",additional_urls=['${additional_urls//;/\',\'}']" additional_urls=",additional_urls=['${additional_urls//;/\',\'}']"
fi fi
if [[ -n $auth_header ]] if [[ -n $auth_header ]]; then
then if [ $auth_header == "true" ]; then
if [ $auth_header == "true" ]
then
auth_header=",auth_header=True" auth_header=",auth_header=True"
else else
auth_header=",auth_header=False" auth_header=",auth_header=False"
fi fi
fi fi
if [[ -n $allowed ]] if [[ -n $allowed ]]; then
then
# Convert a list from getopts to python list # Convert a list from getopts to python list
# Note that getopts separate the args with ';' # Note that getopts separate the args with ';'
# By example: # By example:
@ -127,20 +122,16 @@ ynh_permission_create() {
label=",label='$permission'" label=",label='$permission'"
fi fi
if [[ -n ${show_tile:-} ]] if [[ -n ${show_tile:-} ]]; then
then if [ $show_tile == "true" ]; then
if [ $show_tile == "true" ]
then
show_tile=",show_tile=True" show_tile=",show_tile=True"
else else
show_tile=",show_tile=False" show_tile=",show_tile=False"
fi fi
fi fi
if [[ -n ${protected:-} ]] if [[ -n ${protected:-} ]]; then
then if [ $protected == "true" ]; then
if [ $protected == "true" ]
then
protected=",protected=True" protected=",protected=True"
else else
protected=",protected=False" protected=",protected=False"
@ -215,13 +206,11 @@ ynh_permission_url() {
auth_header=${auth_header:-} auth_header=${auth_header:-}
clear_urls=${clear_urls:-} clear_urls=${clear_urls:-}
if [[ -n $url ]] if [[ -n $url ]]; then
then
url=",url='$url'" url=",url='$url'"
fi fi
if [[ -n $add_url ]] if [[ -n $add_url ]]; then
then
# Convert a list from getopts to python list # Convert a list from getopts to python list
# Note that getopts separate the args with ';' # Note that getopts separate the args with ';'
# For example: # For example:
@ -231,8 +220,7 @@ ynh_permission_url() {
add_url=",add_url=['${add_url//;/\',\'}']" add_url=",add_url=['${add_url//;/\',\'}']"
fi fi
if [[ -n $remove_url ]] if [[ -n $remove_url ]]; then
then
# Convert a list from getopts to python list # Convert a list from getopts to python list
# Note that getopts separate the args with ';' # Note that getopts separate the args with ';'
# For example: # For example:
@ -242,25 +230,21 @@ ynh_permission_url() {
remove_url=",remove_url=['${remove_url//;/\',\'}']" remove_url=",remove_url=['${remove_url//;/\',\'}']"
fi fi
if [[ -n $auth_header ]] if [[ -n $auth_header ]]; then
then if [ $auth_header == "true" ]; then
if [ $auth_header == "true" ]
then
auth_header=",auth_header=True" auth_header=",auth_header=True"
else else
auth_header=",auth_header=False" auth_header=",auth_header=False"
fi fi
fi fi
if [[ -n $clear_urls ]] && [ $clear_urls -eq 1 ] if [[ -n $clear_urls ]] && [ $clear_urls -eq 1 ]; then
then
clear_urls=",clear_urls=True" clear_urls=",clear_urls=True"
fi fi
yunohost tools shell -c "from yunohost.permission import permission_url; permission_url('$app.$permission' $url $add_url $remove_url $auth_header $clear_urls)" yunohost tools shell -c "from yunohost.permission import permission_url; permission_url('$app.$permission' $url $add_url $remove_url $auth_header $clear_urls)"
} }
# Update a permission for the app # Update a permission for the app
# #
# usage: ynh_permission_update --permission "permission" [--add="group" ["group" ...]] [--remove="group" ["group" ...]] # usage: ynh_permission_update --permission "permission" [--add="group" ["group" ...]] [--remove="group" ["group" ...]]
@ -290,8 +274,7 @@ ynh_permission_update() {
show_tile=${show_tile:-} show_tile=${show_tile:-}
protected=${protected:-} protected=${protected:-}
if [[ -n $add ]] if [[ -n $add ]]; then
then
# Convert a list from getopts to python list # Convert a list from getopts to python list
# Note that getopts separate the args with ';' # Note that getopts separate the args with ';'
# For example: # For example:
@ -300,8 +283,7 @@ ynh_permission_update() {
# add=['alice', 'bob'] # add=['alice', 'bob']
add=",add=['${add//';'/"','"}']" add=",add=['${add//';'/"','"}']"
fi fi
if [[ -n $remove ]] if [[ -n $remove ]]; then
then
# Convert a list from getopts to python list # Convert a list from getopts to python list
# Note that getopts separate the args with ';' # Note that getopts separate the args with ';'
# For example: # For example:
@ -311,15 +293,12 @@ ynh_permission_update() {
remove=",remove=['${remove//';'/"','"}']" remove=",remove=['${remove//';'/"','"}']"
fi fi
if [[ -n $label ]] if [[ -n $label ]]; then
then
label=",label='$label'" label=",label='$label'"
fi fi
if [[ -n $show_tile ]] if [[ -n $show_tile ]]; then
then if [ $show_tile == "true" ]; then
if [ $show_tile == "true" ]
then
show_tile=",show_tile=True" show_tile=",show_tile=True"
else else
show_tile=",show_tile=False" show_tile=",show_tile=False"
@ -327,8 +306,7 @@ ynh_permission_update() {
fi fi
if [[ -n $protected ]]; then if [[ -n $protected ]]; then
if [ $protected == "true" ] if [ $protected == "true" ]; then
then
protected=",protected=True" protected=",protected=True"
else else
protected=",protected=False" protected=",protected=False"
@ -357,17 +335,14 @@ ynh_permission_has_user() {
# Manage arguments with getopts # Manage arguments with getopts
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
if ! ynh_permission_exists --permission=$permission if ! ynh_permission_exists --permission=$permission; then
then
return 1 return 1
fi fi
# Check both allowed and corresponding_users sections in the json # Check both allowed and corresponding_users sections in the json
for section in "allowed" "corresponding_users" for section in "allowed" "corresponding_users"; do
do
if yunohost user permission info "$app.$permission" --output-as json --quiet \ if yunohost user permission info "$app.$permission" --output-as json --quiet \
| jq -e --arg user $user --arg section $section '.[$section] | index($user)' >/dev/null | jq -e --arg user $user --arg section $section '.[$section] | index($user)' >/dev/null; then
then
return 0 return 0
fi fi
done done
@ -382,8 +357,7 @@ ynh_permission_has_user() {
# #
# Requires YunoHost version 4.1.2 or higher. # Requires YunoHost version 4.1.2 or higher.
ynh_legacy_permissions_exists() { ynh_legacy_permissions_exists() {
for permission in "skipped" "unprotected" "protected" for permission in "skipped" "unprotected" "protected"; do
do
if ynh_permission_exists --permission="legacy_${permission}_uris"; then if ynh_permission_exists --permission="legacy_${permission}_uris"; then
return 0 return 0
fi fi
@ -403,8 +377,7 @@ ynh_legacy_permissions_exists () {
# fi # fi
# Requires YunoHost version 4.1.2 or higher. # Requires YunoHost version 4.1.2 or higher.
ynh_legacy_permissions_delete_all() { ynh_legacy_permissions_delete_all() {
for permission in "skipped" "unprotected" "protected" for permission in "skipped" "unprotected" "protected"; do
do
if ynh_permission_exists --permission="legacy_${permission}_uris"; then if ynh_permission_exists --permission="legacy_${permission}_uris"; then
ynh_permission_delete --permission="legacy_${permission}_uris" ynh_permission_delete --permission="legacy_${permission}_uris"
fi fi

View file

@ -86,8 +86,7 @@ ynh_add_fpm_config () {
local old_phpversion=$(ynh_app_setting_get --app=$app --key=phpversion) local old_phpversion=$(ynh_app_setting_get --app=$app --key=phpversion)
# If the PHP version changed, remove the old fpm conf # If the PHP version changed, remove the old fpm conf
if [ -n "$old_phpversion" ] && [ "$old_phpversion" != "$phpversion" ] if [ -n "$old_phpversion" ] && [ "$old_phpversion" != "$phpversion" ]; then
then
local old_php_fpm_config_dir=$(ynh_app_setting_get --app=$app --key=fpm_config_dir) local old_php_fpm_config_dir=$(ynh_app_setting_get --app=$app --key=fpm_config_dir)
local old_php_finalphpconf="$old_php_fpm_config_dir/pool.d/$app.conf" local old_php_finalphpconf="$old_php_fpm_config_dir/pool.d/$app.conf"
@ -97,25 +96,21 @@ ynh_add_fpm_config () {
fi fi
# If the requested PHP version is not the default version for YunoHost # If the requested PHP version is not the default version for YunoHost
if [ "$phpversion" != "$YNH_DEFAULT_PHP_VERSION" ] if [ "$phpversion" != "$YNH_DEFAULT_PHP_VERSION" ]; then
then
# If the argument --package is used, add the packages to ynh_install_php to install them from sury # If the argument --package is used, add the packages to ynh_install_php to install them from sury
if [ -n "$package" ] if [ -n "$package" ]; then
then
local additionnal_packages="--package=$package" local additionnal_packages="--package=$package"
else else
local additionnal_packages="" local additionnal_packages=""
fi fi
# Install this specific version of PHP. # Install this specific version of PHP.
ynh_install_php --phpversion="$phpversion" "$additionnal_packages" ynh_install_php --phpversion="$phpversion" "$additionnal_packages"
elif [ -n "$package" ] elif [ -n "$package" ]; then
then
# Install the additionnal packages from the default repository # Install the additionnal packages from the default repository
ynh_add_app_dependencies --package="$package" ynh_install_app_dependencies "$package"
fi fi
if [ $dedicated_service -eq 1 ] if [ $dedicated_service -eq 1 ]; then
then
local fpm_service="${app}-phpfpm" local fpm_service="${app}-phpfpm"
local fpm_config_dir="/etc/php/$phpversion/dedicated-fpm" local fpm_config_dir="/etc/php/$phpversion/dedicated-fpm"
else else
@ -132,12 +127,10 @@ ynh_add_fpm_config () {
ynh_app_setting_set --app=$app --key=phpversion --value=$phpversion ynh_app_setting_set --app=$app --key=phpversion --value=$phpversion
# Migrate from mutual PHP service to dedicated one. # Migrate from mutual PHP service to dedicated one.
if [ $dedicated_service -eq 1 ] if [ $dedicated_service -eq 1 ]; then
then
local old_fpm_config_dir="/etc/php/$phpversion/fpm" local old_fpm_config_dir="/etc/php/$phpversion/fpm"
# If a config file exist in the common pool, move it. # If a config file exist in the common pool, move it.
if [ -e "$old_fpm_config_dir/pool.d/$app.conf" ] if [ -e "$old_fpm_config_dir/pool.d/$app.conf" ]; then
then
ynh_print_info --message="Migrate to a dedicated php-fpm service for $app." ynh_print_info --message="Migrate to a dedicated php-fpm service for $app."
# Create a backup of the old file before migration # Create a backup of the old file before migration
ynh_backup_if_checksum_is_different --file="$old_fpm_config_dir/pool.d/$app.conf" ynh_backup_if_checksum_is_different --file="$old_fpm_config_dir/pool.d/$app.conf"
@ -148,8 +141,7 @@ ynh_add_fpm_config () {
fi fi
fi fi
if [ $use_template -eq 1 ] if [ $use_template -eq 1 ]; then
then
# Usage 1, use the template in conf/php-fpm.conf # Usage 1, use the template in conf/php-fpm.conf
local phpfpm_path="$YNH_APP_BASEDIR/conf/php-fpm.conf" local phpfpm_path="$YNH_APP_BASEDIR/conf/php-fpm.conf"
# Make sure now that the template indeed exists # Make sure now that the template indeed exists
@ -183,16 +175,14 @@ pm.max_requests = 500
request_terminate_timeout = 1d request_terminate_timeout = 1d
" >$phpfpm_path " >$phpfpm_path
if [ "$php_pm" = "dynamic" ] if [ "$php_pm" = "dynamic" ]; then
then
echo " echo "
pm.start_servers = __PHP_START_SERVERS__ pm.start_servers = __PHP_START_SERVERS__
pm.min_spare_servers = __PHP_MIN_SPARE_SERVERS__ pm.min_spare_servers = __PHP_MIN_SPARE_SERVERS__
pm.max_spare_servers = __PHP_MAX_SPARE_SERVERS__ pm.max_spare_servers = __PHP_MAX_SPARE_SERVERS__
" >>$phpfpm_path " >>$phpfpm_path
elif [ "$php_pm" = "ondemand" ] elif [ "$php_pm" = "ondemand" ]; then
then
echo " echo "
pm.process_idle_timeout = 10s pm.process_idle_timeout = 10s
" >>$phpfpm_path " >>$phpfpm_path
@ -207,14 +197,12 @@ pm.process_idle_timeout = 10s
local finalphpconf="$fpm_config_dir/pool.d/$app.conf" local finalphpconf="$fpm_config_dir/pool.d/$app.conf"
ynh_add_config --template="$phpfpm_path" --destination="$finalphpconf" ynh_add_config --template="$phpfpm_path" --destination="$finalphpconf"
if [ -e "$YNH_APP_BASEDIR/conf/php-fpm.ini" ] if [ -e "$YNH_APP_BASEDIR/conf/php-fpm.ini" ]; then
then
ynh_print_warn --message="Packagers ! Please do not use a separate php ini file, merge your directives in the pool file instead." ynh_print_warn --message="Packagers ! Please do not use a separate php ini file, merge your directives in the pool file instead."
ynh_add_config --template="$YNH_APP_BASEDIR/conf/php-fpm.ini" --destination="$fpm_config_dir/conf.d/20-$app.ini" ynh_add_config --template="$YNH_APP_BASEDIR/conf/php-fpm.ini" --destination="$fpm_config_dir/conf.d/20-$app.ini"
fi fi
if [ $dedicated_service -eq 1 ] if [ $dedicated_service -eq 1 ]; then
then
# Create a dedicated php-fpm.conf for the service # Create a dedicated php-fpm.conf for the service
local globalphpconf=$fpm_config_dir/php-fpm-$app.conf local globalphpconf=$fpm_config_dir/php-fpm-$app.conf
@ -252,8 +240,7 @@ WantedBy=multi-user.target
ynh_systemd_action --service_name=$fpm_service --action=restart ynh_systemd_action --service_name=$fpm_service --action=restart
else else
# Validate that the new php conf doesn't break php-fpm entirely # Validate that the new php conf doesn't break php-fpm entirely
if ! php-fpm${phpversion} --test 2>/dev/null if ! php-fpm${phpversion} --test 2>/dev/null; then
then
php-fpm${phpversion} --test || true php-fpm${phpversion} --test || true
ynh_secure_remove --file="$finalphpconf" ynh_secure_remove --file="$finalphpconf"
ynh_die --message="The new configuration broke php-fpm?" ynh_die --message="The new configuration broke php-fpm?"
@ -279,20 +266,17 @@ ynh_remove_fpm_config () {
phpversion="${phpversion:-$YNH_DEFAULT_PHP_VERSION}" phpversion="${phpversion:-$YNH_DEFAULT_PHP_VERSION}"
# Assume default PHP files if not set # Assume default PHP files if not set
if [ -z "$fpm_config_dir" ] if [ -z "$fpm_config_dir" ]; then
then
fpm_config_dir="/etc/php/$YNH_DEFAULT_PHP_VERSION/fpm" fpm_config_dir="/etc/php/$YNH_DEFAULT_PHP_VERSION/fpm"
fpm_service="php$YNH_DEFAULT_PHP_VERSION-fpm" fpm_service="php$YNH_DEFAULT_PHP_VERSION-fpm"
fi fi
ynh_secure_remove --file="$fpm_config_dir/pool.d/$app.conf" ynh_secure_remove --file="$fpm_config_dir/pool.d/$app.conf"
if [ -e $fpm_config_dir/conf.d/20-$app.ini ] if [ -e $fpm_config_dir/conf.d/20-$app.ini ]; then
then
ynh_secure_remove --file="$fpm_config_dir/conf.d/20-$app.ini" ynh_secure_remove --file="$fpm_config_dir/conf.d/20-$app.ini"
fi fi
if [ $dedicated_service -eq 1 ] if [ $dedicated_service -eq 1 ]; then
then
# Remove the dedicated service PHP-FPM service for the app # Remove the dedicated service PHP-FPM service for the app
ynh_remove_systemd_config --service=$fpm_service ynh_remove_systemd_config --service=$fpm_service
# Remove the global PHP-FPM conf # Remove the global PHP-FPM conf
@ -304,8 +288,7 @@ ynh_remove_fpm_config () {
fi fi
# If the PHP version used is not the default version for YunoHost # If the PHP version used is not the default version for YunoHost
if [ "$phpversion" != "$YNH_DEFAULT_PHP_VERSION" ] if [ "$phpversion" != "$YNH_DEFAULT_PHP_VERSION" ]; then
then
# Remove this specific version of PHP # Remove this specific version of PHP
ynh_remove_php ynh_remove_php
fi fi
@ -330,37 +313,12 @@ ynh_install_php () {
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
package=${package:-} package=${package:-}
# Store phpversion into the config of this app if [ "$phpversion" == "$YNH_DEFAULT_PHP_VERSION" ]; then
ynh_app_setting_set $app phpversion $phpversion
if [ "$phpversion" == "$YNH_DEFAULT_PHP_VERSION" ]
then
ynh_die --message="Do not use ynh_install_php to install php$YNH_DEFAULT_PHP_VERSION" ynh_die --message="Do not use ynh_install_php to install php$YNH_DEFAULT_PHP_VERSION"
fi fi
# Create the file if doesn't exist already ynh_install_app_dependencies "$package"
touch /etc/php/ynh_app_version ynh_app_setting_set --app=$app --key=phpversion --value=$specific_php_version
# Do not add twice the same line
if ! grep --quiet "$YNH_APP_INSTANCE_NAME:" "/etc/php/ynh_app_version"
then
# Store the ID of this app and the version of PHP requested for it
echo "$YNH_APP_INSTANCE_NAME:$phpversion" | tee --append "/etc/php/ynh_app_version"
fi
# Add an extra repository for those packages
ynh_install_extra_repo --repo="https://packages.sury.org/php/ $(ynh_get_debian_release) main" --key="https://packages.sury.org/php/apt.gpg" --name=extra_php_version --priority=600
# Install requested dependencies from this extra repository.
# Install PHP-FPM first, otherwise PHP will install apache as a dependency.
ynh_add_app_dependencies --package="php${phpversion}-fpm"
ynh_add_app_dependencies --package="php$phpversion php${phpversion}-common $package"
# Set the default PHP version back as the default version for php-cli.
update-alternatives --set php /usr/bin/php$YNH_DEFAULT_PHP_VERSION
# Advertise service in admin panel
yunohost service add php${phpversion}-fpm --log "/var/log/php${phpversion}-fpm.log"
} }
# Remove the specific version of PHP used by the app. # Remove the specific version of PHP used by the app.
@ -371,35 +329,7 @@ ynh_install_php () {
# #
# Requires YunoHost version 3.8.1 or higher. # Requires YunoHost version 3.8.1 or higher.
ynh_remove_php () { ynh_remove_php () {
# Get the version of PHP used by this app ynh_remove_app_dependencies
local phpversion=$(ynh_app_setting_get --app=$app --key=phpversion)
if [ "$phpversion" == "$YNH_DEFAULT_PHP_VERSION" ] || [ -z "$phpversion" ]
then
if [ "$phpversion" == "$YNH_DEFAULT_PHP_VERSION" ]
then
ynh_print_err "Do not use ynh_remove_php to remove php$YNH_DEFAULT_PHP_VERSION !"
fi
return 0
fi
# Create the file if doesn't exist already
touch /etc/php/ynh_app_version
# Remove the line for this app
sed --in-place "/$YNH_APP_INSTANCE_NAME:$phpversion/d" "/etc/php/ynh_app_version"
# If no other app uses this version of PHP, remove it.
if ! grep --quiet "$phpversion" "/etc/php/ynh_app_version"
then
# Remove the service from the admin panel
if ynh_package_is_installed --package="php${phpversion}-fpm"; then
yunohost service remove php${phpversion}-fpm
fi
# Purge PHP dependencies for this version.
ynh_package_autopurge "php$phpversion php${phpversion}-fpm php${phpversion}-common"
fi
} }
# Define the values to configure PHP-FPM # Define the values to configure PHP-FPM
@ -435,38 +365,30 @@ ynh_get_scalable_phpfpm () {
usage=${usage,,} usage=${usage,,}
print=${print:-0} print=${print:-0}
if [ "$footprint" = "low" ] if [ "$footprint" = "low" ]; then
then
footprint=20 footprint=20
elif [ "$footprint" = "medium" ] elif [ "$footprint" = "medium" ]; then
then
footprint=35 footprint=35
elif [ "$footprint" = "high" ] elif [ "$footprint" = "high" ]; then
then
footprint=50 footprint=50
fi fi
# Define the factor to determine min_spare_servers # Define the factor to determine min_spare_servers
# to avoid having too few children ready to start for heavy apps # to avoid having too few children ready to start for heavy apps
if [ $footprint -le 20 ] if [ $footprint -le 20 ]; then
then
min_spare_servers_factor=8 min_spare_servers_factor=8
elif [ $footprint -le 35 ] elif [ $footprint -le 35 ]; then
then
min_spare_servers_factor=5 min_spare_servers_factor=5
else else
min_spare_servers_factor=3 min_spare_servers_factor=3
fi fi
# Define the way the process manager handle child processes. # Define the way the process manager handle child processes.
if [ "$usage" = "low" ] if [ "$usage" = "low" ]; then
then
php_pm=ondemand php_pm=ondemand
elif [ "$usage" = "medium" ] elif [ "$usage" = "medium" ]; then
then
php_pm=dynamic php_pm=dynamic
elif [ "$usage" = "high" ] elif [ "$usage" = "high" ]; then
then
php_pm=static php_pm=static
else else
ynh_die --message="Does not recognize '$usage' as an usage value." ynh_die --message="Does not recognize '$usage' as an usage value."
@ -477,8 +399,7 @@ ynh_get_scalable_phpfpm () {
at_least_one() { at_least_one() {
# Do not allow value below 1 # Do not allow value below 1
if [ $1 -le 0 ] if [ $1 -le 0 ]; then
then
echo 1 echo 1
else else
echo $1 echo $1
@ -491,8 +412,7 @@ ynh_get_scalable_phpfpm () {
php_max_children=$(($max_ram / 2 / $footprint)) php_max_children=$(($max_ram / 2 / $footprint))
# If process manager is set as static, use half less children. # If process manager is set as static, use half less children.
# Used as static, there's always as many children as the value of pm.max_children # Used as static, there's always as many children as the value of pm.max_children
if [ "$php_pm" = "static" ] if [ "$php_pm" = "static" ]; then
then
php_max_children=$(($php_max_children / 2)) php_max_children=$(($php_max_children / 2))
fi fi
php_max_children=$(at_least_one $php_max_children) php_max_children=$(at_least_one $php_max_children)
@ -500,8 +420,7 @@ ynh_get_scalable_phpfpm () {
# To not overload the proc, limit the number of children to 4 times the number of cores. # To not overload the proc, limit the number of children to 4 times the number of cores.
local core_number=$(nproc) local core_number=$(nproc)
local max_proc=$(($core_number * 4)) local max_proc=$(($core_number * 4))
if [ $php_max_children -gt $max_proc ] if [ $php_max_children -gt $max_proc ]; then
then
php_max_children=$max_proc php_max_children=$max_proc
fi fi
@ -511,8 +430,7 @@ ynh_get_scalable_phpfpm () {
php_max_children=$php_forced_max_children php_max_children=$php_forced_max_children
fi fi
if [ "$php_pm" = "dynamic" ] if [ "$php_pm" = "dynamic" ]; then
then
# Define pm.start_servers, pm.min_spare_servers and pm.max_spare_servers for a dynamic process manager # Define pm.start_servers, pm.min_spare_servers and pm.max_spare_servers for a dynamic process manager
php_min_spare_servers=$(($php_max_children / $min_spare_servers_factor)) php_min_spare_servers=$(($php_max_children / $min_spare_servers_factor))
php_min_spare_servers=$(at_least_one $php_min_spare_servers) php_min_spare_servers=$(at_least_one $php_min_spare_servers)
@ -528,30 +446,25 @@ ynh_get_scalable_phpfpm () {
php_start_servers=0 php_start_servers=0
fi fi
if [ $print -eq 1 ] if [ $print -eq 1 ]; then
then ynh_print_warn --message="Footprint=${footprint}Mb by pool."
ynh_debug --message="Footprint=${footprint}Mb by pool." ynh_print_warn --message="Process manager=$php_pm"
ynh_debug --message="Process manager=$php_pm" ynh_print_warn --message="Max RAM=${max_ram}Mb"
ynh_debug --message="Max RAM=${max_ram}Mb" if [ "$php_pm" != "static" ]; then
if [ "$php_pm" != "static" ] ynh_print_warn --message="\nMax estimated footprint=$(($php_max_children * $footprint))"
then ynh_print_warn --message="Min estimated footprint=$(($php_min_spare_servers * $footprint))"
ynh_debug --message="\nMax estimated footprint=$(( $php_max_children * $footprint ))"
ynh_debug --message="Min estimated footprint=$(( $php_min_spare_servers * $footprint ))"
fi fi
if [ "$php_pm" = "dynamic" ] if [ "$php_pm" = "dynamic" ]; then
then ynh_print_warn --message="Estimated average footprint=$(($php_max_spare_servers * $footprint))"
ynh_debug --message="Estimated average footprint=$(( $php_max_spare_servers * $footprint ))" elif [ "$php_pm" = "static" ]; then
elif [ "$php_pm" = "static" ] ynh_print_warn --message="Estimated footprint=$(($php_max_children * $footprint))"
then
ynh_debug --message="Estimated footprint=$(( $php_max_children * $footprint ))"
fi fi
ynh_debug --message="\nRaw php-fpm values:" ynh_print_warn --message="\nRaw php-fpm values:"
ynh_debug --message="pm.max_children = $php_max_children" ynh_print_warn --message="pm.max_children = $php_max_children"
if [ "$php_pm" = "dynamic" ] if [ "$php_pm" = "dynamic" ]; then
then ynh_print_warn --message="pm.start_servers = $php_start_servers"
ynh_debug --message="pm.start_servers = $php_start_servers" ynh_print_warn --message="pm.min_spare_servers = $php_min_spare_servers"
ynh_debug --message="pm.min_spare_servers = $php_min_spare_servers" ynh_print_warn --message="pm.max_spare_servers = $php_max_spare_servers"
ynh_debug --message="pm.max_spare_servers = $php_max_spare_servers"
fi fi
fi fi
} }

View file

@ -46,8 +46,7 @@ ynh_psql_execute_as_root() {
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
database="${database:-}" database="${database:-}"
if [ -n "$database" ] if [ -n "$database" ]; then
then
database="--database=$database" database="--database=$database"
fi fi
@ -72,8 +71,7 @@ ynh_psql_execute_file_as_root() {
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
database="${database:-}" database="${database:-}"
if [ -n "$database" ] if [ -n "$database" ]; then
then
database="--database=$database" database="--database=$database"
fi fi
@ -175,8 +173,7 @@ ynh_psql_user_exists() {
# Manage arguments with getopts # Manage arguments with getopts
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
if ! sudo --login --user=postgres PGUSER="postgres" PGPASSWORD="$(cat $PSQL_ROOT_PWD_FILE)" psql -tAc "SELECT rolname FROM pg_roles WHERE rolname='$user';" | grep --quiet "$user" if ! sudo --login --user=postgres PGUSER="postgres" PGPASSWORD="$(cat $PSQL_ROOT_PWD_FILE)" psql -tAc "SELECT rolname FROM pg_roles WHERE rolname='$user';" | grep --quiet "$user"; then
then
return 1 return 1
else else
return 0 return 0
@ -198,8 +195,7 @@ ynh_psql_database_exists() {
# Manage arguments with getopts # Manage arguments with getopts
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
if ! sudo --login --user=postgres PGUSER="postgres" PGPASSWORD="$(cat $PSQL_ROOT_PWD_FILE)" psql -tAc "SELECT datname FROM pg_database WHERE datname='$database';" | grep --quiet "$database" if ! sudo --login --user=postgres PGUSER="postgres" PGPASSWORD="$(cat $PSQL_ROOT_PWD_FILE)" psql -tAc "SELECT datname FROM pg_database WHERE datname='$database';" | grep --quiet "$database"; then
then
return 1 return 1
else else
return 0 return 0
@ -269,16 +265,14 @@ ynh_psql_remove_db() {
# Manage arguments with getopts # Manage arguments with getopts
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
if ynh_psql_database_exists --database=$db_name if ynh_psql_database_exists --database=$db_name; then # Check if the database exists
then # Check if the database exists
ynh_psql_drop_db $db_name # Remove the database ynh_psql_drop_db $db_name # Remove the database
else else
ynh_print_warn --message="Database $db_name not found" ynh_print_warn --message="Database $db_name not found"
fi fi
# Remove psql user if it exists # Remove psql user if it exists
if ynh_psql_user_exists --user=$db_user if ynh_psql_user_exists --user=$db_user; then
then
ynh_psql_drop_user $db_user ynh_psql_drop_user $db_user
else else
ynh_print_warn --message="User $db_user not found" ynh_print_warn --message="User $db_user not found"
@ -310,8 +304,7 @@ ynh_psql_test_if_first_run() {
# If this is the very first time, we define the root password # If this is the very first time, we define the root password
# and configure a few things # and configure a few things
if [ ! -f "$PSQL_ROOT_PWD_FILE" ] if [ ! -f "$PSQL_ROOT_PWD_FILE" ]; then
then
local pg_hba=/etc/postgresql/$PSQL_VERSION/main/pg_hba.conf local pg_hba=/etc/postgresql/$PSQL_VERSION/main/pg_hba.conf
local psql_root_password="$(ynh_string_random)" local psql_root_password="$(ynh_string_random)"

View file

@ -76,8 +76,7 @@ ynh_app_setting_delete() {
# #
# [internal] # [internal]
# #
ynh_app_setting() ynh_app_setting() {
{
set +o xtrace # set +x set +o xtrace # set +x
ACTION="$1" APP="$2" KEY="$3" VALUE="${4:-}" python3 - <<EOF ACTION="$1" APP="$2" KEY="$3" VALUE="${4:-}" python3 - <<EOF
import os, yaml, sys import os, yaml, sys

View file

@ -45,8 +45,7 @@ ynh_remove_systemd_config () {
local service="${service:-$app}" local service="${service:-$app}"
local finalsystemdconf="/etc/systemd/system/$service.service" local finalsystemdconf="/etc/systemd/system/$service.service"
if [ -e "$finalsystemdconf" ] if [ -e "$finalsystemdconf" ]; then
then
ynh_systemd_action --service_name=$service --action=stop ynh_systemd_action --service_name=$service --action=stop
systemctl disable $service --quiet systemctl disable $service --quiet
ynh_secure_remove --file="$finalsystemdconf" ynh_secure_remove --file="$finalsystemdconf"
@ -85,18 +84,15 @@ ynh_systemd_action() {
timeout=${timeout:-300} timeout=${timeout:-300}
# Manage case of service already stopped # Manage case of service already stopped
if [ "$action" == "stop" ] && ! systemctl is-active --quiet $service_name if [ "$action" == "stop" ] && ! systemctl is-active --quiet $service_name; then
then
return 0 return 0
fi fi
# Start to read the log # Start to read the log
if [[ -n "$line_match" ]] if [[ -n "$line_match" ]]; then
then
local templog="$(mktemp)" local templog="$(mktemp)"
# Following the starting of the app in its log # Following the starting of the app in its log
if [ "$log_path" == "systemd" ] if [ "$log_path" == "systemd" ]; then
then
# Read the systemd journal # Read the systemd journal
journalctl --unit=$service_name --follow --since=-0 --quiet >"$templog" & journalctl --unit=$service_name --follow --since=-0 --quiet >"$templog" &
# Get the PID of the journalctl command # Get the PID of the journalctl command
@ -115,13 +111,11 @@ ynh_systemd_action() {
fi fi
# If the service fails to perform the action # If the service fails to perform the action
if ! systemctl $action $service_name if ! systemctl $action $service_name; then
then
# Show syslog for this service # Show syslog for this service
ynh_exec_err journalctl --quiet --no-hostname --no-pager --lines=$length --unit=$service_name ynh_exec_err journalctl --quiet --no-hostname --no-pager --lines=$length --unit=$service_name
# If a log is specified for this service, show also the content of this log # If a log is specified for this service, show also the content of this log
if [ -e "$log_path" ] if [ -e "$log_path" ]; then
then
ynh_exec_err tail --lines=$length "$log_path" ynh_exec_err tail --lines=$length "$log_path"
fi fi
ynh_clean_check_starting ynh_clean_check_starting
@ -129,15 +123,12 @@ ynh_systemd_action() {
fi fi
# Start the timeout and try to find line_match # Start the timeout and try to find line_match
if [[ -n "${line_match:-}" ]] if [[ -n "${line_match:-}" ]]; then
then
set +x set +x
local i=0 local i=0
for i in $(seq 1 $timeout) for i in $(seq 1 $timeout); do
do
# Read the log until the sentence is found, that means the app finished to start. Or run until the timeout # Read the log until the sentence is found, that means the app finished to start. Or run until the timeout
if grep --extended-regexp --quiet "$line_match" "$templog" if grep --extended-regexp --quiet "$line_match" "$templog"; then
then
ynh_print_info --message="The service $service_name has correctly executed the action ${action}." ynh_print_info --message="The service $service_name has correctly executed the action ${action}."
break break
fi fi
@ -150,13 +141,11 @@ ynh_systemd_action() {
if [ $i -ge 3 ]; then if [ $i -ge 3 ]; then
echo "" >&2 echo "" >&2
fi fi
if [ $i -eq $timeout ] if [ $i -eq $timeout ]; then
then
ynh_print_warn --message="The service $service_name didn't fully executed the action ${action} before the timeout." ynh_print_warn --message="The service $service_name didn't fully executed the action ${action} before the timeout."
ynh_print_warn --message="Please find here an extract of the end of the log of the service $service_name:" ynh_print_warn --message="Please find here an extract of the end of the log of the service $service_name:"
ynh_exec_warn journalctl --quiet --no-hostname --no-pager --lines=$length --unit=$service_name ynh_exec_warn journalctl --quiet --no-hostname --no-pager --lines=$length --unit=$service_name
if [ -e "$log_path" ] if [ -e "$log_path" ]; then
then
ynh_print_warn --message="\-\-\-" ynh_print_warn --message="\-\-\-"
ynh_exec_warn tail --lines=$length "$log_path" ynh_exec_warn tail --lines=$length "$log_path"
fi fi
@ -171,13 +160,11 @@ ynh_systemd_action() {
# #
# Requires YunoHost version 3.5.0 or higher. # Requires YunoHost version 3.5.0 or higher.
ynh_clean_check_starting() { ynh_clean_check_starting() {
if [ -n "${pid_tail:-}" ] if [ -n "${pid_tail:-}" ]; then
then
# Stop the execution of tail. # Stop the execution of tail.
kill -SIGTERM $pid_tail 2>&1 kill -SIGTERM $pid_tail 2>&1
fi fi
if [ -n "${templog:-}" ] if [ -n "${templog:-}" ]; then
then
ynh_secure_remove --file="$templog" 2>&1 ynh_secure_remove --file="$templog" 2>&1
fi fi
} }

View file

@ -123,16 +123,14 @@ ynh_system_user_create () {
home_dir="${home_dir:-}" home_dir="${home_dir:-}"
groups="${groups:-}" groups="${groups:-}"
if ! ynh_system_user_exists "$username" # Check if the user exists on the system if ! ynh_system_user_exists "$username"; then # Check if the user exists on the system
then # If the user doesn't exist # If the user doesn't exist
if [ -n "$home_dir" ] if [ -n "$home_dir" ]; then # If a home dir is mentioned
then # If a home dir is mentioned
local user_home_dir="--home-dir $home_dir" local user_home_dir="--home-dir $home_dir"
else else
local user_home_dir="--no-create-home" local user_home_dir="--no-create-home"
fi fi
if [ $use_shell -eq 1 ] if [ $use_shell -eq 1 ]; then # If we want a shell for the user
then # If we want a shell for the user
local shell="" # Use default shell local shell="" # Use default shell
else else
local shell="--shell /usr/sbin/nologin" local shell="--shell /usr/sbin/nologin"
@ -141,8 +139,7 @@ ynh_system_user_create () {
fi fi
local group local group
for group in $groups for group in $groups; do
do
usermod -a -G "$group" "$username" usermod -a -G "$group" "$username"
done done
} }
@ -162,16 +159,14 @@ ynh_system_user_delete () {
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
# Check if the user exists on the system # Check if the user exists on the system
if ynh_system_user_exists "$username" if ynh_system_user_exists "$username"; then
then
deluser $username deluser $username
else else
ynh_print_warn --message="The user $username was not found" ynh_print_warn --message="The user $username was not found"
fi fi
# Check if the group exists on the system # Check if the group exists on the system
if ynh_system_group_exists "$username" if ynh_system_group_exists "$username"; then
then
delgroup $username delgroup $username
fi fi
} }

View file

@ -133,15 +133,13 @@ ynh_setup_source () {
src_filename="${source_id}.${src_format}" src_filename="${source_id}.${src_format}"
fi fi
# (Unused?) mecanism where one can have the file in a special local cache to not have to download it... # (Unused?) mecanism where one can have the file in a special local cache to not have to download it...
local local_src="/opt/yunohost-apps-src/${YNH_APP_ID}/${src_filename}" local local_src="/opt/yunohost-apps-src/${YNH_APP_ID}/${src_filename}"
mkdir -p /var/cache/yunohost/download/${YNH_APP_ID}/ mkdir -p /var/cache/yunohost/download/${YNH_APP_ID}/
src_filename="/var/cache/yunohost/download/${YNH_APP_ID}/${src_filename}" src_filename="/var/cache/yunohost/download/${YNH_APP_ID}/${src_filename}"
if test -e "$local_src" if test -e "$local_src"; then
then
cp $local_src $src_filename cp $local_src $src_filename
else else
[ -n "$src_url" ] || ynh_die "Couldn't parse SOURCE_URL from $src_file_path ?" [ -n "$src_url" ] || ynh_die "Couldn't parse SOURCE_URL from $src_file_path ?"
@ -162,15 +160,12 @@ ynh_setup_source () {
# Keep files to be backup/restored at the end of the helper # Keep files to be backup/restored at the end of the helper
# Assuming $dest_dir already exists # Assuming $dest_dir already exists
rm -rf /var/cache/yunohost/files_to_keep_during_setup_source/ rm -rf /var/cache/yunohost/files_to_keep_during_setup_source/
if [ -n "$keep" ] && [ -e "$dest_dir" ] if [ -n "$keep" ] && [ -e "$dest_dir" ]; then
then
local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID} local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID}
mkdir -p $keep_dir mkdir -p $keep_dir
local stuff_to_keep local stuff_to_keep
for stuff_to_keep in $keep for stuff_to_keep in $keep; do
do if [ -e "$dest_dir/$stuff_to_keep" ]; then
if [ -e "$dest_dir/$stuff_to_keep" ]
then
mkdir --parents "$(dirname "$keep_dir/$stuff_to_keep")" mkdir --parents "$(dirname "$keep_dir/$stuff_to_keep")"
cp --archive "$dest_dir/$stuff_to_keep" "$keep_dir/$stuff_to_keep" cp --archive "$dest_dir/$stuff_to_keep" "$keep_dir/$stuff_to_keep"
fi fi
@ -180,20 +175,16 @@ ynh_setup_source () {
# Extract source into the app dir # Extract source into the app dir
mkdir --parents "$dest_dir" mkdir --parents "$dest_dir"
if [ -n "${final_path:-}" ] && [ "$dest_dir" == "$final_path" ] if [ -n "${final_path:-}" ] && [ "$dest_dir" == "$final_path" ]; then
then
_ynh_apply_default_permissions $dest_dir _ynh_apply_default_permissions $dest_dir
fi fi
if ! "$src_extract" if ! "$src_extract"; then
then
mv $src_filename $dest_dir mv $src_filename $dest_dir
elif [ "$src_format" = "zip" ] elif [ "$src_format" = "zip" ]; then
then
# Zip format # Zip format
# Using of a temp directory, because unzip doesn't manage --strip-components # Using of a temp directory, because unzip doesn't manage --strip-components
if $src_in_subdir if $src_in_subdir; then
then
local tmp_dir=$(mktemp --directory) local tmp_dir=$(mktemp --directory)
unzip -quo $src_filename -d "$tmp_dir" unzip -quo $src_filename -d "$tmp_dir"
cp --archive $tmp_dir/*/. "$dest_dir" cp --archive $tmp_dir/*/. "$dest_dir"
@ -204,18 +195,15 @@ ynh_setup_source () {
ynh_secure_remove --file="$src_filename" ynh_secure_remove --file="$src_filename"
else else
local strip="" local strip=""
if [ "$src_in_subdir" != "false" ] if [ "$src_in_subdir" != "false" ]; then
then if [ "$src_in_subdir" == "true" ]; then
if [ "$src_in_subdir" == "true" ]
then
local sub_dirs=1 local sub_dirs=1
else else
local sub_dirs="$src_in_subdir" local sub_dirs="$src_in_subdir"
fi fi
strip="--strip-components $sub_dirs" strip="--strip-components $sub_dirs"
fi fi
if [[ "$src_format" =~ ^tar.gz|tar.bz2|tar.xz$ ]] if [[ "$src_format" =~ ^tar.gz|tar.bz2|tar.xz$ ]]; then
then
tar --extract --file=$src_filename --directory="$dest_dir" $strip tar --extract --file=$src_filename --directory="$dest_dir" $strip
else else
ynh_die --message="Archive format unrecognized." ynh_die --message="Archive format unrecognized."
@ -224,17 +212,16 @@ ynh_setup_source () {
fi fi
# Apply patches # Apply patches
if [ -d "$YNH_APP_BASEDIR/sources/patches/" ] if [ -d "$YNH_APP_BASEDIR/sources/patches/" ]; then
then
local patches_folder=$(realpath $YNH_APP_BASEDIR/sources/patches/) local patches_folder=$(realpath $YNH_APP_BASEDIR/sources/patches/)
if (( $(find $patches_folder -type f -name "${source_id}-*.patch" 2> /dev/null | wc --lines) > "0" )) if (($(find $patches_folder -type f -name "${source_id}-*.patch" 2>/dev/null | wc --lines) > "0")); then
then (
(cd "$dest_dir" cd "$dest_dir"
for p in $patches_folder/${source_id}-*.patch for p in $patches_folder/${source_id}-*.patch; do
do
echo $p echo $p
patch --strip=1 <$p patch --strip=1 <$p
done) || ynh_die --message="Unable to apply patches" done
) || ynh_die --message="Unable to apply patches"
fi fi
fi fi
@ -245,14 +232,11 @@ ynh_setup_source () {
# Keep files to be backup/restored at the end of the helper # Keep files to be backup/restored at the end of the helper
# Assuming $dest_dir already exists # Assuming $dest_dir already exists
if [ -n "$keep" ] if [ -n "$keep" ]; then
then
local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID} local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID}
local stuff_to_keep local stuff_to_keep
for stuff_to_keep in $keep for stuff_to_keep in $keep; do
do if [ -e "$keep_dir/$stuff_to_keep" ]; then
if [ -e "$keep_dir/$stuff_to_keep" ]
then
mkdir --parents "$(dirname "$dest_dir/$stuff_to_keep")" mkdir --parents "$(dirname "$dest_dir/$stuff_to_keep")"
cp --archive "$keep_dir/$stuff_to_keep" "$dest_dir/$stuff_to_keep" cp --archive "$keep_dir/$stuff_to_keep" "$dest_dir/$stuff_to_keep"
fi fi
@ -290,12 +274,10 @@ ynh_local_curl () {
# Concatenate all other arguments with '&' to prepare POST data # Concatenate all other arguments with '&' to prepare POST data
local POST_data="" local POST_data=""
local arg="" local arg=""
for arg in "${@:2}" for arg in "${@:2}"; do
do
POST_data="${POST_data}${arg}&" POST_data="${POST_data}${arg}&"
done done
if [ -n "$POST_data" ] if [ -n "$POST_data" ]; then
then
# Add --data arg and remove the last character, which is an unecessary '&' # Add --data arg and remove the last character, which is an unecessary '&'
POST_data="--data ${POST_data::-1}" POST_data="--data ${POST_data::-1}"
fi fi
@ -423,8 +405,7 @@ ynh_replace_vars () {
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
# Replace specific YunoHost variables # Replace specific YunoHost variables
if test -n "${path_url:-}" if test -n "${path_url:-}"; then
then
# path_url_slash_less is path_url, or a blank value if path_url is only '/' # path_url_slash_less is path_url, or a blank value if path_url is only '/'
local path_url_slash_less=${path_url%/} local path_url_slash_less=${path_url%/}
ynh_replace_string --match_string="__PATH__/" --replace_string="$path_url_slash_less/" --target_file="$file" ynh_replace_string --match_string="__PATH__/" --replace_string="$path_url_slash_less/" --target_file="$file"
@ -452,8 +433,7 @@ ynh_replace_vars () {
# Do the replacement # Do the replacement
local delimit=@ local delimit=@
for one_var in "${uniques_vars[@]}" for one_var in "${uniques_vars[@]}"; do
do
# Validate that one_var is indeed defined # Validate that one_var is indeed defined
# -v checks if the variable is defined, for example: # -v checks if the variable is defined, for example:
# -v FOO tests if $FOO is defined # -v FOO tests if $FOO is defined
@ -523,11 +503,9 @@ ynh_read_var_in_file() {
# Get the line number after which we search for the variable # Get the line number after which we search for the variable
local line_number=1 local line_number=1
if [[ -n "$after" ]]; if [[ -n "$after" ]]; then
then
line_number=$(grep -n $after $file | cut -d: -f1) line_number=$(grep -n $after $file | cut -d: -f1)
if [[ -z "$line_number" ]]; if [[ -z "$line_number" ]]; then
then
set -o xtrace # set -x set -o xtrace # set -x
return 1 return 1
fi fi
@ -564,7 +542,7 @@ ynh_read_var_in_file() {
fi fi
# Remove comments if needed # Remove comments if needed
local expression="$(echo "$expression_with_comment" | sed "s@$comments[^$string]*\$@@g" | sed "s@\s*[$endline]*\s*]*\$@@")" local expression="$(echo "$expression_with_comment" | sed "s@${comments}[^$string]*\$@@g" | sed "s@\s*[$endline]*\s*]*\$@@")"
local first_char="${expression:0:1}" local first_char="${expression:0:1}"
if [[ "$first_char" == '"' ]]; then if [[ "$first_char" == '"' ]]; then
@ -603,11 +581,9 @@ ynh_write_var_in_file() {
# Get the line number after which we search for the variable # Get the line number after which we search for the variable
local line_number=1 local line_number=1
if [[ -n "$after" ]]; if [[ -n "$after" ]]; then
then
line_number=$(grep -n $after $file | cut -d: -f1) line_number=$(grep -n $after $file | cut -d: -f1)
if [[ -z "$line_number" ]]; if [[ -z "$line_number" ]]; then
then
set -o xtrace # set -x set -o xtrace # set -x
return 1 return 1
fi fi
@ -644,7 +620,7 @@ ynh_write_var_in_file() {
fi fi
# Remove comments if needed # Remove comments if needed
local expression="$(echo "$expression_with_comment" | sed "s@$comments[^$string]*\$@@g" | sed "s@\s*[$endline]*\s*]*\$@@")" local expression="$(echo "$expression_with_comment" | sed "s@${comments}[^$string]*\$@@g" | sed "s@\s*[$endline]*\s*]*\$@@")"
endline=${expression_with_comment#"$expression"} endline=${expression_with_comment#"$expression"}
endline="$(echo "$endline" | sed 's/\\/\\\\/g')" endline="$(echo "$endline" | sed 's/\\/\\\\/g')"
value="$(echo "$value" | sed 's/\\/\\\\/g')" value="$(echo "$value" | sed 's/\\/\\\\/g')"
@ -673,7 +649,6 @@ ynh_write_var_in_file() {
set -o xtrace # set -x set -o xtrace # set -x
} }
# Render templates with Jinja2 # Render templates with Jinja2
# #
# [internal] # [internal]
@ -704,6 +679,27 @@ ynh_get_debian_release () {
echo $(lsb_release --codename --short) echo $(lsb_release --codename --short)
} }
_acceptable_path_to_delete() {
local file=$1
local forbidden_paths=$(ls -d / /* /{var,home,usr}/* /etc/{default,sudoers.d,yunohost,cron*})
# Legacy : A couple apps still have data in /home/$app ...
if [[ -n "$app" ]]
then
forbidden_paths=$(echo "$forbidden_paths" | grep -v "/home/$app")
fi
# Use realpath to normalize the path ..
# i.e convert ///foo//bar//..///baz//// to /foo/baz
file=$(realpath --no-symlinks "$file")
if [ -z "$file" ] || grep -q -x -F "$file" <<< "$forbidden_paths"; then
return 1
else
return 0
fi
}
# Remove a file or a directory securely # Remove a file or a directory securely
# #
# usage: ynh_secure_remove --file=path_to_remove # usage: ynh_secure_remove --file=path_to_remove
@ -719,31 +715,18 @@ ynh_secure_remove () {
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
set +o xtrace # set +x set +o xtrace # set +x
local forbidden_path=" \ if [ $# -ge 2 ]; then
/var/www \
/home/yunohost.app"
if [ $# -ge 2 ]
then
ynh_print_warn --message="/!\ Packager ! You provided more than one argument to ynh_secure_remove but it will be ignored... Use this helper with one argument at time." ynh_print_warn --message="/!\ Packager ! You provided more than one argument to ynh_secure_remove but it will be ignored... Use this helper with one argument at time."
fi fi
if [[ -z "$file" ]] if [[ -z "$file" ]]; then
then
ynh_print_warn --message="ynh_secure_remove called with empty argument, ignoring." ynh_print_warn --message="ynh_secure_remove called with empty argument, ignoring."
elif [[ "$forbidden_path" =~ "$file" \ elif [[ ! -e $file ]]; then
# Match all paths or subpaths in $forbidden_path
|| "$file" =~ ^/[[:alnum:]]+$ \
# Match all first level paths from / (Like /var, /root, etc...)
|| "${file:${#file}-1}" = "/" ]]
# Match if the path finishes by /. Because it seems there is an empty variable
then
ynh_print_warn --message="Not deleting '$file' because it is not an acceptable path to delete."
elif [ -e "$file" ]
then
rm --recursive "$file"
else
ynh_print_info --message="'$file' wasn't deleted because it doesn't exist." ynh_print_info --message="'$file' wasn't deleted because it doesn't exist."
elif ! _acceptable_path_to_delete "$file"; then
ynh_print_warn --message="Not deleting '$file' because it is not an acceptable path to delete."
else
rm --recursive "$file"
fi fi
set -o xtrace # set -x set -o xtrace # set -x
@ -796,8 +779,7 @@ ynh_app_upstream_version () {
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
manifest="${manifest:-}" manifest="${manifest:-}"
if [[ "$manifest" != "" ]] && [[ -e "$manifest" ]]; if [[ "$manifest" != "" ]] && [[ -e "$manifest" ]]; then
then
version_key_=$(ynh_read_manifest --manifest="$manifest" --manifest_key="version") version_key_=$(ynh_read_manifest --manifest="$manifest" --manifest_key="version")
else else
version_key_=$YNH_APP_MANIFEST_VERSION version_key_=$YNH_APP_MANIFEST_VERSION
@ -845,8 +827,7 @@ ynh_app_package_version () {
ynh_check_app_version_changed() { ynh_check_app_version_changed() {
local return_value=${YNH_APP_UPGRADE_TYPE} local return_value=${YNH_APP_UPGRADE_TYPE}
if [ "$return_value" == "UPGRADE_FULL" ] || [ "$return_value" == "UPGRADE_FORCED" ] || [ "$return_value" == "DOWNGRADE_FORCED" ] if [ "$return_value" == "UPGRADE_FULL" ] || [ "$return_value" == "UPGRADE_FORCED" ] || [ "$return_value" == "DOWNGRADE_FORCED" ]; then
then
return_value="UPGRADE_APP" return_value="UPGRADE_APP"
fi fi
@ -884,8 +865,7 @@ ynh_compare_current_package_version() {
local current_version=$YNH_APP_CURRENT_VERSION local current_version=$YNH_APP_CURRENT_VERSION
# Check the syntax of the versions # Check the syntax of the versions
if [[ ! $version =~ '~ynh' ]] || [[ ! $current_version =~ '~ynh' ]] if [[ ! $version =~ '~ynh' ]] || [[ ! $current_version =~ '~ynh' ]]; then
then
ynh_die --message="Invalid argument for version." ynh_die --message="Invalid argument for version."
fi fi
@ -920,13 +900,11 @@ _ynh_apply_default_permissions() {
local ynh_requirement=$(jq -r '.requirements.yunohost' $YNH_APP_BASEDIR/manifest.json | tr -d '>= ') local ynh_requirement=$(jq -r '.requirements.yunohost' $YNH_APP_BASEDIR/manifest.json | tr -d '>= ')
if [ -z "$ynh_requirement" ] || [ "$ynh_requirement" == "null" ] || dpkg --compare-versions $ynh_requirement ge 4.2 if [ -z "$ynh_requirement" ] || [ "$ynh_requirement" == "null" ] || dpkg --compare-versions $ynh_requirement ge 4.2; then
then
chmod o-rwx $target chmod o-rwx $target
chmod g-w $target chmod g-w $target
chown -R root:root $target chown -R root:root $target
if ynh_system_user_exists $app if ynh_system_user_exists $app; then
then
chown $app:$app $target chown $app:$app $target
fi fi
fi fi

View file

@ -10,8 +10,7 @@ yunohost tools shell -c "from yunohost.regenconf import manually_modified_files;
ynh_backup --src_path="./manually_modified_files_list" ynh_backup --src_path="./manually_modified_files_list"
for file in $(cat ./manually_modified_files_list) for file in $(cat ./manually_modified_files_list); do
do
[[ -e $file ]] && ynh_backup --src_path="$file" [[ -e $file ]] && ynh_backup --src_path="$file"
done done

View file

@ -98,8 +98,7 @@ EOF
# If we subscribed to a dyndns domain, add the corresponding cron # If we subscribed to a dyndns domain, add the corresponding cron
# - delay between 0 and 60 secs to spread the check over a 1 min window # - delay between 0 and 60 secs to spread the check over a 1 min window
# - do not run the command if some process already has the lock, to avoid queuing hundreds of commands... # - do not run the command if some process already has the lock, to avoid queuing hundreds of commands...
if ls -l /etc/yunohost/dyndns/K*.private 2>/dev/null if ls -l /etc/yunohost/dyndns/K*.private 2>/dev/null; then
then
cat >$pending_dir/etc/cron.d/yunohost-dyndns <<EOF cat >$pending_dir/etc/cron.d/yunohost-dyndns <<EOF
SHELL=/bin/bash SHELL=/bin/bash
*/10 * * * * root : YunoHost DynDNS update; sleep \$((RANDOM\\%60)); test -e /var/run/moulinette_yunohost.lock || yunohost dyndns update >> /dev/null */10 * * * * root : YunoHost DynDNS update; sleep \$((RANDOM\\%60)); test -e /var/run/moulinette_yunohost.lock || yunohost dyndns update >> /dev/null
@ -108,11 +107,11 @@ EOF
# Skip ntp if inside a container (inspired from the conf of systemd-timesyncd) # Skip ntp if inside a container (inspired from the conf of systemd-timesyncd)
mkdir -p ${pending_dir}/etc/systemd/system/ntp.service.d/ mkdir -p ${pending_dir}/etc/systemd/system/ntp.service.d/
echo " cat >${pending_dir}/etc/systemd/system/ntp.service.d/ynh-override.conf <<EOF
[Unit] [Unit]
ConditionCapability=CAP_SYS_TIME ConditionCapability=CAP_SYS_TIME
ConditionVirtualization=!container ConditionVirtualization=!container
" > ${pending_dir}/etc/systemd/system/ntp.service.d/ynh-override.conf EOF
# Make nftable conflict with yunohost-firewall # Make nftable conflict with yunohost-firewall
mkdir -p ${pending_dir}/etc/systemd/system/nftables.service.d/ mkdir -p ${pending_dir}/etc/systemd/system/nftables.service.d/
@ -135,8 +134,7 @@ EOF
cp yunoprompt.service ${pending_dir}/etc/systemd/system/yunoprompt.service cp yunoprompt.service ${pending_dir}/etc/systemd/system/yunoprompt.service
if [[ "$(yunohost settings get 'security.experimental.enabled')" == "True" ]] if [[ "$(yunohost settings get 'security.experimental.enabled')" == "True" ]]; then
then
cp proc-hidepid.service ${pending_dir}/etc/systemd/system/proc-hidepid.service cp proc-hidepid.service ${pending_dir}/etc/systemd/system/proc-hidepid.service
else else
touch ${pending_dir}/etc/systemd/system/proc-hidepid.service touch ${pending_dir}/etc/systemd/system/proc-hidepid.service
@ -183,8 +181,7 @@ do_post_regen() {
setfacl -m g:all_users:--- /etc/yunohost setfacl -m g:all_users:--- /etc/yunohost
setfacl -m g:all_users:--- /etc/ssowat setfacl -m g:all_users:--- /etc/ssowat
for USER in $(yunohost user list --quiet --output-as json | jq -r '.users | .[] | .username') for USER in $(yunohost user list --quiet --output-as json | jq -r '.users | .[] | .username'); do
do
[ ! -e "/home/$USER" ] || setfacl -m g:all_users:--- /home/$USER [ ! -e "/home/$USER" ] || setfacl -m g:all_users:--- /home/$USER
done done
@ -205,17 +202,18 @@ do_post_regen() {
grep -q '^sftp.app:' /etc/group || groupadd sftp.app grep -q '^sftp.app:' /etc/group || groupadd sftp.app
# Propagates changes in systemd service config overrides # Propagates changes in systemd service config overrides
[[ ! "$regen_conf_files" =~ "ntp.service.d/ynh-override.conf" ]] || { systemctl daemon-reload; systemctl restart ntp; } [[ ! "$regen_conf_files" =~ "ntp.service.d/ynh-override.conf" ]] || {
systemctl daemon-reload
systemctl restart ntp
}
[[ ! "$regen_conf_files" =~ "nftables.service.d/ynh-override.conf" ]] || systemctl daemon-reload [[ ! "$regen_conf_files" =~ "nftables.service.d/ynh-override.conf" ]] || systemctl daemon-reload
[[ ! "$regen_conf_files" =~ "login.conf.d/ynh-override.conf" ]] || systemctl daemon-reload [[ ! "$regen_conf_files" =~ "login.conf.d/ynh-override.conf" ]] || systemctl daemon-reload
if [[ "$regen_conf_files" =~ "yunoprompt.service" ]] if [[ "$regen_conf_files" =~ "yunoprompt.service" ]]; then
then
systemctl daemon-reload systemctl daemon-reload
action=$([[ -e /etc/systemd/system/yunoprompt.service ]] && echo 'enable' || echo 'disable') action=$([[ -e /etc/systemd/system/yunoprompt.service ]] && echo 'enable' || echo 'disable')
systemctl $action yunoprompt --quiet --now systemctl $action yunoprompt --quiet --now
fi fi
if [[ "$regen_conf_files" =~ "proc-hidepid.service" ]] if [[ "$regen_conf_files" =~ "proc-hidepid.service" ]]; then
then
systemctl daemon-reload systemctl daemon-reload
action=$([[ -e /etc/systemd/system/proc-hidepid.service ]] && echo 'enable' || echo 'disable') action=$([[ -e /etc/systemd/system/proc-hidepid.service ]] && echo 'enable' || echo 'disable')
systemctl $action proc-hidepid --quiet --now systemctl $action proc-hidepid --quiet --now

View file

@ -110,8 +110,7 @@ do_post_regen() {
current_local_ca_domain=$(openssl x509 -in $ynh_ca -text | tr ',' '\n' | grep Issuer | awk '{print $4}') current_local_ca_domain=$(openssl x509 -in $ynh_ca -text | tr ',' '\n' | grep Issuer | awk '{print $4}')
main_domain=$(cat /etc/yunohost/current_host) main_domain=$(cat /etc/yunohost/current_host)
if [[ "$current_local_ca_domain" != "$main_domain" ]] if [[ "$current_local_ca_domain" != "$main_domain" ]]; then
then
regen_local_ca $main_domain regen_local_ca $main_domain
# Idk how useful this is, but this was in the previous python code (domain.main_domain()) # Idk how useful this is, but this was in the previous python code (domain.main_domain())
ln -sf /etc/yunohost/certs/$domain/crt.pem /etc/ssl/certs/yunohost_crt.pem ln -sf /etc/yunohost/certs/$domain/crt.pem /etc/ssl/certs/yunohost_crt.pem

View file

@ -62,8 +62,7 @@ EOF
# We don't use mkhomedir_helper because 'admin' may not be recognized # We don't use mkhomedir_helper because 'admin' may not be recognized
# when this script is ran in a chroot (e.g. ISO install) # when this script is ran in a chroot (e.g. ISO install)
# We also refer to admin as uid 1007 for the same reason # We also refer to admin as uid 1007 for the same reason
if [ ! -d /home/admin ] if [ ! -d /home/admin ]; then
then
cp -r /etc/skel /home/admin cp -r /etc/skel /home/admin
chown -R 1007:1007 /home/admin chown -R 1007:1007 /home/admin
fi fi
@ -97,8 +96,8 @@ do_pre_regen() {
# Define if we need to migrate from hdb to mdb # Define if we need to migrate from hdb to mdb
curr_backend=$(grep '^database' /etc/ldap/slapd.conf 2>/dev/null | awk '{print $2}') curr_backend=$(grep '^database' /etc/ldap/slapd.conf 2>/dev/null | awk '{print $2}')
if [ -e /etc/ldap/slapd.conf ] && [ -n "$curr_backend" ] && \ if [ -e /etc/ldap/slapd.conf ] && [ -n "$curr_backend" ] \
[ $curr_backend != 'mdb' ]; then && [ $curr_backend != 'mdb' ]; then
backup_dir="/var/backups/dc=yunohost,dc=org-${curr_backend}-$(date +%s)" backup_dir="/var/backups/dc=yunohost,dc=org-${curr_backend}-$(date +%s)"
mkdir -p "$backup_dir" mkdir -p "$backup_dir"
slapcat -b dc=yunohost,dc=org -l "${backup_dir}/dc=yunohost-dc=org.ldif" slapcat -b dc=yunohost,dc=org -l "${backup_dir}/dc=yunohost-dc=org.ldif"
@ -133,16 +132,14 @@ do_post_regen() {
chown -R openldap:openldap /etc/ldap/slapd.d/ chown -R openldap:openldap /etc/ldap/slapd.d/
# If we changed the systemd ynh-override conf # If we changed the systemd ynh-override conf
if echo "$regen_conf_files" | sed 's/,/\n/g' | grep -q "^/etc/systemd/system/slapd.service.d/ynh-override.conf$" if echo "$regen_conf_files" | sed 's/,/\n/g' | grep -q "^/etc/systemd/system/slapd.service.d/ynh-override.conf$"; then
then
systemctl daemon-reload systemctl daemon-reload
systemctl restart slapd systemctl restart slapd
sleep 3 sleep 3
fi fi
# For some reason, old setups don't have the admins group defined... # For some reason, old setups don't have the admins group defined...
if ! slapcat | grep -q 'cn=admins,ou=groups,dc=yunohost,dc=org' if ! slapcat | grep -q 'cn=admins,ou=groups,dc=yunohost,dc=org'; then
then
slapadd -F /etc/ldap/slapd.d -b dc=yunohost,dc=org <<< \ slapadd -F /etc/ldap/slapd.d -b dc=yunohost,dc=org <<< \
"dn: cn=admins,ou=groups,dc=yunohost,dc=org "dn: cn=admins,ou=groups,dc=yunohost,dc=org
cn: admins cn: admins
@ -187,8 +184,7 @@ objectClass: top"
# wait a maximum time of 5 minutes # wait a maximum time of 5 minutes
# yes, force-reload behave like a restart # yes, force-reload behave like a restart
number_of_wait=0 number_of_wait=0
while ! su admin -c '' && ((number_of_wait < 60)) while ! su admin -c '' && ((number_of_wait < 60)); do
do
sleep 5 sleep 5
((number_of_wait += 1)) ((number_of_wait += 1))
done done

View file

@ -8,8 +8,7 @@ do_pre_regen() {
mkdir --parents "${pending_dir}/etc/apt/preferences.d" mkdir --parents "${pending_dir}/etc/apt/preferences.d"
packages_to_refuse_from_sury="php php-fpm php-mysql php-xml php-zip php-mbstring php-ldap php-gd php-curl php-bz2 php-json php-sqlite3 php-intl openssl libssl1.1 libssl-dev" packages_to_refuse_from_sury="php php-fpm php-mysql php-xml php-zip php-mbstring php-ldap php-gd php-curl php-bz2 php-json php-sqlite3 php-intl openssl libssl1.1 libssl-dev"
for package in $packages_to_refuse_from_sury for package in $packages_to_refuse_from_sury; do
do
echo " echo "
Package: $package Package: $package
Pin: origin \"packages.sury.org\" Pin: origin \"packages.sury.org\"

View file

@ -32,8 +32,14 @@ do_init_regen() {
cp "redirect_to_admin.conf" $nginx_conf_dir/default.d/ cp "redirect_to_admin.conf" $nginx_conf_dir/default.d/
# Restart nginx if conf looks good, otherwise display error and exit unhappy # Restart nginx if conf looks good, otherwise display error and exit unhappy
nginx -t 2>/dev/null || { nginx -t; exit 1; } nginx -t 2>/dev/null || {
systemctl restart nginx || { journalctl --no-pager --lines=10 -u nginx >&2; exit 1; } nginx -t
exit 1
}
systemctl restart nginx || {
journalctl --no-pager --lines=10 -u nginx >&2
exit 1
}
exit 0 exit 0
} }
@ -51,8 +57,7 @@ do_pre_regen() {
cp plain/* "$nginx_conf_dir" cp plain/* "$nginx_conf_dir"
# remove the panel overlay if this is specified in settings # remove the panel overlay if this is specified in settings
panel_overlay=$(yunohost settings get 'ssowat.panel_overlay.enabled') panel_overlay=$(yunohost settings get 'ssowat.panel_overlay.enabled')
if [ "$panel_overlay" == "false" ] || [ "$panel_overlay" == "False" ] if [ "$panel_overlay" == "false" ] || [ "$panel_overlay" == "False" ]; then
then
echo "#" >"${nginx_conf_dir}/yunohost_panel.conf.inc" echo "#" >"${nginx_conf_dir}/yunohost_panel.conf.inc"
fi fi
@ -88,8 +93,7 @@ do_pre_regen() {
done done
export webadmin_allowlist_enabled=$(yunohost settings get security.webadmin.allowlist.enabled) export webadmin_allowlist_enabled=$(yunohost settings get security.webadmin.allowlist.enabled)
if [ "$webadmin_allowlist_enabled" == "True" ] if [ "$webadmin_allowlist_enabled" == "True" ]; then
then
export webadmin_allowlist=$(yunohost settings get security.webadmin.allowlist) export webadmin_allowlist=$(yunohost settings get security.webadmin.allowlist)
fi fi
ynh_render_template "yunohost_admin.conf.inc" "${nginx_conf_dir}/yunohost_admin.conf.inc" ynh_render_template "yunohost_admin.conf.inc" "${nginx_conf_dir}/yunohost_admin.conf.inc"
@ -131,8 +135,14 @@ do_post_regen() {
done done
# Reload nginx if conf looks good, otherwise display error and exit unhappy # Reload nginx if conf looks good, otherwise display error and exit unhappy
nginx -t 2>/dev/null || { nginx -t; exit 1; } nginx -t 2>/dev/null || {
pgrep nginx && systemctl reload nginx || { journalctl --no-pager --lines=10 -u nginx >&2; exit 1; } nginx -t
exit 1
}
pgrep nginx && systemctl reload nginx || {
journalctl --no-pager --lines=10 -u nginx >&2
exit 1
}
} }
do_$1_regen ${@:2} do_$1_regen ${@:2}

View file

@ -29,8 +29,7 @@ do_pre_regen() {
export relay_port="" export relay_port=""
export relay_user="" export relay_user=""
export relay_host="$(yunohost settings get 'smtp.relay.host')" export relay_host="$(yunohost settings get 'smtp.relay.host')"
if [ -n "${relay_host}" ] if [ -n "${relay_host}" ]; then
then
relay_port="$(yunohost settings get 'smtp.relay.port')" relay_port="$(yunohost settings get 'smtp.relay.port')"
relay_user="$(yunohost settings get 'smtp.relay.user')" relay_user="$(yunohost settings get 'smtp.relay.user')"
relay_password="$(yunohost settings get 'smtp.relay.password')" relay_password="$(yunohost settings get 'smtp.relay.password')"
@ -69,8 +68,7 @@ do_pre_regen() {
do_post_regen() { do_post_regen() {
regen_conf_files=$1 regen_conf_files=$1
if [ -e /etc/postfix/sasl_passwd ] if [ -e /etc/postfix/sasl_passwd ]; then
then
chmod 750 /etc/postfix/sasl_passwd* chmod 750 /etc/postfix/sasl_passwd*
chown postfix:root /etc/postfix/sasl_passwd* chown postfix:root /etc/postfix/sasl_passwd*
fi fi

View file

@ -14,8 +14,7 @@ do_pre_regen() {
do_post_regen() { do_post_regen() {
regen_conf_files=$1 regen_conf_files=$1
if [[ ! -d /var/lib/mysql/mysql ]] if [[ ! -d /var/lib/mysql/mysql ]]; then
then
# dpkg-reconfigure will initialize mysql (if it ain't already) # dpkg-reconfigure will initialize mysql (if it ain't already)
# It enabled auth_socket for root, so no need to define any root password... # It enabled auth_socket for root, so no need to define any root password...
# c.f. : cat /var/lib/dpkg/info/mariadb-server-10.3.postinst | grep install_db -C3 # c.f. : cat /var/lib/dpkg/info/mariadb-server-10.3.postinst | grep install_db -C3
@ -33,8 +32,7 @@ do_post_regen() {
# mysql is supposed to be an alias to mariadb... but in some weird case is not # mysql is supposed to be an alias to mariadb... but in some weird case is not
# c.f. https://forum.yunohost.org/t/mysql-ne-fonctionne-pas/11661 # c.f. https://forum.yunohost.org/t/mysql-ne-fonctionne-pas/11661
# Playing with enable/disable allows to recreate the proper symlinks. # Playing with enable/disable allows to recreate the proper symlinks.
if [ ! -e /etc/systemd/system/mysql.service ] if [ ! -e /etc/systemd/system/mysql.service ]; then
then
systemctl stop mysql -q systemctl stop mysql -q
systemctl disable mysql -q systemctl disable mysql -q
systemctl disable mariadb -q systemctl disable mariadb -q

View file

@ -5,8 +5,7 @@ set -e
_generate_config() { _generate_config() {
echo "domains:" echo "domains:"
echo " - yunohost.local" echo " - yunohost.local"
for domain in $YNH_DOMAINS for domain in $YNH_DOMAINS; do
do
# Only keep .local domains (don't keep # Only keep .local domains (don't keep
[[ "$domain" =~ [^.]+\.[^.]+\.local$ ]] && echo "Subdomain $domain cannot be handled by Bonjour/Zeroconf/mDNS" >&2 [[ "$domain" =~ [^.]+\.[^.]+\.local$ ]] && echo "Subdomain $domain cannot be handled by Bonjour/Zeroconf/mDNS" >&2
[[ "$domain" =~ ^[^.]+\.local$ ]] || continue [[ "$domain" =~ ^[^.]+\.local$ ]] || continue
@ -39,8 +38,7 @@ do_post_regen() {
chown mdns:mdns /etc/yunohost/mdns.yml chown mdns:mdns /etc/yunohost/mdns.yml
# If we changed the systemd ynh-override conf # If we changed the systemd ynh-override conf
if echo "$regen_conf_files" | sed 's/,/\n/g' | grep -q "^/etc/systemd/system/yunomdns.service$" if echo "$regen_conf_files" | sed 's/,/\n/g' | grep -q "^/etc/systemd/system/yunomdns.service$"; then
then
systemctl daemon-reload systemctl daemon-reload
fi fi

View file

@ -32,6 +32,7 @@ do_pre_regen() {
# add domain conf files # add domain conf files
for domain in $YNH_DOMAINS; do for domain in $YNH_DOMAINS; do
[[ ! $domain =~ \.local$ ]] || continue
export domain export domain
ynh_render_template "domain.tpl" "${dnsmasq_dir}/${domain}" ynh_render_template "domain.tpl" "${dnsmasq_dir}/${domain}"
done done
@ -40,8 +41,10 @@ do_pre_regen() {
conf_files=$(ls -1 /etc/dnsmasq.d \ conf_files=$(ls -1 /etc/dnsmasq.d \
| awk '/^[^\.]+\.[^\.]+.*$/ { print $1 }') | awk '/^[^\.]+\.[^\.]+.*$/ { print $1 }')
for domain in $conf_files; do for domain in $conf_files; do
[[ $YNH_DOMAINS =~ $domain ]] \ if [[ ! $YNH_DOMAINS =~ $domain ]] && [[ ! $domain =~ \.local$ ]]
|| touch "${dnsmasq_dir}/${domain}" then
touch "${dnsmasq_dir}/${domain}"
fi
done done
} }
@ -50,10 +53,8 @@ do_post_regen() {
# Fuck it, those domain/search entries from dhclient are usually annoying # Fuck it, those domain/search entries from dhclient are usually annoying
# lying shit from the ISP trying to MiTM # lying shit from the ISP trying to MiTM
if grep -q -E "^ *(domain|search)" /run/resolvconf/resolv.conf if grep -q -E "^ *(domain|search)" /run/resolvconf/resolv.conf; then
then if grep -q -E "^ *(domain|search)" /run/resolvconf/interface/*.dhclient 2>/dev/null; then
if grep -q -E "^ *(domain|search)" /run/resolvconf/interface/*.dhclient 2>/dev/null
then
sed -E "s/^(domain|search)/#\1/g" -i /run/resolvconf/interface/*.dhclient sed -E "s/^(domain|search)/#\1/g" -i /run/resolvconf/interface/*.dhclient
fi fi
@ -71,8 +72,7 @@ do_post_regen() {
[[ -n "$regen_conf_files" ]] || return [[ -n "$regen_conf_files" ]] || return
# Remove / disable services likely to conflict with dnsmasq # Remove / disable services likely to conflict with dnsmasq
for SERVICE in systemd-resolved bind9 for SERVICE in systemd-resolved bind9; do
do
systemctl is-enabled $SERVICE &>/dev/null && systemctl disable $SERVICE 2>/dev/null systemctl is-enabled $SERVICE &>/dev/null && systemctl disable $SERVICE 2>/dev/null
systemctl is-active $SERVICE &>/dev/null && systemctl stop $SERVICE systemctl is-active $SERVICE &>/dev/null && systemctl stop $SERVICE
done done

View file

@ -76,7 +76,7 @@ class AppDiagnoser(Diagnoser):
for deprecated_helper in deprecated_helpers: for deprecated_helper in deprecated_helpers:
if ( if (
os.system( os.system(
f"grep -hr '{deprecated_helper}' {app['setting_path']}/scripts/ | grep -v -q '^\s*#'" f"grep -hr '{deprecated_helper}' {app['setting_path']}/scripts/ | grep -v -q '^\\s*#'"
) )
== 0 == 0
): ):

View file

@ -14,11 +14,11 @@ die() {
# Restore saved configuration and database # Restore saved configuration and database
[[ $state -ge 1 ]] \ [[ $state -ge 1 ]] \
&& (rm -rf /etc/ldap/slapd.d && && (rm -rf /etc/ldap/slapd.d \
mv "${TMPDIR}/slapd.d" /etc/ldap/slapd.d) && mv "${TMPDIR}/slapd.d" /etc/ldap/slapd.d)
[[ $state -ge 2 ]] \ [[ $state -ge 2 ]] \
&& (rm -rf /var/lib/ldap && && (rm -rf /var/lib/ldap \
mv "${TMPDIR}/ldap" /var/lib/ldap) && mv "${TMPDIR}/ldap" /var/lib/ldap)
chown -R openldap: /etc/ldap/slapd.d /var/lib/ldap chown -R openldap: /etc/ldap/slapd.d /var/lib/ldap
systemctl start slapd systemctl start slapd

View file

@ -5,8 +5,7 @@ ynh_abort_if_errors
YNH_CWD="${YNH_BACKUP_DIR%/}/conf/manually_modified_files" YNH_CWD="${YNH_BACKUP_DIR%/}/conf/manually_modified_files"
cd "$YNH_CWD" cd "$YNH_CWD"
for file in $(cat ./manually_modified_files_list) for file in $(cat ./manually_modified_files_list); do
do
ynh_restore_file --origin_path="$file" --not_mandatory ynh_restore_file --origin_path="$file" --not_mandatory
done done

View file

@ -78,6 +78,20 @@ service quota-warning {
} }
} }
service stats {
unix_listener stats-reader {
user = vmail
group = mail
mode = 0660
}
unix_listener stats-writer {
user = vmail
group = mail
mode = 0660
}
}
plugin { plugin {
sieve = /var/mail/sievescript/%n/.dovecot.sieve sieve = /var/mail/sievescript/%n/.dovecot.sieve
sieve_dir = /var/mail/sievescript/%n/scripts/ sieve_dir = /var/mail/sievescript/%n/scripts/

20
debian/changelog vendored
View file

@ -4,6 +4,26 @@ yunohost (11.0.0~alpha) unstable; urgency=low
-- Alexandre Aubin <alex.aubin@mailoo.org> Fri, 05 Feb 2021 00:02:38 +0100 -- Alexandre Aubin <alex.aubin@mailoo.org> Fri, 05 Feb 2021 00:02:38 +0100
yunohost (4.3.1.3) testing; urgency=low
- [fix] app: repo url branch names may contain dots (38cff4a9)
-- Alexandre Aubin <alex.aubin@mailoo.org> Thu, 07 Oct 2021 18:31:09 +0200
yunohost (4.3.1.2) testing; urgency=low
- [fix] apps: upgrade was broken because of typo ([#1350](https://github.com/YunoHost/yunohost/pull/1350))
- [enh] apps: in app_info, return a new is_webapp info meant to be used by API/webadmin (4cd5e9b6)
- [fix] configpanel: handle case where file question didnt get modified from webadmin, in which case self.value contains a path (54d901ad)
- [fix] configpanel: bind_key -> bind_key_ to prevent yunohost from redacting key names which leads to broken log metadata.yml somehow (941cc294)
- [enh] questions: Add visible attribute support in cli (74256845)
- [enh] helpers: Simplify apt/php dependencies helpers ([#1018](https://github.com/YunoHost/yunohost/pull/1018))
- [enh] helpers: In logrotate helper, enforce decent permissions on log file if app user exists ([#1352](https://github.com/YunoHost/yunohost/pull/1352))
Thanks to all contributors <3 ! (Éric Gaspar, Kay0u, ljf)
-- Alexandre Aubin <alex.aubin@mailoo.org> Thu, 07 Oct 2021 10:42:06 +0200
yunohost (4.3.1.1) testing; urgency=low yunohost (4.3.1.1) testing; urgency=low
- [enh] app helpers: Update n version ([#1347](https://github.com/YunoHost/yunohost/pull/1347)) - [enh] app helpers: Update n version ([#1347](https://github.com/YunoHost/yunohost/pull/1347))

7
debian/postinst vendored
View file

@ -11,8 +11,7 @@ do_configure() {
if [ ! -f /etc/yunohost/installed ]; then if [ ! -f /etc/yunohost/installed ]; then
# If apps/ is not empty, we're probably already installed in the past and # If apps/ is not empty, we're probably already installed in the past and
# something funky happened ... # something funky happened ...
if [ -d /etc/yunohost/apps/ ] && ls /etc/yunohost/apps/* >/dev/null 2>&1 if [ -d /etc/yunohost/apps/ ] && ls /etc/yunohost/apps/* >/dev/null 2>&1; then
then
echo "Sounds like /etc/yunohost/installed mysteriously disappeared ... You should probably contact the Yunohost support ..." echo "Sounds like /etc/yunohost/installed mysteriously disappeared ... You should probably contact the Yunohost support ..."
else else
bash /usr/share/yunohost/hooks/conf_regen/01-yunohost init bash /usr/share/yunohost/hooks/conf_regen/01-yunohost init
@ -51,8 +50,8 @@ case "$1" in
configure) configure)
do_configure do_configure
;; ;;
abort-upgrade|abort-remove|abort-deconfigure) abort-upgrade | abort-remove | abort-deconfigure) ;;
;;
*) *)
echo "postinst called with unknown argument \`$1'" >&2 echo "postinst called with unknown argument \`$1'" >&2
exit 1 exit 1

View file

@ -78,7 +78,7 @@ re_app_instance_name = re.compile(
) )
APP_REPO_URL = re.compile( APP_REPO_URL = re.compile(
r"^https://[a-zA-Z0-9-_.]+/[a-zA-Z0-9-_./]+/[a-zA-Z0-9-_.]+_ynh(/?(-/)?tree/[a-zA-Z0-9-_]+)?(\.git)?/?$" r"^https://[a-zA-Z0-9-_.]+/[a-zA-Z0-9-_./]+/[a-zA-Z0-9-_.]+_ynh(/?(-/)?tree/[a-zA-Z0-9-_.]+)?(\.git)?/?$"
) )
APP_FILES_TO_COPY = [ APP_FILES_TO_COPY = [
@ -150,6 +150,9 @@ def app_info(app, full=False):
absolute_app_name, _ = _parse_app_instance_name(app) absolute_app_name, _ = _parse_app_instance_name(app)
ret["from_catalog"] = _load_apps_catalog()["apps"].get(absolute_app_name, {}) ret["from_catalog"] = _load_apps_catalog()["apps"].get(absolute_app_name, {})
ret["upgradable"] = _app_upgradable(ret) ret["upgradable"] = _app_upgradable(ret)
ret["is_webapp"] = "domain" in settings and "path" in settings
ret["supports_change_url"] = os.path.exists( ret["supports_change_url"] = os.path.exists(
os.path.join(setting_path, "scripts", "change_url") os.path.join(setting_path, "scripts", "change_url")
) )
@ -489,7 +492,7 @@ def app_upgrade(app=[], url=None, file=None, force=False, no_safety_backup=False
logger.warning(m18n.n("custom_app_url_required", app=app_instance_name)) logger.warning(m18n.n("custom_app_url_required", app=app_instance_name))
continue continue
elif app_dict["upgradable"] == "yes" or force: elif app_dict["upgradable"] == "yes" or force:
new_app_src = app_dict["id"] new_app_src = app_dict["manifest"]["id"]
else: else:
logger.success(m18n.n("app_already_up_to_date", app=app_instance_name)) logger.success(m18n.n("app_already_up_to_date", app=app_instance_name))
continue continue

View file

@ -407,7 +407,7 @@ def is_unit_operation(
if isinstance(value, IOBase): if isinstance(value, IOBase):
try: try:
context[field] = value.name context[field] = value.name
except: except Exception:
context[field] = "IOBase" context[field] = "IOBase"
operation_logger = OperationLogger(op_key, related_to, args=context) operation_logger = OperationLogger(op_key, related_to, args=context)

View file

@ -474,7 +474,7 @@ def permission_create(
protected=protected, protected=protected,
sync_perm=sync_perm, sync_perm=sync_perm,
) )
except: except Exception:
permission_delete(permission, force=True) permission_delete(permission, force=True)
raise raise

View file

@ -41,7 +41,13 @@ def clean():
os.system("mkdir -p /etc/ssowat/") os.system("mkdir -p /etc/ssowat/")
app_ssowatconf() app_ssowatconf()
test_apps = ["break_yo_system", "legacy_app", "legacy_app__2", "full_domain_app", "my_webapp"] test_apps = [
"break_yo_system",
"legacy_app",
"legacy_app__2",
"full_domain_app",
"my_webapp",
]
for test_app in test_apps: for test_app in test_apps:
@ -192,7 +198,10 @@ def test_legacy_app_install_main_domain():
def test_app_from_catalog(): def test_app_from_catalog():
main_domain = _get_maindomain() main_domain = _get_maindomain()
app_install("my_webapp", args=f"domain={main_domain}&path=/site&with_sftp=0&password=superpassword&is_public=1&with_mysql=0") app_install(
"my_webapp",
args=f"domain={main_domain}&path=/site&with_sftp=0&password=superpassword&is_public=1&with_mysql=0",
)
app_map_ = app_map(raw=True) app_map_ = app_map(raw=True)
assert main_domain in app_map_ assert main_domain in app_map_
assert "/site" in app_map_[main_domain] assert "/site" in app_map_[main_domain]

View file

@ -68,6 +68,7 @@ def test_repo_url_definition():
assert _is_app_repo_url( assert _is_app_repo_url(
"https://gitlab.domainepublic.net/Neutrinet/neutrinet_ynh/-/tree/unstable" "https://gitlab.domainepublic.net/Neutrinet/neutrinet_ynh/-/tree/unstable"
) )
assert _is_app_repo_url("https://github.com/YunoHost-Apps/foobar_ynh/tree/1.23.4")
assert _is_app_repo_url("git@github.com:YunoHost-Apps/foobar_ynh.git") assert _is_app_repo_url("git@github.com:YunoHost-Apps/foobar_ynh.git")
assert not _is_app_repo_url("github.com/YunoHost-Apps/foobar_ynh") assert not _is_app_repo_url("github.com/YunoHost-Apps/foobar_ynh")

View file

@ -15,6 +15,7 @@ from yunohost.utils.config import (
PathQuestion, PathQuestion,
BooleanQuestion, BooleanQuestion,
FileQuestion, FileQuestion,
evaluate_simple_js_expression,
) )
from yunohost.utils.error import YunohostError, YunohostValidationError from yunohost.utils.error import YunohostError, YunohostValidationError
@ -2093,3 +2094,96 @@ def test_normalize_path():
assert PathQuestion.normalize("/macnuggets/") == "/macnuggets" assert PathQuestion.normalize("/macnuggets/") == "/macnuggets"
assert PathQuestion.normalize("macnuggets/") == "/macnuggets" assert PathQuestion.normalize("macnuggets/") == "/macnuggets"
assert PathQuestion.normalize("////macnuggets///") == "/macnuggets" assert PathQuestion.normalize("////macnuggets///") == "/macnuggets"
def test_simple_evaluate():
context = {
"a1": 1,
"b2": 2,
"c10": 10,
"foo": "bar",
"comp": "1>2",
"empty": "",
"lorem": "Lorem ipsum dolor et si qua met!",
"warning": "Warning! This sentence will fail!",
"quote": "Je s'apelle Groot",
"and_": "&&",
"object": {"a": "Security risk"},
}
supported = {
"42": 42,
"9.5": 9.5,
"'bopbidibopbopbop'": "bopbidibopbopbop",
"true": True,
"false": False,
"null": None,
# Math
"1 * (2 + 3 * (4 - 3))": 5,
"1 * (2 + 3 * (4 - 3)) > 10 - 2 || 3 * 2 > 9 - 2 * 3": True,
"(9 - 2) * 3 - 10": 11,
"12 - 2 * -2 + (3 - 4) * 3.1": 12.9,
"9 / 12 + 12 * 3 - 5": 31.75,
"9 / 12 + 12 * (3 - 5)": -23.25,
"12 > 13.1": False,
"12 < 14": True,
"12 <= 14": True,
"12 >= 14": False,
"12 == 14": False,
"12 % 5 > 3": False,
"12 != 14": True,
"9 - 1 > 10 && 3 * 5 > 10": False,
"9 - 1 > 10 || 3 * 5 > 10": True,
"a1 > 0 || a1 < -12": True,
"a1 > 0 && a1 < -12": False,
"a1 + 1 > 0 && -a1 > -12": True,
"-(a1 + 1) < 0 || -(a1 + 2) > -12": True,
"-a1 * 2": -2,
"(9 - 2) * 3 - c10": 11,
"(9 - b2) * 3 - c10": 11,
"c10 > b2": True,
# String
"foo == 'bar'": True,
"foo != 'bar'": False,
'foo == "bar" && 1 > 0': True,
"!!foo": True,
"!foo": False,
"foo": "bar",
'!(foo > "baa") || 1 > 2': False,
'!(foo > "baa") || 1 < 2': True,
'empty == ""': True,
'1 == "1"': True,
'1.0 == "1"': True,
'1 == "aaa"': False,
"'I am ' + b2 + ' years'": "I am 2 years",
"quote == 'Je s\\'apelle Groot'": True,
"lorem == 'Lorem ipsum dolor et si qua met!'": True,
"and_ == '&&'": True,
"warning == 'Warning! This sentence will fail!'": True,
# Match
"match(lorem, '^Lorem [ia]psumE?')": bool,
"match(foo, '^Lorem [ia]psumE?')": None,
"match(lorem, '^Lorem [ia]psumE?') && 1 == 1": bool,
# No code
"": False,
" ": False,
}
trigger_errors = {
"object.a": YunohostError, # Keep unsupported, for security reasons
"a1 ** b2": YunohostError, # Keep unsupported, for security reasons
"().__class__.__bases__[0].__subclasses__()": YunohostError, # Very dangerous code
"a1 > 11 ? 1 : 0": SyntaxError,
"c10 > b2 == false": YunohostError, # JS and Python doesn't do the same thing for this situation
"c10 > b2 == true": YunohostError,
}
for expression, result in supported.items():
if result == bool:
assert bool(evaluate_simple_js_expression(expression, context)), expression
else:
assert (
evaluate_simple_js_expression(expression, context) == result
), expression
for expression, error in trigger_errors.items():
with pytest.raises(error):
evaluate_simple_js_expression(expression, context)

View file

@ -670,7 +670,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False):
def to_list(str_list): def to_list(str_list):
L = str_list.split(",") if str_list else [] L = str_list.split(",") if str_list else []
L = [l.strip() for l in L] L = [element.strip() for element in L]
return L return L
existing_users = user_list()["users"] existing_users = user_list()["users"]

View file

@ -24,6 +24,8 @@ import re
import urllib.parse import urllib.parse
import tempfile import tempfile
import shutil import shutil
import ast
import operator as op
from collections import OrderedDict from collections import OrderedDict
from typing import Optional, Dict, List, Union, Any, Mapping from typing import Optional, Dict, List, Union, Any, Mapping
@ -46,6 +48,145 @@ from yunohost.log import OperationLogger
logger = getActionLogger("yunohost.config") logger = getActionLogger("yunohost.config")
CONFIG_PANEL_VERSION_SUPPORTED = 1.0 CONFIG_PANEL_VERSION_SUPPORTED = 1.0
# Those js-like evaluate functions are used to eval safely visible attributes
# The goal is to evaluate in the same way than js simple-evaluate
# https://github.com/shepherdwind/simple-evaluate
def evaluate_simple_ast(node, context={}):
operators = {
ast.Not: op.not_,
ast.Mult: op.mul,
ast.Div: op.truediv, # number
ast.Mod: op.mod, # number
ast.Add: op.add, # str
ast.Sub: op.sub, # number
ast.USub: op.neg, # Negative number
ast.Gt: op.gt,
ast.Lt: op.lt,
ast.GtE: op.ge,
ast.LtE: op.le,
ast.Eq: op.eq,
ast.NotEq: op.ne,
}
context["true"] = True
context["false"] = False
context["null"] = None
# Variable
if isinstance(node, ast.Name): # Variable
return context[node.id]
# Python <=3.7 String
elif isinstance(node, ast.Str):
return node.s
# Python <=3.7 Number
elif isinstance(node, ast.Num):
return node.n
# Boolean, None and Python 3.8 for Number, Boolean, String and None
elif isinstance(node, (ast.Constant, ast.NameConstant)):
return node.value
# + - * / %
elif (
isinstance(node, ast.BinOp) and type(node.op) in operators
): # <left> <operator> <right>
left = evaluate_simple_ast(node.left, context)
right = evaluate_simple_ast(node.right, context)
if type(node.op) == ast.Add:
if isinstance(left, str) or isinstance(right, str): # support 'I am ' + 42
left = str(left)
right = str(right)
elif type(left) != type(right): # support "111" - "1" -> 110
left = float(left)
right = float(right)
return operators[type(node.op)](left, right)
# Comparison
# JS and Python don't give the same result for multi operators
# like True == 10 > 2.
elif (
isinstance(node, ast.Compare) and len(node.comparators) == 1
): # <left> <ops> <comparators>
left = evaluate_simple_ast(node.left, context)
right = evaluate_simple_ast(node.comparators[0], context)
operator = node.ops[0]
if isinstance(left, (int, float)) or isinstance(right, (int, float)):
try:
left = float(left)
right = float(right)
except ValueError:
return type(operator) == ast.NotEq
try:
return operators[type(operator)](left, right)
except TypeError: # support "e" > 1 -> False like in JS
return False
# and / or
elif isinstance(node, ast.BoolOp): # <op> <values>
for value in node.values:
value = evaluate_simple_ast(value, context)
if isinstance(node.op, ast.And) and not value:
return False
elif isinstance(node.op, ast.Or) and value:
return True
return isinstance(node.op, ast.And)
# not / USub (it's negation number -\d)
elif isinstance(node, ast.UnaryOp): # <operator> <operand> e.g., -1
return operators[type(node.op)](evaluate_simple_ast(node.operand, context))
# match function call
elif isinstance(node, ast.Call) and node.func.__dict__.get("id") == "match":
return re.match(
evaluate_simple_ast(node.args[1], context), context[node.args[0].id]
)
# Unauthorized opcode
else:
opcode = str(type(node))
raise YunohostError(
f"Unauthorize opcode '{opcode}' in visible attribute", raw_msg=True
)
def js_to_python(expr):
in_string = None
py_expr = ""
i = 0
escaped = False
for char in expr:
if char in r"\"'":
# Start a string
if not in_string:
in_string = char
# Finish a string
elif in_string == char and not escaped:
in_string = None
# If we are not in a string, replace operators
elif not in_string:
if char == "!" and expr[i + 1] != "=":
char = "not "
elif char in "|&" and py_expr[-1:] == char:
py_expr = py_expr[:-1]
char = " and " if char == "&" else " or "
# Determine if next loop will be in escaped mode
escaped = char == "\\" and not escaped
py_expr += char
i += 1
return py_expr
def evaluate_simple_js_expression(expr, context={}):
if not expr.strip():
return False
node = ast.parse(js_to_python(expr), mode="eval").body
return evaluate_simple_ast(node, context)
class ConfigPanel: class ConfigPanel:
def __init__(self, config_path, save_path=None): def __init__(self, config_path, save_path=None):
@ -466,11 +607,13 @@ class Question(object):
hide_user_input_in_prompt = False hide_user_input_in_prompt = False
pattern: Optional[Dict] = None pattern: Optional[Dict] = None
def __init__(self, question: Dict[str, Any]): def __init__(self, question: Dict[str, Any], context: Mapping[str, Any] = {}):
self.name = question["name"] self.name = question["name"]
self.type = question.get("type", "string") self.type = question.get("type", "string")
self.default = question.get("default", None) self.default = question.get("default", None)
self.optional = question.get("optional", False) self.optional = question.get("optional", False)
self.visible = question.get("visible", None)
self.context = context
self.choices = question.get("choices", []) self.choices = question.get("choices", [])
self.pattern = question.get("pattern", self.pattern) self.pattern = question.get("pattern", self.pattern)
self.ask = question.get("ask", {"en": self.name}) self.ask = question.get("ask", {"en": self.name})
@ -512,6 +655,17 @@ class Question(object):
) )
def ask_if_needed(self): def ask_if_needed(self):
if self.visible and not evaluate_simple_js_expression(
self.visible, context=self.context
):
# FIXME There could be several use case if the question is not displayed:
# - we doesn't want to give a specific value
# - we want to keep the previous value
# - we want the default value
self.value = None
return self.value
for i in range(5): for i in range(5):
# Display question if no value filled or if it's a readonly message # Display question if no value filled or if it's a readonly message
if Moulinette.interface.type == "cli" and os.isatty(1): if Moulinette.interface.type == "cli" and os.isatty(1):
@ -577,7 +731,7 @@ class Question(object):
# Prevent displaying a shitload of choices # Prevent displaying a shitload of choices
# (e.g. 100+ available users when choosing an app admin...) # (e.g. 100+ available users when choosing an app admin...)
choices = ( choices = (
list(self.choices.values()) list(self.choices.keys())
if isinstance(self.choices, dict) if isinstance(self.choices, dict)
else self.choices else self.choices
) )
@ -710,8 +864,8 @@ class PasswordQuestion(Question):
default_value = "" default_value = ""
forbidden_chars = "{}" forbidden_chars = "{}"
def __init__(self, question): def __init__(self, question, context: Mapping[str, Any] = {}):
super().__init__(question) super().__init__(question, context)
self.redact = True self.redact = True
if self.default is not None: if self.default is not None:
raise YunohostValidationError( raise YunohostValidationError(
@ -829,8 +983,8 @@ class BooleanQuestion(Question):
choices="yes/no", choices="yes/no",
) )
def __init__(self, question): def __init__(self, question, context: Mapping[str, Any] = {}):
super().__init__(question) super().__init__(question, context)
self.yes = question.get("yes", 1) self.yes = question.get("yes", 1)
self.no = question.get("no", 0) self.no = question.get("no", 0)
if self.default is None: if self.default is None:
@ -850,10 +1004,10 @@ class BooleanQuestion(Question):
class DomainQuestion(Question): class DomainQuestion(Question):
argument_type = "domain" argument_type = "domain"
def __init__(self, question): def __init__(self, question, context: Mapping[str, Any] = {}):
from yunohost.domain import domain_list, _get_maindomain from yunohost.domain import domain_list, _get_maindomain
super().__init__(question) super().__init__(question, context)
if self.default is None: if self.default is None:
self.default = _get_maindomain() self.default = _get_maindomain()
@ -876,11 +1030,11 @@ class DomainQuestion(Question):
class UserQuestion(Question): class UserQuestion(Question):
argument_type = "user" argument_type = "user"
def __init__(self, question): def __init__(self, question, context: Mapping[str, Any] = {}):
from yunohost.user import user_list, user_info from yunohost.user import user_list, user_info
from yunohost.domain import _get_maindomain from yunohost.domain import _get_maindomain
super().__init__(question) super().__init__(question, context)
self.choices = list(user_list()["users"].keys()) self.choices = list(user_list()["users"].keys())
if not self.choices: if not self.choices:
@ -902,8 +1056,8 @@ class NumberQuestion(Question):
argument_type = "number" argument_type = "number"
default_value = None default_value = None
def __init__(self, question): def __init__(self, question, context: Mapping[str, Any] = {}):
super().__init__(question) super().__init__(question, context)
self.min = question.get("min", None) self.min = question.get("min", None)
self.max = question.get("max", None) self.max = question.get("max", None)
self.step = question.get("step", None) self.step = question.get("step", None)
@ -954,8 +1108,8 @@ class DisplayTextQuestion(Question):
argument_type = "display_text" argument_type = "display_text"
readonly = True readonly = True
def __init__(self, question): def __init__(self, question, context: Mapping[str, Any] = {}):
super().__init__(question) super().__init__(question, context)
self.optional = True self.optional = True
self.style = question.get( self.style = question.get(
@ -989,8 +1143,8 @@ class FileQuestion(Question):
if os.path.exists(upload_dir): if os.path.exists(upload_dir):
shutil.rmtree(upload_dir) shutil.rmtree(upload_dir)
def __init__(self, question): def __init__(self, question, context: Mapping[str, Any] = {}):
super().__init__(question) super().__init__(question, context)
self.accept = question.get("accept", "") self.accept = question.get("accept", "")
def _prevalidate(self): def _prevalidate(self):
@ -1019,10 +1173,13 @@ class FileQuestion(Question):
FileQuestion.upload_dirs += [upload_dir] FileQuestion.upload_dirs += [upload_dir]
logger.debug(f"Saving file {self.name} for file question into {file_path}") logger.debug(f"Saving file {self.name} for file question into {file_path}")
if Moulinette.interface.type != "api":
content = read_file(str(self.value), file_mode="rb")
if Moulinette.interface.type == "api": def is_file_path(s):
return isinstance(s, str) and s.startswith("/") and os.path.exists(s)
if Moulinette.interface.type != "api" or is_file_path(self.value):
content = read_file(str(self.value), file_mode="rb")
else:
content = b64decode(self.value) content = b64decode(self.value)
write_to_file(file_path, content, file_mode="wb") write_to_file(file_path, content, file_mode="wb")
@ -1057,13 +1214,13 @@ ARGUMENTS_TYPE_PARSERS = {
def ask_questions_and_parse_answers( def ask_questions_and_parse_answers(
questions: Dict, prefilled_answers: Union[str, Mapping[str, Any]] = {} raw_questions: Dict, prefilled_answers: Union[str, Mapping[str, Any]] = {}
) -> List[Question]: ) -> List[Question]:
"""Parse arguments store in either manifest.json or actions.json or from a """Parse arguments store in either manifest.json or actions.json or from a
config panel against the user answers when they are present. config panel against the user answers when they are present.
Keyword arguments: Keyword arguments:
questions -- the arguments description store in yunohost raw_questions -- the arguments description store in yunohost
format from actions.json/toml, manifest.json/toml format from actions.json/toml, manifest.json/toml
or config_panel.json/toml or config_panel.json/toml
prefilled_answers -- a url "query-string" such as "domain=yolo.test&path=/foobar&admin=sam" prefilled_answers -- a url "query-string" such as "domain=yolo.test&path=/foobar&admin=sam"
@ -1076,21 +1233,21 @@ def ask_questions_and_parse_answers(
# whereas parse.qs return list of values (which is useful for tags, etc) # whereas parse.qs return list of values (which is useful for tags, etc)
# For now, let's not migrate this piece of code to parse_qs # For now, let's not migrate this piece of code to parse_qs
# Because Aleks believes some bits of the app CI rely on overriding values (e.g. foo=foo&...&foo=bar) # Because Aleks believes some bits of the app CI rely on overriding values (e.g. foo=foo&...&foo=bar)
prefilled_answers = dict( answers = dict(
urllib.parse.parse_qsl(prefilled_answers or "", keep_blank_values=True) urllib.parse.parse_qsl(prefilled_answers or "", keep_blank_values=True)
) )
elif isinstance(prefilled_answers, Mapping):
if not prefilled_answers: answers = {**prefilled_answers}
prefilled_answers = {} else:
answers = {}
out = [] out = []
for question in questions: for raw_question in raw_questions:
question_class = ARGUMENTS_TYPE_PARSERS[question.get("type", "string")] question_class = ARGUMENTS_TYPE_PARSERS[raw_question.get("type", "string")]
question["value"] = prefilled_answers.get(question["name"]) raw_question["value"] = answers.get(raw_question["name"])
question = question_class(question) question = question_class(raw_question, context=answers)
answers[question.name] = question.ask_if_needed()
question.ask_if_needed()
out.append(question) out.append(question)
return out return out

View file

@ -0,0 +1,92 @@
ynhtest_exec_warn_less() {
FOO='foo'
bar=""
BAR='$bar'
FOOBAR="foo bar"
# These looks like stupid edge case
# but in fact happens when dealing with passwords
# (which could also contain bash chars like [], {}, ...)
# or urls containing &, ...
FOOANDBAR="foo&bar"
FOO1QUOTEBAR="foo'bar"
FOO2QUOTEBAR="foo\"bar"
ynh_exec_warn_less uptime
test ! -e $FOO
ynh_exec_warn_less touch $FOO
test -e $FOO
rm $FOO
test ! -e $FOO1QUOTEBAR
ynh_exec_warn_less touch $FOO1QUOTEBAR
test -e $FOO1QUOTEBAR
rm $FOO1QUOTEBAR
test ! -e $FOO2QUOTEBAR
ynh_exec_warn_less touch $FOO2QUOTEBAR
test -e $FOO2QUOTEBAR
rm $FOO2QUOTEBAR
test ! -e $BAR
ynh_exec_warn_less touch $BAR
test -e $BAR
rm $BAR
test ! -e "$FOOBAR"
ynh_exec_warn_less touch "$FOOBAR"
test -e "$FOOBAR"
rm "$FOOBAR"
test ! -e "$FOOANDBAR"
ynh_exec_warn_less touch $FOOANDBAR
test -e "$FOOANDBAR"
rm "$FOOANDBAR"
###########################
# Legacy stuff using eval #
###########################
test ! -e $FOO
ynh_exec_warn_less "touch $FOO"
test -e $FOO
rm $FOO
test ! -e $FOO1QUOTEBAR
ynh_exec_warn_less "touch \"$FOO1QUOTEBAR\""
# (this works but expliciy *double* quotes have to be provided)
test -e $FOO1QUOTEBAR
rm $FOO1QUOTEBAR
#test ! -e $FOO2QUOTEBAR
#ynh_exec_warn_less "touch \'$FOO2QUOTEBAR\'"
## (this doesn't work with simple or double quotes)
#test -e $FOO2QUOTEBAR
#rm $FOO2QUOTEBAR
test ! -e $BAR
ynh_exec_warn_less 'touch $BAR'
# That one works because $BAR is only interpreted during eval
test -e $BAR
rm $BAR
#test ! -e $BAR
#ynh_exec_warn_less "touch $BAR"
# That one doesn't work because $bar gets interpreted as empty var by eval...
#test -e $BAR
#rm $BAR
test ! -e "$FOOBAR"
ynh_exec_warn_less "touch \"$FOOBAR\""
# (works but requires explicit double quotes otherwise eval would interpret 'foo bar' as two separate args..)
test -e "$FOOBAR"
rm "$FOOBAR"
test ! -e "$FOOANDBAR"
ynh_exec_warn_less "touch \"$FOOANDBAR\""
# (works but requires explicit double quotes otherwise eval would interpret '&' as a "run command in background" and also bar is not a valid command)
test -e "$FOOANDBAR"
rm "$FOOANDBAR"
}

View file

@ -0,0 +1,71 @@
ynhtest_acceptable_path_to_delete() {
mkdir -p /home/someuser
mkdir -p /home/$app
mkdir -p /home/yunohost.app/$app
mkdir -p /var/www/$app
touch /var/www/$app/bar
touch /etc/cron.d/$app
! _acceptable_path_to_delete /
! _acceptable_path_to_delete ////
! _acceptable_path_to_delete " //// "
! _acceptable_path_to_delete /var
! _acceptable_path_to_delete /var/www
! _acceptable_path_to_delete /var/cache
! _acceptable_path_to_delete /usr
! _acceptable_path_to_delete /usr/bin
! _acceptable_path_to_delete /home
! _acceptable_path_to_delete /home/yunohost.backup
! _acceptable_path_to_delete /home/yunohost.app
! _acceptable_path_to_delete /home/yunohost.app/
! _acceptable_path_to_delete ///home///yunohost.app///
! _acceptable_path_to_delete /home/yunohost.app/$app/..
! _acceptable_path_to_delete ///home///yunohost.app///$app///..//
! _acceptable_path_to_delete /home/yunohost.app/../$app/..
! _acceptable_path_to_delete /home/someuser
! _acceptable_path_to_delete /home/yunohost.app//../../$app
! _acceptable_path_to_delete " /home/yunohost.app/// "
! _acceptable_path_to_delete /etc/cron.d/
! _acceptable_path_to_delete /etc/yunohost/
_acceptable_path_to_delete /home/yunohost.app/$app
_acceptable_path_to_delete /home/yunohost.app/$app/bar
_acceptable_path_to_delete /etc/cron.d/$app
_acceptable_path_to_delete /var/www/$app/bar
_acceptable_path_to_delete /var/www/$app
rm /var/www/$app/bar
rm /etc/cron.d/$app
rmdir /home/yunohost.app/$app
rmdir /home/$app
rmdir /home/someuser
rmdir /var/www/$app
}
ynhtest_secure_remove() {
mkdir -p /home/someuser
mkdir -p /home/yunohost.app/$app
mkdir -p /var/www/$app
mkdir -p /var/whatever
touch /var/www/$app/bar
touch /etc/cron.d/$app
! ynh_secure_remove --file="/home/someuser"
! ynh_secure_remove --file="/home/yunohost.app/"
! ynh_secure_remove --file="/var/whatever"
ynh_secure_remove --file="/home/yunohost.app/$app"
ynh_secure_remove --file="/var/www/$app"
ynh_secure_remove --file="/etc/cron.d/$app"
test -e /home/someuser
test -e /home/yunohost.app
test -e /var/whatever
! test -e /home/yunohost.app/$app
! test -e /var/www/$app
! test -e /etc/cron.d/$app
rmdir /home/someuser
rmdir /var/whatever
}

View file

@ -9,7 +9,7 @@ deps =
py39-mypy: mypy >= 0.900 py39-mypy: mypy >= 0.900
commands = commands =
py39-lint: flake8 src doc data tests --ignore E402,E501,E203,W503 --exclude src/yunohost/vendor py39-lint: flake8 src doc data tests --ignore E402,E501,E203,W503 --exclude src/yunohost/vendor
py39-invalidcode: flake8 src data --exclude src/yunohost/tests,src/yunohost/vendor --select F py39-invalidcode: flake8 src data --exclude src/yunohost/tests,src/yunohost/vendor --select F,E722,W605
py39-black-check: black --check --diff src doc data tests py39-black-check: black --check --diff src doc data tests
py39-black-run: black src doc data tests py39-black-run: black src doc data tests
py39-mypy: mypy --ignore-missing-import --install-types --non-interactive --follow-imports silent src/yunohost/ --exclude (acme_tiny|data_migrations) py39-mypy: mypy --ignore-missing-import --install-types --non-interactive --follow-imports silent src/yunohost/ --exclude (acme_tiny|data_migrations)