mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge branch 'migrate_to_bullseye' into bullseye
This commit is contained in:
commit
0b4aa81f8c
57 changed files with 2126 additions and 1939 deletions
|
@ -12,11 +12,9 @@ ynh_wait_dpkg_free() {
|
|||
local try
|
||||
set +o xtrace # set +x
|
||||
# With seq 1 17, timeout will be almost 30 minutes
|
||||
for try in `seq 1 17`
|
||||
do
|
||||
for try in $(seq 1 17); do
|
||||
# Check if /var/lib/dpkg/lock is used by another process
|
||||
if lsof /var/lib/dpkg/lock > /dev/null
|
||||
then
|
||||
if lsof /var/lib/dpkg/lock >/dev/null; then
|
||||
echo "apt is already in use..."
|
||||
# Sleep an exponential time at each round
|
||||
sleep $((try * try))
|
||||
|
@ -26,11 +24,9 @@ ynh_wait_dpkg_free() {
|
|||
local dpkg_dir="/var/lib/dpkg/updates/"
|
||||
|
||||
# For each file in $dpkg_dir
|
||||
while read dpkg_file <&9
|
||||
do
|
||||
while read dpkg_file <&9; do
|
||||
# Check if the name of this file contains only numbers.
|
||||
if echo "$dpkg_file" | grep --perl-regexp --quiet "^[[:digit:]]+$"
|
||||
then
|
||||
if echo "$dpkg_file" | grep --perl-regexp --quiet "^[[:digit:]]+$"; then
|
||||
# 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."
|
||||
set -o xtrace # set -x
|
||||
|
@ -84,8 +80,7 @@ ynh_package_version() {
|
|||
# Manage arguments with getopts
|
||||
ynh_handle_getopts_args "$@"
|
||||
|
||||
if ynh_package_is_installed "$package"
|
||||
then
|
||||
if ynh_package_is_installed "$package"; then
|
||||
dpkg-query --show --showformat='${Version}' "$package" 2>/dev/null
|
||||
else
|
||||
echo ''
|
||||
|
@ -191,12 +186,14 @@ ynh_package_install_from_equivs () {
|
|||
# Install missing dependencies with ynh_package_install
|
||||
ynh_wait_dpkg_free
|
||||
cp "$controlfile" "${TMPDIR}/control"
|
||||
(cd "$TMPDIR"
|
||||
(
|
||||
cd "$TMPDIR"
|
||||
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 || \
|
||||
{ # If the installation failed
|
||||
ynh_package_install --fix-broken \
|
||||
|| { # If the installation failed
|
||||
# (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 ...
|
||||
# (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
|
||||
# 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
|
||||
ynh_die --message="Unable to install dependencies"; }
|
||||
ynh_die --message="Unable to install dependencies"
|
||||
}
|
||||
[[ -n "$TMPDIR" ]] && rm --recursive --force $TMPDIR # Remove the temp dir.
|
||||
|
||||
# check if the package is actually installed
|
||||
ynh_package_is_installed "$pkgname"
|
||||
}
|
||||
|
||||
YNH_INSTALL_APP_DEPENDENCIES_REPLACE="true"
|
||||
|
||||
# Define and install dependencies with a equivs control file
|
||||
#
|
||||
# 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 '-'
|
||||
|
||||
# Handle specific versions
|
||||
if [[ "$dependencies" =~ [\<=\>] ]]
|
||||
then
|
||||
if [[ "$dependencies" =~ [\<=\>] ]]; then
|
||||
# Replace version specifications by relationships syntax
|
||||
# https://www.debian.org/doc/debian-policy/ch-relationships.html
|
||||
# Sed clarification
|
||||
|
@ -249,22 +248,57 @@ ynh_install_app_dependencies () {
|
|||
dependencies="$(echo "$dependencies" | sed 's/\([^(\<=\>]\)\([\<=\>]\+\)\([^,]\+\)/\1 (\2 \3)/g')"
|
||||
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
|
||||
# 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
|
||||
#
|
||||
# If we require to install php dependency
|
||||
if echo $dependencies | grep --quiet 'php'
|
||||
then
|
||||
if grep --quiet 'php' <<< "$dependencies"; then
|
||||
# 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"
|
||||
then
|
||||
if dpkg --list | grep "php7.0" | grep --quiet --invert-match "7.0.33-0+deb9"; then
|
||||
# And sury ain't already in sources.lists
|
||||
if ! grep --recursive --quiet "^ *deb.*sury" /etc/apt/sources.list*
|
||||
then
|
||||
if ! grep --recursive --quiet "^ *deb.*sury" /etc/apt/sources.list*; then
|
||||
# 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
|
||||
|
@ -282,14 +316,43 @@ EOF
|
|||
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
|
||||
rm /tmp/${dep_app}-ynh-deps.control
|
||||
|
||||
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
|
||||
#
|
||||
# usage: ynh_add_app_dependencies --package=phpversion [--replace]
|
||||
# | 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.
|
||||
ynh_add_app_dependencies() {
|
||||
|
@ -297,24 +360,11 @@ ynh_add_app_dependencies () {
|
|||
local legacy_args=pr
|
||||
local -A args_array=([p]=package= [r]=replace)
|
||||
local package
|
||||
local replace
|
||||
# Manage arguments with getopts
|
||||
ynh_handle_getopts_args "$@"
|
||||
replace=${replace:-0}
|
||||
|
||||
local current_dependencies=""
|
||||
if [ $replace -eq 0 ]
|
||||
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}"
|
||||
ynh_print_warn --message="Packagers: ynh_add_app_dependencies is deprecated and is now only an alias to ynh_install_app_dependencies"
|
||||
ynh_install_app_dependencies "${package}"
|
||||
}
|
||||
|
||||
# Remove fake package and its dependencies
|
||||
|
@ -326,7 +376,24 @@ ynh_add_app_dependencies () {
|
|||
# Requires YunoHost version 2.6.4 or higher.
|
||||
ynh_remove_app_dependencies() {
|
||||
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.
|
||||
|
||||
# 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.
|
||||
|
@ -352,15 +419,14 @@ ynh_install_extra_app_dependencies () {
|
|||
key=${key:-}
|
||||
|
||||
# Set a key only if asked
|
||||
if [ -n "$key" ]
|
||||
then
|
||||
if [ -n "$key" ]; then
|
||||
key="--key=$key"
|
||||
fi
|
||||
# Add an extra repository for those packages
|
||||
ynh_install_extra_repo --repo="$repo" $key --priority=995 --name=$name
|
||||
|
||||
# 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
|
||||
ynh_remove_extra_repo --name=$app
|
||||
|
@ -394,8 +460,7 @@ ynh_install_extra_repo () {
|
|||
key=${key:-}
|
||||
priority=${priority:-}
|
||||
|
||||
if [ $append -eq 1 ]
|
||||
then
|
||||
if [ $append -eq 1 ]; then
|
||||
append="--append"
|
||||
wget_append="tee --append"
|
||||
else
|
||||
|
@ -424,15 +489,13 @@ ynh_install_extra_repo () {
|
|||
local pin="${uri#*://}"
|
||||
pin="${pin%%/*}"
|
||||
# Set a priority only if asked
|
||||
if [ -n "$priority" ]
|
||||
then
|
||||
if [ -n "$priority" ]; then
|
||||
priority="--priority=$priority"
|
||||
fi
|
||||
ynh_pin_repo --package="*" --pin="origin \"$pin\"" $priority --name="$name" $append
|
||||
|
||||
# Get the public key for the repo
|
||||
if [ -n "$key" ]
|
||||
then
|
||||
if [ -n "$key" ]; then
|
||||
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)
|
||||
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}"
|
||||
append=${append:-0}
|
||||
|
||||
if [ $append -eq 1 ]
|
||||
then
|
||||
if [ $append -eq 1 ]; then
|
||||
append="tee --append"
|
||||
else
|
||||
append="tee"
|
||||
|
@ -542,8 +604,7 @@ ynh_pin_repo () {
|
|||
name="${name:-$app}"
|
||||
append=${append:-0}
|
||||
|
||||
if [ $append -eq 1 ]
|
||||
then
|
||||
if [ $append -eq 1 ]; then
|
||||
append="tee --append"
|
||||
else
|
||||
append="tee"
|
||||
|
|
|
@ -82,10 +82,8 @@ ynh_backup() {
|
|||
|
||||
# If backing up core only (used by ynh_backup_before_upgrade),
|
||||
# don't backup big data items
|
||||
if [ $is_big -eq 1 ] && ( [ ${do_not_backup_data:-0} -eq 1 ] || [ $BACKUP_CORE_ONLY -eq 1 ] )
|
||||
then
|
||||
if [ $BACKUP_CORE_ONLY -eq 1 ]
|
||||
then
|
||||
if [ $is_big -eq 1 ] && ([ ${do_not_backup_data:-0} -eq 1 ] || [ $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."
|
||||
else
|
||||
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
|
||||
# ==============================================================================
|
||||
# Be sure the source path is not empty
|
||||
if [ ! -e "$src_path" ]
|
||||
then
|
||||
if [ ! -e "$src_path" ]; then
|
||||
ynh_print_warn --message="Source path '${src_path}' does not exist"
|
||||
if [ "$not_mandatory" == "0" ]
|
||||
then
|
||||
if [ "$not_mandatory" == "0" ]; then
|
||||
# This is a temporary fix for fail2ban config files missing after the migration to stretch.
|
||||
if echo "${src_path}" | grep --quiet "/etc/fail2ban"
|
||||
then
|
||||
if echo "${src_path}" | grep --quiet "/etc/fail2ban"; then
|
||||
touch "${src_path}"
|
||||
ynh_print_info --message="The missing file will be replaced by a dummy one for the backup !!!"
|
||||
else
|
||||
|
@ -122,13 +117,11 @@ ynh_backup() {
|
|||
# If there is no destination path, initialize it with the source path
|
||||
# relative to "/".
|
||||
# eg: src_path=/etc/yunohost -> dest_path=etc/yunohost
|
||||
if [[ -z "$dest_path" ]]
|
||||
then
|
||||
if [[ -z "$dest_path" ]]; then
|
||||
dest_path="${src_path#/}"
|
||||
|
||||
else
|
||||
if [[ "${dest_path:0:1}" == "/" ]]
|
||||
then
|
||||
if [[ "${dest_path:0:1}" == "/" ]]; then
|
||||
|
||||
# If the destination path is an absolute path, transform it as a path
|
||||
# relative to the current working directory ($YNH_CWD)
|
||||
|
@ -152,8 +145,7 @@ ynh_backup() {
|
|||
fi
|
||||
|
||||
# Check if dest_path already exists in tmp archive
|
||||
if [[ -e "${dest_path}" ]]
|
||||
then
|
||||
if [[ -e "${dest_path}" ]]; then
|
||||
ynh_print_err --message="Destination path '${dest_path}' already exist"
|
||||
return 1
|
||||
fi
|
||||
|
@ -190,9 +182,8 @@ ynh_restore () {
|
|||
REL_DIR="${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.*\"$" | \
|
||||
while read line
|
||||
do
|
||||
cat ${YNH_BACKUP_CSV} | tr --delete $'\r' | grep --only-matching --no-filename --perl-regexp "^\".*\",\"$REL_DIR.*\"$" \
|
||||
| while read line; do
|
||||
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.*(?=\"$)")
|
||||
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}"
|
||||
# If archive_path doesn't exist, search for a corresponding path in CSV
|
||||
if [ ! -d "$archive_path" ] && [ ! -f "$archive_path" ] && [ ! -L "$archive_path" ]
|
||||
then
|
||||
if [ "$not_mandatory" == "0" ]
|
||||
then
|
||||
if [ ! -d "$archive_path" ] && [ ! -f "$archive_path" ] && [ ! -L "$archive_path" ]; then
|
||||
if [ "$not_mandatory" == "0" ]; then
|
||||
archive_path="$YNH_BACKUP_DIR/$(_get_archive_path \"$origin_path\")"
|
||||
else
|
||||
return 0
|
||||
|
@ -271,11 +260,9 @@ ynh_restore_file () {
|
|||
fi
|
||||
|
||||
# Move the old directory if it already exists
|
||||
if [[ -e "${dest_path}" ]]
|
||||
then
|
||||
if [[ -e "${dest_path}" ]]; then
|
||||
# Check if the file/dir size is less than 500 Mo
|
||||
if [[ $(du --summarize --bytes ${dest_path} | cut --delimiter="/" --fields=1) -le "500000000" ]]
|
||||
then
|
||||
if [[ $(du --summarize --bytes ${dest_path} | cut --delimiter="/" --fields=1) -le "500000000" ]]; then
|
||||
local backup_file="/home/yunohost.conf/backup/${dest_path}.backup.$(date '+%Y%m%d.%H%M%S')"
|
||||
mkdir --parents "$(dirname "$backup_file")"
|
||||
mv "${dest_path}" "$backup_file" # Move the current file or directory
|
||||
|
@ -288,10 +275,8 @@ ynh_restore_file () {
|
|||
mkdir --parents $(dirname "$dest_path")
|
||||
|
||||
# Do a copy if it's just a mounting point
|
||||
if mountpoint --quiet $YNH_BACKUP_DIR
|
||||
then
|
||||
if [[ -d "${archive_path}" ]]
|
||||
then
|
||||
if mountpoint --quiet $YNH_BACKUP_DIR; then
|
||||
if [[ -d "${archive_path}" ]]; then
|
||||
archive_path="${archive_path}/."
|
||||
mkdir --parents "$dest_path"
|
||||
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)
|
||||
|
||||
# If backup_file_checksum isn't empty, ynh_backup_if_checksum_is_different has made a backup
|
||||
if [ -n "${backup_file_checksum-}" ]
|
||||
then
|
||||
if [ -n "${backup_file_checksum-}" ]; then
|
||||
# Print the diff between the previous file and the new one.
|
||||
# diff return 1 if the files are different, so the || 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)
|
||||
# backup_file_checksum isn't declare as local, so it can be reuse by ynh_store_file_checksum
|
||||
backup_file_checksum=""
|
||||
if [ -n "$checksum_value" ]
|
||||
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 [ -n "$checksum_value" ]; 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
|
||||
backup_file_checksum="/home/yunohost.conf/backup/$file.backup.$(date '+%Y%m%d.%H%M%S')"
|
||||
mkdir --parents "$(dirname "$backup_file_checksum")"
|
||||
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.
|
||||
ynh_backup_before_upgrade() {
|
||||
if [ ! -e "/etc/yunohost/apps/$app/scripts/backup" ]
|
||||
then
|
||||
if [ ! -e "/etc/yunohost/apps/$app/scripts/backup" ]; then
|
||||
ynh_print_warn --message="This app doesn't have any backup script."
|
||||
return
|
||||
fi
|
||||
|
@ -434,11 +415,9 @@ ynh_backup_before_upgrade () {
|
|||
local app_bck=${app//_/-} # Replace all '_' by '-'
|
||||
NO_BACKUP_UPGRADE=${NO_BACKUP_UPGRADE:-0}
|
||||
|
||||
if [ "$NO_BACKUP_UPGRADE" -eq 0 ]
|
||||
then
|
||||
if [ "$NO_BACKUP_UPGRADE" -eq 0 ]; then
|
||||
# Check if a backup already exists with the prefix 1
|
||||
if ynh_backup_archive_exists "$app_bck-pre-upgrade1"
|
||||
then
|
||||
if ynh_backup_archive_exists "$app_bck-pre-upgrade1"; then
|
||||
# Prefix becomes 2 to preserve the previous backup
|
||||
backup_number=2
|
||||
old_backup_number=1
|
||||
|
@ -446,11 +425,9 @@ ynh_backup_before_upgrade () {
|
|||
|
||||
# Create backup
|
||||
BACKUP_CORE_ONLY=1 yunohost backup create --apps $app --name $app_bck-pre-upgrade$backup_number --debug
|
||||
if [ "$?" -eq 0 ]
|
||||
then
|
||||
if [ "$?" -eq 0 ]; then
|
||||
# If the backup succeeded, remove the previous backup
|
||||
if ynh_backup_archive_exists "$app_bck-pre-upgrade$old_backup_number"
|
||||
then
|
||||
if ynh_backup_archive_exists "$app_bck-pre-upgrade$old_backup_number"; then
|
||||
# Remove the previous backup only if it exists
|
||||
yunohost backup delete $app_bck-pre-upgrade$old_backup_number >/dev/null
|
||||
fi
|
||||
|
@ -482,11 +459,9 @@ ynh_restore_upgradebackup () {
|
|||
|
||||
NO_BACKUP_UPGRADE=${NO_BACKUP_UPGRADE:-0}
|
||||
|
||||
if [ "$NO_BACKUP_UPGRADE" -eq 0 ]
|
||||
then
|
||||
if [ "$NO_BACKUP_UPGRADE" -eq 0 ]; then
|
||||
# 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"
|
||||
then
|
||||
if ynh_backup_archive_exists "$app_bck-pre-upgrade$backup_number"; then
|
||||
# Remove the application then restore it
|
||||
yunohost app remove $app
|
||||
# Restore the backup
|
||||
|
|
|
@ -1,44 +1,35 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
_ynh_app_config_get_one() {
|
||||
local short_setting="$1"
|
||||
local type="$2"
|
||||
local bind="$3"
|
||||
local getter="get__${short_setting}"
|
||||
# Get value from getter if exists
|
||||
if type -t $getter 2>/dev/null | grep -q '^function$' 2>/dev/null;
|
||||
then
|
||||
if type -t $getter 2>/dev/null | grep -q '^function$' 2>/dev/null; then
|
||||
old[$short_setting]="$($getter)"
|
||||
formats[${short_setting}]="yaml"
|
||||
|
||||
elif [[ "$bind" == *"("* ]] && type -t "get__${bind%%(*}" 2>/dev/null | grep -q '^function$' 2>/dev/null;
|
||||
then
|
||||
elif [[ "$bind" == *"("* ]] && type -t "get__${bind%%(*}" 2>/dev/null | grep -q '^function$' 2>/dev/null; then
|
||||
old[$short_setting]="$("get__${bind%%(*}" $short_setting $type $bind)"
|
||||
formats[${short_setting}]="yaml"
|
||||
|
||||
elif [[ "$bind" == "null" ]]
|
||||
then
|
||||
elif [[ "$bind" == "null" ]]; then
|
||||
old[$short_setting]="YNH_NULL"
|
||||
|
||||
# Get value from app settings or from another file
|
||||
elif [[ "$type" == "file" ]]
|
||||
then
|
||||
if [[ "$bind" == "settings" ]]
|
||||
then
|
||||
elif [[ "$type" == "file" ]]; then
|
||||
if [[ "$bind" == "settings" ]]; then
|
||||
ynh_die --message="File '${short_setting}' can't be stored in settings"
|
||||
fi
|
||||
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"
|
||||
|
||||
# Get multiline text from settings or from a full file
|
||||
elif [[ "$type" == "text" ]]
|
||||
then
|
||||
if [[ "$bind" == "settings" ]]
|
||||
then
|
||||
elif [[ "$type" == "text" ]]; then
|
||||
if [[ "$bind" == "settings" ]]; then
|
||||
old[$short_setting]="$(ynh_app_setting_get $app $short_setting)"
|
||||
elif [[ "$bind" == *":"* ]]
|
||||
then
|
||||
elif [[ "$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"
|
||||
else
|
||||
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
|
||||
else
|
||||
local bind_after=""
|
||||
if [[ "$bind" == "settings" ]]
|
||||
then
|
||||
if [[ "$bind" == "settings" ]]; then
|
||||
bind=":/etc/yunohost/apps/$app/settings.yml"
|
||||
fi
|
||||
local bind_key="$(echo "$bind" | cut -d: -f1)"
|
||||
bind_key=${bind_key:-$short_setting}
|
||||
if [[ "$bind_key" == *">"* ]];
|
||||
then
|
||||
bind_after="$(echo "${bind_key}" | cut -d'>' -f1)"
|
||||
bind_key="$(echo "${bind_key}" | cut -d'>' -f2)"
|
||||
local bind_key_="$(echo "$bind" | cut -d: -f1)"
|
||||
bind_key_=${bind_key_:-$short_setting}
|
||||
if [[ "$bind_key_" == *">"* ]]; then
|
||||
bind_after="$(echo "${bind_key_}" | cut -d'>' -f1)"
|
||||
bind_key_="$(echo "${bind_key_}" | cut -d'>' -f2)"
|
||||
fi
|
||||
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
|
||||
}
|
||||
|
@ -68,83 +57,71 @@ _ynh_app_config_apply_one() {
|
|||
local setter="set__${short_setting}"
|
||||
local bind="${binds[$short_setting]}"
|
||||
local type="${types[$short_setting]}"
|
||||
if [ "${changed[$short_setting]}" == "true" ]
|
||||
then
|
||||
if [ "${changed[$short_setting]}" == "true" ]; then
|
||||
# Apply setter if exists
|
||||
if type -t $setter 2>/dev/null | grep -q '^function$' 2>/dev/null;
|
||||
then
|
||||
if type -t $setter 2>/dev/null | grep -q '^function$' 2>/dev/null; then
|
||||
$setter
|
||||
|
||||
elif [[ "$bind" == *"("* ]] && type -t "set__${bind%%(*}" 2>/dev/null | grep -q '^function$' 2>/dev/null;
|
||||
then
|
||||
elif [[ "$bind" == *"("* ]] && type -t "set__${bind%%(*}" 2>/dev/null | grep -q '^function$' 2>/dev/null; then
|
||||
"set__${bind%%(*}" $short_setting $type $bind
|
||||
|
||||
elif [[ "$bind" == "null" ]]
|
||||
then
|
||||
continue
|
||||
elif [[ "$bind" == "null" ]]; then
|
||||
return
|
||||
|
||||
# Save in a file
|
||||
elif [[ "$type" == "file" ]]
|
||||
then
|
||||
if [[ "$bind" == "settings" ]]
|
||||
then
|
||||
elif [[ "$type" == "file" ]]; then
|
||||
if [[ "$bind" == "settings" ]]; then
|
||||
ynh_die --message="File '${short_setting}' can't be stored in settings"
|
||||
fi
|
||||
local bind_file="$(echo "$bind" | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)"
|
||||
if [[ "${!short_setting}" == "" ]]
|
||||
then
|
||||
if [[ "${!short_setting}" == "" ]]; then
|
||||
ynh_backup_if_checksum_is_different --file="$bind_file"
|
||||
ynh_secure_remove --file="$bind_file"
|
||||
ynh_delete_file_checksum --file="$bind_file" --update_only
|
||||
ynh_print_info --message="File '$bind_file' removed"
|
||||
else
|
||||
ynh_backup_if_checksum_is_different --file="$bind_file"
|
||||
if [[ "${!short_setting}" != "$bind_file" ]]
|
||||
then
|
||||
if [[ "${!short_setting}" != "$bind_file" ]]; then
|
||||
cp "${!short_setting}" "$bind_file"
|
||||
fi
|
||||
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
|
||||
|
||||
# Save value in app settings
|
||||
elif [[ "$bind" == "settings" ]]
|
||||
then
|
||||
elif [[ "$bind" == "settings" ]]; then
|
||||
ynh_app_setting_set --app=$app --key=$short_setting --value="${!short_setting}"
|
||||
ynh_print_info --message="Configuration key '$short_setting' edited in app settings"
|
||||
|
||||
# Save multiline text in a file
|
||||
elif [[ "$type" == "text" ]]
|
||||
then
|
||||
if [[ "$bind" == *":"* ]]
|
||||
then
|
||||
elif [[ "$type" == "text" ]]; 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"
|
||||
fi
|
||||
local bind_file="$(echo "$bind" | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)"
|
||||
ynh_backup_if_checksum_is_different --file="$bind_file"
|
||||
echo "${!short_setting}" >"$bind_file"
|
||||
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
|
||||
else
|
||||
local bind_after=""
|
||||
local bind_key="$(echo "$bind" | cut -d: -f1)"
|
||||
bind_key=${bind_key:-$short_setting}
|
||||
if [[ "$bind_key" == *">"* ]];
|
||||
then
|
||||
bind_after="$(echo "${bind_key}" | cut -d'>' -f1)"
|
||||
bind_key="$(echo "${bind_key}" | cut -d'>' -f2)"
|
||||
local bind_key_="$(echo "$bind" | cut -d: -f1)"
|
||||
bind_key_=${bind_key_:-$short_setting}
|
||||
if [[ "$bind_key_" == *">"* ]]; then
|
||||
bind_after="$(echo "${bind_key_}" | cut -d'>' -f1)"
|
||||
bind_key_="$(echo "${bind_key_}" | cut -d'>' -f2)"
|
||||
fi
|
||||
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_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
|
||||
|
||||
# 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_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
|
||||
|
@ -152,7 +129,8 @@ _ynh_app_config_apply_one() {
|
|||
_ynh_app_config_get() {
|
||||
# From settings
|
||||
local lines
|
||||
lines=$(python3 << EOL
|
||||
lines=$(
|
||||
python3 <<EOL
|
||||
import toml
|
||||
from collections import OrderedDict
|
||||
with open("../config_panel.toml", "r") as f:
|
||||
|
@ -173,8 +151,7 @@ for panel_name, panel in loaded_toml.items():
|
|||
]))
|
||||
EOL
|
||||
)
|
||||
for line in $lines
|
||||
do
|
||||
for line in $lines; do
|
||||
# Split line into short_setting, type and bind
|
||||
IFS=';' read short_setting type bind <<<"$line"
|
||||
binds[${short_setting}]="$bind"
|
||||
|
@ -184,23 +161,18 @@ EOL
|
|||
ynh_app_config_get_one $short_setting $type $bind
|
||||
done
|
||||
|
||||
|
||||
}
|
||||
|
||||
_ynh_app_config_apply() {
|
||||
for short_setting in "${!old[@]}"
|
||||
do
|
||||
for short_setting in "${!old[@]}"; do
|
||||
ynh_app_config_apply_one $short_setting
|
||||
done
|
||||
}
|
||||
|
||||
_ynh_app_config_show() {
|
||||
for short_setting in "${!old[@]}"
|
||||
do
|
||||
if [[ "${old[$short_setting]}" != YNH_NULL ]]
|
||||
then
|
||||
if [[ "${formats[$short_setting]}" == "yaml" ]]
|
||||
then
|
||||
for short_setting in "${!old[@]}"; do
|
||||
if [[ "${old[$short_setting]}" != YNH_NULL ]]; then
|
||||
if [[ "${formats[$short_setting]}" == "yaml" ]]; then
|
||||
ynh_return "${short_setting}:"
|
||||
ynh_return "$(echo "${old[$short_setting]}" | sed 's/^/ /g')"
|
||||
else
|
||||
|
@ -216,48 +188,39 @@ _ynh_app_config_validate() {
|
|||
ynh_script_progression --message="Checking what changed in the new configuration..." --weight=1
|
||||
local nothing_changed=true
|
||||
local changes_validated=true
|
||||
for short_setting in "${!old[@]}"
|
||||
do
|
||||
for short_setting in "${!old[@]}"; do
|
||||
changed[$short_setting]=false
|
||||
if [ -z ${!short_setting+x} ]
|
||||
then
|
||||
if [ -z ${!short_setting+x} ]; then
|
||||
# Assign the var with the old value in order to allows multiple
|
||||
# args validation
|
||||
declare "$short_setting"="${old[$short_setting]}"
|
||||
continue
|
||||
fi
|
||||
if [ ! -z "${file_hash[${short_setting}]}" ]
|
||||
then
|
||||
if [ ! -z "${file_hash[${short_setting}]}" ]; then
|
||||
file_hash[old__$short_setting]=""
|
||||
file_hash[new__$short_setting]=""
|
||||
if [ -f "${old[$short_setting]}" ]
|
||||
then
|
||||
if [ -f "${old[$short_setting]}" ]; then
|
||||
file_hash[old__$short_setting]=$(sha256sum "${old[$short_setting]}" | cut -d' ' -f1)
|
||||
if [ -z "${!short_setting}" ]
|
||||
then
|
||||
if [ -z "${!short_setting}" ]; then
|
||||
changed[$short_setting]=true
|
||||
nothing_changed=false
|
||||
fi
|
||||
fi
|
||||
if [ -f "${!short_setting}" ]
|
||||
then
|
||||
if [ -f "${!short_setting}" ]; then
|
||||
file_hash[new__$short_setting]=$(sha256sum "${!short_setting}" | cut -d' ' -f1)
|
||||
if [[ "${file_hash[old__$short_setting]}" != "${file_hash[new__$short_setting]}" ]]
|
||||
then
|
||||
if [[ "${file_hash[old__$short_setting]}" != "${file_hash[new__$short_setting]}" ]]; then
|
||||
changed[$short_setting]=true
|
||||
nothing_changed=false
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if [[ "${!short_setting}" != "${old[$short_setting]}" ]]
|
||||
then
|
||||
if [[ "${!short_setting}" != "${old[$short_setting]}" ]]; then
|
||||
changed[$short_setting]=true
|
||||
nothing_changed=false
|
||||
fi
|
||||
fi
|
||||
done
|
||||
if [[ "$nothing_changed" == "true" ]]
|
||||
then
|
||||
if [[ "$nothing_changed" == "true" ]]; then
|
||||
ynh_print_info --message="Nothing has changed"
|
||||
exit 0
|
||||
fi
|
||||
|
@ -265,19 +228,15 @@ _ynh_app_config_validate() {
|
|||
# Run validation if something is changed
|
||||
ynh_script_progression --message="Validating the new configuration..." --weight=1
|
||||
|
||||
for short_setting in "${!old[@]}"
|
||||
do
|
||||
for short_setting in "${!old[@]}"; do
|
||||
[[ "${changed[$short_setting]}" == "false" ]] && continue
|
||||
local result=""
|
||||
if type -t validate__$short_setting | grep -q '^function$' 2>/dev/null;
|
||||
then
|
||||
if type -t validate__$short_setting | grep -q '^function$' 2>/dev/null; then
|
||||
result="$(validate__$short_setting)"
|
||||
elif [[ "$bind" == *"("* ]] && type -t "validate__${bind%%(*}" 2>/dev/null | grep -q '^function$' 2>/dev/null;
|
||||
then
|
||||
elif [[ "$bind" == *"("* ]] && type -t "validate__${bind%%(*}" 2>/dev/null | grep -q '^function$' 2>/dev/null; then
|
||||
"validate__${bind%%(*}" $short_setting
|
||||
fi
|
||||
if [ -n "$result" ]
|
||||
then
|
||||
if [ -n "$result" ]; then
|
||||
#
|
||||
# Return a yaml such as:
|
||||
#
|
||||
|
@ -287,8 +246,7 @@ _ynh_app_config_validate() {
|
|||
#
|
||||
# We use changes_validated to know if this is
|
||||
# the first validation error
|
||||
if [[ "$changes_validated" == true ]]
|
||||
then
|
||||
if [[ "$changes_validated" == true ]]; then
|
||||
ynh_return "validation_errors:"
|
||||
fi
|
||||
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)
|
||||
# Yunohost core will pick up the errors returned via ynh_return previously
|
||||
if [[ "$changes_validated" == "false" ]]
|
||||
then
|
||||
if [[ "$changes_validated" == "false" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
@ -354,4 +311,3 @@ ynh_app_config_run() {
|
|||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
|
|
@ -76,8 +76,7 @@ ynh_add_fail2ban_config () {
|
|||
ports=${ports:-http,https}
|
||||
use_template="${use_template:-0}"
|
||||
|
||||
if [ $use_template -ne 1 ]
|
||||
then
|
||||
if [ $use_template -ne 1 ]; then
|
||||
# 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 "$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
|
||||
|
||||
local fail2ban_error="$(journalctl --no-hostname --unit=fail2ban | tail --lines=50 | grep "WARNING.*$app.*")"
|
||||
if [[ -n "$fail2ban_error" ]]
|
||||
then
|
||||
if [[ -n "$fail2ban_error" ]]; then
|
||||
ynh_print_err --message="Fail2ban failed to load the jail for $app"
|
||||
ynh_print_warn --message="${fail2ban_error#*WARNING}"
|
||||
fi
|
||||
|
|
|
@ -48,8 +48,7 @@
|
|||
ynh_handle_getopts_args() {
|
||||
# Manage arguments only if there's some provided
|
||||
set +o xtrace # set +x
|
||||
if [ $# -ne 0 ]
|
||||
then
|
||||
if [ $# -ne 0 ]; then
|
||||
# Store arguments in an array to keep each argument separated
|
||||
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)
|
||||
local getopts_parameters=""
|
||||
local option_flag=""
|
||||
for option_flag in "${!args_array[@]}"
|
||||
do
|
||||
for option_flag in "${!args_array[@]}"; do
|
||||
# Concatenate each option_flags of the array to build the string of arguments for getopts
|
||||
# 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)
|
||||
# Check the last character of the value associate to the option_flag
|
||||
if [ "${args_array[$option_flag]: -1}" = "=" ]
|
||||
then
|
||||
if [ "${args_array[$option_flag]: -1}" = "=" ]; then
|
||||
# For an option with additionnal values, add a ':' after the letter for getopts.
|
||||
getopts_parameters="${getopts_parameters}${option_flag}:"
|
||||
else
|
||||
|
@ -74,8 +71,7 @@ ynh_handle_getopts_args () {
|
|||
# Check each argument given to the function
|
||||
local arg=""
|
||||
# ${#arguments[@]} is the size of the array
|
||||
for arg in `seq 0 $(( ${#arguments[@]} - 1 ))`
|
||||
do
|
||||
for arg in $(seq 0 $((${#arguments[@]} - 1))); do
|
||||
# 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\\-}"
|
||||
# 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.
|
||||
parse_arg() {
|
||||
# Read all arguments, until no arguments are left
|
||||
while [ $# -ne 0 ]
|
||||
do
|
||||
while [ $# -ne 0 ]; do
|
||||
# Initialize the index of getopts
|
||||
OPTIND=1
|
||||
# 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=""
|
||||
getopts ":$getopts_parameters" parameter || true
|
||||
|
||||
if [ "$parameter" = "?" ]
|
||||
then
|
||||
if [ "$parameter" = "?" ]; then
|
||||
ynh_die --message="Invalid argument: -${OPTARG:-}"
|
||||
elif [ "$parameter" = ":" ]
|
||||
then
|
||||
elif [ "$parameter" = ":" ]; then
|
||||
ynh_die --message="-$OPTARG parameter requires an argument."
|
||||
else
|
||||
local shift_value=1
|
||||
|
@ -115,8 +108,7 @@ ynh_handle_getopts_args () {
|
|||
local option_var="${args_array[$parameter]%=}"
|
||||
# If this option doesn't take values
|
||||
# if there's a '=' at the end of the long option name, this option takes values
|
||||
if [ "${args_array[$parameter]: -1}" != "=" ]
|
||||
then
|
||||
if [ "${args_array[$parameter]: -1}" != "=" ]; then
|
||||
# 'eval ${option_var}' will use the content of 'option_var'
|
||||
eval ${option_var}=1
|
||||
else
|
||||
|
@ -126,14 +118,12 @@ ynh_handle_getopts_args () {
|
|||
|
||||
# If the first argument is longer than 2 characters,
|
||||
# There's a value attached to the option, in the same array cell
|
||||
if [ ${#all_args[0]} -gt 2 ]
|
||||
then
|
||||
if [ ${#all_args[0]} -gt 2 ]; then
|
||||
# Remove the option and the space, so keep only the value itself.
|
||||
all_args[0]="${all_args[0]#-${parameter} }"
|
||||
|
||||
# At this point, if all_args[0] start with "-", then the argument is not well formed
|
||||
if [ "${all_args[0]:0:1}" == "-" ]
|
||||
then
|
||||
if [ "${all_args[0]:0:1}" == "-" ]; then
|
||||
ynh_die --message="Argument \"${all_args[0]}\" not valid! Did you use a single \"-\" instead of two?"
|
||||
fi
|
||||
# Reduce the value of shift, because the option has been removed manually
|
||||
|
@ -144,23 +134,19 @@ ynh_handle_getopts_args () {
|
|||
eval ${option_var}=""
|
||||
# Then read the array value per value
|
||||
local i
|
||||
for i in `seq 0 $(( ${#all_args[@]} - 1 ))`
|
||||
do
|
||||
for i in $(seq 0 $((${#all_args[@]} - 1))); do
|
||||
# If this argument is an option, end here.
|
||||
if [ "${all_args[$i]:0:1}" == "-" ]
|
||||
then
|
||||
if [ "${all_args[$i]:0:1}" == "-" ]; then
|
||||
# Ignore the first value of the array, which is the option itself
|
||||
if [ "$i" -ne 0 ]; then
|
||||
break
|
||||
fi
|
||||
else
|
||||
# Ignore empty parameters
|
||||
if [ -n "${all_args[$i]}" ]
|
||||
then
|
||||
if [ -n "${all_args[$i]}" ]; then
|
||||
# Else, add this value to this option
|
||||
# Each value will be separated by ';'
|
||||
if [ -n "${!option_var}" ]
|
||||
then
|
||||
if [ -n "${!option_var}" ]; then
|
||||
# If there's already another value for this option, add a ; before adding the new value
|
||||
eval ${option_var}+="\;"
|
||||
fi
|
||||
|
@ -190,22 +176,21 @@ ynh_handle_getopts_args () {
|
|||
|
||||
# LEGACY MODE
|
||||
# Check if there's getopts arguments
|
||||
if [ "${arguments[0]:0:1}" != "-" ]
|
||||
then
|
||||
if [ "${arguments[0]:0:1}" != "-" ]; then
|
||||
# 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.
|
||||
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
|
||||
for i in `seq 0 $(( ${#arguments[@]} -1 ))`
|
||||
do
|
||||
for i in $(seq 0 $((${#arguments[@]} - 1))); do
|
||||
# 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...
|
||||
# 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.
|
||||
option_flag=${getopts_parameters:$i:1}
|
||||
if [ -z "$option_flag" ]
|
||||
then
|
||||
if [ -z "$option_flag" ]; then
|
||||
ynh_print_warn --message="Too many arguments ! \"${arguments[$i]}\" will be ignored."
|
||||
continue
|
||||
fi
|
||||
|
|
|
@ -25,41 +25,34 @@ ynh_get_ram () {
|
|||
free=${free:-0}
|
||||
total=${total:-0}
|
||||
|
||||
if [ $free -eq $total ]
|
||||
then
|
||||
if [ $free -eq $total ]; then
|
||||
ynh_print_warn --message="You have to choose --free or --total when using ynh_get_ram"
|
||||
ram=0
|
||||
# Use the total amount of ram
|
||||
elif [ $free -eq 1 ]
|
||||
then
|
||||
elif [ $free -eq 1 ]; then
|
||||
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_ram_swap=$((free_ram + free_swap))
|
||||
|
||||
# Use the total amount of free ram
|
||||
local ram=$free_ram_swap
|
||||
if [ $ignore_swap -eq 1 ]
|
||||
then
|
||||
if [ $ignore_swap -eq 1 ]; then
|
||||
# Use only the amount of free ram
|
||||
ram=$free_ram
|
||||
elif [ $only_swap -eq 1 ]
|
||||
then
|
||||
elif [ $only_swap -eq 1 ]; then
|
||||
# Use only the amount of free swap
|
||||
ram=$free_swap
|
||||
fi
|
||||
elif [ $total -eq 1 ]
|
||||
then
|
||||
elif [ $total -eq 1 ]; then
|
||||
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_ram_swap=$((total_ram + total_swap))
|
||||
|
||||
local ram=$total_ram_swap
|
||||
if [ $ignore_swap -eq 1 ]
|
||||
then
|
||||
if [ $ignore_swap -eq 1 ]; then
|
||||
# Use only the amount of free ram
|
||||
ram=$total_ram
|
||||
elif [ $only_swap -eq 1 ]
|
||||
then
|
||||
elif [ $only_swap -eq 1 ]; then
|
||||
# Use only the amount of free swap
|
||||
ram=$total_swap
|
||||
fi
|
||||
|
@ -100,8 +93,7 @@ ynh_require_ram () {
|
|||
|
||||
local ram=$(ynh_get_ram $free $total $ignore_swap $only_swap)
|
||||
|
||||
if [ $ram -lt $required ]
|
||||
then
|
||||
if [ $ram -lt $required ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
|
|
@ -38,25 +38,6 @@ ynh_print_info() {
|
|||
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.
|
||||
#
|
||||
# [internal]
|
||||
|
@ -102,78 +83,115 @@ ynh_print_err () {
|
|||
|
||||
# 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
|
||||
#
|
||||
# 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.
|
||||
# Note that you should NOT quote the command but only prefix it with ynh_exec_err
|
||||
#
|
||||
# Requires YunoHost version 3.2.0 or higher.
|
||||
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 $@)"
|
||||
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
|
||||
#
|
||||
# usage: ynh_exec_warn "your_command [ | other_command ]"
|
||||
# usage: ynh_exec_warn your command and args
|
||||
# | 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.
|
||||
# Note that you should NOT quote the command but only prefix it with ynh_exec_warn
|
||||
#
|
||||
# Requires YunoHost version 3.2.0 or higher.
|
||||
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 $@)"
|
||||
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
|
||||
#
|
||||
# usage: ynh_exec_warn_less "your_command [ | other_command ]"
|
||||
# usage: ynh_exec_warn_less your command and args
|
||||
# | 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.
|
||||
# Note that you should NOT quote the command but only prefix it with ynh_exec_warn
|
||||
#
|
||||
# Requires YunoHost version 3.2.0 or higher.
|
||||
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
|
||||
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
|
||||
#
|
||||
# usage: ynh_exec_quiet "your_command [ | other_command ]"
|
||||
# usage: ynh_exec_quiet your command and args
|
||||
# | 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.
|
||||
# Note that you should NOT quote the command but only prefix it with ynh_exec_warn
|
||||
#
|
||||
# Requires YunoHost version 3.2.0 or higher.
|
||||
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
|
||||
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
|
||||
#
|
||||
# usage: ynh_exec_fully_quiet "your_command [ | other_command ]"
|
||||
# usage: ynh_exec_quiet your command and args
|
||||
# | 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.
|
||||
# Note that you should NOT quote the command but only prefix it with ynh_exec_quiet
|
||||
#
|
||||
# Requires YunoHost version 3.2.0 or higher.
|
||||
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
|
||||
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.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# Requires YunoHost version 3.2.0 or higher.
|
||||
|
@ -185,6 +203,8 @@ ynh_print_OFF () {
|
|||
#
|
||||
# usage: ynh_print_ON
|
||||
#
|
||||
# [internal]
|
||||
#
|
||||
# Requires YunoHost version 3.2.0 or higher.
|
||||
ynh_print_ON() {
|
||||
exec {BASH_XTRACEFD}>&1
|
||||
|
@ -236,8 +256,7 @@ ynh_script_progression () {
|
|||
base_time=$(date +%s)
|
||||
|
||||
# Compute $max_progression (if we didn't already)
|
||||
if [ "$max_progression" = -1 ]
|
||||
then
|
||||
if [ "$max_progression" = -1 ]; then
|
||||
# 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)"
|
||||
# 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')"
|
||||
# Each value will be on a different line.
|
||||
# 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.
|
||||
# Less the number of calls with a weight value.
|
||||
|
@ -263,8 +282,7 @@ ynh_script_progression () {
|
|||
previous_weight=$weight
|
||||
|
||||
# Reduce $increment_progression to the size of the scale
|
||||
if [ $last -eq 0 ]
|
||||
then
|
||||
if [ $last -eq 0 ]; then
|
||||
local effective_progression=$(($increment_progression * $progress_scale / $max_progression))
|
||||
# If last is specified, fill immediately the progression_bar
|
||||
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
|
||||
# expected_progression is the progression expected after the current task
|
||||
local expected_progression="$((($increment_progression + $weight) * $progress_scale / $max_progression - $effective_progression))"
|
||||
if [ $last -eq 1 ]
|
||||
then
|
||||
if [ $last -eq 1 ]; then
|
||||
expected_progression=0
|
||||
fi
|
||||
# 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 print_exec_time=""
|
||||
if [ $time -eq 1 ]
|
||||
then
|
||||
if [ $time -eq 1 ]; then
|
||||
print_exec_time=" [$(date +%Hh%Mm,%Ss --date="0 + $exec_time sec")]"
|
||||
fi
|
||||
|
||||
|
@ -302,70 +318,3 @@ ynh_script_progression () {
|
|||
ynh_return() {
|
||||
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 $@)"
|
||||
}
|
||||
|
|
|
@ -30,22 +30,18 @@ ynh_use_logrotate () {
|
|||
specific_user="${specific_user:-}"
|
||||
|
||||
# LEGACY CODE - PRE GETOPTS
|
||||
if [ $# -gt 0 ] && [ "$1" == "--non-append" ]
|
||||
then
|
||||
if [ $# -gt 0 ] && [ "$1" == "--non-append" ]; then
|
||||
nonappend=1
|
||||
# Destroy this argument for the next command.
|
||||
shift
|
||||
elif [ $# -gt 1 ] && [ "$2" == "--non-append" ]
|
||||
then
|
||||
elif [ $# -gt 1 ] && [ "$2" == "--non-append" ]; then
|
||||
nonappend=1
|
||||
fi
|
||||
|
||||
if [ $# -gt 0 ] && [ "$(echo ${1:0:1})" != "-" ]
|
||||
then
|
||||
if [ $# -gt 0 ] && [ "$(echo ${1:0:1})" != "-" ]; then
|
||||
# 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
|
||||
if [ -f "$1" ] || [ "$(echo ${1##*.})" == "log" ]
|
||||
then
|
||||
if [ -f "$1" ] || [ "$(echo ${1##*.})" == "log" ]; then
|
||||
local logfile=$1
|
||||
# Otherwise we assume we want to manage a directory and all its .log file inside
|
||||
else
|
||||
|
@ -58,8 +54,7 @@ ynh_use_logrotate () {
|
|||
if [ "$nonappend" -eq 1 ]; then
|
||||
customtee="tee"
|
||||
fi
|
||||
if [ -n "$logfile" ]
|
||||
then
|
||||
if [ -n "$logfile" ]; then
|
||||
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.
|
||||
fi
|
||||
|
@ -67,8 +62,7 @@ ynh_use_logrotate () {
|
|||
logfile="/var/log/${app}/*.log" # Without argument, use a defaut directory in /var/log
|
||||
fi
|
||||
local su_directive=""
|
||||
if [[ -n $specific_user ]]
|
||||
then
|
||||
if [[ -n $specific_user ]]; then
|
||||
su_directive=" # Run logorotate as specific user - group
|
||||
su ${specific_user%/*} ${specific_user#*/}"
|
||||
fi
|
||||
|
@ -96,6 +90,11 @@ $logfile {
|
|||
EOF
|
||||
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)
|
||||
|
||||
if ynh_user_exists --username="$app"; then
|
||||
chown $app:$app "$logfile"
|
||||
chmod o-rwx "$logfile"
|
||||
fi
|
||||
}
|
||||
|
||||
# Remove the app's logrotate config.
|
||||
|
|
|
@ -22,8 +22,7 @@ ynh_multimedia_build_main_dir() {
|
|||
mkdir -p "$MEDIA_DIRECTORY/share/eBook"
|
||||
|
||||
## Création des dossiers utilisateurs
|
||||
for user in $(yunohost user list --output-as json | jq -r '.users | keys[]')
|
||||
do
|
||||
for user in $(yunohost user list --output-as json | jq -r '.users | keys[]'); do
|
||||
mkdir -p "$MEDIA_DIRECTORY/$user"
|
||||
mkdir -p "$MEDIA_DIRECTORY/$user/Music"
|
||||
mkdir -p "$MEDIA_DIRECTORY/$user/Picture"
|
||||
|
|
|
@ -43,8 +43,7 @@ ynh_mysql_execute_as_root() {
|
|||
ynh_handle_getopts_args "$@"
|
||||
database="${database:-}"
|
||||
|
||||
if [ -n "$database" ]
|
||||
then
|
||||
if [ -n "$database" ]; then
|
||||
database="--database=$database"
|
||||
fi
|
||||
|
||||
|
@ -68,8 +67,7 @@ ynh_mysql_execute_file_as_root() {
|
|||
ynh_handle_getopts_args "$@"
|
||||
database="${database:-}"
|
||||
|
||||
if [ -n "$database" ]
|
||||
then
|
||||
if [ -n "$database" ]; then
|
||||
database="--database=$database"
|
||||
fi
|
||||
|
||||
|
@ -92,8 +90,7 @@ ynh_mysql_create_db() {
|
|||
local sql="CREATE DATABASE ${db};"
|
||||
|
||||
# grant all privilegies to user
|
||||
if [[ $# -gt 1 ]]
|
||||
then
|
||||
if [[ $# -gt 1 ]]; then
|
||||
sql+=" GRANT ALL PRIVILEGES ON ${db}.* TO '${2}'@'localhost'"
|
||||
if [[ -n ${3:-} ]]; then
|
||||
sql+=" IDENTIFIED BY '${3}'"
|
||||
|
@ -160,8 +157,7 @@ ynh_mysql_create_user() {
|
|||
# | ret: 0 if the user exists, 1 otherwise.
|
||||
#
|
||||
# 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.
|
||||
local legacy_args=u
|
||||
local -A args_array=([u]=user=)
|
||||
|
@ -169,8 +165,7 @@ ynh_mysql_user_exists()
|
|||
# Manage arguments with getopts
|
||||
ynh_handle_getopts_args "$@"
|
||||
|
||||
if [[ -z $(ynh_mysql_execute_as_root --sql="SELECT User from mysql.user WHERE User = '$user';") ]]
|
||||
then
|
||||
if [[ -z $(ynh_mysql_execute_as_root --sql="SELECT User from mysql.user WHERE User = '$user';") ]]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
|
|
@ -18,8 +18,7 @@ ynh_find_port () {
|
|||
ynh_handle_getopts_args "$@"
|
||||
|
||||
test -n "$port" || ynh_die --message="The argument of ynh_find_port must be a valid port."
|
||||
while ! ynh_port_available --port=$port
|
||||
do
|
||||
while ! ynh_port_available --port=$port; do
|
||||
port=$((port + 1))
|
||||
done
|
||||
echo $port
|
||||
|
@ -43,19 +42,16 @@ ynh_port_available () {
|
|||
ynh_handle_getopts_args "$@"
|
||||
|
||||
# Check if the port is free
|
||||
if ss --numeric --listening --tcp --udp | awk '{print$5}' | grep --quiet --extended-regexp ":$port$"
|
||||
then
|
||||
if ss --numeric --listening --tcp --udp | awk '{print$5}' | grep --quiet --extended-regexp ":$port$"; then
|
||||
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)
|
||||
elif grep -q "port: '$port'" /etc/yunohost/apps/*/settings.yml
|
||||
then
|
||||
elif grep -q "port: '$port'" /etc/yunohost/apps/*/settings.yml; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Validate an IP address
|
||||
#
|
||||
# [internal]
|
||||
|
@ -66,8 +62,7 @@ ynh_port_available () {
|
|||
# example: ynh_validate_ip 4 111.222.333.444
|
||||
#
|
||||
# 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
|
||||
|
||||
# Declare an array to define the options of this helper.
|
||||
|
@ -101,8 +96,7 @@ EOF
|
|||
# example: ynh_validate_ip4 111.222.333.444
|
||||
#
|
||||
# Requires YunoHost version 2.2.4 or higher.
|
||||
ynh_validate_ip4()
|
||||
{
|
||||
ynh_validate_ip4() {
|
||||
# Declare an array to define the options of this helper.
|
||||
local legacy_args=i
|
||||
local -A args_array=([i]=ip_address=)
|
||||
|
@ -113,7 +107,6 @@ ynh_validate_ip4()
|
|||
ynh_validate_ip --family=4 --ip_address=$ip_address
|
||||
}
|
||||
|
||||
|
||||
# Validate an IPv6 address
|
||||
#
|
||||
# usage: ynh_validate_ip6 --ip_address=ip_address
|
||||
|
@ -123,8 +116,7 @@ ynh_validate_ip4()
|
|||
# example: ynh_validate_ip6 2000:dead:beef::1
|
||||
#
|
||||
# Requires YunoHost version 2.2.4 or higher.
|
||||
ynh_validate_ip6()
|
||||
{
|
||||
ynh_validate_ip6() {
|
||||
# Declare an array to define the options of this helper.
|
||||
local legacy_args=i
|
||||
local -A args_array=([i]=ip_address=)
|
||||
|
|
|
@ -20,8 +20,7 @@ ynh_add_nginx_config () {
|
|||
|
||||
local finalnginxconf="/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||
|
||||
if [ "${path_url:-}" != "/" ]
|
||||
then
|
||||
if [ "${path_url:-}" != "/" ]; then
|
||||
ynh_replace_string --match_string="^#sub_path_only" --replace_string="" --target_file="$YNH_APP_BASEDIR/conf/nginx.conf"
|
||||
else
|
||||
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_systemd_action --service_name=nginx --action=reload
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,10 @@ SOURCE_SUM=d4da7ea91f680de0c9b5876e097e2a793e8234fcd0f7ca87a0599b925be087a3" > "
|
|||
# Download and extract n
|
||||
ynh_setup_source --dest_dir="$n_install_dir/git" --source_id=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.
|
||||
|
@ -132,11 +134,9 @@ ynh_install_nodejs () {
|
|||
test -x /usr/bin/npm && mv /usr/bin/npm /usr/bin/npm_n
|
||||
|
||||
# If n is not previously setup, install it
|
||||
if ! $n_install_dir/bin/n --version > /dev/null 2>&1
|
||||
then
|
||||
if ! $n_install_dir/bin/n --version >/dev/null 2>&1; then
|
||||
ynh_install_n
|
||||
elif dpkg --compare-versions "$($n_install_dir/bin/n --version)" lt $n_version
|
||||
then
|
||||
elif dpkg --compare-versions "$($n_install_dir/bin/n --version)" lt $n_version; then
|
||||
ynh_install_n
|
||||
fi
|
||||
|
||||
|
@ -152,8 +152,7 @@ ynh_install_nodejs () {
|
|||
|
||||
# Install the requested version of nodejs
|
||||
uname=$(uname --machine)
|
||||
if [[ $uname =~ aarch64 || $uname =~ arm64 ]]
|
||||
then
|
||||
if [[ $uname =~ aarch64 || $uname =~ arm64 ]]; then
|
||||
n $nodejs_version --arch=arm64
|
||||
else
|
||||
n $nodejs_version
|
||||
|
@ -164,8 +163,7 @@ ynh_install_nodejs () {
|
|||
real_nodejs_version=$(basename $real_nodejs_version)
|
||||
|
||||
# Create a symbolic link for this major version if the file doesn't already exist
|
||||
if [ ! -e "$node_version_path/$nodejs_version" ]
|
||||
then
|
||||
if [ ! -e "$node_version_path/$nodejs_version" ]; then
|
||||
ln --symbolic --force --no-target-directory $node_version_path/$real_nodejs_version $node_version_path/$nodejs_version
|
||||
fi
|
||||
|
||||
|
@ -197,14 +195,12 @@ ynh_remove_nodejs () {
|
|||
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 ! grep --quiet "$nodejs_version" "$n_install_dir/ynh_app_version"
|
||||
then
|
||||
if ! grep --quiet "$nodejs_version" "$n_install_dir/ynh_app_version"; then
|
||||
$n_install_dir/bin/n rm $nodejs_version
|
||||
fi
|
||||
|
||||
# If no other app uses n, remove n
|
||||
if [ ! -s "$n_install_dir/ynh_app_version" ]
|
||||
then
|
||||
if [ ! -s "$n_install_dir/ynh_app_version" ]; then
|
||||
ynh_secure_remove --file="$n_install_dir"
|
||||
ynh_secure_remove --file="/usr/local/n"
|
||||
sed --in-place "/N_PREFIX/d" /root/.bashrc
|
||||
|
|
|
@ -84,13 +84,11 @@ ynh_permission_create() {
|
|||
show_tile=${show_tile:-}
|
||||
protected=${protected:-}
|
||||
|
||||
if [[ -n $url ]]
|
||||
then
|
||||
if [[ -n $url ]]; then
|
||||
url=",url='$url'"
|
||||
fi
|
||||
|
||||
if [[ -n $additional_urls ]]
|
||||
then
|
||||
if [[ -n $additional_urls ]]; then
|
||||
# Convert a list from getopts to python list
|
||||
# Note that getopts separate the args with ';'
|
||||
# By example:
|
||||
|
@ -100,18 +98,15 @@ ynh_permission_create() {
|
|||
additional_urls=",additional_urls=['${additional_urls//;/\',\'}']"
|
||||
fi
|
||||
|
||||
if [[ -n $auth_header ]]
|
||||
then
|
||||
if [ $auth_header == "true" ]
|
||||
then
|
||||
if [[ -n $auth_header ]]; then
|
||||
if [ $auth_header == "true" ]; then
|
||||
auth_header=",auth_header=True"
|
||||
else
|
||||
auth_header=",auth_header=False"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n $allowed ]]
|
||||
then
|
||||
if [[ -n $allowed ]]; then
|
||||
# Convert a list from getopts to python list
|
||||
# Note that getopts separate the args with ';'
|
||||
# By example:
|
||||
|
@ -127,20 +122,16 @@ ynh_permission_create() {
|
|||
label=",label='$permission'"
|
||||
fi
|
||||
|
||||
if [[ -n ${show_tile:-} ]]
|
||||
then
|
||||
if [ $show_tile == "true" ]
|
||||
then
|
||||
if [[ -n ${show_tile:-} ]]; then
|
||||
if [ $show_tile == "true" ]; then
|
||||
show_tile=",show_tile=True"
|
||||
else
|
||||
show_tile=",show_tile=False"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n ${protected:-} ]]
|
||||
then
|
||||
if [ $protected == "true" ]
|
||||
then
|
||||
if [[ -n ${protected:-} ]]; then
|
||||
if [ $protected == "true" ]; then
|
||||
protected=",protected=True"
|
||||
else
|
||||
protected=",protected=False"
|
||||
|
@ -215,13 +206,11 @@ ynh_permission_url() {
|
|||
auth_header=${auth_header:-}
|
||||
clear_urls=${clear_urls:-}
|
||||
|
||||
if [[ -n $url ]]
|
||||
then
|
||||
if [[ -n $url ]]; then
|
||||
url=",url='$url'"
|
||||
fi
|
||||
|
||||
if [[ -n $add_url ]]
|
||||
then
|
||||
if [[ -n $add_url ]]; then
|
||||
# Convert a list from getopts to python list
|
||||
# Note that getopts separate the args with ';'
|
||||
# For example:
|
||||
|
@ -231,8 +220,7 @@ ynh_permission_url() {
|
|||
add_url=",add_url=['${add_url//;/\',\'}']"
|
||||
fi
|
||||
|
||||
if [[ -n $remove_url ]]
|
||||
then
|
||||
if [[ -n $remove_url ]]; then
|
||||
# Convert a list from getopts to python list
|
||||
# Note that getopts separate the args with ';'
|
||||
# For example:
|
||||
|
@ -242,25 +230,21 @@ ynh_permission_url() {
|
|||
remove_url=",remove_url=['${remove_url//;/\',\'}']"
|
||||
fi
|
||||
|
||||
if [[ -n $auth_header ]]
|
||||
then
|
||||
if [ $auth_header == "true" ]
|
||||
then
|
||||
if [[ -n $auth_header ]]; then
|
||||
if [ $auth_header == "true" ]; then
|
||||
auth_header=",auth_header=True"
|
||||
else
|
||||
auth_header=",auth_header=False"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n $clear_urls ]] && [ $clear_urls -eq 1 ]
|
||||
then
|
||||
if [[ -n $clear_urls ]] && [ $clear_urls -eq 1 ]; then
|
||||
clear_urls=",clear_urls=True"
|
||||
fi
|
||||
|
||||
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
|
||||
#
|
||||
# usage: ynh_permission_update --permission "permission" [--add="group" ["group" ...]] [--remove="group" ["group" ...]]
|
||||
|
@ -290,8 +274,7 @@ ynh_permission_update() {
|
|||
show_tile=${show_tile:-}
|
||||
protected=${protected:-}
|
||||
|
||||
if [[ -n $add ]]
|
||||
then
|
||||
if [[ -n $add ]]; then
|
||||
# Convert a list from getopts to python list
|
||||
# Note that getopts separate the args with ';'
|
||||
# For example:
|
||||
|
@ -300,8 +283,7 @@ ynh_permission_update() {
|
|||
# add=['alice', 'bob']
|
||||
add=",add=['${add//';'/"','"}']"
|
||||
fi
|
||||
if [[ -n $remove ]]
|
||||
then
|
||||
if [[ -n $remove ]]; then
|
||||
# Convert a list from getopts to python list
|
||||
# Note that getopts separate the args with ';'
|
||||
# For example:
|
||||
|
@ -311,15 +293,12 @@ ynh_permission_update() {
|
|||
remove=",remove=['${remove//';'/"','"}']"
|
||||
fi
|
||||
|
||||
if [[ -n $label ]]
|
||||
then
|
||||
if [[ -n $label ]]; then
|
||||
label=",label='$label'"
|
||||
fi
|
||||
|
||||
if [[ -n $show_tile ]]
|
||||
then
|
||||
if [ $show_tile == "true" ]
|
||||
then
|
||||
if [[ -n $show_tile ]]; then
|
||||
if [ $show_tile == "true" ]; then
|
||||
show_tile=",show_tile=True"
|
||||
else
|
||||
show_tile=",show_tile=False"
|
||||
|
@ -327,8 +306,7 @@ ynh_permission_update() {
|
|||
fi
|
||||
|
||||
if [[ -n $protected ]]; then
|
||||
if [ $protected == "true" ]
|
||||
then
|
||||
if [ $protected == "true" ]; then
|
||||
protected=",protected=True"
|
||||
else
|
||||
protected=",protected=False"
|
||||
|
@ -357,17 +335,14 @@ ynh_permission_has_user() {
|
|||
# Manage arguments with getopts
|
||||
ynh_handle_getopts_args "$@"
|
||||
|
||||
if ! ynh_permission_exists --permission=$permission
|
||||
then
|
||||
if ! ynh_permission_exists --permission=$permission; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check both allowed and corresponding_users sections in the json
|
||||
for section in "allowed" "corresponding_users"
|
||||
do
|
||||
for section in "allowed" "corresponding_users"; do
|
||||
if yunohost user permission info "$app.$permission" --output-as json --quiet \
|
||||
| jq -e --arg user $user --arg section $section '.[$section] | index($user)' >/dev/null
|
||||
then
|
||||
| jq -e --arg user $user --arg section $section '.[$section] | index($user)' >/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
@ -382,8 +357,7 @@ ynh_permission_has_user() {
|
|||
#
|
||||
# Requires YunoHost version 4.1.2 or higher.
|
||||
ynh_legacy_permissions_exists() {
|
||||
for permission in "skipped" "unprotected" "protected"
|
||||
do
|
||||
for permission in "skipped" "unprotected" "protected"; do
|
||||
if ynh_permission_exists --permission="legacy_${permission}_uris"; then
|
||||
return 0
|
||||
fi
|
||||
|
@ -403,8 +377,7 @@ ynh_legacy_permissions_exists () {
|
|||
# fi
|
||||
# Requires YunoHost version 4.1.2 or higher.
|
||||
ynh_legacy_permissions_delete_all() {
|
||||
for permission in "skipped" "unprotected" "protected"
|
||||
do
|
||||
for permission in "skipped" "unprotected" "protected"; do
|
||||
if ynh_permission_exists --permission="legacy_${permission}_uris"; then
|
||||
ynh_permission_delete --permission="legacy_${permission}_uris"
|
||||
fi
|
||||
|
|
|
@ -86,8 +86,7 @@ ynh_add_fpm_config () {
|
|||
local old_phpversion=$(ynh_app_setting_get --app=$app --key=phpversion)
|
||||
|
||||
# If the PHP version changed, remove the old fpm conf
|
||||
if [ -n "$old_phpversion" ] && [ "$old_phpversion" != "$phpversion" ]
|
||||
then
|
||||
if [ -n "$old_phpversion" ] && [ "$old_phpversion" != "$phpversion" ]; then
|
||||
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"
|
||||
|
||||
|
@ -97,25 +96,21 @@ ynh_add_fpm_config () {
|
|||
fi
|
||||
|
||||
# If the requested PHP version is not the default version for YunoHost
|
||||
if [ "$phpversion" != "$YNH_DEFAULT_PHP_VERSION" ]
|
||||
then
|
||||
if [ "$phpversion" != "$YNH_DEFAULT_PHP_VERSION" ]; then
|
||||
# If the argument --package is used, add the packages to ynh_install_php to install them from sury
|
||||
if [ -n "$package" ]
|
||||
then
|
||||
if [ -n "$package" ]; then
|
||||
local additionnal_packages="--package=$package"
|
||||
else
|
||||
local additionnal_packages=""
|
||||
fi
|
||||
# Install this specific version of PHP.
|
||||
ynh_install_php --phpversion="$phpversion" "$additionnal_packages"
|
||||
elif [ -n "$package" ]
|
||||
then
|
||||
elif [ -n "$package" ]; then
|
||||
# Install the additionnal packages from the default repository
|
||||
ynh_add_app_dependencies --package="$package"
|
||||
ynh_install_app_dependencies "$package"
|
||||
fi
|
||||
|
||||
if [ $dedicated_service -eq 1 ]
|
||||
then
|
||||
if [ $dedicated_service -eq 1 ]; then
|
||||
local fpm_service="${app}-phpfpm"
|
||||
local fpm_config_dir="/etc/php/$phpversion/dedicated-fpm"
|
||||
else
|
||||
|
@ -132,12 +127,10 @@ ynh_add_fpm_config () {
|
|||
ynh_app_setting_set --app=$app --key=phpversion --value=$phpversion
|
||||
|
||||
# Migrate from mutual PHP service to dedicated one.
|
||||
if [ $dedicated_service -eq 1 ]
|
||||
then
|
||||
if [ $dedicated_service -eq 1 ]; then
|
||||
local old_fpm_config_dir="/etc/php/$phpversion/fpm"
|
||||
# If a config file exist in the common pool, move it.
|
||||
if [ -e "$old_fpm_config_dir/pool.d/$app.conf" ]
|
||||
then
|
||||
if [ -e "$old_fpm_config_dir/pool.d/$app.conf" ]; then
|
||||
ynh_print_info --message="Migrate to a dedicated php-fpm service for $app."
|
||||
# Create a backup of the old file before migration
|
||||
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
|
||||
|
||||
if [ $use_template -eq 1 ]
|
||||
then
|
||||
if [ $use_template -eq 1 ]; then
|
||||
# Usage 1, use the template in conf/php-fpm.conf
|
||||
local phpfpm_path="$YNH_APP_BASEDIR/conf/php-fpm.conf"
|
||||
# Make sure now that the template indeed exists
|
||||
|
@ -183,16 +175,14 @@ pm.max_requests = 500
|
|||
request_terminate_timeout = 1d
|
||||
" >$phpfpm_path
|
||||
|
||||
if [ "$php_pm" = "dynamic" ]
|
||||
then
|
||||
if [ "$php_pm" = "dynamic" ]; then
|
||||
echo "
|
||||
pm.start_servers = __PHP_START_SERVERS__
|
||||
pm.min_spare_servers = __PHP_MIN_SPARE_SERVERS__
|
||||
pm.max_spare_servers = __PHP_MAX_SPARE_SERVERS__
|
||||
" >>$phpfpm_path
|
||||
|
||||
elif [ "$php_pm" = "ondemand" ]
|
||||
then
|
||||
elif [ "$php_pm" = "ondemand" ]; then
|
||||
echo "
|
||||
pm.process_idle_timeout = 10s
|
||||
" >>$phpfpm_path
|
||||
|
@ -207,14 +197,12 @@ pm.process_idle_timeout = 10s
|
|||
local finalphpconf="$fpm_config_dir/pool.d/$app.conf"
|
||||
ynh_add_config --template="$phpfpm_path" --destination="$finalphpconf"
|
||||
|
||||
if [ -e "$YNH_APP_BASEDIR/conf/php-fpm.ini" ]
|
||||
then
|
||||
if [ -e "$YNH_APP_BASEDIR/conf/php-fpm.ini" ]; then
|
||||
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"
|
||||
fi
|
||||
|
||||
if [ $dedicated_service -eq 1 ]
|
||||
then
|
||||
if [ $dedicated_service -eq 1 ]; then
|
||||
# Create a dedicated php-fpm.conf for the service
|
||||
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
|
||||
else
|
||||
# Validate that the new php conf doesn't break php-fpm entirely
|
||||
if ! php-fpm${phpversion} --test 2>/dev/null
|
||||
then
|
||||
if ! php-fpm${phpversion} --test 2>/dev/null; then
|
||||
php-fpm${phpversion} --test || true
|
||||
ynh_secure_remove --file="$finalphpconf"
|
||||
ynh_die --message="The new configuration broke php-fpm?"
|
||||
|
@ -279,20 +266,17 @@ ynh_remove_fpm_config () {
|
|||
phpversion="${phpversion:-$YNH_DEFAULT_PHP_VERSION}"
|
||||
|
||||
# Assume default PHP files if not set
|
||||
if [ -z "$fpm_config_dir" ]
|
||||
then
|
||||
if [ -z "$fpm_config_dir" ]; then
|
||||
fpm_config_dir="/etc/php/$YNH_DEFAULT_PHP_VERSION/fpm"
|
||||
fpm_service="php$YNH_DEFAULT_PHP_VERSION-fpm"
|
||||
fi
|
||||
|
||||
ynh_secure_remove --file="$fpm_config_dir/pool.d/$app.conf"
|
||||
if [ -e $fpm_config_dir/conf.d/20-$app.ini ]
|
||||
then
|
||||
if [ -e $fpm_config_dir/conf.d/20-$app.ini ]; then
|
||||
ynh_secure_remove --file="$fpm_config_dir/conf.d/20-$app.ini"
|
||||
fi
|
||||
|
||||
if [ $dedicated_service -eq 1 ]
|
||||
then
|
||||
if [ $dedicated_service -eq 1 ]; then
|
||||
# Remove the dedicated service PHP-FPM service for the app
|
||||
ynh_remove_systemd_config --service=$fpm_service
|
||||
# Remove the global PHP-FPM conf
|
||||
|
@ -304,8 +288,7 @@ ynh_remove_fpm_config () {
|
|||
fi
|
||||
|
||||
# If the PHP version used is not the default version for YunoHost
|
||||
if [ "$phpversion" != "$YNH_DEFAULT_PHP_VERSION" ]
|
||||
then
|
||||
if [ "$phpversion" != "$YNH_DEFAULT_PHP_VERSION" ]; then
|
||||
# Remove this specific version of PHP
|
||||
ynh_remove_php
|
||||
fi
|
||||
|
@ -330,37 +313,12 @@ ynh_install_php () {
|
|||
ynh_handle_getopts_args "$@"
|
||||
package=${package:-}
|
||||
|
||||
# Store phpversion into the config of this app
|
||||
ynh_app_setting_set $app phpversion $phpversion
|
||||
|
||||
if [ "$phpversion" == "$YNH_DEFAULT_PHP_VERSION" ]
|
||||
then
|
||||
if [ "$phpversion" == "$YNH_DEFAULT_PHP_VERSION" ]; then
|
||||
ynh_die --message="Do not use ynh_install_php to install php$YNH_DEFAULT_PHP_VERSION"
|
||||
fi
|
||||
|
||||
# Create the file if doesn't exist already
|
||||
touch /etc/php/ynh_app_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"
|
||||
ynh_install_app_dependencies "$package"
|
||||
ynh_app_setting_set --app=$app --key=phpversion --value=$specific_php_version
|
||||
}
|
||||
|
||||
# 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.
|
||||
ynh_remove_php () {
|
||||
# Get the version of PHP used by this app
|
||||
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
|
||||
ynh_remove_app_dependencies
|
||||
}
|
||||
|
||||
# Define the values to configure PHP-FPM
|
||||
|
@ -435,38 +365,30 @@ ynh_get_scalable_phpfpm () {
|
|||
usage=${usage,,}
|
||||
print=${print:-0}
|
||||
|
||||
if [ "$footprint" = "low" ]
|
||||
then
|
||||
if [ "$footprint" = "low" ]; then
|
||||
footprint=20
|
||||
elif [ "$footprint" = "medium" ]
|
||||
then
|
||||
elif [ "$footprint" = "medium" ]; then
|
||||
footprint=35
|
||||
elif [ "$footprint" = "high" ]
|
||||
then
|
||||
elif [ "$footprint" = "high" ]; then
|
||||
footprint=50
|
||||
fi
|
||||
|
||||
# Define the factor to determine min_spare_servers
|
||||
# to avoid having too few children ready to start for heavy apps
|
||||
if [ $footprint -le 20 ]
|
||||
then
|
||||
if [ $footprint -le 20 ]; then
|
||||
min_spare_servers_factor=8
|
||||
elif [ $footprint -le 35 ]
|
||||
then
|
||||
elif [ $footprint -le 35 ]; then
|
||||
min_spare_servers_factor=5
|
||||
else
|
||||
min_spare_servers_factor=3
|
||||
fi
|
||||
|
||||
# Define the way the process manager handle child processes.
|
||||
if [ "$usage" = "low" ]
|
||||
then
|
||||
if [ "$usage" = "low" ]; then
|
||||
php_pm=ondemand
|
||||
elif [ "$usage" = "medium" ]
|
||||
then
|
||||
elif [ "$usage" = "medium" ]; then
|
||||
php_pm=dynamic
|
||||
elif [ "$usage" = "high" ]
|
||||
then
|
||||
elif [ "$usage" = "high" ]; then
|
||||
php_pm=static
|
||||
else
|
||||
ynh_die --message="Does not recognize '$usage' as an usage value."
|
||||
|
@ -477,8 +399,7 @@ ynh_get_scalable_phpfpm () {
|
|||
|
||||
at_least_one() {
|
||||
# Do not allow value below 1
|
||||
if [ $1 -le 0 ]
|
||||
then
|
||||
if [ $1 -le 0 ]; then
|
||||
echo 1
|
||||
else
|
||||
echo $1
|
||||
|
@ -491,8 +412,7 @@ ynh_get_scalable_phpfpm () {
|
|||
php_max_children=$(($max_ram / 2 / $footprint))
|
||||
# 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
|
||||
if [ "$php_pm" = "static" ]
|
||||
then
|
||||
if [ "$php_pm" = "static" ]; then
|
||||
php_max_children=$(($php_max_children / 2))
|
||||
fi
|
||||
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.
|
||||
local core_number=$(nproc)
|
||||
local max_proc=$(($core_number * 4))
|
||||
if [ $php_max_children -gt $max_proc ]
|
||||
then
|
||||
if [ $php_max_children -gt $max_proc ]; then
|
||||
php_max_children=$max_proc
|
||||
fi
|
||||
|
||||
|
@ -511,8 +430,7 @@ ynh_get_scalable_phpfpm () {
|
|||
php_max_children=$php_forced_max_children
|
||||
fi
|
||||
|
||||
if [ "$php_pm" = "dynamic" ]
|
||||
then
|
||||
if [ "$php_pm" = "dynamic" ]; then
|
||||
# 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=$(at_least_one $php_min_spare_servers)
|
||||
|
@ -528,30 +446,25 @@ ynh_get_scalable_phpfpm () {
|
|||
php_start_servers=0
|
||||
fi
|
||||
|
||||
if [ $print -eq 1 ]
|
||||
then
|
||||
ynh_debug --message="Footprint=${footprint}Mb by pool."
|
||||
ynh_debug --message="Process manager=$php_pm"
|
||||
ynh_debug --message="Max RAM=${max_ram}Mb"
|
||||
if [ "$php_pm" != "static" ]
|
||||
then
|
||||
ynh_debug --message="\nMax estimated footprint=$(( $php_max_children * $footprint ))"
|
||||
ynh_debug --message="Min estimated footprint=$(( $php_min_spare_servers * $footprint ))"
|
||||
if [ $print -eq 1 ]; then
|
||||
ynh_print_warn --message="Footprint=${footprint}Mb by pool."
|
||||
ynh_print_warn --message="Process manager=$php_pm"
|
||||
ynh_print_warn --message="Max RAM=${max_ram}Mb"
|
||||
if [ "$php_pm" != "static" ]; then
|
||||
ynh_print_warn --message="\nMax estimated footprint=$(($php_max_children * $footprint))"
|
||||
ynh_print_warn --message="Min estimated footprint=$(($php_min_spare_servers * $footprint))"
|
||||
fi
|
||||
if [ "$php_pm" = "dynamic" ]
|
||||
then
|
||||
ynh_debug --message="Estimated average footprint=$(( $php_max_spare_servers * $footprint ))"
|
||||
elif [ "$php_pm" = "static" ]
|
||||
then
|
||||
ynh_debug --message="Estimated footprint=$(( $php_max_children * $footprint ))"
|
||||
if [ "$php_pm" = "dynamic" ]; then
|
||||
ynh_print_warn --message="Estimated average footprint=$(($php_max_spare_servers * $footprint))"
|
||||
elif [ "$php_pm" = "static" ]; then
|
||||
ynh_print_warn --message="Estimated footprint=$(($php_max_children * $footprint))"
|
||||
fi
|
||||
ynh_debug --message="\nRaw php-fpm values:"
|
||||
ynh_debug --message="pm.max_children = $php_max_children"
|
||||
if [ "$php_pm" = "dynamic" ]
|
||||
then
|
||||
ynh_debug --message="pm.start_servers = $php_start_servers"
|
||||
ynh_debug --message="pm.min_spare_servers = $php_min_spare_servers"
|
||||
ynh_debug --message="pm.max_spare_servers = $php_max_spare_servers"
|
||||
ynh_print_warn --message="\nRaw php-fpm values:"
|
||||
ynh_print_warn --message="pm.max_children = $php_max_children"
|
||||
if [ "$php_pm" = "dynamic" ]; then
|
||||
ynh_print_warn --message="pm.start_servers = $php_start_servers"
|
||||
ynh_print_warn --message="pm.min_spare_servers = $php_min_spare_servers"
|
||||
ynh_print_warn --message="pm.max_spare_servers = $php_max_spare_servers"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
|
|
@ -46,8 +46,7 @@ ynh_psql_execute_as_root() {
|
|||
ynh_handle_getopts_args "$@"
|
||||
database="${database:-}"
|
||||
|
||||
if [ -n "$database" ]
|
||||
then
|
||||
if [ -n "$database" ]; then
|
||||
database="--database=$database"
|
||||
fi
|
||||
|
||||
|
@ -72,8 +71,7 @@ ynh_psql_execute_file_as_root() {
|
|||
ynh_handle_getopts_args "$@"
|
||||
database="${database:-}"
|
||||
|
||||
if [ -n "$database" ]
|
||||
then
|
||||
if [ -n "$database" ]; then
|
||||
database="--database=$database"
|
||||
fi
|
||||
|
||||
|
@ -175,8 +173,7 @@ ynh_psql_user_exists() {
|
|||
# Manage arguments with getopts
|
||||
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"
|
||||
then
|
||||
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
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
@ -198,8 +195,7 @@ ynh_psql_database_exists() {
|
|||
# Manage arguments with getopts
|
||||
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"
|
||||
then
|
||||
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
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
@ -269,16 +265,14 @@ ynh_psql_remove_db() {
|
|||
# Manage arguments with getopts
|
||||
ynh_handle_getopts_args "$@"
|
||||
|
||||
if ynh_psql_database_exists --database=$db_name
|
||||
then # Check if the database exists
|
||||
if ynh_psql_database_exists --database=$db_name; then # Check if the database exists
|
||||
ynh_psql_drop_db $db_name # Remove the database
|
||||
else
|
||||
ynh_print_warn --message="Database $db_name not found"
|
||||
fi
|
||||
|
||||
# Remove psql user if it exists
|
||||
if ynh_psql_user_exists --user=$db_user
|
||||
then
|
||||
if ynh_psql_user_exists --user=$db_user; then
|
||||
ynh_psql_drop_user $db_user
|
||||
else
|
||||
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
|
||||
# and configure a few things
|
||||
if [ ! -f "$PSQL_ROOT_PWD_FILE" ]
|
||||
then
|
||||
if [ ! -f "$PSQL_ROOT_PWD_FILE" ]; then
|
||||
local pg_hba=/etc/postgresql/$PSQL_VERSION/main/pg_hba.conf
|
||||
|
||||
local psql_root_password="$(ynh_string_random)"
|
||||
|
|
|
@ -76,8 +76,7 @@ ynh_app_setting_delete() {
|
|||
#
|
||||
# [internal]
|
||||
#
|
||||
ynh_app_setting()
|
||||
{
|
||||
ynh_app_setting() {
|
||||
set +o xtrace # set +x
|
||||
ACTION="$1" APP="$2" KEY="$3" VALUE="${4:-}" python3 - <<EOF
|
||||
import os, yaml, sys
|
||||
|
|
|
@ -45,8 +45,7 @@ ynh_remove_systemd_config () {
|
|||
local service="${service:-$app}"
|
||||
|
||||
local finalsystemdconf="/etc/systemd/system/$service.service"
|
||||
if [ -e "$finalsystemdconf" ]
|
||||
then
|
||||
if [ -e "$finalsystemdconf" ]; then
|
||||
ynh_systemd_action --service_name=$service --action=stop
|
||||
systemctl disable $service --quiet
|
||||
ynh_secure_remove --file="$finalsystemdconf"
|
||||
|
@ -85,18 +84,15 @@ ynh_systemd_action() {
|
|||
timeout=${timeout:-300}
|
||||
|
||||
# Manage case of service already stopped
|
||||
if [ "$action" == "stop" ] && ! systemctl is-active --quiet $service_name
|
||||
then
|
||||
if [ "$action" == "stop" ] && ! systemctl is-active --quiet $service_name; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Start to read the log
|
||||
if [[ -n "$line_match" ]]
|
||||
then
|
||||
if [[ -n "$line_match" ]]; then
|
||||
local templog="$(mktemp)"
|
||||
# Following the starting of the app in its log
|
||||
if [ "$log_path" == "systemd" ]
|
||||
then
|
||||
if [ "$log_path" == "systemd" ]; then
|
||||
# Read the systemd journal
|
||||
journalctl --unit=$service_name --follow --since=-0 --quiet >"$templog" &
|
||||
# Get the PID of the journalctl command
|
||||
|
@ -115,13 +111,11 @@ ynh_systemd_action() {
|
|||
fi
|
||||
|
||||
# If the service fails to perform the action
|
||||
if ! systemctl $action $service_name
|
||||
then
|
||||
if ! systemctl $action $service_name; then
|
||||
# Show syslog for this service
|
||||
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 [ -e "$log_path" ]
|
||||
then
|
||||
if [ -e "$log_path" ]; then
|
||||
ynh_exec_err tail --lines=$length "$log_path"
|
||||
fi
|
||||
ynh_clean_check_starting
|
||||
|
@ -129,15 +123,12 @@ ynh_systemd_action() {
|
|||
fi
|
||||
|
||||
# Start the timeout and try to find line_match
|
||||
if [[ -n "${line_match:-}" ]]
|
||||
then
|
||||
if [[ -n "${line_match:-}" ]]; then
|
||||
set +x
|
||||
local i=0
|
||||
for i in $(seq 1 $timeout)
|
||||
do
|
||||
for i in $(seq 1 $timeout); do
|
||||
# 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"
|
||||
then
|
||||
if grep --extended-regexp --quiet "$line_match" "$templog"; then
|
||||
ynh_print_info --message="The service $service_name has correctly executed the action ${action}."
|
||||
break
|
||||
fi
|
||||
|
@ -150,13 +141,11 @@ ynh_systemd_action() {
|
|||
if [ $i -ge 3 ]; then
|
||||
echo "" >&2
|
||||
fi
|
||||
if [ $i -eq $timeout ]
|
||||
then
|
||||
if [ $i -eq $timeout ]; then
|
||||
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_exec_warn journalctl --quiet --no-hostname --no-pager --lines=$length --unit=$service_name
|
||||
if [ -e "$log_path" ]
|
||||
then
|
||||
if [ -e "$log_path" ]; then
|
||||
ynh_print_warn --message="\-\-\-"
|
||||
ynh_exec_warn tail --lines=$length "$log_path"
|
||||
fi
|
||||
|
@ -171,13 +160,11 @@ ynh_systemd_action() {
|
|||
#
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
ynh_clean_check_starting() {
|
||||
if [ -n "${pid_tail:-}" ]
|
||||
then
|
||||
if [ -n "${pid_tail:-}" ]; then
|
||||
# Stop the execution of tail.
|
||||
kill -SIGTERM $pid_tail 2>&1
|
||||
fi
|
||||
if [ -n "${templog:-}" ]
|
||||
then
|
||||
if [ -n "${templog:-}" ]; then
|
||||
ynh_secure_remove --file="$templog" 2>&1
|
||||
fi
|
||||
}
|
||||
|
|
|
@ -123,16 +123,14 @@ ynh_system_user_create () {
|
|||
home_dir="${home_dir:-}"
|
||||
groups="${groups:-}"
|
||||
|
||||
if ! ynh_system_user_exists "$username" # Check if the user exists on the system
|
||||
then # If the user doesn't exist
|
||||
if [ -n "$home_dir" ]
|
||||
then # If a home dir is mentioned
|
||||
if ! ynh_system_user_exists "$username"; then # Check if the user exists on the system
|
||||
# If the user doesn't exist
|
||||
if [ -n "$home_dir" ]; then # If a home dir is mentioned
|
||||
local user_home_dir="--home-dir $home_dir"
|
||||
else
|
||||
local user_home_dir="--no-create-home"
|
||||
fi
|
||||
if [ $use_shell -eq 1 ]
|
||||
then # If we want a shell for the user
|
||||
if [ $use_shell -eq 1 ]; then # If we want a shell for the user
|
||||
local shell="" # Use default shell
|
||||
else
|
||||
local shell="--shell /usr/sbin/nologin"
|
||||
|
@ -141,8 +139,7 @@ ynh_system_user_create () {
|
|||
fi
|
||||
|
||||
local group
|
||||
for group in $groups
|
||||
do
|
||||
for group in $groups; do
|
||||
usermod -a -G "$group" "$username"
|
||||
done
|
||||
}
|
||||
|
@ -162,16 +159,14 @@ ynh_system_user_delete () {
|
|||
ynh_handle_getopts_args "$@"
|
||||
|
||||
# Check if the user exists on the system
|
||||
if ynh_system_user_exists "$username"
|
||||
then
|
||||
if ynh_system_user_exists "$username"; then
|
||||
deluser $username
|
||||
else
|
||||
ynh_print_warn --message="The user $username was not found"
|
||||
fi
|
||||
|
||||
# Check if the group exists on the system
|
||||
if ynh_system_group_exists "$username"
|
||||
then
|
||||
if ynh_system_group_exists "$username"; then
|
||||
delgroup $username
|
||||
fi
|
||||
}
|
||||
|
|
|
@ -133,15 +133,13 @@ ynh_setup_source () {
|
|||
src_filename="${source_id}.${src_format}"
|
||||
fi
|
||||
|
||||
|
||||
# (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}"
|
||||
|
||||
mkdir -p /var/cache/yunohost/download/${YNH_APP_ID}/
|
||||
src_filename="/var/cache/yunohost/download/${YNH_APP_ID}/${src_filename}"
|
||||
|
||||
if test -e "$local_src"
|
||||
then
|
||||
if test -e "$local_src"; then
|
||||
cp $local_src $src_filename
|
||||
else
|
||||
[ -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
|
||||
# Assuming $dest_dir already exists
|
||||
rm -rf /var/cache/yunohost/files_to_keep_during_setup_source/
|
||||
if [ -n "$keep" ] && [ -e "$dest_dir" ]
|
||||
then
|
||||
if [ -n "$keep" ] && [ -e "$dest_dir" ]; then
|
||||
local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID}
|
||||
mkdir -p $keep_dir
|
||||
local stuff_to_keep
|
||||
for stuff_to_keep in $keep
|
||||
do
|
||||
if [ -e "$dest_dir/$stuff_to_keep" ]
|
||||
then
|
||||
for stuff_to_keep in $keep; do
|
||||
if [ -e "$dest_dir/$stuff_to_keep" ]; then
|
||||
mkdir --parents "$(dirname "$keep_dir/$stuff_to_keep")"
|
||||
cp --archive "$dest_dir/$stuff_to_keep" "$keep_dir/$stuff_to_keep"
|
||||
fi
|
||||
|
@ -180,20 +175,16 @@ ynh_setup_source () {
|
|||
# Extract source into the app dir
|
||||
mkdir --parents "$dest_dir"
|
||||
|
||||
if [ -n "${final_path:-}" ] && [ "$dest_dir" == "$final_path" ]
|
||||
then
|
||||
if [ -n "${final_path:-}" ] && [ "$dest_dir" == "$final_path" ]; then
|
||||
_ynh_apply_default_permissions $dest_dir
|
||||
fi
|
||||
|
||||
if ! "$src_extract"
|
||||
then
|
||||
if ! "$src_extract"; then
|
||||
mv $src_filename $dest_dir
|
||||
elif [ "$src_format" = "zip" ]
|
||||
then
|
||||
elif [ "$src_format" = "zip" ]; then
|
||||
# Zip format
|
||||
# Using of a temp directory, because unzip doesn't manage --strip-components
|
||||
if $src_in_subdir
|
||||
then
|
||||
if $src_in_subdir; then
|
||||
local tmp_dir=$(mktemp --directory)
|
||||
unzip -quo $src_filename -d "$tmp_dir"
|
||||
cp --archive $tmp_dir/*/. "$dest_dir"
|
||||
|
@ -204,18 +195,15 @@ ynh_setup_source () {
|
|||
ynh_secure_remove --file="$src_filename"
|
||||
else
|
||||
local strip=""
|
||||
if [ "$src_in_subdir" != "false" ]
|
||||
then
|
||||
if [ "$src_in_subdir" == "true" ]
|
||||
then
|
||||
if [ "$src_in_subdir" != "false" ]; then
|
||||
if [ "$src_in_subdir" == "true" ]; then
|
||||
local sub_dirs=1
|
||||
else
|
||||
local sub_dirs="$src_in_subdir"
|
||||
fi
|
||||
strip="--strip-components $sub_dirs"
|
||||
fi
|
||||
if [[ "$src_format" =~ ^tar.gz|tar.bz2|tar.xz$ ]]
|
||||
then
|
||||
if [[ "$src_format" =~ ^tar.gz|tar.bz2|tar.xz$ ]]; then
|
||||
tar --extract --file=$src_filename --directory="$dest_dir" $strip
|
||||
else
|
||||
ynh_die --message="Archive format unrecognized."
|
||||
|
@ -224,17 +212,16 @@ ynh_setup_source () {
|
|||
fi
|
||||
|
||||
# Apply patches
|
||||
if [ -d "$YNH_APP_BASEDIR/sources/patches/" ]
|
||||
then
|
||||
if [ -d "$YNH_APP_BASEDIR/sources/patches/" ]; then
|
||||
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" ))
|
||||
then
|
||||
(cd "$dest_dir"
|
||||
for p in $patches_folder/${source_id}-*.patch
|
||||
do
|
||||
if (($(find $patches_folder -type f -name "${source_id}-*.patch" 2>/dev/null | wc --lines) > "0")); then
|
||||
(
|
||||
cd "$dest_dir"
|
||||
for p in $patches_folder/${source_id}-*.patch; do
|
||||
echo $p
|
||||
patch --strip=1 <$p
|
||||
done) || ynh_die --message="Unable to apply patches"
|
||||
done
|
||||
) || ynh_die --message="Unable to apply patches"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -245,14 +232,11 @@ ynh_setup_source () {
|
|||
|
||||
# Keep files to be backup/restored at the end of the helper
|
||||
# Assuming $dest_dir already exists
|
||||
if [ -n "$keep" ]
|
||||
then
|
||||
if [ -n "$keep" ]; then
|
||||
local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID}
|
||||
local stuff_to_keep
|
||||
for stuff_to_keep in $keep
|
||||
do
|
||||
if [ -e "$keep_dir/$stuff_to_keep" ]
|
||||
then
|
||||
for stuff_to_keep in $keep; do
|
||||
if [ -e "$keep_dir/$stuff_to_keep" ]; then
|
||||
mkdir --parents "$(dirname "$dest_dir/$stuff_to_keep")"
|
||||
cp --archive "$keep_dir/$stuff_to_keep" "$dest_dir/$stuff_to_keep"
|
||||
fi
|
||||
|
@ -290,12 +274,10 @@ ynh_local_curl () {
|
|||
# Concatenate all other arguments with '&' to prepare POST data
|
||||
local POST_data=""
|
||||
local arg=""
|
||||
for arg in "${@:2}"
|
||||
do
|
||||
for arg in "${@:2}"; do
|
||||
POST_data="${POST_data}${arg}&"
|
||||
done
|
||||
if [ -n "$POST_data" ]
|
||||
then
|
||||
if [ -n "$POST_data" ]; then
|
||||
# Add --data arg and remove the last character, which is an unecessary '&'
|
||||
POST_data="--data ${POST_data::-1}"
|
||||
fi
|
||||
|
@ -423,8 +405,7 @@ ynh_replace_vars () {
|
|||
ynh_handle_getopts_args "$@"
|
||||
|
||||
# Replace specific YunoHost variables
|
||||
if test -n "${path_url:-}"
|
||||
then
|
||||
if test -n "${path_url:-}"; then
|
||||
# path_url_slash_less is path_url, or a blank value if path_url is only '/'
|
||||
local path_url_slash_less=${path_url%/}
|
||||
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
|
||||
local delimit=@
|
||||
for one_var in "${uniques_vars[@]}"
|
||||
do
|
||||
for one_var in "${uniques_vars[@]}"; do
|
||||
# Validate that one_var is indeed defined
|
||||
# -v checks if the variable is defined, for example:
|
||||
# -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
|
||||
local line_number=1
|
||||
if [[ -n "$after" ]];
|
||||
then
|
||||
if [[ -n "$after" ]]; then
|
||||
line_number=$(grep -n $after $file | cut -d: -f1)
|
||||
if [[ -z "$line_number" ]];
|
||||
then
|
||||
if [[ -z "$line_number" ]]; then
|
||||
set -o xtrace # set -x
|
||||
return 1
|
||||
fi
|
||||
|
@ -564,7 +542,7 @@ ynh_read_var_in_file() {
|
|||
fi
|
||||
|
||||
# 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}"
|
||||
if [[ "$first_char" == '"' ]]; then
|
||||
|
@ -603,11 +581,9 @@ ynh_write_var_in_file() {
|
|||
|
||||
# Get the line number after which we search for the variable
|
||||
local line_number=1
|
||||
if [[ -n "$after" ]];
|
||||
then
|
||||
if [[ -n "$after" ]]; then
|
||||
line_number=$(grep -n $after $file | cut -d: -f1)
|
||||
if [[ -z "$line_number" ]];
|
||||
then
|
||||
if [[ -z "$line_number" ]]; then
|
||||
set -o xtrace # set -x
|
||||
return 1
|
||||
fi
|
||||
|
@ -644,7 +620,7 @@ ynh_write_var_in_file() {
|
|||
fi
|
||||
|
||||
# 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="$(echo "$endline" | sed 's/\\/\\\\/g')"
|
||||
value="$(echo "$value" | sed 's/\\/\\\\/g')"
|
||||
|
@ -673,7 +649,6 @@ ynh_write_var_in_file() {
|
|||
set -o xtrace # set -x
|
||||
}
|
||||
|
||||
|
||||
# Render templates with Jinja2
|
||||
#
|
||||
# [internal]
|
||||
|
@ -704,6 +679,27 @@ ynh_get_debian_release () {
|
|||
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
|
||||
#
|
||||
# usage: ynh_secure_remove --file=path_to_remove
|
||||
|
@ -719,31 +715,18 @@ ynh_secure_remove () {
|
|||
ynh_handle_getopts_args "$@"
|
||||
set +o xtrace # set +x
|
||||
|
||||
local forbidden_path=" \
|
||||
/var/www \
|
||||
/home/yunohost.app"
|
||||
|
||||
if [ $# -ge 2 ]
|
||||
then
|
||||
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."
|
||||
fi
|
||||
|
||||
if [[ -z "$file" ]]
|
||||
then
|
||||
if [[ -z "$file" ]]; then
|
||||
ynh_print_warn --message="ynh_secure_remove called with empty argument, ignoring."
|
||||
elif [[ "$forbidden_path" =~ "$file" \
|
||||
# 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
|
||||
elif [[ ! -e $file ]]; then
|
||||
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
|
||||
|
||||
set -o xtrace # set -x
|
||||
|
@ -796,8 +779,7 @@ ynh_app_upstream_version () {
|
|||
ynh_handle_getopts_args "$@"
|
||||
manifest="${manifest:-}"
|
||||
|
||||
if [[ "$manifest" != "" ]] && [[ -e "$manifest" ]];
|
||||
then
|
||||
if [[ "$manifest" != "" ]] && [[ -e "$manifest" ]]; then
|
||||
version_key_=$(ynh_read_manifest --manifest="$manifest" --manifest_key="version")
|
||||
else
|
||||
version_key_=$YNH_APP_MANIFEST_VERSION
|
||||
|
@ -845,8 +827,7 @@ ynh_app_package_version () {
|
|||
ynh_check_app_version_changed() {
|
||||
local return_value=${YNH_APP_UPGRADE_TYPE}
|
||||
|
||||
if [ "$return_value" == "UPGRADE_FULL" ] || [ "$return_value" == "UPGRADE_FORCED" ] || [ "$return_value" == "DOWNGRADE_FORCED" ]
|
||||
then
|
||||
if [ "$return_value" == "UPGRADE_FULL" ] || [ "$return_value" == "UPGRADE_FORCED" ] || [ "$return_value" == "DOWNGRADE_FORCED" ]; then
|
||||
return_value="UPGRADE_APP"
|
||||
fi
|
||||
|
||||
|
@ -884,8 +865,7 @@ ynh_compare_current_package_version() {
|
|||
local current_version=$YNH_APP_CURRENT_VERSION
|
||||
|
||||
# Check the syntax of the versions
|
||||
if [[ ! $version =~ '~ynh' ]] || [[ ! $current_version =~ '~ynh' ]]
|
||||
then
|
||||
if [[ ! $version =~ '~ynh' ]] || [[ ! $current_version =~ '~ynh' ]]; then
|
||||
ynh_die --message="Invalid argument for version."
|
||||
fi
|
||||
|
||||
|
@ -920,13 +900,11 @@ _ynh_apply_default_permissions() {
|
|||
|
||||
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
|
||||
then
|
||||
if [ -z "$ynh_requirement" ] || [ "$ynh_requirement" == "null" ] || dpkg --compare-versions $ynh_requirement ge 4.2; then
|
||||
chmod o-rwx $target
|
||||
chmod g-w $target
|
||||
chown -R root:root $target
|
||||
if ynh_system_user_exists $app
|
||||
then
|
||||
if ynh_system_user_exists $app; then
|
||||
chown $app:$app $target
|
||||
fi
|
||||
fi
|
||||
|
|
|
@ -10,8 +10,7 @@ yunohost tools shell -c "from yunohost.regenconf import manually_modified_files;
|
|||
|
||||
ynh_backup --src_path="./manually_modified_files_list"
|
||||
|
||||
for file in $(cat ./manually_modified_files_list)
|
||||
do
|
||||
for file in $(cat ./manually_modified_files_list); do
|
||||
[[ -e $file ]] && ynh_backup --src_path="$file"
|
||||
done
|
||||
|
||||
|
|
|
@ -98,8 +98,7 @@ EOF
|
|||
# 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
|
||||
# - 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
|
||||
then
|
||||
if ls -l /etc/yunohost/dyndns/K*.private 2>/dev/null; then
|
||||
cat >$pending_dir/etc/cron.d/yunohost-dyndns <<EOF
|
||||
SHELL=/bin/bash
|
||||
*/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)
|
||||
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]
|
||||
ConditionCapability=CAP_SYS_TIME
|
||||
ConditionVirtualization=!container
|
||||
" > ${pending_dir}/etc/systemd/system/ntp.service.d/ynh-override.conf
|
||||
EOF
|
||||
|
||||
# Make nftable conflict with yunohost-firewall
|
||||
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
|
||||
|
||||
if [[ "$(yunohost settings get 'security.experimental.enabled')" == "True" ]]
|
||||
then
|
||||
if [[ "$(yunohost settings get 'security.experimental.enabled')" == "True" ]]; then
|
||||
cp proc-hidepid.service ${pending_dir}/etc/systemd/system/proc-hidepid.service
|
||||
else
|
||||
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/ssowat
|
||||
|
||||
for USER in $(yunohost user list --quiet --output-as json | jq -r '.users | .[] | .username')
|
||||
do
|
||||
for USER in $(yunohost user list --quiet --output-as json | jq -r '.users | .[] | .username'); do
|
||||
[ ! -e "/home/$USER" ] || setfacl -m g:all_users:--- /home/$USER
|
||||
done
|
||||
|
||||
|
@ -205,17 +202,18 @@ do_post_regen() {
|
|||
grep -q '^sftp.app:' /etc/group || groupadd sftp.app
|
||||
|
||||
# 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" =~ "login.conf.d/ynh-override.conf" ]] || systemctl daemon-reload
|
||||
if [[ "$regen_conf_files" =~ "yunoprompt.service" ]]
|
||||
then
|
||||
if [[ "$regen_conf_files" =~ "yunoprompt.service" ]]; then
|
||||
systemctl daemon-reload
|
||||
action=$([[ -e /etc/systemd/system/yunoprompt.service ]] && echo 'enable' || echo 'disable')
|
||||
systemctl $action yunoprompt --quiet --now
|
||||
fi
|
||||
if [[ "$regen_conf_files" =~ "proc-hidepid.service" ]]
|
||||
then
|
||||
if [[ "$regen_conf_files" =~ "proc-hidepid.service" ]]; then
|
||||
systemctl daemon-reload
|
||||
action=$([[ -e /etc/systemd/system/proc-hidepid.service ]] && echo 'enable' || echo 'disable')
|
||||
systemctl $action proc-hidepid --quiet --now
|
||||
|
|
|
@ -110,8 +110,7 @@ do_post_regen() {
|
|||
current_local_ca_domain=$(openssl x509 -in $ynh_ca -text | tr ',' '\n' | grep Issuer | awk '{print $4}')
|
||||
main_domain=$(cat /etc/yunohost/current_host)
|
||||
|
||||
if [[ "$current_local_ca_domain" != "$main_domain" ]]
|
||||
then
|
||||
if [[ "$current_local_ca_domain" != "$main_domain" ]]; then
|
||||
regen_local_ca $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
|
||||
|
|
|
@ -62,8 +62,7 @@ EOF
|
|||
# We don't use mkhomedir_helper because 'admin' may not be recognized
|
||||
# when this script is ran in a chroot (e.g. ISO install)
|
||||
# We also refer to admin as uid 1007 for the same reason
|
||||
if [ ! -d /home/admin ]
|
||||
then
|
||||
if [ ! -d /home/admin ]; then
|
||||
cp -r /etc/skel /home/admin
|
||||
chown -R 1007:1007 /home/admin
|
||||
fi
|
||||
|
@ -97,8 +96,8 @@ do_pre_regen() {
|
|||
|
||||
# Define if we need to migrate from hdb to mdb
|
||||
curr_backend=$(grep '^database' /etc/ldap/slapd.conf 2>/dev/null | awk '{print $2}')
|
||||
if [ -e /etc/ldap/slapd.conf ] && [ -n "$curr_backend" ] && \
|
||||
[ $curr_backend != 'mdb' ]; then
|
||||
if [ -e /etc/ldap/slapd.conf ] && [ -n "$curr_backend" ] \
|
||||
&& [ $curr_backend != 'mdb' ]; then
|
||||
backup_dir="/var/backups/dc=yunohost,dc=org-${curr_backend}-$(date +%s)"
|
||||
mkdir -p "$backup_dir"
|
||||
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/
|
||||
|
||||
# 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$"
|
||||
then
|
||||
if echo "$regen_conf_files" | sed 's/,/\n/g' | grep -q "^/etc/systemd/system/slapd.service.d/ynh-override.conf$"; then
|
||||
systemctl daemon-reload
|
||||
systemctl restart slapd
|
||||
sleep 3
|
||||
fi
|
||||
|
||||
# For some reason, old setups don't have the admins group defined...
|
||||
if ! slapcat | grep -q 'cn=admins,ou=groups,dc=yunohost,dc=org'
|
||||
then
|
||||
if ! slapcat | grep -q 'cn=admins,ou=groups,dc=yunohost,dc=org'; then
|
||||
slapadd -F /etc/ldap/slapd.d -b dc=yunohost,dc=org <<< \
|
||||
"dn: cn=admins,ou=groups,dc=yunohost,dc=org
|
||||
cn: admins
|
||||
|
@ -187,8 +184,7 @@ objectClass: top"
|
|||
# wait a maximum time of 5 minutes
|
||||
# yes, force-reload behave like a restart
|
||||
number_of_wait=0
|
||||
while ! su admin -c '' && ((number_of_wait < 60))
|
||||
do
|
||||
while ! su admin -c '' && ((number_of_wait < 60)); do
|
||||
sleep 5
|
||||
((number_of_wait += 1))
|
||||
done
|
||||
|
|
|
@ -8,8 +8,7 @@ do_pre_regen() {
|
|||
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"
|
||||
for package in $packages_to_refuse_from_sury
|
||||
do
|
||||
for package in $packages_to_refuse_from_sury; do
|
||||
echo "
|
||||
Package: $package
|
||||
Pin: origin \"packages.sury.org\"
|
||||
|
|
|
@ -32,8 +32,14 @@ do_init_regen() {
|
|||
cp "redirect_to_admin.conf" $nginx_conf_dir/default.d/
|
||||
|
||||
# Restart nginx if conf looks good, otherwise display error and exit unhappy
|
||||
nginx -t 2>/dev/null || { nginx -t; exit 1; }
|
||||
systemctl restart nginx || { journalctl --no-pager --lines=10 -u nginx >&2; exit 1; }
|
||||
nginx -t 2>/dev/null || {
|
||||
nginx -t
|
||||
exit 1
|
||||
}
|
||||
systemctl restart nginx || {
|
||||
journalctl --no-pager --lines=10 -u nginx >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
@ -51,8 +57,7 @@ do_pre_regen() {
|
|||
cp plain/* "$nginx_conf_dir"
|
||||
# remove the panel overlay if this is specified in settings
|
||||
panel_overlay=$(yunohost settings get 'ssowat.panel_overlay.enabled')
|
||||
if [ "$panel_overlay" == "false" ] || [ "$panel_overlay" == "False" ]
|
||||
then
|
||||
if [ "$panel_overlay" == "false" ] || [ "$panel_overlay" == "False" ]; then
|
||||
echo "#" >"${nginx_conf_dir}/yunohost_panel.conf.inc"
|
||||
fi
|
||||
|
||||
|
@ -88,8 +93,7 @@ do_pre_regen() {
|
|||
done
|
||||
|
||||
export webadmin_allowlist_enabled=$(yunohost settings get security.webadmin.allowlist.enabled)
|
||||
if [ "$webadmin_allowlist_enabled" == "True" ]
|
||||
then
|
||||
if [ "$webadmin_allowlist_enabled" == "True" ]; then
|
||||
export webadmin_allowlist=$(yunohost settings get security.webadmin.allowlist)
|
||||
fi
|
||||
ynh_render_template "yunohost_admin.conf.inc" "${nginx_conf_dir}/yunohost_admin.conf.inc"
|
||||
|
@ -131,8 +135,14 @@ do_post_regen() {
|
|||
done
|
||||
|
||||
# Reload nginx if conf looks good, otherwise display error and exit unhappy
|
||||
nginx -t 2>/dev/null || { nginx -t; exit 1; }
|
||||
pgrep nginx && systemctl reload nginx || { journalctl --no-pager --lines=10 -u nginx >&2; exit 1; }
|
||||
nginx -t 2>/dev/null || {
|
||||
nginx -t
|
||||
exit 1
|
||||
}
|
||||
pgrep nginx && systemctl reload nginx || {
|
||||
journalctl --no-pager --lines=10 -u nginx >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
do_$1_regen ${@:2}
|
||||
|
|
|
@ -29,8 +29,7 @@ do_pre_regen() {
|
|||
export relay_port=""
|
||||
export relay_user=""
|
||||
export relay_host="$(yunohost settings get 'smtp.relay.host')"
|
||||
if [ -n "${relay_host}" ]
|
||||
then
|
||||
if [ -n "${relay_host}" ]; then
|
||||
relay_port="$(yunohost settings get 'smtp.relay.port')"
|
||||
relay_user="$(yunohost settings get 'smtp.relay.user')"
|
||||
relay_password="$(yunohost settings get 'smtp.relay.password')"
|
||||
|
@ -69,8 +68,7 @@ do_pre_regen() {
|
|||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
if [ -e /etc/postfix/sasl_passwd ]
|
||||
then
|
||||
if [ -e /etc/postfix/sasl_passwd ]; then
|
||||
chmod 750 /etc/postfix/sasl_passwd*
|
||||
chown postfix:root /etc/postfix/sasl_passwd*
|
||||
fi
|
||||
|
|
|
@ -14,8 +14,7 @@ do_pre_regen() {
|
|||
do_post_regen() {
|
||||
regen_conf_files=$1
|
||||
|
||||
if [[ ! -d /var/lib/mysql/mysql ]]
|
||||
then
|
||||
if [[ ! -d /var/lib/mysql/mysql ]]; then
|
||||
# dpkg-reconfigure will initialize mysql (if it ain't already)
|
||||
# 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
|
||||
|
@ -33,8 +32,7 @@ do_post_regen() {
|
|||
# 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
|
||||
# Playing with enable/disable allows to recreate the proper symlinks.
|
||||
if [ ! -e /etc/systemd/system/mysql.service ]
|
||||
then
|
||||
if [ ! -e /etc/systemd/system/mysql.service ]; then
|
||||
systemctl stop mysql -q
|
||||
systemctl disable mysql -q
|
||||
systemctl disable mariadb -q
|
||||
|
|
|
@ -5,8 +5,7 @@ set -e
|
|||
_generate_config() {
|
||||
echo "domains:"
|
||||
echo " - yunohost.local"
|
||||
for domain in $YNH_DOMAINS
|
||||
do
|
||||
for domain in $YNH_DOMAINS; do
|
||||
# Only keep .local domains (don't keep
|
||||
[[ "$domain" =~ [^.]+\.[^.]+\.local$ ]] && echo "Subdomain $domain cannot be handled by Bonjour/Zeroconf/mDNS" >&2
|
||||
[[ "$domain" =~ ^[^.]+\.local$ ]] || continue
|
||||
|
@ -39,8 +38,7 @@ do_post_regen() {
|
|||
chown mdns:mdns /etc/yunohost/mdns.yml
|
||||
|
||||
# If we changed the systemd ynh-override conf
|
||||
if echo "$regen_conf_files" | sed 's/,/\n/g' | grep -q "^/etc/systemd/system/yunomdns.service$"
|
||||
then
|
||||
if echo "$regen_conf_files" | sed 's/,/\n/g' | grep -q "^/etc/systemd/system/yunomdns.service$"; then
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ do_pre_regen() {
|
|||
|
||||
# add domain conf files
|
||||
for domain in $YNH_DOMAINS; do
|
||||
[[ ! $domain =~ \.local$ ]] || continue
|
||||
export domain
|
||||
ynh_render_template "domain.tpl" "${dnsmasq_dir}/${domain}"
|
||||
done
|
||||
|
@ -40,8 +41,10 @@ do_pre_regen() {
|
|||
conf_files=$(ls -1 /etc/dnsmasq.d \
|
||||
| awk '/^[^\.]+\.[^\.]+.*$/ { print $1 }')
|
||||
for domain in $conf_files; do
|
||||
[[ $YNH_DOMAINS =~ $domain ]] \
|
||||
|| touch "${dnsmasq_dir}/${domain}"
|
||||
if [[ ! $YNH_DOMAINS =~ $domain ]] && [[ ! $domain =~ \.local$ ]]
|
||||
then
|
||||
touch "${dnsmasq_dir}/${domain}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
@ -50,10 +53,8 @@ do_post_regen() {
|
|||
|
||||
# Fuck it, those domain/search entries from dhclient are usually annoying
|
||||
# lying shit from the ISP trying to MiTM
|
||||
if grep -q -E "^ *(domain|search)" /run/resolvconf/resolv.conf
|
||||
then
|
||||
if grep -q -E "^ *(domain|search)" /run/resolvconf/interface/*.dhclient 2>/dev/null
|
||||
then
|
||||
if grep -q -E "^ *(domain|search)" /run/resolvconf/resolv.conf; 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
|
||||
fi
|
||||
|
||||
|
@ -71,8 +72,7 @@ do_post_regen() {
|
|||
[[ -n "$regen_conf_files" ]] || return
|
||||
|
||||
# Remove / disable services likely to conflict with dnsmasq
|
||||
for SERVICE in systemd-resolved bind9
|
||||
do
|
||||
for SERVICE in systemd-resolved bind9; do
|
||||
systemctl is-enabled $SERVICE &>/dev/null && systemctl disable $SERVICE 2>/dev/null
|
||||
systemctl is-active $SERVICE &>/dev/null && systemctl stop $SERVICE
|
||||
done
|
||||
|
|
|
@ -76,7 +76,7 @@ class AppDiagnoser(Diagnoser):
|
|||
for deprecated_helper in deprecated_helpers:
|
||||
if (
|
||||
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
|
||||
):
|
||||
|
|
|
@ -14,11 +14,11 @@ die() {
|
|||
|
||||
# Restore saved configuration and database
|
||||
[[ $state -ge 1 ]] \
|
||||
&& (rm -rf /etc/ldap/slapd.d &&
|
||||
mv "${TMPDIR}/slapd.d" /etc/ldap/slapd.d)
|
||||
&& (rm -rf /etc/ldap/slapd.d \
|
||||
&& mv "${TMPDIR}/slapd.d" /etc/ldap/slapd.d)
|
||||
[[ $state -ge 2 ]] \
|
||||
&& (rm -rf /var/lib/ldap &&
|
||||
mv "${TMPDIR}/ldap" /var/lib/ldap)
|
||||
&& (rm -rf /var/lib/ldap \
|
||||
&& mv "${TMPDIR}/ldap" /var/lib/ldap)
|
||||
chown -R openldap: /etc/ldap/slapd.d /var/lib/ldap
|
||||
|
||||
systemctl start slapd
|
||||
|
|
|
@ -5,8 +5,7 @@ ynh_abort_if_errors
|
|||
YNH_CWD="${YNH_BACKUP_DIR%/}/conf/manually_modified_files"
|
||||
cd "$YNH_CWD"
|
||||
|
||||
for file in $(cat ./manually_modified_files_list)
|
||||
do
|
||||
for file in $(cat ./manually_modified_files_list); do
|
||||
ynh_restore_file --origin_path="$file" --not_mandatory
|
||||
done
|
||||
|
||||
|
|
|
@ -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 {
|
||||
sieve = /var/mail/sievescript/%n/.dovecot.sieve
|
||||
sieve_dir = /var/mail/sievescript/%n/scripts/
|
||||
|
|
20
debian/changelog
vendored
20
debian/changelog
vendored
|
@ -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
|
||||
|
||||
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
|
||||
|
||||
- [enh] app helpers: Update n version ([#1347](https://github.com/YunoHost/yunohost/pull/1347))
|
||||
|
|
7
debian/postinst
vendored
7
debian/postinst
vendored
|
@ -11,8 +11,7 @@ do_configure() {
|
|||
if [ ! -f /etc/yunohost/installed ]; then
|
||||
# If apps/ is not empty, we're probably already installed in the past and
|
||||
# something funky happened ...
|
||||
if [ -d /etc/yunohost/apps/ ] && ls /etc/yunohost/apps/* >/dev/null 2>&1
|
||||
then
|
||||
if [ -d /etc/yunohost/apps/ ] && ls /etc/yunohost/apps/* >/dev/null 2>&1; then
|
||||
echo "Sounds like /etc/yunohost/installed mysteriously disappeared ... You should probably contact the Yunohost support ..."
|
||||
else
|
||||
bash /usr/share/yunohost/hooks/conf_regen/01-yunohost init
|
||||
|
@ -51,8 +50,8 @@ case "$1" in
|
|||
configure)
|
||||
do_configure
|
||||
;;
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
;;
|
||||
abort-upgrade | abort-remove | abort-deconfigure) ;;
|
||||
|
||||
*)
|
||||
echo "postinst called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
|
|
|
@ -78,7 +78,7 @@ re_app_instance_name = 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 = [
|
||||
|
@ -150,6 +150,9 @@ def app_info(app, full=False):
|
|||
absolute_app_name, _ = _parse_app_instance_name(app)
|
||||
ret["from_catalog"] = _load_apps_catalog()["apps"].get(absolute_app_name, {})
|
||||
ret["upgradable"] = _app_upgradable(ret)
|
||||
|
||||
ret["is_webapp"] = "domain" in settings and "path" in settings
|
||||
|
||||
ret["supports_change_url"] = os.path.exists(
|
||||
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))
|
||||
continue
|
||||
elif app_dict["upgradable"] == "yes" or force:
|
||||
new_app_src = app_dict["id"]
|
||||
new_app_src = app_dict["manifest"]["id"]
|
||||
else:
|
||||
logger.success(m18n.n("app_already_up_to_date", app=app_instance_name))
|
||||
continue
|
||||
|
|
|
@ -407,7 +407,7 @@ def is_unit_operation(
|
|||
if isinstance(value, IOBase):
|
||||
try:
|
||||
context[field] = value.name
|
||||
except:
|
||||
except Exception:
|
||||
context[field] = "IOBase"
|
||||
operation_logger = OperationLogger(op_key, related_to, args=context)
|
||||
|
||||
|
|
|
@ -474,7 +474,7 @@ def permission_create(
|
|||
protected=protected,
|
||||
sync_perm=sync_perm,
|
||||
)
|
||||
except:
|
||||
except Exception:
|
||||
permission_delete(permission, force=True)
|
||||
raise
|
||||
|
||||
|
|
|
@ -41,7 +41,13 @@ def clean():
|
|||
os.system("mkdir -p /etc/ssowat/")
|
||||
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:
|
||||
|
||||
|
@ -192,7 +198,10 @@ def test_legacy_app_install_main_domain():
|
|||
def test_app_from_catalog():
|
||||
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)
|
||||
assert main_domain in app_map_
|
||||
assert "/site" in app_map_[main_domain]
|
||||
|
|
|
@ -68,6 +68,7 @@ def test_repo_url_definition():
|
|||
assert _is_app_repo_url(
|
||||
"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 not _is_app_repo_url("github.com/YunoHost-Apps/foobar_ynh")
|
||||
|
|
|
@ -15,6 +15,7 @@ from yunohost.utils.config import (
|
|||
PathQuestion,
|
||||
BooleanQuestion,
|
||||
FileQuestion,
|
||||
evaluate_simple_js_expression,
|
||||
)
|
||||
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"
|
||||
|
||||
|
||||
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)
|
||||
|
|
|
@ -670,7 +670,7 @@ def user_import(operation_logger, csvfile, update=False, delete=False):
|
|||
|
||||
def to_list(str_list):
|
||||
L = str_list.split(",") if str_list else []
|
||||
L = [l.strip() for l in L]
|
||||
L = [element.strip() for element in L]
|
||||
return L
|
||||
|
||||
existing_users = user_list()["users"]
|
||||
|
|
|
@ -24,6 +24,8 @@ import re
|
|||
import urllib.parse
|
||||
import tempfile
|
||||
import shutil
|
||||
import ast
|
||||
import operator as op
|
||||
from collections import OrderedDict
|
||||
from typing import Optional, Dict, List, Union, Any, Mapping
|
||||
|
||||
|
@ -46,6 +48,145 @@ from yunohost.log import OperationLogger
|
|||
logger = getActionLogger("yunohost.config")
|
||||
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:
|
||||
def __init__(self, config_path, save_path=None):
|
||||
|
@ -466,11 +607,13 @@ class Question(object):
|
|||
hide_user_input_in_prompt = False
|
||||
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.type = question.get("type", "string")
|
||||
self.default = question.get("default", None)
|
||||
self.optional = question.get("optional", False)
|
||||
self.visible = question.get("visible", None)
|
||||
self.context = context
|
||||
self.choices = question.get("choices", [])
|
||||
self.pattern = question.get("pattern", self.pattern)
|
||||
self.ask = question.get("ask", {"en": self.name})
|
||||
|
@ -512,6 +655,17 @@ class Question(object):
|
|||
)
|
||||
|
||||
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):
|
||||
# Display question if no value filled or if it's a readonly message
|
||||
if Moulinette.interface.type == "cli" and os.isatty(1):
|
||||
|
@ -577,7 +731,7 @@ class Question(object):
|
|||
# Prevent displaying a shitload of choices
|
||||
# (e.g. 100+ available users when choosing an app admin...)
|
||||
choices = (
|
||||
list(self.choices.values())
|
||||
list(self.choices.keys())
|
||||
if isinstance(self.choices, dict)
|
||||
else self.choices
|
||||
)
|
||||
|
@ -710,8 +864,8 @@ class PasswordQuestion(Question):
|
|||
default_value = ""
|
||||
forbidden_chars = "{}"
|
||||
|
||||
def __init__(self, question):
|
||||
super().__init__(question)
|
||||
def __init__(self, question, context: Mapping[str, Any] = {}):
|
||||
super().__init__(question, context)
|
||||
self.redact = True
|
||||
if self.default is not None:
|
||||
raise YunohostValidationError(
|
||||
|
@ -829,8 +983,8 @@ class BooleanQuestion(Question):
|
|||
choices="yes/no",
|
||||
)
|
||||
|
||||
def __init__(self, question):
|
||||
super().__init__(question)
|
||||
def __init__(self, question, context: Mapping[str, Any] = {}):
|
||||
super().__init__(question, context)
|
||||
self.yes = question.get("yes", 1)
|
||||
self.no = question.get("no", 0)
|
||||
if self.default is None:
|
||||
|
@ -850,10 +1004,10 @@ class BooleanQuestion(Question):
|
|||
class DomainQuestion(Question):
|
||||
argument_type = "domain"
|
||||
|
||||
def __init__(self, question):
|
||||
def __init__(self, question, context: Mapping[str, Any] = {}):
|
||||
from yunohost.domain import domain_list, _get_maindomain
|
||||
|
||||
super().__init__(question)
|
||||
super().__init__(question, context)
|
||||
|
||||
if self.default is None:
|
||||
self.default = _get_maindomain()
|
||||
|
@ -876,11 +1030,11 @@ class DomainQuestion(Question):
|
|||
class UserQuestion(Question):
|
||||
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.domain import _get_maindomain
|
||||
|
||||
super().__init__(question)
|
||||
super().__init__(question, context)
|
||||
self.choices = list(user_list()["users"].keys())
|
||||
|
||||
if not self.choices:
|
||||
|
@ -902,8 +1056,8 @@ class NumberQuestion(Question):
|
|||
argument_type = "number"
|
||||
default_value = None
|
||||
|
||||
def __init__(self, question):
|
||||
super().__init__(question)
|
||||
def __init__(self, question, context: Mapping[str, Any] = {}):
|
||||
super().__init__(question, context)
|
||||
self.min = question.get("min", None)
|
||||
self.max = question.get("max", None)
|
||||
self.step = question.get("step", None)
|
||||
|
@ -954,8 +1108,8 @@ class DisplayTextQuestion(Question):
|
|||
argument_type = "display_text"
|
||||
readonly = True
|
||||
|
||||
def __init__(self, question):
|
||||
super().__init__(question)
|
||||
def __init__(self, question, context: Mapping[str, Any] = {}):
|
||||
super().__init__(question, context)
|
||||
|
||||
self.optional = True
|
||||
self.style = question.get(
|
||||
|
@ -989,8 +1143,8 @@ class FileQuestion(Question):
|
|||
if os.path.exists(upload_dir):
|
||||
shutil.rmtree(upload_dir)
|
||||
|
||||
def __init__(self, question):
|
||||
super().__init__(question)
|
||||
def __init__(self, question, context: Mapping[str, Any] = {}):
|
||||
super().__init__(question, context)
|
||||
self.accept = question.get("accept", "")
|
||||
|
||||
def _prevalidate(self):
|
||||
|
@ -1019,10 +1173,13 @@ class FileQuestion(Question):
|
|||
FileQuestion.upload_dirs += [upload_dir]
|
||||
|
||||
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)
|
||||
|
||||
write_to_file(file_path, content, file_mode="wb")
|
||||
|
@ -1057,13 +1214,13 @@ ARGUMENTS_TYPE_PARSERS = {
|
|||
|
||||
|
||||
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]:
|
||||
"""Parse arguments store in either manifest.json or actions.json or from a
|
||||
config panel against the user answers when they are present.
|
||||
|
||||
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
|
||||
or config_panel.json/toml
|
||||
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)
|
||||
# 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)
|
||||
prefilled_answers = dict(
|
||||
answers = dict(
|
||||
urllib.parse.parse_qsl(prefilled_answers or "", keep_blank_values=True)
|
||||
)
|
||||
|
||||
if not prefilled_answers:
|
||||
prefilled_answers = {}
|
||||
elif isinstance(prefilled_answers, Mapping):
|
||||
answers = {**prefilled_answers}
|
||||
else:
|
||||
answers = {}
|
||||
|
||||
out = []
|
||||
|
||||
for question in questions:
|
||||
question_class = ARGUMENTS_TYPE_PARSERS[question.get("type", "string")]
|
||||
question["value"] = prefilled_answers.get(question["name"])
|
||||
question = question_class(question)
|
||||
|
||||
question.ask_if_needed()
|
||||
for raw_question in raw_questions:
|
||||
question_class = ARGUMENTS_TYPE_PARSERS[raw_question.get("type", "string")]
|
||||
raw_question["value"] = answers.get(raw_question["name"])
|
||||
question = question_class(raw_question, context=answers)
|
||||
answers[question.name] = question.ask_if_needed()
|
||||
out.append(question)
|
||||
|
||||
return out
|
||||
|
|
92
tests/test_helpers.d/ynhtest_logging.sh
Normal file
92
tests/test_helpers.d/ynhtest_logging.sh
Normal 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"
|
||||
}
|
71
tests/test_helpers.d/ynhtest_secure_remove.sh
Normal file
71
tests/test_helpers.d/ynhtest_secure_remove.sh
Normal 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
|
||||
}
|
2
tox.ini
2
tox.ini
|
@ -9,7 +9,7 @@ deps =
|
|||
py39-mypy: mypy >= 0.900
|
||||
commands =
|
||||
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-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)
|
||||
|
|
Loading…
Add table
Reference in a new issue