mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge pull request #717 from YunoHost/reorganize-helpers
[enh] Reorganize helpers
This commit is contained in:
commit
441157615e
18 changed files with 1219 additions and 1217 deletions
|
@ -1,463 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Use logrotate to manage the logfile
|
|
||||||
#
|
|
||||||
# usage: ynh_use_logrotate [--logfile=/log/file] [--nonappend] [--specific_user=user/group]
|
|
||||||
# | arg: -l, --logfile - absolute path of logfile
|
|
||||||
# | arg: -n, --nonappend - (optional) Replace the config file instead of appending this new config.
|
|
||||||
# | arg: -u, --specific_user : run logrotate as the specified user and group. If not specified logrotate is runned as root.
|
|
||||||
#
|
|
||||||
# If no --logfile is provided, /var/log/${app} will be used as default.
|
|
||||||
# logfile can be just a directory, or a full path to a logfile :
|
|
||||||
# /parentdir/logdir
|
|
||||||
# /parentdir/logdir/logfile.log
|
|
||||||
#
|
|
||||||
# It's possible to use this helper multiple times, each config will be added to
|
|
||||||
# the same logrotate config file. Unless you use the option --non-append
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_use_logrotate () {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=lnuya
|
|
||||||
declare -Ar args_array=( [l]=logfile= [n]=nonappend [u]=specific_user= [y]=non [a]=append )
|
|
||||||
# [y]=non [a]=append are only for legacy purpose, to not fail on the old option '--non-append'
|
|
||||||
local logfile
|
|
||||||
local nonappend
|
|
||||||
local specific_user
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
local logfile="${logfile:-}"
|
|
||||||
local nonappend="${nonappend:-0}"
|
|
||||||
local specific_user="${specific_user:-}"
|
|
||||||
|
|
||||||
# LEGACY CODE - PRE GETOPTS
|
|
||||||
if [ $# -gt 0 ] && [ "$1" == "--non-append" ]; then
|
|
||||||
nonappend=1
|
|
||||||
# Destroy this argument for the next command.
|
|
||||||
shift
|
|
||||||
elif [ $# -gt 1 ] && [ "$2" == "--non-append" ]; then
|
|
||||||
nonappend=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $# -gt 0 ] && [ "$(echo ${1:0:1})" != "-" ]; then
|
|
||||||
if [ "$(echo ${1##*.})" == "log" ]; then # Keep only the extension to check if it's a logfile
|
|
||||||
local logfile=$1 # In this case, focus logrotate on the logfile
|
|
||||||
else
|
|
||||||
local logfile=$1/*.log # Else, uses the directory and all logfile into it.
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
# LEGACY CODE
|
|
||||||
|
|
||||||
local customtee="tee -a"
|
|
||||||
if [ "$nonappend" -eq 1 ]; then
|
|
||||||
customtee="tee"
|
|
||||||
fi
|
|
||||||
if [ -n "$logfile" ]
|
|
||||||
then
|
|
||||||
if [ "$(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
|
|
||||||
else
|
|
||||||
logfile="/var/log/${app}/*.log" # Without argument, use a defaut directory in /var/log
|
|
||||||
fi
|
|
||||||
local su_directive=""
|
|
||||||
if [[ -n $specific_user ]]; then
|
|
||||||
su_directive=" # Run logorotate as specific user - group
|
|
||||||
su ${specific_user%/*} ${specific_user#*/}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat > ./${app}-logrotate << EOF # Build a config file for logrotate
|
|
||||||
$logfile {
|
|
||||||
# Rotate if the logfile exceeds 100Mo
|
|
||||||
size 100M
|
|
||||||
# Keep 12 old log maximum
|
|
||||||
rotate 12
|
|
||||||
# Compress the logs with gzip
|
|
||||||
compress
|
|
||||||
# Compress the log at the next cycle. So keep always 2 non compressed logs
|
|
||||||
delaycompress
|
|
||||||
# Copy and truncate the log to allow to continue write on it. Instead of move the log.
|
|
||||||
copytruncate
|
|
||||||
# Do not do an error if the log is missing
|
|
||||||
missingok
|
|
||||||
# Not rotate if the log is empty
|
|
||||||
notifempty
|
|
||||||
# Keep old logs in the same dir
|
|
||||||
noolddir
|
|
||||||
$su_directive
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
sudo mkdir -p $(dirname "$logfile") # Create the log directory, if not exist
|
|
||||||
cat ${app}-logrotate | sudo $customtee /etc/logrotate.d/$app > /dev/null # Append this config to the existing config file, or replace the whole config file (depending on $customtee)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Remove the app's logrotate config.
|
|
||||||
#
|
|
||||||
# usage: ynh_remove_logrotate
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_remove_logrotate () {
|
|
||||||
if [ -e "/etc/logrotate.d/$app" ]; then
|
|
||||||
sudo rm "/etc/logrotate.d/$app"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create a dedicated systemd config
|
|
||||||
#
|
|
||||||
# usage: ynh_add_systemd_config [--service=service] [--template=template]
|
|
||||||
# | arg: -s, --service - Service name (optionnal, $app by default)
|
|
||||||
# | arg: -t, --template - Name of template file (optionnal, this is 'systemd' by default, meaning ./conf/systemd.service will be used as template)
|
|
||||||
#
|
|
||||||
# This will use the template ../conf/<templatename>.service
|
|
||||||
# to generate a systemd config, by replacing the following keywords
|
|
||||||
# with global variables that should be defined before calling
|
|
||||||
# this helper :
|
|
||||||
#
|
|
||||||
# __APP__ by $app
|
|
||||||
# __FINALPATH__ by $final_path
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
|
||||||
ynh_add_systemd_config () {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=st
|
|
||||||
declare -Ar args_array=( [s]=service= [t]=template= )
|
|
||||||
local service
|
|
||||||
local template
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
local service="${service:-$app}"
|
|
||||||
local template="${template:-systemd.service}"
|
|
||||||
|
|
||||||
finalsystemdconf="/etc/systemd/system/$service.service"
|
|
||||||
ynh_backup_if_checksum_is_different --file="$finalsystemdconf"
|
|
||||||
sudo cp ../conf/$template "$finalsystemdconf"
|
|
||||||
|
|
||||||
# To avoid a break by set -u, use a void substitution ${var:-}. If the variable is not set, it's simply set with an empty variable.
|
|
||||||
# Substitute in a nginx config file only if the variable is not empty
|
|
||||||
if test -n "${final_path:-}"; then
|
|
||||||
ynh_replace_string --match_string="__FINALPATH__" --replace_string="$final_path" --target_file="$finalsystemdconf"
|
|
||||||
fi
|
|
||||||
if test -n "${app:-}"; then
|
|
||||||
ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$finalsystemdconf"
|
|
||||||
fi
|
|
||||||
ynh_store_file_checksum --file="$finalsystemdconf"
|
|
||||||
|
|
||||||
sudo chown root: "$finalsystemdconf"
|
|
||||||
sudo systemctl enable $service
|
|
||||||
sudo systemctl daemon-reload
|
|
||||||
}
|
|
||||||
|
|
||||||
# Remove the dedicated systemd config
|
|
||||||
#
|
|
||||||
# usage: ynh_remove_systemd_config [--service=service]
|
|
||||||
# | arg: -s, --service - Service name (optionnal, $app by default)
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
|
||||||
ynh_remove_systemd_config () {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=s
|
|
||||||
declare -Ar args_array=( [s]=service= )
|
|
||||||
local service
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
local service="${service:-$app}"
|
|
||||||
|
|
||||||
local finalsystemdconf="/etc/systemd/system/$service.service"
|
|
||||||
if [ -e "$finalsystemdconf" ]; then
|
|
||||||
ynh_systemd_action --service_name=$service --action=stop
|
|
||||||
systemctl disable $service
|
|
||||||
ynh_secure_remove --file="$finalsystemdconf"
|
|
||||||
systemctl daemon-reload
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create a dedicated nginx config
|
|
||||||
#
|
|
||||||
# usage: ynh_add_nginx_config "list of others variables to replace"
|
|
||||||
#
|
|
||||||
# | arg: list - (Optional) list of others variables to replace separated by spaces. For example : 'path_2 port_2 ...'
|
|
||||||
#
|
|
||||||
# This will use a template in ../conf/nginx.conf
|
|
||||||
# __PATH__ by $path_url
|
|
||||||
# __DOMAIN__ by $domain
|
|
||||||
# __PORT__ by $port
|
|
||||||
# __NAME__ by $app
|
|
||||||
# __FINALPATH__ by $final_path
|
|
||||||
#
|
|
||||||
# And dynamic variables (from the last example) :
|
|
||||||
# __PATH_2__ by $path_2
|
|
||||||
# __PORT_2__ by $port_2
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
|
||||||
ynh_add_nginx_config () {
|
|
||||||
finalnginxconf="/etc/nginx/conf.d/$domain.d/$app.conf"
|
|
||||||
local others_var=${1:-}
|
|
||||||
ynh_backup_if_checksum_is_different --file="$finalnginxconf"
|
|
||||||
sudo cp ../conf/nginx.conf "$finalnginxconf"
|
|
||||||
|
|
||||||
# To avoid a break by set -u, use a void substitution ${var:-}. If the variable is not set, it's simply set with an empty variable.
|
|
||||||
# Substitute in a nginx config file only if the variable is not empty
|
|
||||||
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="$finalnginxconf"
|
|
||||||
ynh_replace_string --match_string="__PATH__" --replace_string="$path_url" --target_file="$finalnginxconf"
|
|
||||||
fi
|
|
||||||
if test -n "${domain:-}"; then
|
|
||||||
ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$finalnginxconf"
|
|
||||||
fi
|
|
||||||
if test -n "${port:-}"; then
|
|
||||||
ynh_replace_string --match_string="__PORT__" --replace_string="$port" --target_file="$finalnginxconf"
|
|
||||||
fi
|
|
||||||
if test -n "${app:-}"; then
|
|
||||||
ynh_replace_string --match_string="__NAME__" --replace_string="$app" --target_file="$finalnginxconf"
|
|
||||||
fi
|
|
||||||
if test -n "${final_path:-}"; then
|
|
||||||
ynh_replace_string --match_string="__FINALPATH__" --replace_string="$final_path" --target_file="$finalnginxconf"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Replace all other variable given as arguments
|
|
||||||
for var_to_replace in $others_var
|
|
||||||
do
|
|
||||||
# ${var_to_replace^^} make the content of the variable on upper-cases
|
|
||||||
# ${!var_to_replace} get the content of the variable named $var_to_replace
|
|
||||||
ynh_replace_string --match_string="__${var_to_replace^^}__" --replace_string="${!var_to_replace}" --target_file="$finalnginxconf"
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ "${path_url:-}" != "/" ]
|
|
||||||
then
|
|
||||||
ynh_replace_string --match_string="^#sub_path_only" --replace_string="" --target_file="$finalnginxconf"
|
|
||||||
else
|
|
||||||
ynh_replace_string --match_string="^#root_path_only" --replace_string="" --target_file="$finalnginxconf"
|
|
||||||
fi
|
|
||||||
|
|
||||||
ynh_store_file_checksum --file="$finalnginxconf"
|
|
||||||
|
|
||||||
ynh_systemd_action --service_name=nginx --action=reload
|
|
||||||
}
|
|
||||||
|
|
||||||
# Remove the dedicated nginx config
|
|
||||||
#
|
|
||||||
# usage: ynh_remove_nginx_config
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
|
||||||
ynh_remove_nginx_config () {
|
|
||||||
ynh_secure_remove --file="/etc/nginx/conf.d/$domain.d/$app.conf"
|
|
||||||
ynh_systemd_action --service_name=nginx --action=reload
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create a dedicated php-fpm config
|
|
||||||
#
|
|
||||||
# usage: ynh_add_fpm_config [--phpversion=7.X]
|
|
||||||
# | arg: -v, --phpversion - Version of php to use.
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
|
||||||
ynh_add_fpm_config () {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=v
|
|
||||||
declare -Ar args_array=( [v]=phpversion= )
|
|
||||||
local phpversion
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
# Configure PHP-FPM 7.0 by default
|
|
||||||
phpversion="${phpversion:-7.0}"
|
|
||||||
|
|
||||||
local fpm_config_dir="/etc/php/$phpversion/fpm"
|
|
||||||
local fpm_service="php${phpversion}-fpm"
|
|
||||||
# Configure PHP-FPM 5 on Debian Jessie
|
|
||||||
if [ "$(ynh_get_debian_release)" == "jessie" ]; then
|
|
||||||
fpm_config_dir="/etc/php5/fpm"
|
|
||||||
fpm_service="php5-fpm"
|
|
||||||
fi
|
|
||||||
ynh_app_setting_set --app=$app --key=fpm_config_dir --value="$fpm_config_dir"
|
|
||||||
ynh_app_setting_set --app=$app --key=fpm_service --value="$fpm_service"
|
|
||||||
finalphpconf="$fpm_config_dir/pool.d/$app.conf"
|
|
||||||
ynh_backup_if_checksum_is_different --file="$finalphpconf"
|
|
||||||
sudo cp ../conf/php-fpm.conf "$finalphpconf"
|
|
||||||
ynh_replace_string --match_string="__NAMETOCHANGE__" --replace_string="$app" --target_file="$finalphpconf"
|
|
||||||
ynh_replace_string --match_string="__FINALPATH__" --replace_string="$final_path" --target_file="$finalphpconf"
|
|
||||||
ynh_replace_string --match_string="__USER__" --replace_string="$app" --target_file="$finalphpconf"
|
|
||||||
ynh_replace_string --match_string="__PHPVERSION__" --replace_string="$phpversion" --target_file="$finalphpconf"
|
|
||||||
sudo chown root: "$finalphpconf"
|
|
||||||
ynh_store_file_checksum --file="$finalphpconf"
|
|
||||||
|
|
||||||
if [ -e "../conf/php-fpm.ini" ]
|
|
||||||
then
|
|
||||||
echo "Packagers ! Please do not use a separate php ini file, merge your directives in the pool file instead." >&2
|
|
||||||
finalphpini="$fpm_config_dir/conf.d/20-$app.ini"
|
|
||||||
ynh_backup_if_checksum_is_different "$finalphpini"
|
|
||||||
sudo cp ../conf/php-fpm.ini "$finalphpini"
|
|
||||||
sudo chown root: "$finalphpini"
|
|
||||||
ynh_store_file_checksum "$finalphpini"
|
|
||||||
fi
|
|
||||||
ynh_systemd_action --service_name=$fpm_service --action=reload
|
|
||||||
}
|
|
||||||
|
|
||||||
# Remove the dedicated php-fpm config
|
|
||||||
#
|
|
||||||
# usage: ynh_remove_fpm_config
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
|
||||||
ynh_remove_fpm_config () {
|
|
||||||
local fpm_config_dir=$(ynh_app_setting_get --app=$app --key=fpm_config_dir)
|
|
||||||
local fpm_service=$(ynh_app_setting_get --app=$app --key=fpm_service)
|
|
||||||
# Assume php version 7 if not set
|
|
||||||
if [ -z "$fpm_config_dir" ]; then
|
|
||||||
fpm_config_dir="/etc/php/7.0/fpm"
|
|
||||||
fpm_service="php7.0-fpm"
|
|
||||||
fi
|
|
||||||
ynh_secure_remove --file="$fpm_config_dir/pool.d/$app.conf"
|
|
||||||
ynh_secure_remove --file="$fpm_config_dir/conf.d/20-$app.ini" 2>&1
|
|
||||||
ynh_systemd_action --service_name=$fpm_service --action=reload
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create a dedicated fail2ban config (jail and filter conf files)
|
|
||||||
#
|
|
||||||
# usage 1: ynh_add_fail2ban_config --logpath=log_file --failregex=filter [--max_retry=max_retry] [--ports=ports]
|
|
||||||
# | arg: -l, --logpath= - Log file to be checked by fail2ban
|
|
||||||
# | arg: -r, --failregex= - Failregex to be looked for by fail2ban
|
|
||||||
# | arg: -m, --max_retry= - Maximum number of retries allowed before banning IP address - default: 3
|
|
||||||
# | arg: -p, --ports= - Ports blocked for a banned IP address - default: http,https
|
|
||||||
#
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# usage 2: ynh_add_fail2ban_config --use_template [--others_var="list of others variables to replace"]
|
|
||||||
# | arg: -t, --use_template - Use this helper in template mode
|
|
||||||
# | arg: -v, --others_var= - List of others variables to replace separeted by a space
|
|
||||||
# | for example : 'var_1 var_2 ...'
|
|
||||||
#
|
|
||||||
# This will use a template in ../conf/f2b_jail.conf and ../conf/f2b_filter.conf
|
|
||||||
# __APP__ by $app
|
|
||||||
#
|
|
||||||
# You can dynamically replace others variables by example :
|
|
||||||
# __VAR_1__ by $var_1
|
|
||||||
# __VAR_2__ by $var_2
|
|
||||||
#
|
|
||||||
# Generally your template will look like that by example (for synapse):
|
|
||||||
#
|
|
||||||
# f2b_jail.conf:
|
|
||||||
# [__APP__]
|
|
||||||
# enabled = true
|
|
||||||
# port = http,https
|
|
||||||
# filter = __APP__
|
|
||||||
# logpath = /var/log/__APP__/logfile.log
|
|
||||||
# maxretry = 3
|
|
||||||
#
|
|
||||||
# f2b_filter.conf:
|
|
||||||
# [INCLUDES]
|
|
||||||
# before = common.conf
|
|
||||||
# [Definition]
|
|
||||||
#
|
|
||||||
# # Part of regex definition (just used to make more easy to make the global regex)
|
|
||||||
# __synapse_start_line = .? \- synapse\..+ \-
|
|
||||||
#
|
|
||||||
# # Regex definition.
|
|
||||||
# failregex = ^%(__synapse_start_line)s INFO \- POST\-(\d+)\- <HOST> \- \d+ \- Received request\: POST /_matrix/client/r0/login\??<SKIPLINES>%(__synapse_start_line)s INFO \- POST\-\1\- Got login request with identifier: \{u'type': u'm.id.user', u'user'\: u'(.+?)'\}, medium\: None, address: None, user\: u'\5'<SKIPLINES>%(__synapse_start_line)s WARNING \- \- (Attempted to login as @\5\:.+ but they do not exist|Failed password login for user @\5\:.+)$
|
|
||||||
#
|
|
||||||
# ignoreregex =
|
|
||||||
#
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Note about the "failregex" option:
|
|
||||||
# regex to match the password failure messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
|
||||||
#
|
|
||||||
# You can find some more explainations about how to make a regex here :
|
|
||||||
# https://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Filters
|
|
||||||
#
|
|
||||||
# Note that the logfile need to exist before to call this helper !!
|
|
||||||
#
|
|
||||||
# To validate your regex you can test with this command:
|
|
||||||
# fail2ban-regex /var/log/YOUR_LOG_FILE_PATH /etc/fail2ban/filter.d/YOUR_APP.conf
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.?.? or higher.
|
|
||||||
ynh_add_fail2ban_config () {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=lrmptv
|
|
||||||
declare -Ar args_array=( [l]=logpath= [r]=failregex= [m]=max_retry= [p]=ports= [t]=use_template [v]=others_var=)
|
|
||||||
local logpath
|
|
||||||
local failregex
|
|
||||||
local max_retry
|
|
||||||
local ports
|
|
||||||
local others_var
|
|
||||||
local use_template
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
use_template="${use_template:-0}"
|
|
||||||
max_retry=${max_retry:-3}
|
|
||||||
ports=${ports:-http,https}
|
|
||||||
|
|
||||||
finalfail2banjailconf="/etc/fail2ban/jail.d/$app.conf"
|
|
||||||
finalfail2banfilterconf="/etc/fail2ban/filter.d/$app.conf"
|
|
||||||
ynh_backup_if_checksum_is_different "$finalfail2banjailconf"
|
|
||||||
ynh_backup_if_checksum_is_different "$finalfail2banfilterconf"
|
|
||||||
|
|
||||||
if [ $use_template -eq 1 ]
|
|
||||||
then
|
|
||||||
# Usage 2, templates
|
|
||||||
cp ../conf/f2b_jail.conf $finalfail2banjailconf
|
|
||||||
cp ../conf/f2b_filter.conf $finalfail2banfilterconf
|
|
||||||
|
|
||||||
if [ -n "${app:-}" ]
|
|
||||||
then
|
|
||||||
ynh_replace_string "__APP__" "$app" "$finalfail2banjailconf"
|
|
||||||
ynh_replace_string "__APP__" "$app" "$finalfail2banfilterconf"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Replace all other variable given as arguments
|
|
||||||
for var_to_replace in ${others_var:-}; do
|
|
||||||
# ${var_to_replace^^} make the content of the variable on upper-cases
|
|
||||||
# ${!var_to_replace} get the content of the variable named $var_to_replace
|
|
||||||
ynh_replace_string --match_string="__${var_to_replace^^}__" --replace_string="${!var_to_replace}" --target_file="$finalfail2banjailconf"
|
|
||||||
ynh_replace_string --match_string="__${var_to_replace^^}__" --replace_string="${!var_to_replace}" --target_file="$finalfail2banfilterconf"
|
|
||||||
done
|
|
||||||
|
|
||||||
else
|
|
||||||
# Usage 1, no template. Build a config file from scratch.
|
|
||||||
test -n "$logpath" || ynh_die "ynh_add_fail2ban_config expects a logfile path as first argument and received nothing."
|
|
||||||
test -n "$failregex" || ynh_die "ynh_add_fail2ban_config expects a failure regex as second argument and received nothing."
|
|
||||||
|
|
||||||
tee $finalfail2banjailconf <<EOF
|
|
||||||
[$app]
|
|
||||||
enabled = true
|
|
||||||
port = $ports
|
|
||||||
filter = $app
|
|
||||||
logpath = $logpath
|
|
||||||
maxretry = $max_retry
|
|
||||||
EOF
|
|
||||||
|
|
||||||
tee $finalfail2banfilterconf <<EOF
|
|
||||||
[INCLUDES]
|
|
||||||
before = common.conf
|
|
||||||
[Definition]
|
|
||||||
failregex = $failregex
|
|
||||||
ignoreregex =
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Common to usage 1 and 2.
|
|
||||||
ynh_store_file_checksum "$finalfail2banjailconf"
|
|
||||||
ynh_store_file_checksum "$finalfail2banfilterconf"
|
|
||||||
|
|
||||||
ynh_systemd_action --service_name=fail2ban --action=reload
|
|
||||||
|
|
||||||
local fail2ban_error="$(journalctl -u fail2ban | tail -n50 | grep "WARNING.*$app.*")"
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
# Remove the dedicated fail2ban config (jail and filter conf files)
|
|
||||||
#
|
|
||||||
# usage: ynh_remove_fail2ban_config
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.?.? or higher.
|
|
||||||
ynh_remove_fail2ban_config () {
|
|
||||||
ynh_secure_remove "/etc/fail2ban/jail.d/$app.conf"
|
|
||||||
ynh_secure_remove "/etc/fail2ban/filter.d/$app.conf"
|
|
||||||
ynh_systemd_action --service_name=fail2ban --action=reload
|
|
||||||
}
|
|
|
@ -1,21 +1,19 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
source /usr/share/yunohost/helpers.d/getopts
|
|
||||||
|
|
||||||
CAN_BIND=${CAN_BIND:-1}
|
CAN_BIND=${CAN_BIND:-1}
|
||||||
|
|
||||||
# Add a file or a directory to the list of paths to backup
|
# Add a file or a directory to the list of paths to backup
|
||||||
#
|
#
|
||||||
# Note: this helper could be used in backup hook or in backup script inside an
|
# Note: this helper could be used in backup hook or in backup script inside an
|
||||||
# app package
|
# app package
|
||||||
#
|
#
|
||||||
# Details: ynh_backup writes SRC and the relative DEST into a CSV file. And it
|
# Details: ynh_backup writes SRC and the relative DEST into a CSV file. And it
|
||||||
# creates the parent destination directory
|
# creates the parent destination directory
|
||||||
#
|
#
|
||||||
# If DEST is ended by a slash it complete this path with the basename of SRC.
|
# If DEST is ended by a slash it complete this path with the basename of SRC.
|
||||||
#
|
#
|
||||||
# usage: ynh_backup --src_path=src_path [--dest_path=dest_path] [--is_big] [--not_mandatory]
|
# usage: ynh_backup --src_path=src_path [--dest_path=dest_path] [--is_big] [--not_mandatory]
|
||||||
# | arg: -s, --src_path - file or directory to bind or symlink or copy. it shouldn't be in the backup dir.
|
# | arg: -s, --src_path - file or directory to bind or symlink or copy. it shouldn't be in the backup dir.
|
||||||
# | arg: -d, --dest_path - destination file or directory inside the backup dir
|
# | arg: -d, --dest_path - destination file or directory inside the backup dir
|
||||||
# | arg: -b, --is_big - Indicate data are big (mail, video, image ...)
|
# | arg: -b, --is_big - Indicate data are big (mail, video, image ...)
|
||||||
# | arg: -m, --not_mandatory - Indicate that if the file is missing, the backup can ignore it.
|
# | arg: -m, --not_mandatory - Indicate that if the file is missing, the backup can ignore it.
|
||||||
|
@ -32,7 +30,7 @@ CAN_BIND=${CAN_BIND:-1}
|
||||||
#
|
#
|
||||||
# ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf" "conf/"
|
# ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf" "conf/"
|
||||||
# # => "/etc/nginx/conf.d/$domain.d/$app.conf","apps/wordpress/conf/$app.conf"
|
# # => "/etc/nginx/conf.d/$domain.d/$app.conf","apps/wordpress/conf/$app.conf"
|
||||||
#
|
#
|
||||||
# ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf" "conf"
|
# ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf" "conf"
|
||||||
# # => "/etc/nginx/conf.d/$domain.d/$app.conf","apps/wordpress/conf"
|
# # => "/etc/nginx/conf.d/$domain.d/$app.conf","apps/wordpress/conf"
|
||||||
#
|
#
|
||||||
|
@ -190,7 +188,7 @@ with open(sys.argv[1], 'r') as backup_file:
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
# Restore a file or a directory
|
# Restore a file or a directory
|
||||||
#
|
#
|
||||||
# Use the registered path in backup_list by ynh_backup to restore the file at
|
# Use the registered path in backup_list by ynh_backup to restore the file at
|
||||||
# the right place.
|
# the right place.
|
||||||
|
@ -205,7 +203,7 @@ with open(sys.argv[1], 'r') as backup_file:
|
||||||
# # You can also use relative paths:
|
# # You can also use relative paths:
|
||||||
# ynh_restore_file "conf/nginx.conf"
|
# ynh_restore_file "conf/nginx.conf"
|
||||||
#
|
#
|
||||||
# If DEST_PATH already exists and is lighter than 500 Mo, a backup will be made in
|
# If DEST_PATH already exists and is lighter than 500 Mo, a backup will be made in
|
||||||
# /home/yunohost.conf/backup/. Otherwise, the existing file is removed.
|
# /home/yunohost.conf/backup/. Otherwise, the existing file is removed.
|
||||||
#
|
#
|
||||||
# if apps/wordpress/etc/nginx/conf.d/$domain.d/$app.conf exists, restore it into
|
# if apps/wordpress/etc/nginx/conf.d/$domain.d/$app.conf exists, restore it into
|
||||||
|
@ -248,7 +246,7 @@ ynh_restore_file () {
|
||||||
then
|
then
|
||||||
local backup_file="/home/yunohost.conf/backup/${dest_path}.backup.$(date '+%Y%m%d.%H%M%S')"
|
local backup_file="/home/yunohost.conf/backup/${dest_path}.backup.$(date '+%Y%m%d.%H%M%S')"
|
||||||
mkdir -p "$(dirname "$backup_file")"
|
mkdir -p "$(dirname "$backup_file")"
|
||||||
mv "${dest_path}" "$backup_file" # Move the current file or directory
|
mv "${dest_path}" "$backup_file" # Move the current file or directory
|
||||||
else
|
else
|
||||||
ynh_secure_remove --file=${dest_path}
|
ynh_secure_remove --file=${dest_path}
|
||||||
fi
|
fi
|
||||||
|
@ -282,26 +280,6 @@ ynh_bind_or_cp() {
|
||||||
ynh_backup "$1" "$2" 1
|
ynh_backup "$1" "$2" 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create a directory under /tmp
|
|
||||||
#
|
|
||||||
# [internal]
|
|
||||||
#
|
|
||||||
# Deprecated helper
|
|
||||||
#
|
|
||||||
# usage: ynh_mkdir_tmp
|
|
||||||
# | ret: the created directory path
|
|
||||||
ynh_mkdir_tmp() {
|
|
||||||
ynh_print_warn --message="The helper ynh_mkdir_tmp is deprecated."
|
|
||||||
ynh_print_warn --message="You should use 'mktemp -d' instead and manage permissions \
|
|
||||||
properly with chmod/chown."
|
|
||||||
local TMP_DIR=$(mktemp -d)
|
|
||||||
|
|
||||||
# Give rights to other users could be a security risk.
|
|
||||||
# But for retrocompatibility we need it. (This helpers is deprecated)
|
|
||||||
chmod 755 $TMP_DIR
|
|
||||||
echo $TMP_DIR
|
|
||||||
}
|
|
||||||
|
|
||||||
# Calculate and store a file checksum into the app settings
|
# Calculate and store a file checksum into the app settings
|
||||||
#
|
#
|
||||||
# $app should be defined when calling this helper
|
# $app should be defined when calling this helper
|
||||||
|
@ -311,29 +289,29 @@ properly with chmod/chown."
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_store_file_checksum () {
|
ynh_store_file_checksum () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=f
|
local legacy_args=f
|
||||||
declare -Ar args_array=( [f]=file= )
|
declare -Ar args_array=( [f]=file= )
|
||||||
local file
|
local file
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
local checksum_setting_name=checksum_${file//[\/ ]/_} # Replace all '/' and ' ' by '_'
|
local checksum_setting_name=checksum_${file//[\/ ]/_} # Replace all '/' and ' ' by '_'
|
||||||
ynh_app_setting_set --app=$app --key=$checksum_setting_name --value=$(sudo md5sum "$file" | cut -d' ' -f1)
|
ynh_app_setting_set --app=$app --key=$checksum_setting_name --value=$(sudo md5sum "$file" | cut -d' ' -f1)
|
||||||
|
|
||||||
# If backup_file_checksum isn't empty, ynh_backup_if_checksum_is_different has made a backup
|
# If backup_file_checksum isn't empty, ynh_backup_if_checksum_is_different has made a backup
|
||||||
if [ -n "${backup_file_checksum-}" ]
|
if [ -n "${backup_file_checksum-}" ]
|
||||||
then
|
then
|
||||||
# Print the diff between the previous file and the new one.
|
# Print the diff between the previous file and the new one.
|
||||||
# diff return 1 if the files are different, so the || true
|
# diff return 1 if the files are different, so the || true
|
||||||
diff --report-identical-files --unified --color=always $backup_file_checksum $file >&2 || true
|
diff --report-identical-files --unified --color=always $backup_file_checksum $file >&2 || true
|
||||||
fi
|
fi
|
||||||
# Unset the variable, so it wouldn't trig a ynh_store_file_checksum without a ynh_backup_if_checksum_is_different before it.
|
# Unset the variable, so it wouldn't trig a ynh_store_file_checksum without a ynh_backup_if_checksum_is_different before it.
|
||||||
unset backup_file_checksum
|
unset backup_file_checksum
|
||||||
}
|
}
|
||||||
|
|
||||||
# Verify the checksum and backup the file if it's different
|
# Verify the checksum and backup the file if it's different
|
||||||
# This helper is primarily meant to allow to easily backup personalised/manually
|
# This helper is primarily meant to allow to easily backup personalised/manually
|
||||||
# modified config files.
|
# modified config files.
|
||||||
#
|
#
|
||||||
# $app should be defined when calling this helper
|
# $app should be defined when calling this helper
|
||||||
|
@ -344,28 +322,28 @@ ynh_store_file_checksum () {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_backup_if_checksum_is_different () {
|
ynh_backup_if_checksum_is_different () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=f
|
local legacy_args=f
|
||||||
declare -Ar args_array=( [f]=file= )
|
declare -Ar args_array=( [f]=file= )
|
||||||
local file
|
local file
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
local checksum_setting_name=checksum_${file//[\/ ]/_} # Replace all '/' and ' ' by '_'
|
local checksum_setting_name=checksum_${file//[\/ ]/_} # Replace all '/' and ' ' by '_'
|
||||||
local checksum_value=$(ynh_app_setting_get --app=$app --key=$checksum_setting_name)
|
local checksum_value=$(ynh_app_setting_get --app=$app --key=$checksum_setting_name)
|
||||||
# backup_file_checksum isn't declare as local, so it can be reuse by ynh_store_file_checksum
|
# backup_file_checksum isn't declare as local, so it can be reuse by ynh_store_file_checksum
|
||||||
backup_file_checksum=""
|
backup_file_checksum=""
|
||||||
if [ -n "$checksum_value" ]
|
if [ -n "$checksum_value" ]
|
||||||
then # Proceed only if a value was stored into the app settings
|
then # Proceed only if a value was stored into the app settings
|
||||||
if ! echo "$checksum_value $file" | sudo md5sum -c --status
|
if ! echo "$checksum_value $file" | sudo md5sum -c --status
|
||||||
then # If the checksum is now different
|
then # If the checksum is now different
|
||||||
backup_file_checksum="/home/yunohost.conf/backup/$file.backup.$(date '+%Y%m%d.%H%M%S')"
|
backup_file_checksum="/home/yunohost.conf/backup/$file.backup.$(date '+%Y%m%d.%H%M%S')"
|
||||||
sudo mkdir -p "$(dirname "$backup_file_checksum")"
|
sudo mkdir -p "$(dirname "$backup_file_checksum")"
|
||||||
sudo cp -a "$file" "$backup_file_checksum" # Backup the current file
|
sudo cp -a "$file" "$backup_file_checksum" # Backup the current file
|
||||||
ynh_print_warn "File $file has been manually modified since the installation or last upgrade. So it has been duplicated in $backup_file_checksum"
|
ynh_print_warn "File $file has been manually modified since the installation or last upgrade. So it has been duplicated in $backup_file_checksum"
|
||||||
echo "$backup_file_checksum" # Return the name of the backup file
|
echo "$backup_file_checksum" # Return the name of the backup file
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Delete a file checksum from the app settings
|
# Delete a file checksum from the app settings
|
||||||
|
@ -377,54 +355,94 @@ ynh_backup_if_checksum_is_different () {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 3.3.1 or higher.
|
# Requires YunoHost version 3.3.1 or higher.
|
||||||
ynh_delete_file_checksum () {
|
ynh_delete_file_checksum () {
|
||||||
# Declare an array to define the options of this helper.
|
# Declare an array to define the options of this helper.
|
||||||
local legacy_args=f
|
local legacy_args=f
|
||||||
declare -Ar args_array=( [f]=file= )
|
declare -Ar args_array=( [f]=file= )
|
||||||
local file
|
local file
|
||||||
# Manage arguments with getopts
|
# Manage arguments with getopts
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
local checksum_setting_name=checksum_${file//[\/ ]/_} # Replace all '/' and ' ' by '_'
|
local checksum_setting_name=checksum_${file//[\/ ]/_} # Replace all '/' and ' ' by '_'
|
||||||
ynh_app_setting_delete --app=$app --key=$checksum_setting_name
|
ynh_app_setting_delete --app=$app --key=$checksum_setting_name
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove a file or a directory securely
|
# Make a backup in case of failed upgrade
|
||||||
#
|
#
|
||||||
# usage: ynh_secure_remove --file=path_to_remove
|
# usage:
|
||||||
# | arg: -f, --file - File or directory to remove
|
# ynh_backup_before_upgrade
|
||||||
|
# ynh_clean_setup () {
|
||||||
|
# ynh_restore_upgradebackup
|
||||||
|
# }
|
||||||
|
# ynh_abort_if_errors
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.7.2 or higher.
|
||||||
ynh_secure_remove () {
|
ynh_backup_before_upgrade () {
|
||||||
# Declare an array to define the options of this helper.
|
if [ ! -e "/etc/yunohost/apps/$app/scripts/backup" ]
|
||||||
local legacy_args=f
|
then
|
||||||
declare -Ar args_array=( [f]=file= )
|
ynh_print_warn --message="This app doesn't have any backup script."
|
||||||
local file
|
return
|
||||||
# Manage arguments with getopts
|
fi
|
||||||
ynh_handle_getopts_args "$@"
|
backup_number=1
|
||||||
|
local old_backup_number=2
|
||||||
|
local app_bck=${app//_/-} # Replace all '_' by '-'
|
||||||
|
NO_BACKUP_UPGRADE=${NO_BACKUP_UPGRADE:-0}
|
||||||
|
|
||||||
local forbidden_path=" \
|
if [ "$NO_BACKUP_UPGRADE" -eq 0 ]
|
||||||
/var/www \
|
then
|
||||||
/home/yunohost.app"
|
# Check if a backup already exists with the prefix 1
|
||||||
|
if sudo yunohost backup list | grep -q $app_bck-pre-upgrade1
|
||||||
|
then
|
||||||
|
# Prefix becomes 2 to preserve the previous backup
|
||||||
|
backup_number=2
|
||||||
|
old_backup_number=1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ $# -ge 2 ]
|
# Create backup
|
||||||
then
|
sudo BACKUP_CORE_ONLY=1 yunohost backup create --apps $app --name $app_bck-pre-upgrade$backup_number --debug
|
||||||
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."
|
if [ "$?" -eq 0 ]
|
||||||
fi
|
then
|
||||||
|
# If the backup succeeded, remove the previous backup
|
||||||
if [[ "$forbidden_path" =~ "$file" \
|
if sudo yunohost backup list | grep -q $app_bck-pre-upgrade$old_backup_number
|
||||||
# Match all paths or subpaths in $forbidden_path
|
then
|
||||||
|| "$file" =~ ^/[[:alnum:]]+$ \
|
# Remove the previous backup only if it exists
|
||||||
# Match all first level paths from / (Like /var, /root, etc...)
|
sudo yunohost backup delete $app_bck-pre-upgrade$old_backup_number > /dev/null
|
||||||
|| "${file:${#file}-1}" = "/" ]]
|
fi
|
||||||
# Match if the path finishes by /. Because it seems there is an empty variable
|
else
|
||||||
then
|
ynh_die --message="Backup failed, the upgrade process was aborted."
|
||||||
ynh_print_warn --message="Avoid deleting $file."
|
fi
|
||||||
else
|
else
|
||||||
if [ -e "$file" ]
|
ynh_print_warn --message="\$NO_BACKUP_UPGRADE is set, backup will be avoided. Be careful, this upgrade is going to be operated without a security backup"
|
||||||
then
|
fi
|
||||||
sudo rm -R "$file"
|
}
|
||||||
else
|
|
||||||
ynh_print_info --message="$file wasn't deleted because it doesn't exist."
|
# Restore a previous backup if the upgrade process failed
|
||||||
fi
|
#
|
||||||
fi
|
# usage:
|
||||||
|
# ynh_backup_before_upgrade
|
||||||
|
# ynh_clean_setup () {
|
||||||
|
# ynh_restore_upgradebackup
|
||||||
|
# }
|
||||||
|
# ynh_abort_if_errors
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.7.2 or higher.
|
||||||
|
ynh_restore_upgradebackup () {
|
||||||
|
ynh_print_err --message="Upgrade failed."
|
||||||
|
local app_bck=${app//_/-} # Replace all '_' by '-'
|
||||||
|
|
||||||
|
NO_BACKUP_UPGRADE=${NO_BACKUP_UPGRADE:-0}
|
||||||
|
|
||||||
|
if [ "$NO_BACKUP_UPGRADE" -eq 0 ]
|
||||||
|
then
|
||||||
|
# Check if an existing backup can be found before removing and restoring the application.
|
||||||
|
if sudo yunohost backup list | grep -q $app_bck-pre-upgrade$backup_number
|
||||||
|
then
|
||||||
|
# Remove the application then restore it
|
||||||
|
sudo yunohost app remove $app
|
||||||
|
# Restore the backup
|
||||||
|
sudo yunohost backup restore $app_bck-pre-upgrade$backup_number --apps $app --force --debug
|
||||||
|
ynh_die --message="The app was restored to the way it was before the failed upgrade."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
ynh_print_warn --message="\$NO_BACKUP_UPGRADE is set, that means there's no backup to restore. You have to fix this upgrade by yourself !"
|
||||||
|
fi
|
||||||
}
|
}
|
|
@ -1,67 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# 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.?.? or higher.
|
|
||||||
ynh_debug () {
|
|
||||||
# Disable set xtrace for the helper itself, to not pollute the debug log
|
|
||||||
set +x
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=mt
|
|
||||||
declare -Ar args_array=( [m]=message= [t]=trace= )
|
|
||||||
local message
|
|
||||||
local trace
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
# Redisable xtrace, ynh_handle_getopts_args set it back
|
|
||||||
set +x
|
|
||||||
message=${message:-}
|
|
||||||
trace=${trace:-}
|
|
||||||
|
|
||||||
if [ -n "$message" ]
|
|
||||||
then
|
|
||||||
ynh_print_log "\e[34m\e[1m[DEBUG]\e[0m ${message}" >&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$trace" == "1" ]
|
|
||||||
then
|
|
||||||
ynh_debug --message="Enable debugging"
|
|
||||||
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 +x
|
|
||||||
# Put xtrace back to its original fild descriptor
|
|
||||||
BASH_XTRACEFD=$old_bash_xtracefd
|
|
||||||
# Restore stdout
|
|
||||||
exec 1>&1
|
|
||||||
fi
|
|
||||||
# Renable set xtrace
|
|
||||||
set -x
|
|
||||||
}
|
|
||||||
|
|
||||||
# Execute a command and print the result as debug
|
|
||||||
#
|
|
||||||
# usage: ynh_debug_exec command to execute
|
|
||||||
# usage: ynh_debug_exec "command to execute | following command"
|
|
||||||
# In case of use of pipes, you have to use double quotes. Otherwise, this helper will be executed with the first command, then be sent to the next pipe.
|
|
||||||
#
|
|
||||||
# | arg: command - command to execute
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.?.? or higher.
|
|
||||||
ynh_debug_exec () {
|
|
||||||
ynh_debug --message="$(eval $@)"
|
|
||||||
}
|
|
151
data/helpers.d/fail2ban
Normal file
151
data/helpers.d/fail2ban
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Create a dedicated fail2ban config (jail and filter conf files)
|
||||||
|
#
|
||||||
|
# usage 1: ynh_add_fail2ban_config --logpath=log_file --failregex=filter [--max_retry=max_retry] [--ports=ports]
|
||||||
|
# | arg: -l, --logpath= - Log file to be checked by fail2ban
|
||||||
|
# | arg: -r, --failregex= - Failregex to be looked for by fail2ban
|
||||||
|
# | arg: -m, --max_retry= - Maximum number of retries allowed before banning IP address - default: 3
|
||||||
|
# | arg: -p, --ports= - Ports blocked for a banned IP address - default: http,https
|
||||||
|
#
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# usage 2: ynh_add_fail2ban_config --use_template [--others_var="list of others variables to replace"]
|
||||||
|
# | arg: -t, --use_template - Use this helper in template mode
|
||||||
|
# | arg: -v, --others_var= - List of others variables to replace separeted by a space
|
||||||
|
# | for example : 'var_1 var_2 ...'
|
||||||
|
#
|
||||||
|
# This will use a template in ../conf/f2b_jail.conf and ../conf/f2b_filter.conf
|
||||||
|
# __APP__ by $app
|
||||||
|
#
|
||||||
|
# You can dynamically replace others variables by example :
|
||||||
|
# __VAR_1__ by $var_1
|
||||||
|
# __VAR_2__ by $var_2
|
||||||
|
#
|
||||||
|
# Generally your template will look like that by example (for synapse):
|
||||||
|
#
|
||||||
|
# f2b_jail.conf:
|
||||||
|
# [__APP__]
|
||||||
|
# enabled = true
|
||||||
|
# port = http,https
|
||||||
|
# filter = __APP__
|
||||||
|
# logpath = /var/log/__APP__/logfile.log
|
||||||
|
# maxretry = 3
|
||||||
|
#
|
||||||
|
# f2b_filter.conf:
|
||||||
|
# [INCLUDES]
|
||||||
|
# before = common.conf
|
||||||
|
# [Definition]
|
||||||
|
#
|
||||||
|
# # Part of regex definition (just used to make more easy to make the global regex)
|
||||||
|
# __synapse_start_line = .? \- synapse\..+ \-
|
||||||
|
#
|
||||||
|
# # Regex definition.
|
||||||
|
# failregex = ^%(__synapse_start_line)s INFO \- POST\-(\d+)\- <HOST> \- \d+ \- Received request\: POST /_matrix/client/r0/login\??<SKIPLINES>%(__synapse_start_line)s INFO \- POST\-\1\- Got login request with identifier: \{u'type': u'm.id.user', u'user'\: u'(.+?)'\}, medium\: None, address: None, user\: u'\5'<SKIPLINES>%(__synapse_start_line)s WARNING \- \- (Attempted to login as @\5\:.+ but they do not exist|Failed password login for user @\5\:.+)$
|
||||||
|
#
|
||||||
|
# ignoreregex =
|
||||||
|
#
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Note about the "failregex" option:
|
||||||
|
# regex to match the password failure messages in the logfile. The
|
||||||
|
# host must be matched by a group named "host". The tag "<HOST>" can
|
||||||
|
# be used for standard IP/hostname matching and is only an alias for
|
||||||
|
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
||||||
|
#
|
||||||
|
# You can find some more explainations about how to make a regex here :
|
||||||
|
# https://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Filters
|
||||||
|
#
|
||||||
|
# Note that the logfile need to exist before to call this helper !!
|
||||||
|
#
|
||||||
|
# To validate your regex you can test with this command:
|
||||||
|
# fail2ban-regex /var/log/YOUR_LOG_FILE_PATH /etc/fail2ban/filter.d/YOUR_APP.conf
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.?.? or higher.
|
||||||
|
ynh_add_fail2ban_config () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=lrmptv
|
||||||
|
declare -Ar args_array=( [l]=logpath= [r]=failregex= [m]=max_retry= [p]=ports= [t]=use_template [v]=others_var=)
|
||||||
|
local logpath
|
||||||
|
local failregex
|
||||||
|
local max_retry
|
||||||
|
local ports
|
||||||
|
local others_var
|
||||||
|
local use_template
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
use_template="${use_template:-0}"
|
||||||
|
max_retry=${max_retry:-3}
|
||||||
|
ports=${ports:-http,https}
|
||||||
|
|
||||||
|
finalfail2banjailconf="/etc/fail2ban/jail.d/$app.conf"
|
||||||
|
finalfail2banfilterconf="/etc/fail2ban/filter.d/$app.conf"
|
||||||
|
ynh_backup_if_checksum_is_different "$finalfail2banjailconf"
|
||||||
|
ynh_backup_if_checksum_is_different "$finalfail2banfilterconf"
|
||||||
|
|
||||||
|
if [ $use_template -eq 1 ]
|
||||||
|
then
|
||||||
|
# Usage 2, templates
|
||||||
|
cp ../conf/f2b_jail.conf $finalfail2banjailconf
|
||||||
|
cp ../conf/f2b_filter.conf $finalfail2banfilterconf
|
||||||
|
|
||||||
|
if [ -n "${app:-}" ]
|
||||||
|
then
|
||||||
|
ynh_replace_string "__APP__" "$app" "$finalfail2banjailconf"
|
||||||
|
ynh_replace_string "__APP__" "$app" "$finalfail2banfilterconf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Replace all other variable given as arguments
|
||||||
|
for var_to_replace in ${others_var:-}; do
|
||||||
|
# ${var_to_replace^^} make the content of the variable on upper-cases
|
||||||
|
# ${!var_to_replace} get the content of the variable named $var_to_replace
|
||||||
|
ynh_replace_string --match_string="__${var_to_replace^^}__" --replace_string="${!var_to_replace}" --target_file="$finalfail2banjailconf"
|
||||||
|
ynh_replace_string --match_string="__${var_to_replace^^}__" --replace_string="${!var_to_replace}" --target_file="$finalfail2banfilterconf"
|
||||||
|
done
|
||||||
|
|
||||||
|
else
|
||||||
|
# Usage 1, no template. Build a config file from scratch.
|
||||||
|
test -n "$logpath" || ynh_die "ynh_add_fail2ban_config expects a logfile path as first argument and received nothing."
|
||||||
|
test -n "$failregex" || ynh_die "ynh_add_fail2ban_config expects a failure regex as second argument and received nothing."
|
||||||
|
|
||||||
|
tee $finalfail2banjailconf <<EOF
|
||||||
|
[$app]
|
||||||
|
enabled = true
|
||||||
|
port = $ports
|
||||||
|
filter = $app
|
||||||
|
logpath = $logpath
|
||||||
|
maxretry = $max_retry
|
||||||
|
EOF
|
||||||
|
|
||||||
|
tee $finalfail2banfilterconf <<EOF
|
||||||
|
[INCLUDES]
|
||||||
|
before = common.conf
|
||||||
|
[Definition]
|
||||||
|
failregex = $failregex
|
||||||
|
ignoreregex =
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Common to usage 1 and 2.
|
||||||
|
ynh_store_file_checksum "$finalfail2banjailconf"
|
||||||
|
ynh_store_file_checksum "$finalfail2banfilterconf"
|
||||||
|
|
||||||
|
ynh_systemd_action --service_name=fail2ban --action=reload
|
||||||
|
|
||||||
|
local fail2ban_error="$(journalctl -u fail2ban | tail -n50 | grep "WARNING.*$app.*")"
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove the dedicated fail2ban config (jail and filter conf files)
|
||||||
|
#
|
||||||
|
# usage: ynh_remove_fail2ban_config
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.?.? or higher.
|
||||||
|
ynh_remove_fail2ban_config () {
|
||||||
|
ynh_secure_remove "/etc/fail2ban/jail.d/$app.conf"
|
||||||
|
ynh_secure_remove "/etc/fail2ban/filter.d/$app.conf"
|
||||||
|
ynh_systemd_action --service_name=fail2ban --action=reload
|
||||||
|
}
|
|
@ -1,76 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Validate an IP address
|
|
||||||
#
|
|
||||||
# usage: ynh_validate_ip --family=family --ip_address=ip_address
|
|
||||||
# | ret: 0 for valid ip addresses, 1 otherwise
|
|
||||||
#
|
|
||||||
# example: ynh_validate_ip 4 111.222.333.444
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
|
||||||
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.
|
|
||||||
local legacy_args=fi
|
|
||||||
declare -Ar args_array=( [f]=family= [i]=ip_address= )
|
|
||||||
local family
|
|
||||||
local ip_address
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
[ "$family" == "4" ] || [ "$family" == "6" ] || return 1
|
|
||||||
|
|
||||||
python /dev/stdin << EOF
|
|
||||||
import socket
|
|
||||||
import sys
|
|
||||||
family = { "4" : socket.AF_INET, "6" : socket.AF_INET6 }
|
|
||||||
try:
|
|
||||||
socket.inet_pton(family["$family"], "$ip_address")
|
|
||||||
except socket.error:
|
|
||||||
sys.exit(1)
|
|
||||||
sys.exit(0)
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# Validate an IPv4 address
|
|
||||||
#
|
|
||||||
# example: ynh_validate_ip4 111.222.333.444
|
|
||||||
#
|
|
||||||
# usage: ynh_validate_ip4 --ip_address=ip_address
|
|
||||||
# | ret: 0 for valid ipv4 addresses, 1 otherwise
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
|
||||||
ynh_validate_ip4()
|
|
||||||
{
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=i
|
|
||||||
declare -Ar args_array=( [i]=ip_address= )
|
|
||||||
local ip_address
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
ynh_validate_ip 4 $ip_address
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Validate an IPv6 address
|
|
||||||
#
|
|
||||||
# example: ynh_validate_ip6 2000:dead:beef::1
|
|
||||||
#
|
|
||||||
# usage: ynh_validate_ip6 --ip_address=ip_address
|
|
||||||
# | ret: 0 for valid ipv6 addresses, 1 otherwise
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
|
||||||
ynh_validate_ip6()
|
|
||||||
{
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=i
|
|
||||||
declare -Ar args_array=( [i]=ip_address= )
|
|
||||||
local ip_address
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
ynh_validate_ip 6 $ip_address
|
|
||||||
}
|
|
|
@ -277,3 +277,69 @@ ynh_script_progression () {
|
||||||
|
|
||||||
ynh_print_info "[$progression_bar] > ${message}${print_exec_time}"
|
ynh_print_info "[$progression_bar] > ${message}${print_exec_time}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 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.?.? or higher.
|
||||||
|
ynh_debug () {
|
||||||
|
# Disable set xtrace for the helper itself, to not pollute the debug log
|
||||||
|
set +x
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=mt
|
||||||
|
declare -Ar args_array=( [m]=message= [t]=trace= )
|
||||||
|
local message
|
||||||
|
local trace
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
# Redisable xtrace, ynh_handle_getopts_args set it back
|
||||||
|
set +x
|
||||||
|
message=${message:-}
|
||||||
|
trace=${trace:-}
|
||||||
|
|
||||||
|
if [ -n "$message" ]
|
||||||
|
then
|
||||||
|
ynh_print_log "\e[34m\e[1m[DEBUG]\e[0m ${message}" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$trace" == "1" ]
|
||||||
|
then
|
||||||
|
ynh_debug --message="Enable debugging"
|
||||||
|
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 +x
|
||||||
|
# Put xtrace back to its original fild descriptor
|
||||||
|
BASH_XTRACEFD=$old_bash_xtracefd
|
||||||
|
# Restore stdout
|
||||||
|
exec 1>&1
|
||||||
|
fi
|
||||||
|
# Renable set xtrace
|
||||||
|
set -x
|
||||||
|
}
|
||||||
|
|
||||||
|
# Execute a command and print the result as debug
|
||||||
|
#
|
||||||
|
# usage: ynh_debug_exec command to execute
|
||||||
|
# usage: ynh_debug_exec "command to execute | following command"
|
||||||
|
# In case of use of pipes, you have to use double quotes. Otherwise, this helper will be executed with the first command, then be sent to the next pipe.
|
||||||
|
#
|
||||||
|
# | arg: command - command to execute
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.?.? or higher.
|
||||||
|
ynh_debug_exec () {
|
||||||
|
ynh_debug --message="$(eval $@)"
|
||||||
|
}
|
103
data/helpers.d/logrotate
Normal file
103
data/helpers.d/logrotate
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Use logrotate to manage the logfile
|
||||||
|
#
|
||||||
|
# usage: ynh_use_logrotate [--logfile=/log/file] [--nonappend] [--specific_user=user/group]
|
||||||
|
# | arg: -l, --logfile - absolute path of logfile
|
||||||
|
# | arg: -n, --nonappend - (optional) Replace the config file instead of appending this new config.
|
||||||
|
# | arg: -u, --specific_user : run logrotate as the specified user and group. If not specified logrotate is runned as root.
|
||||||
|
#
|
||||||
|
# If no --logfile is provided, /var/log/${app} will be used as default.
|
||||||
|
# logfile can be just a directory, or a full path to a logfile :
|
||||||
|
# /parentdir/logdir
|
||||||
|
# /parentdir/logdir/logfile.log
|
||||||
|
#
|
||||||
|
# It's possible to use this helper multiple times, each config will be added to
|
||||||
|
# the same logrotate config file. Unless you use the option --non-append
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
|
ynh_use_logrotate () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=lnuya
|
||||||
|
declare -Ar args_array=( [l]=logfile= [n]=nonappend [u]=specific_user= [y]=non [a]=append )
|
||||||
|
# [y]=non [a]=append are only for legacy purpose, to not fail on the old option '--non-append'
|
||||||
|
local logfile
|
||||||
|
local nonappend
|
||||||
|
local specific_user
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
local logfile="${logfile:-}"
|
||||||
|
local nonappend="${nonappend:-0}"
|
||||||
|
local specific_user="${specific_user:-}"
|
||||||
|
|
||||||
|
# LEGACY CODE - PRE GETOPTS
|
||||||
|
if [ $# -gt 0 ] && [ "$1" == "--non-append" ]; then
|
||||||
|
nonappend=1
|
||||||
|
# Destroy this argument for the next command.
|
||||||
|
shift
|
||||||
|
elif [ $# -gt 1 ] && [ "$2" == "--non-append" ]; then
|
||||||
|
nonappend=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $# -gt 0 ] && [ "$(echo ${1:0:1})" != "-" ]; then
|
||||||
|
if [ "$(echo ${1##*.})" == "log" ]; then # Keep only the extension to check if it's a logfile
|
||||||
|
local logfile=$1 # In this case, focus logrotate on the logfile
|
||||||
|
else
|
||||||
|
local logfile=$1/*.log # Else, uses the directory and all logfile into it.
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# LEGACY CODE
|
||||||
|
|
||||||
|
local customtee="tee -a"
|
||||||
|
if [ "$nonappend" -eq 1 ]; then
|
||||||
|
customtee="tee"
|
||||||
|
fi
|
||||||
|
if [ -n "$logfile" ]
|
||||||
|
then
|
||||||
|
if [ "$(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
|
||||||
|
else
|
||||||
|
logfile="/var/log/${app}/*.log" # Without argument, use a defaut directory in /var/log
|
||||||
|
fi
|
||||||
|
local su_directive=""
|
||||||
|
if [[ -n $specific_user ]]; then
|
||||||
|
su_directive=" # Run logorotate as specific user - group
|
||||||
|
su ${specific_user%/*} ${specific_user#*/}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat > ./${app}-logrotate << EOF # Build a config file for logrotate
|
||||||
|
$logfile {
|
||||||
|
# Rotate if the logfile exceeds 100Mo
|
||||||
|
size 100M
|
||||||
|
# Keep 12 old log maximum
|
||||||
|
rotate 12
|
||||||
|
# Compress the logs with gzip
|
||||||
|
compress
|
||||||
|
# Compress the log at the next cycle. So keep always 2 non compressed logs
|
||||||
|
delaycompress
|
||||||
|
# Copy and truncate the log to allow to continue write on it. Instead of move the log.
|
||||||
|
copytruncate
|
||||||
|
# Do not do an error if the log is missing
|
||||||
|
missingok
|
||||||
|
# Not rotate if the log is empty
|
||||||
|
notifempty
|
||||||
|
# Keep old logs in the same dir
|
||||||
|
noolddir
|
||||||
|
$su_directive
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
sudo mkdir -p $(dirname "$logfile") # Create the log directory, if not exist
|
||||||
|
cat ${app}-logrotate | sudo $customtee /etc/logrotate.d/$app > /dev/null # Append this config to the existing config file, or replace the whole config file (depending on $customtee)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove the app's logrotate config.
|
||||||
|
#
|
||||||
|
# usage: ynh_remove_logrotate
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
|
ynh_remove_logrotate () {
|
||||||
|
if [ -e "/etc/logrotate.d/$app" ]; then
|
||||||
|
sudo rm "/etc/logrotate.d/$app"
|
||||||
|
fi
|
||||||
|
}
|
|
@ -237,24 +237,3 @@ ynh_mysql_remove_db () {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Sanitize a string intended to be the name of a database
|
|
||||||
# (More specifically : replace - and . by _)
|
|
||||||
#
|
|
||||||
# example: dbname=$(ynh_sanitize_dbid $app)
|
|
||||||
#
|
|
||||||
# usage: ynh_sanitize_dbid --db_name=name
|
|
||||||
# | arg: -n, --db_name - name to correct/sanitize
|
|
||||||
# | ret: the corrected name
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
|
||||||
ynh_sanitize_dbid () {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=n
|
|
||||||
declare -Ar args_array=( [n]=db_name= )
|
|
||||||
local db_name
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
# We should avoid having - and . in the name of databases. They are replaced by _
|
|
||||||
echo ${db_name//[-.]/_}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,39 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Normalize the url path syntax
|
|
||||||
#
|
|
||||||
# Handle the slash at the beginning of path and its absence at ending
|
|
||||||
# Return a normalized url path
|
|
||||||
#
|
|
||||||
# examples:
|
|
||||||
# url_path=$(ynh_normalize_url_path $url_path)
|
|
||||||
# ynh_normalize_url_path example # -> /example
|
|
||||||
# ynh_normalize_url_path /example # -> /example
|
|
||||||
# ynh_normalize_url_path /example/ # -> /example
|
|
||||||
# ynh_normalize_url_path / # -> /
|
|
||||||
#
|
|
||||||
# usage: ynh_normalize_url_path --path_url=path_to_normalize
|
|
||||||
# | arg: -p, --path_url - URL path to normalize before using it
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_normalize_url_path () {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=p
|
|
||||||
declare -Ar args_array=( [p]=path_url= )
|
|
||||||
local path_url
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
test -n "$path_url" || ynh_die --message="ynh_normalize_url_path expect a URL path as first argument and received nothing."
|
|
||||||
if [ "${path_url:0:1}" != "/" ]; then # If the first character is not a /
|
|
||||||
path_url="/$path_url" # Add / at begin of path variable
|
|
||||||
fi
|
|
||||||
if [ "${path_url:${#path_url}-1}" == "/" ] && [ ${#path_url} -gt 1 ]; then # If the last character is a / and that not the only character.
|
|
||||||
path_url="${path_url:0:${#path_url}-1}" # Delete the last character
|
|
||||||
fi
|
|
||||||
echo $path_url
|
|
||||||
}
|
|
||||||
|
|
||||||
# Find a free port and return it
|
# Find a free port and return it
|
||||||
#
|
#
|
||||||
# example: port=$(ynh_find_port --port=8080)
|
# example: port=$(ynh_find_port --port=8080)
|
||||||
|
@ -58,46 +24,77 @@ ynh_find_port () {
|
||||||
echo $port
|
echo $port
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check availability of a web path
|
# Validate an IP address
|
||||||
#
|
#
|
||||||
# example: ynh_webpath_available --domain=some.domain.tld --path_url=/coffee
|
# usage: ynh_validate_ip --family=family --ip_address=ip_address
|
||||||
|
# | ret: 0 for valid ip addresses, 1 otherwise
|
||||||
#
|
#
|
||||||
# usage: ynh_webpath_available --domain=domain --path_url=path
|
# example: ynh_validate_ip 4 111.222.333.444
|
||||||
# | arg: -d, --domain - the domain/host of the url
|
|
||||||
# | arg: -p, --path_url - the web path to check the availability of
|
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_webpath_available () {
|
ynh_validate_ip()
|
||||||
# Declare an array to define the options of this helper.
|
{
|
||||||
local legacy_args=dp
|
# http://stackoverflow.com/questions/319279/how-to-validate-ip-address-in-python#319298
|
||||||
declare -Ar args_array=( [d]=domain= [p]=path_url= )
|
|
||||||
local domain
|
|
||||||
local path_url
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
sudo yunohost domain url-available $domain $path_url
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=fi
|
||||||
|
declare -Ar args_array=( [f]=family= [i]=ip_address= )
|
||||||
|
local family
|
||||||
|
local ip_address
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
[ "$family" == "4" ] || [ "$family" == "6" ] || return 1
|
||||||
|
|
||||||
|
python /dev/stdin << EOF
|
||||||
|
import socket
|
||||||
|
import sys
|
||||||
|
family = { "4" : socket.AF_INET, "6" : socket.AF_INET6 }
|
||||||
|
try:
|
||||||
|
socket.inet_pton(family["$family"], "$ip_address")
|
||||||
|
except socket.error:
|
||||||
|
sys.exit(1)
|
||||||
|
sys.exit(0)
|
||||||
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
# Register/book a web path for an app
|
# Validate an IPv4 address
|
||||||
#
|
#
|
||||||
# example: ynh_webpath_register --app=wordpress --domain=some.domain.tld --path_url=/coffee
|
# example: ynh_validate_ip4 111.222.333.444
|
||||||
#
|
#
|
||||||
# usage: ynh_webpath_register --app=app --domain=domain --path_url=path
|
# usage: ynh_validate_ip4 --ip_address=ip_address
|
||||||
# | arg: -a, --app - the app for which the domain should be registered
|
# | ret: 0 for valid ipv4 addresses, 1 otherwise
|
||||||
# | arg: -d, --domain - the domain/host of the web path
|
|
||||||
# | arg: -p, --path_url - the web path to be registered
|
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
ynh_webpath_register () {
|
ynh_validate_ip4()
|
||||||
# Declare an array to define the options of this helper.
|
{
|
||||||
local legacy_args=adp
|
# Declare an array to define the options of this helper.
|
||||||
declare -Ar args_array=( [a]=app= [d]=domain= [p]=path_url= )
|
local legacy_args=i
|
||||||
local app
|
declare -Ar args_array=( [i]=ip_address= )
|
||||||
local domain
|
local ip_address
|
||||||
local path_url
|
# Manage arguments with getopts
|
||||||
# Manage arguments with getopts
|
ynh_handle_getopts_args "$@"
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
sudo yunohost app register-url $app $domain $path_url
|
ynh_validate_ip 4 $ip_address
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Validate an IPv6 address
|
||||||
|
#
|
||||||
|
# example: ynh_validate_ip6 2000:dead:beef::1
|
||||||
|
#
|
||||||
|
# usage: ynh_validate_ip6 --ip_address=ip_address
|
||||||
|
# | ret: 0 for valid ipv6 addresses, 1 otherwise
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
|
ynh_validate_ip6()
|
||||||
|
{
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=i
|
||||||
|
declare -Ar args_array=( [i]=ip_address= )
|
||||||
|
local ip_address
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
ynh_validate_ip 6 $ip_address
|
||||||
}
|
}
|
||||||
|
|
76
data/helpers.d/nginx
Normal file
76
data/helpers.d/nginx
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Create a dedicated nginx config
|
||||||
|
#
|
||||||
|
# usage: ynh_add_nginx_config "list of others variables to replace"
|
||||||
|
#
|
||||||
|
# | arg: list - (Optional) list of others variables to replace separated by spaces. For example : 'path_2 port_2 ...'
|
||||||
|
#
|
||||||
|
# This will use a template in ../conf/nginx.conf
|
||||||
|
# __PATH__ by $path_url
|
||||||
|
# __DOMAIN__ by $domain
|
||||||
|
# __PORT__ by $port
|
||||||
|
# __NAME__ by $app
|
||||||
|
# __FINALPATH__ by $final_path
|
||||||
|
#
|
||||||
|
# And dynamic variables (from the last example) :
|
||||||
|
# __PATH_2__ by $path_2
|
||||||
|
# __PORT_2__ by $port_2
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.7.2 or higher.
|
||||||
|
ynh_add_nginx_config () {
|
||||||
|
finalnginxconf="/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||||
|
local others_var=${1:-}
|
||||||
|
ynh_backup_if_checksum_is_different --file="$finalnginxconf"
|
||||||
|
sudo cp ../conf/nginx.conf "$finalnginxconf"
|
||||||
|
|
||||||
|
# To avoid a break by set -u, use a void substitution ${var:-}. If the variable is not set, it's simply set with an empty variable.
|
||||||
|
# Substitute in a nginx config file only if the variable is not empty
|
||||||
|
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="$finalnginxconf"
|
||||||
|
ynh_replace_string --match_string="__PATH__" --replace_string="$path_url" --target_file="$finalnginxconf"
|
||||||
|
fi
|
||||||
|
if test -n "${domain:-}"; then
|
||||||
|
ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$finalnginxconf"
|
||||||
|
fi
|
||||||
|
if test -n "${port:-}"; then
|
||||||
|
ynh_replace_string --match_string="__PORT__" --replace_string="$port" --target_file="$finalnginxconf"
|
||||||
|
fi
|
||||||
|
if test -n "${app:-}"; then
|
||||||
|
ynh_replace_string --match_string="__NAME__" --replace_string="$app" --target_file="$finalnginxconf"
|
||||||
|
fi
|
||||||
|
if test -n "${final_path:-}"; then
|
||||||
|
ynh_replace_string --match_string="__FINALPATH__" --replace_string="$final_path" --target_file="$finalnginxconf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Replace all other variable given as arguments
|
||||||
|
for var_to_replace in $others_var
|
||||||
|
do
|
||||||
|
# ${var_to_replace^^} make the content of the variable on upper-cases
|
||||||
|
# ${!var_to_replace} get the content of the variable named $var_to_replace
|
||||||
|
ynh_replace_string --match_string="__${var_to_replace^^}__" --replace_string="${!var_to_replace}" --target_file="$finalnginxconf"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${path_url:-}" != "/" ]
|
||||||
|
then
|
||||||
|
ynh_replace_string --match_string="^#sub_path_only" --replace_string="" --target_file="$finalnginxconf"
|
||||||
|
else
|
||||||
|
ynh_replace_string --match_string="^#root_path_only" --replace_string="" --target_file="$finalnginxconf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ynh_store_file_checksum --file="$finalnginxconf"
|
||||||
|
|
||||||
|
ynh_systemd_action --service_name=nginx --action=reload
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove the dedicated nginx config
|
||||||
|
#
|
||||||
|
# usage: ynh_remove_nginx_config
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.7.2 or higher.
|
||||||
|
ynh_remove_nginx_config () {
|
||||||
|
ynh_secure_remove --file="/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||||
|
ynh_systemd_action --service_name=nginx --action=reload
|
||||||
|
}
|
67
data/helpers.d/php
Normal file
67
data/helpers.d/php
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Create a dedicated php-fpm config
|
||||||
|
#
|
||||||
|
# usage: ynh_add_fpm_config [--phpversion=7.X]
|
||||||
|
# | arg: -v, --phpversion - Version of php to use.
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.7.2 or higher.
|
||||||
|
ynh_add_fpm_config () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=v
|
||||||
|
declare -Ar args_array=( [v]=phpversion= )
|
||||||
|
local phpversion
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
# Configure PHP-FPM 7.0 by default
|
||||||
|
phpversion="${phpversion:-7.0}"
|
||||||
|
|
||||||
|
local fpm_config_dir="/etc/php/$phpversion/fpm"
|
||||||
|
local fpm_service="php${phpversion}-fpm"
|
||||||
|
# Configure PHP-FPM 5 on Debian Jessie
|
||||||
|
if [ "$(ynh_get_debian_release)" == "jessie" ]; then
|
||||||
|
fpm_config_dir="/etc/php5/fpm"
|
||||||
|
fpm_service="php5-fpm"
|
||||||
|
fi
|
||||||
|
ynh_app_setting_set --app=$app --key=fpm_config_dir --value="$fpm_config_dir"
|
||||||
|
ynh_app_setting_set --app=$app --key=fpm_service --value="$fpm_service"
|
||||||
|
finalphpconf="$fpm_config_dir/pool.d/$app.conf"
|
||||||
|
ynh_backup_if_checksum_is_different --file="$finalphpconf"
|
||||||
|
sudo cp ../conf/php-fpm.conf "$finalphpconf"
|
||||||
|
ynh_replace_string --match_string="__NAMETOCHANGE__" --replace_string="$app" --target_file="$finalphpconf"
|
||||||
|
ynh_replace_string --match_string="__FINALPATH__" --replace_string="$final_path" --target_file="$finalphpconf"
|
||||||
|
ynh_replace_string --match_string="__USER__" --replace_string="$app" --target_file="$finalphpconf"
|
||||||
|
ynh_replace_string --match_string="__PHPVERSION__" --replace_string="$phpversion" --target_file="$finalphpconf"
|
||||||
|
sudo chown root: "$finalphpconf"
|
||||||
|
ynh_store_file_checksum --file="$finalphpconf"
|
||||||
|
|
||||||
|
if [ -e "../conf/php-fpm.ini" ]
|
||||||
|
then
|
||||||
|
echo "Packagers ! Please do not use a separate php ini file, merge your directives in the pool file instead." >&2
|
||||||
|
finalphpini="$fpm_config_dir/conf.d/20-$app.ini"
|
||||||
|
ynh_backup_if_checksum_is_different "$finalphpini"
|
||||||
|
sudo cp ../conf/php-fpm.ini "$finalphpini"
|
||||||
|
sudo chown root: "$finalphpini"
|
||||||
|
ynh_store_file_checksum "$finalphpini"
|
||||||
|
fi
|
||||||
|
ynh_systemd_action --service_name=$fpm_service --action=reload
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove the dedicated php-fpm config
|
||||||
|
#
|
||||||
|
# usage: ynh_remove_fpm_config
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.7.2 or higher.
|
||||||
|
ynh_remove_fpm_config () {
|
||||||
|
local fpm_config_dir=$(ynh_app_setting_get --app=$app --key=fpm_config_dir)
|
||||||
|
local fpm_service=$(ynh_app_setting_get --app=$app --key=fpm_service)
|
||||||
|
# Assume php version 7 if not set
|
||||||
|
if [ -z "$fpm_config_dir" ]; then
|
||||||
|
fpm_config_dir="/etc/php/7.0/fpm"
|
||||||
|
fpm_service="php7.0-fpm"
|
||||||
|
fi
|
||||||
|
ynh_secure_remove --file="$fpm_config_dir/pool.d/$app.conf"
|
||||||
|
ynh_secure_remove --file="$fpm_config_dir/conf.d/20-$app.ini" 2>&1
|
||||||
|
ynh_systemd_action --service_name=$fpm_service --action=reload
|
||||||
|
}
|
|
@ -91,3 +91,47 @@ else:
|
||||||
yaml.safe_dump(settings, f, default_flow_style=False)
|
yaml.safe_dump(settings, f, default_flow_style=False)
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check availability of a web path
|
||||||
|
#
|
||||||
|
# example: ynh_webpath_available --domain=some.domain.tld --path_url=/coffee
|
||||||
|
#
|
||||||
|
# usage: ynh_webpath_available --domain=domain --path_url=path
|
||||||
|
# | arg: -d, --domain - the domain/host of the url
|
||||||
|
# | arg: -p, --path_url - the web path to check the availability of
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
|
ynh_webpath_available () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=dp
|
||||||
|
declare -Ar args_array=( [d]=domain= [p]=path_url= )
|
||||||
|
local domain
|
||||||
|
local path_url
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
sudo yunohost domain url-available $domain $path_url
|
||||||
|
}
|
||||||
|
|
||||||
|
# Register/book a web path for an app
|
||||||
|
#
|
||||||
|
# example: ynh_webpath_register --app=wordpress --domain=some.domain.tld --path_url=/coffee
|
||||||
|
#
|
||||||
|
# usage: ynh_webpath_register --app=app --domain=domain --path_url=path
|
||||||
|
# | arg: -a, --app - the app for which the domain should be registered
|
||||||
|
# | arg: -d, --domain - the domain/host of the web path
|
||||||
|
# | arg: -p, --path_url - the web path to be registered
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
|
ynh_webpath_register () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=adp
|
||||||
|
declare -Ar args_array=( [a]=app= [d]=domain= [p]=path_url= )
|
||||||
|
local app
|
||||||
|
local domain
|
||||||
|
local path_url
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
sudo yunohost app register-url $app $domain $path_url
|
||||||
|
}
|
||||||
|
|
|
@ -83,3 +83,59 @@ ynh_replace_special_string () {
|
||||||
|
|
||||||
ynh_replace_string --match_string="$match_string" --replace_string="$replace_string" --target_file="$target_file"
|
ynh_replace_string --match_string="$match_string" --replace_string="$replace_string" --target_file="$target_file"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Sanitize a string intended to be the name of a database
|
||||||
|
# (More specifically : replace - and . by _)
|
||||||
|
#
|
||||||
|
# example: dbname=$(ynh_sanitize_dbid $app)
|
||||||
|
#
|
||||||
|
# usage: ynh_sanitize_dbid --db_name=name
|
||||||
|
# | arg: -n, --db_name - name to correct/sanitize
|
||||||
|
# | ret: the corrected name
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
|
ynh_sanitize_dbid () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=n
|
||||||
|
declare -Ar args_array=( [n]=db_name= )
|
||||||
|
local db_name
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
# We should avoid having - and . in the name of databases. They are replaced by _
|
||||||
|
echo ${db_name//[-.]/_}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Normalize the url path syntax
|
||||||
|
#
|
||||||
|
# Handle the slash at the beginning of path and its absence at ending
|
||||||
|
# Return a normalized url path
|
||||||
|
#
|
||||||
|
# examples:
|
||||||
|
# url_path=$(ynh_normalize_url_path $url_path)
|
||||||
|
# ynh_normalize_url_path example # -> /example
|
||||||
|
# ynh_normalize_url_path /example # -> /example
|
||||||
|
# ynh_normalize_url_path /example/ # -> /example
|
||||||
|
# ynh_normalize_url_path / # -> /
|
||||||
|
#
|
||||||
|
# usage: ynh_normalize_url_path --path_url=path_to_normalize
|
||||||
|
# | arg: -p, --path_url - URL path to normalize before using it
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
|
ynh_normalize_url_path () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=p
|
||||||
|
declare -Ar args_array=( [p]=path_url= )
|
||||||
|
local path_url
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
test -n "$path_url" || ynh_die --message="ynh_normalize_url_path expect a URL path as first argument and received nothing."
|
||||||
|
if [ "${path_url:0:1}" != "/" ]; then # If the first character is not a /
|
||||||
|
path_url="/$path_url" # Add / at begin of path variable
|
||||||
|
fi
|
||||||
|
if [ "${path_url:${#path_url}-1}" == "/" ] && [ ${#path_url} -gt 1 ]; then # If the last character is a / and that not the only character.
|
||||||
|
path_url="${path_url:0:${#path_url}-1}" # Delete the last character
|
||||||
|
fi
|
||||||
|
echo $path_url
|
||||||
|
}
|
||||||
|
|
|
@ -1,285 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Manage a fail of the script
|
|
||||||
#
|
|
||||||
# [internal]
|
|
||||||
#
|
|
||||||
# usage:
|
|
||||||
# ynh_exit_properly is used only by the helper ynh_abort_if_errors.
|
|
||||||
# You should not use it directly.
|
|
||||||
# Instead, add to your script:
|
|
||||||
# ynh_clean_setup () {
|
|
||||||
# instructions...
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# This function provide a way to clean some residual of installation that not managed by remove script.
|
|
||||||
#
|
|
||||||
# It prints a warning to inform that the script was failed, and execute the ynh_clean_setup function if used in the app script
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_exit_properly () {
|
|
||||||
local exit_code=$?
|
|
||||||
if [ "$exit_code" -eq 0 ]; then
|
|
||||||
exit 0 # Exit without error if the script ended correctly
|
|
||||||
fi
|
|
||||||
|
|
||||||
trap '' EXIT # Ignore new exit signals
|
|
||||||
set +eu # Do not exit anymore if a command fail or if a variable is empty
|
|
||||||
|
|
||||||
ynh_print_err --message="!!\n $app's script has encountered an error. Its execution was cancelled.\n!!"
|
|
||||||
|
|
||||||
if type -t ynh_clean_setup > /dev/null; then # Check if the function exist in the app script.
|
|
||||||
ynh_clean_setup # Call the function to do specific cleaning for the app.
|
|
||||||
fi
|
|
||||||
|
|
||||||
ynh_die # Exit with error status
|
|
||||||
}
|
|
||||||
|
|
||||||
# Exits if an error occurs during the execution of the script.
|
|
||||||
#
|
|
||||||
# usage: ynh_abort_if_errors
|
|
||||||
#
|
|
||||||
# This configure the rest of the script execution such that, if an error occurs
|
|
||||||
# or if an empty variable is used, the execution of the script stops
|
|
||||||
# immediately and a call to `ynh_clean_setup` is triggered if it has been
|
|
||||||
# defined by your script.
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_abort_if_errors () {
|
|
||||||
set -eu # Exit if a command fail, and if a variable is used unset.
|
|
||||||
trap ynh_exit_properly EXIT # Capturing exit signals on shell script
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fetch the Debian release codename
|
|
||||||
#
|
|
||||||
# usage: ynh_get_debian_release
|
|
||||||
# | ret: The Debian release codename (i.e. jessie, stretch, ...)
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.7.12 or higher.
|
|
||||||
ynh_get_debian_release () {
|
|
||||||
echo $(lsb_release --codename --short)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Start (or other actions) a service, print a log in case of failure and optionnaly wait until the service is completely started
|
|
||||||
#
|
|
||||||
# usage: ynh_systemd_action [-n service_name] [-a action] [ [-l "line to match"] [-p log_path] [-t timeout] [-e length] ]
|
|
||||||
# | arg: -n, --service_name= - Name of the service to start. Default : $app
|
|
||||||
# | arg: -a, --action= - Action to perform with systemctl. Default: start
|
|
||||||
# | arg: -l, --line_match= - Line to match - The line to find in the log to attest the service have finished to boot.
|
|
||||||
# If not defined it don't wait until the service is completely started.
|
|
||||||
# WARNING: When using --line_match, you should always add `ynh_clean_check_starting` into your
|
|
||||||
# `ynh_clean_setup` at the beginning of the script. Otherwise, tail will not stop in case of failure
|
|
||||||
# of the script. The script will then hang forever.
|
|
||||||
# | arg: -p, --log_path= - Log file - Path to the log file. Default : /var/log/$app/$app.log
|
|
||||||
# | arg: -t, --timeout= - Timeout - The maximum time to wait before ending the watching. Default : 300 seconds.
|
|
||||||
# | arg: -e, --length= - Length of the error log : Default : 20
|
|
||||||
ynh_systemd_action() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=nalpte
|
|
||||||
declare -Ar args_array=( [n]=service_name= [a]=action= [l]=line_match= [p]=log_path= [t]=timeout= [e]=length= )
|
|
||||||
local service_name
|
|
||||||
local action
|
|
||||||
local line_match
|
|
||||||
local length
|
|
||||||
local log_path
|
|
||||||
local timeout
|
|
||||||
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
local service_name="${service_name:-$app}"
|
|
||||||
local action=${action:-start}
|
|
||||||
local log_path="${log_path:-/var/log/$service_name/$service_name.log}"
|
|
||||||
local length=${length:-20}
|
|
||||||
local timeout=${timeout:-300}
|
|
||||||
|
|
||||||
# Start to read the log
|
|
||||||
if [[ -n "${line_match:-}" ]]
|
|
||||||
then
|
|
||||||
local templog="$(mktemp)"
|
|
||||||
# Following the starting of the app in its log
|
|
||||||
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
|
|
||||||
local pid_tail=$!
|
|
||||||
else
|
|
||||||
# Read the specified log file
|
|
||||||
tail -F -n0 "$log_path" > "$templog" 2>&1 &
|
|
||||||
# Get the PID of the tail command
|
|
||||||
local pid_tail=$!
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
ynh_print_info --message="${action^} the service $service_name"
|
|
||||||
|
|
||||||
# Use reload-or-restart instead of reload. So it wouldn't fail if the service isn't running.
|
|
||||||
if [ "$action" == "reload" ]; then
|
|
||||||
action="reload-or-restart"
|
|
||||||
fi
|
|
||||||
|
|
||||||
systemctl $action $service_name \
|
|
||||||
|| ( journalctl --no-pager --lines=$length -u $service_name >&2 \
|
|
||||||
; test -e "$log_path" && echo "--" >&2 && tail --lines=$length "$log_path" >&2 \
|
|
||||||
; false )
|
|
||||||
|
|
||||||
# Start the timeout and try to find line_match
|
|
||||||
if [[ -n "${line_match:-}" ]]
|
|
||||||
then
|
|
||||||
local i=0
|
|
||||||
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 --quiet "$line_match" "$templog"
|
|
||||||
then
|
|
||||||
ynh_print_info --message="The service $service_name has correctly started."
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
if [ $i -eq 3 ]; then
|
|
||||||
echo -n "Please wait, the service $service_name is ${action}ing" >&2
|
|
||||||
fi
|
|
||||||
if [ $i -ge 3 ]; then
|
|
||||||
echo -n "." >&2
|
|
||||||
fi
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
if [ $i -ge 3 ]; then
|
|
||||||
echo "" >&2
|
|
||||||
fi
|
|
||||||
if [ $i -eq $timeout ]
|
|
||||||
then
|
|
||||||
ynh_print_warn --message="The service $service_name didn't fully started before the timeout."
|
|
||||||
ynh_print_warn --message="Please find here an extract of the end of the log of the service $service_name:"
|
|
||||||
journalctl --no-pager --lines=$length -u $service_name >&2
|
|
||||||
test -e "$log_path" && echo "--" >&2 && tail --lines=$length "$log_path" >&2
|
|
||||||
fi
|
|
||||||
ynh_clean_check_starting
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Clean temporary process and file used by ynh_check_starting
|
|
||||||
# (usually used in ynh_clean_setup scripts)
|
|
||||||
#
|
|
||||||
# usage: ynh_clean_check_starting
|
|
||||||
ynh_clean_check_starting () {
|
|
||||||
# Stop the execution of tail.
|
|
||||||
kill -s 15 $pid_tail 2>&1
|
|
||||||
ynh_secure_remove "$templog" 2>&1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Read the value of a key in a ynh manifest file
|
|
||||||
#
|
|
||||||
# usage: ynh_read_manifest manifest key
|
|
||||||
# | arg: -m, --manifest= - Path of the manifest to read
|
|
||||||
# | arg: -k, --key= - Name of the key to find
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.?.? or higher.
|
|
||||||
ynh_read_manifest () {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=mk
|
|
||||||
declare -Ar args_array=( [m]=manifest= [k]=manifest_key= )
|
|
||||||
local manifest
|
|
||||||
local manifest_key
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
if [ ! -e "$manifest" ]; then
|
|
||||||
# If the manifest isn't found, try the common place for backup and restore script.
|
|
||||||
manifest="../settings/manifest.json"
|
|
||||||
fi
|
|
||||||
|
|
||||||
jq ".$manifest_key" "$manifest" --raw-output
|
|
||||||
}
|
|
||||||
|
|
||||||
# Read the upstream version from the manifest
|
|
||||||
# The version number in the manifest is defined by <upstreamversion>~ynh<packageversion>
|
|
||||||
# For example : 4.3-2~ynh3
|
|
||||||
# This include the number before ~ynh
|
|
||||||
# In the last example it return 4.3-2
|
|
||||||
#
|
|
||||||
# usage: ynh_app_upstream_version [-m manifest]
|
|
||||||
# | arg: -m, --manifest= - Path of the manifest to read
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.?.? or higher.
|
|
||||||
ynh_app_upstream_version () {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=m
|
|
||||||
declare -Ar args_array=( [m]=manifest= )
|
|
||||||
local manifest
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
manifest="${manifest:-../manifest.json}"
|
|
||||||
version_key=$(ynh_read_manifest --manifest="$manifest" --manifest_key="version")
|
|
||||||
echo "${version_key/~ynh*/}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Read package version from the manifest
|
|
||||||
# The version number in the manifest is defined by <upstreamversion>~ynh<packageversion>
|
|
||||||
# For example : 4.3-2~ynh3
|
|
||||||
# This include the number after ~ynh
|
|
||||||
# In the last example it return 3
|
|
||||||
#
|
|
||||||
# usage: ynh_app_package_version [-m manifest]
|
|
||||||
# | arg: -m, --manifest= - Path of the manifest to read
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.?.? or higher.
|
|
||||||
ynh_app_package_version () {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=m
|
|
||||||
declare -Ar args_array=( [m]=manifest= )
|
|
||||||
local manifest
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
manifest="${manifest:-../manifest.json}"
|
|
||||||
version_key=$(ynh_read_manifest --manifest="$manifest" --manifest_key="version")
|
|
||||||
echo "${version_key/*~ynh/}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Checks the app version to upgrade with the existing app version and returns:
|
|
||||||
# - UPGRADE_APP if the upstream app version has changed
|
|
||||||
# - UPGRADE_PACKAGE if only the YunoHost package has changed
|
|
||||||
#
|
|
||||||
# It stops the current script without error if the package is up-to-date
|
|
||||||
#
|
|
||||||
# This helper should be used to avoid an upgrade of an app, or the upstream part
|
|
||||||
# of it, when it's not needed
|
|
||||||
#
|
|
||||||
# To force an upgrade, even if the package is up to date,
|
|
||||||
# you have to set the variable YNH_FORCE_UPGRADE before.
|
|
||||||
# example: sudo YNH_FORCE_UPGRADE=1 yunohost app upgrade MyApp
|
|
||||||
#
|
|
||||||
# usage: ynh_check_app_version_changed
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.?.? or higher.
|
|
||||||
ynh_check_app_version_changed () {
|
|
||||||
local force_upgrade=${YNH_FORCE_UPGRADE:-0}
|
|
||||||
local package_check=${PACKAGE_CHECK_EXEC:-0}
|
|
||||||
|
|
||||||
# By default, upstream app version has changed
|
|
||||||
local return_value="UPGRADE_APP"
|
|
||||||
|
|
||||||
local current_version=$(ynh_read_manifest --manifest="/etc/yunohost/apps/$YNH_APP_INSTANCE_NAME/manifest.json" --manifest_key="version" || echo 1.0)
|
|
||||||
local current_upstream_version="$(ynh_app_upstream_version --manifest="/etc/yunohost/apps/$YNH_APP_INSTANCE_NAME/manifest.json")"
|
|
||||||
local update_version=$(ynh_read_manifest --manifest="../manifest.json" --manifest_key="version" || echo 1.0)
|
|
||||||
local update_upstream_version="$(ynh_app_upstream_version)"
|
|
||||||
|
|
||||||
if [ "$current_version" == "$update_version" ] ; then
|
|
||||||
# Complete versions are the same
|
|
||||||
if [ "$force_upgrade" != "0" ]
|
|
||||||
then
|
|
||||||
ynh_print_info --message="Upgrade forced by YNH_FORCE_UPGRADE."
|
|
||||||
unset YNH_FORCE_UPGRADE
|
|
||||||
elif [ "$package_check" != "0" ]
|
|
||||||
then
|
|
||||||
ynh_print_info --message="Upgrade forced for package check."
|
|
||||||
else
|
|
||||||
ynh_die "Up-to-date, nothing to do" 0
|
|
||||||
fi
|
|
||||||
elif [ "$current_upstream_version" == "$update_upstream_version" ] ; then
|
|
||||||
# Upstream versions are the same, only YunoHost package versions differ
|
|
||||||
return_value="UPGRADE_PACKAGE"
|
|
||||||
fi
|
|
||||||
echo $return_value
|
|
||||||
}
|
|
179
data/helpers.d/systemd
Normal file
179
data/helpers.d/systemd
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Create a dedicated systemd config
|
||||||
|
#
|
||||||
|
# usage: ynh_add_systemd_config [--service=service] [--template=template]
|
||||||
|
# | arg: -s, --service - Service name (optionnal, $app by default)
|
||||||
|
# | arg: -t, --template - Name of template file (optionnal, this is 'systemd' by default, meaning ./conf/systemd.service will be used as template)
|
||||||
|
#
|
||||||
|
# This will use the template ../conf/<templatename>.service
|
||||||
|
# to generate a systemd config, by replacing the following keywords
|
||||||
|
# with global variables that should be defined before calling
|
||||||
|
# this helper :
|
||||||
|
#
|
||||||
|
# __APP__ by $app
|
||||||
|
# __FINALPATH__ by $final_path
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.7.2 or higher.
|
||||||
|
ynh_add_systemd_config () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=st
|
||||||
|
declare -Ar args_array=( [s]=service= [t]=template= )
|
||||||
|
local service
|
||||||
|
local template
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
local service="${service:-$app}"
|
||||||
|
local template="${template:-systemd.service}"
|
||||||
|
|
||||||
|
finalsystemdconf="/etc/systemd/system/$service.service"
|
||||||
|
ynh_backup_if_checksum_is_different --file="$finalsystemdconf"
|
||||||
|
sudo cp ../conf/$template "$finalsystemdconf"
|
||||||
|
|
||||||
|
# To avoid a break by set -u, use a void substitution ${var:-}. If the variable is not set, it's simply set with an empty variable.
|
||||||
|
# Substitute in a nginx config file only if the variable is not empty
|
||||||
|
if test -n "${final_path:-}"; then
|
||||||
|
ynh_replace_string --match_string="__FINALPATH__" --replace_string="$final_path" --target_file="$finalsystemdconf"
|
||||||
|
fi
|
||||||
|
if test -n "${app:-}"; then
|
||||||
|
ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$finalsystemdconf"
|
||||||
|
fi
|
||||||
|
ynh_store_file_checksum --file="$finalsystemdconf"
|
||||||
|
|
||||||
|
sudo chown root: "$finalsystemdconf"
|
||||||
|
sudo systemctl enable $service
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove the dedicated systemd config
|
||||||
|
#
|
||||||
|
# usage: ynh_remove_systemd_config [--service=service]
|
||||||
|
# | arg: -s, --service - Service name (optionnal, $app by default)
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.7.2 or higher.
|
||||||
|
ynh_remove_systemd_config () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=s
|
||||||
|
declare -Ar args_array=( [s]=service= )
|
||||||
|
local service
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
local service="${service:-$app}"
|
||||||
|
|
||||||
|
local finalsystemdconf="/etc/systemd/system/$service.service"
|
||||||
|
if [ -e "$finalsystemdconf" ]; then
|
||||||
|
ynh_systemd_action --service_name=$service --action=stop
|
||||||
|
systemctl disable $service
|
||||||
|
ynh_secure_remove --file="$finalsystemdconf"
|
||||||
|
systemctl daemon-reload
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start (or other actions) a service, print a log in case of failure and optionnaly wait until the service is completely started
|
||||||
|
#
|
||||||
|
# usage: ynh_systemd_action [-n service_name] [-a action] [ [-l "line to match"] [-p log_path] [-t timeout] [-e length] ]
|
||||||
|
# | arg: -n, --service_name= - Name of the service to start. Default : $app
|
||||||
|
# | arg: -a, --action= - Action to perform with systemctl. Default: start
|
||||||
|
# | arg: -l, --line_match= - Line to match - The line to find in the log to attest the service have finished to boot.
|
||||||
|
# If not defined it don't wait until the service is completely started.
|
||||||
|
# WARNING: When using --line_match, you should always add `ynh_clean_check_starting` into your
|
||||||
|
# `ynh_clean_setup` at the beginning of the script. Otherwise, tail will not stop in case of failure
|
||||||
|
# of the script. The script will then hang forever.
|
||||||
|
# | arg: -p, --log_path= - Log file - Path to the log file. Default : /var/log/$app/$app.log
|
||||||
|
# | arg: -t, --timeout= - Timeout - The maximum time to wait before ending the watching. Default : 300 seconds.
|
||||||
|
# | arg: -e, --length= - Length of the error log : Default : 20
|
||||||
|
ynh_systemd_action() {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=nalpte
|
||||||
|
declare -Ar args_array=( [n]=service_name= [a]=action= [l]=line_match= [p]=log_path= [t]=timeout= [e]=length= )
|
||||||
|
local service_name
|
||||||
|
local action
|
||||||
|
local line_match
|
||||||
|
local length
|
||||||
|
local log_path
|
||||||
|
local timeout
|
||||||
|
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
local service_name="${service_name:-$app}"
|
||||||
|
local action=${action:-start}
|
||||||
|
local log_path="${log_path:-/var/log/$service_name/$service_name.log}"
|
||||||
|
local length=${length:-20}
|
||||||
|
local timeout=${timeout:-300}
|
||||||
|
|
||||||
|
# Start to read the log
|
||||||
|
if [[ -n "${line_match:-}" ]]
|
||||||
|
then
|
||||||
|
local templog="$(mktemp)"
|
||||||
|
# Following the starting of the app in its log
|
||||||
|
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
|
||||||
|
local pid_tail=$!
|
||||||
|
else
|
||||||
|
# Read the specified log file
|
||||||
|
tail -F -n0 "$log_path" > "$templog" 2>&1 &
|
||||||
|
# Get the PID of the tail command
|
||||||
|
local pid_tail=$!
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
ynh_print_info --message="${action^} the service $service_name"
|
||||||
|
|
||||||
|
# Use reload-or-restart instead of reload. So it wouldn't fail if the service isn't running.
|
||||||
|
if [ "$action" == "reload" ]; then
|
||||||
|
action="reload-or-restart"
|
||||||
|
fi
|
||||||
|
|
||||||
|
systemctl $action $service_name \
|
||||||
|
|| ( journalctl --no-pager --lines=$length -u $service_name >&2 \
|
||||||
|
; test -e "$log_path" && echo "--" >&2 && tail --lines=$length "$log_path" >&2 \
|
||||||
|
; false )
|
||||||
|
|
||||||
|
# Start the timeout and try to find line_match
|
||||||
|
if [[ -n "${line_match:-}" ]]
|
||||||
|
then
|
||||||
|
local i=0
|
||||||
|
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 --quiet "$line_match" "$templog"
|
||||||
|
then
|
||||||
|
ynh_print_info --message="The service $service_name has correctly started."
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if [ $i -eq 3 ]; then
|
||||||
|
echo -n "Please wait, the service $service_name is ${action}ing" >&2
|
||||||
|
fi
|
||||||
|
if [ $i -ge 3 ]; then
|
||||||
|
echo -n "." >&2
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
if [ $i -ge 3 ]; then
|
||||||
|
echo "" >&2
|
||||||
|
fi
|
||||||
|
if [ $i -eq $timeout ]
|
||||||
|
then
|
||||||
|
ynh_print_warn --message="The service $service_name didn't fully started before the timeout."
|
||||||
|
ynh_print_warn --message="Please find here an extract of the end of the log of the service $service_name:"
|
||||||
|
journalctl --no-pager --lines=$length -u $service_name >&2
|
||||||
|
test -e "$log_path" && echo "--" >&2 && tail --lines=$length "$log_path" >&2
|
||||||
|
fi
|
||||||
|
ynh_clean_check_starting
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Clean temporary process and file used by ynh_check_starting
|
||||||
|
# (usually used in ynh_clean_setup scripts)
|
||||||
|
#
|
||||||
|
# usage: ynh_clean_check_starting
|
||||||
|
ynh_clean_check_starting () {
|
||||||
|
# Stop the execution of tail.
|
||||||
|
kill -s 15 $pid_tail 2>&1
|
||||||
|
ynh_secure_remove "$templog" 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,113 +1,53 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Extract a key from a plain command output
|
# Manage a fail of the script
|
||||||
#
|
#
|
||||||
# example: yunohost user info tata --output-as plain | ynh_get_plain_key mail
|
# [internal]
|
||||||
#
|
|
||||||
# usage: ynh_get_plain_key key [subkey [subsubkey ...]]
|
|
||||||
# | ret: string - the key's value
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.2.4 or higher.
|
|
||||||
ynh_get_plain_key() {
|
|
||||||
local prefix="#"
|
|
||||||
local founded=0
|
|
||||||
local key=$1
|
|
||||||
shift
|
|
||||||
while read line; do
|
|
||||||
if [[ "$founded" == "1" ]] ; then
|
|
||||||
[[ "$line" =~ ^${prefix}[^#] ]] && return
|
|
||||||
echo $line
|
|
||||||
elif [[ "$line" =~ ^${prefix}${key}$ ]]; then
|
|
||||||
if [[ -n "${1:-}" ]]; then
|
|
||||||
prefix+="#"
|
|
||||||
key=$1
|
|
||||||
shift
|
|
||||||
else
|
|
||||||
founded=1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Restore a previous backup if the upgrade process failed
|
|
||||||
#
|
#
|
||||||
# usage:
|
# usage:
|
||||||
# ynh_backup_before_upgrade
|
# ynh_exit_properly is used only by the helper ynh_abort_if_errors.
|
||||||
|
# You should not use it directly.
|
||||||
|
# Instead, add to your script:
|
||||||
# ynh_clean_setup () {
|
# ynh_clean_setup () {
|
||||||
# ynh_restore_upgradebackup
|
# instructions...
|
||||||
# }
|
# }
|
||||||
# ynh_abort_if_errors
|
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
# This function provide a way to clean some residual of installation that not managed by remove script.
|
||||||
ynh_restore_upgradebackup () {
|
|
||||||
ynh_print_err --message="Upgrade failed."
|
|
||||||
local app_bck=${app//_/-} # Replace all '_' by '-'
|
|
||||||
|
|
||||||
NO_BACKUP_UPGRADE=${NO_BACKUP_UPGRADE:-0}
|
|
||||||
|
|
||||||
if [ "$NO_BACKUP_UPGRADE" -eq 0 ]
|
|
||||||
then
|
|
||||||
# Check if an existing backup can be found before removing and restoring the application.
|
|
||||||
if sudo yunohost backup list | grep -q $app_bck-pre-upgrade$backup_number
|
|
||||||
then
|
|
||||||
# Remove the application then restore it
|
|
||||||
sudo yunohost app remove $app
|
|
||||||
# Restore the backup
|
|
||||||
sudo yunohost backup restore $app_bck-pre-upgrade$backup_number --apps $app --force --debug
|
|
||||||
ynh_die --message="The app was restored to the way it was before the failed upgrade."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
ynh_print_warn --message="\$NO_BACKUP_UPGRADE is set, that means there's no backup to restore. You have to fix this upgrade by yourself !"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Make a backup in case of failed upgrade
|
|
||||||
#
|
#
|
||||||
# usage:
|
# It prints a warning to inform that the script was failed, and execute the ynh_clean_setup function if used in the app script
|
||||||
# ynh_backup_before_upgrade
|
|
||||||
# ynh_clean_setup () {
|
|
||||||
# ynh_restore_upgradebackup
|
|
||||||
# }
|
|
||||||
# ynh_abort_if_errors
|
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.7.2 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_backup_before_upgrade () {
|
ynh_exit_properly () {
|
||||||
if [ ! -e "/etc/yunohost/apps/$app/scripts/backup" ]
|
local exit_code=$?
|
||||||
then
|
if [ "$exit_code" -eq 0 ]; then
|
||||||
ynh_print_warn --message="This app doesn't have any backup script."
|
exit 0 # Exit without error if the script ended correctly
|
||||||
return
|
|
||||||
fi
|
fi
|
||||||
backup_number=1
|
|
||||||
local old_backup_number=2
|
|
||||||
local app_bck=${app//_/-} # Replace all '_' by '-'
|
|
||||||
NO_BACKUP_UPGRADE=${NO_BACKUP_UPGRADE:-0}
|
|
||||||
|
|
||||||
if [ "$NO_BACKUP_UPGRADE" -eq 0 ]
|
trap '' EXIT # Ignore new exit signals
|
||||||
then
|
set +eu # Do not exit anymore if a command fail or if a variable is empty
|
||||||
# Check if a backup already exists with the prefix 1
|
|
||||||
if sudo yunohost backup list | grep -q $app_bck-pre-upgrade1
|
|
||||||
then
|
|
||||||
# Prefix becomes 2 to preserve the previous backup
|
|
||||||
backup_number=2
|
|
||||||
old_backup_number=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create backup
|
ynh_print_err --message="!!\n $app's script has encountered an error. Its execution was cancelled.\n!!"
|
||||||
sudo BACKUP_CORE_ONLY=1 yunohost backup create --apps $app --name $app_bck-pre-upgrade$backup_number --debug
|
|
||||||
if [ "$?" -eq 0 ]
|
if type -t ynh_clean_setup > /dev/null; then # Check if the function exist in the app script.
|
||||||
then
|
ynh_clean_setup # Call the function to do specific cleaning for the app.
|
||||||
# If the backup succeeded, remove the previous backup
|
fi
|
||||||
if sudo yunohost backup list | grep -q $app_bck-pre-upgrade$old_backup_number
|
|
||||||
then
|
ynh_die # Exit with error status
|
||||||
# Remove the previous backup only if it exists
|
}
|
||||||
sudo yunohost backup delete $app_bck-pre-upgrade$old_backup_number > /dev/null
|
|
||||||
fi
|
# Exits if an error occurs during the execution of the script.
|
||||||
else
|
#
|
||||||
ynh_die --message="Backup failed, the upgrade process was aborted."
|
# usage: ynh_abort_if_errors
|
||||||
fi
|
#
|
||||||
else
|
# This configure the rest of the script execution such that, if an error occurs
|
||||||
ynh_print_warn --message="\$NO_BACKUP_UPGRADE is set, backup will be avoided. Be careful, this upgrade is going to be operated without a security backup"
|
# or if an empty variable is used, the execution of the script stops
|
||||||
fi
|
# immediately and a call to `ynh_clean_setup` is triggered if it has been
|
||||||
|
# defined by your script.
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
|
ynh_abort_if_errors () {
|
||||||
|
set -eu # Exit if a command fail, and if a variable is used unset.
|
||||||
|
trap ynh_exit_properly EXIT # Capturing exit signals on shell script
|
||||||
}
|
}
|
||||||
|
|
||||||
# Download, check integrity, uncompress and patch the source from app.src
|
# Download, check integrity, uncompress and patch the source from app.src
|
||||||
|
@ -129,7 +69,7 @@ ynh_backup_before_upgrade () {
|
||||||
# SOURCE_IN_SUBDIR=false
|
# SOURCE_IN_SUBDIR=false
|
||||||
# # (Optionnal) Name of the local archive (offline setup support)
|
# # (Optionnal) Name of the local archive (offline setup support)
|
||||||
# # default: ${src_id}.${src_format}
|
# # default: ${src_id}.${src_format}
|
||||||
# SOURCE_FILENAME=example.tar.gz
|
# SOURCE_FILENAME=example.tar.gz
|
||||||
# # (Optional) If it set as false don't extract the source.
|
# # (Optional) If it set as false don't extract the source.
|
||||||
# # (Useful to get a debian package or a python wheel.)
|
# # (Useful to get a debian package or a python wheel.)
|
||||||
# # default: true
|
# # default: true
|
||||||
|
@ -212,7 +152,7 @@ ynh_setup_source () {
|
||||||
then
|
then
|
||||||
mv $src_filename $dest_dir
|
mv $src_filename $dest_dir
|
||||||
elif [ "$src_format" = "zip" ]
|
elif [ "$src_format" = "zip" ]
|
||||||
then
|
then
|
||||||
# Zip format
|
# Zip format
|
||||||
# Using of a temp directory, because unzip doesn't manage --strip-components
|
# Using of a temp directory, because unzip doesn't manage --strip-components
|
||||||
if $src_in_subdir ; then
|
if $src_in_subdir ; then
|
||||||
|
@ -262,7 +202,7 @@ ynh_setup_source () {
|
||||||
# $domain and $path_url should be defined externally (and correspond to the domain.tld and the /path (of the app?))
|
# $domain and $path_url should be defined externally (and correspond to the domain.tld and the /path (of the app?))
|
||||||
#
|
#
|
||||||
# example: ynh_local_curl "/install.php?installButton" "foo=$var1" "bar=$var2"
|
# example: ynh_local_curl "/install.php?installButton" "foo=$var1" "bar=$var2"
|
||||||
#
|
#
|
||||||
# usage: ynh_local_curl "page_uri" "key1=value1" "key2=value2" ...
|
# usage: ynh_local_curl "page_uri" "key1=value1" "key2=value2" ...
|
||||||
# | arg: page_uri - Path (relative to $path_url) of the page where POST data will be sent
|
# | arg: page_uri - Path (relative to $path_url) of the page where POST data will be sent
|
||||||
# | arg: key1=value1 - (Optionnal) POST key and corresponding value
|
# | arg: key1=value1 - (Optionnal) POST key and corresponding value
|
||||||
|
@ -271,38 +211,38 @@ ynh_setup_source () {
|
||||||
#
|
#
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
ynh_local_curl () {
|
ynh_local_curl () {
|
||||||
# Define url of page to curl
|
# Define url of page to curl
|
||||||
local local_page=$(ynh_normalize_url_path $1)
|
local local_page=$(ynh_normalize_url_path $1)
|
||||||
local full_path=$path_url$local_page
|
local full_path=$path_url$local_page
|
||||||
|
|
||||||
if [ "${path_url}" == "/" ]; then
|
|
||||||
full_path=$local_page
|
|
||||||
fi
|
|
||||||
|
|
||||||
local full_page_url=https://localhost$full_path
|
|
||||||
|
|
||||||
# Concatenate all other arguments with '&' to prepare POST data
|
if [ "${path_url}" == "/" ]; then
|
||||||
local POST_data=""
|
full_path=$local_page
|
||||||
local arg=""
|
fi
|
||||||
for arg in "${@:2}"
|
|
||||||
do
|
|
||||||
POST_data="${POST_data}${arg}&"
|
|
||||||
done
|
|
||||||
if [ -n "$POST_data" ]
|
|
||||||
then
|
|
||||||
# Add --data arg and remove the last character, which is an unecessary '&'
|
|
||||||
POST_data="--data ${POST_data::-1}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Wait untils nginx has fully reloaded (avoid curl fail with http2)
|
|
||||||
sleep 2
|
|
||||||
|
|
||||||
# Curl the URL
|
local full_page_url=https://localhost$full_path
|
||||||
curl --silent --show-error -kL -H "Host: $domain" --resolve $domain:443:127.0.0.1 $POST_data "$full_page_url"
|
|
||||||
|
# Concatenate all other arguments with '&' to prepare POST data
|
||||||
|
local POST_data=""
|
||||||
|
local arg=""
|
||||||
|
for arg in "${@:2}"
|
||||||
|
do
|
||||||
|
POST_data="${POST_data}${arg}&"
|
||||||
|
done
|
||||||
|
if [ -n "$POST_data" ]
|
||||||
|
then
|
||||||
|
# Add --data arg and remove the last character, which is an unecessary '&'
|
||||||
|
POST_data="--data ${POST_data::-1}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Wait untils nginx has fully reloaded (avoid curl fail with http2)
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
# Curl the URL
|
||||||
|
curl --silent --show-error -kL -H "Host: $domain" --resolve $domain:443:127.0.0.1 $POST_data "$full_page_url"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Render templates with Jinja2
|
# Render templates with Jinja2
|
||||||
#
|
#
|
||||||
# Attention : Variables should be exported before calling this helper to be
|
# Attention : Variables should be exported before calling this helper to be
|
||||||
# accessible inside templates.
|
# accessible inside templates.
|
||||||
#
|
#
|
||||||
|
@ -318,3 +258,220 @@ ynh_render_template() {
|
||||||
jinja2.Template(sys.stdin.read()
|
jinja2.Template(sys.stdin.read()
|
||||||
).render(os.environ));' < $template_path > $output_path
|
).render(os.environ));' < $template_path > $output_path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Fetch the Debian release codename
|
||||||
|
#
|
||||||
|
# usage: ynh_get_debian_release
|
||||||
|
# | ret: The Debian release codename (i.e. jessie, stretch, ...)
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.7.12 or higher.
|
||||||
|
ynh_get_debian_release () {
|
||||||
|
echo $(lsb_release --codename --short)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create a directory under /tmp
|
||||||
|
#
|
||||||
|
# [internal]
|
||||||
|
#
|
||||||
|
# Deprecated helper
|
||||||
|
#
|
||||||
|
# usage: ynh_mkdir_tmp
|
||||||
|
# | ret: the created directory path
|
||||||
|
ynh_mkdir_tmp() {
|
||||||
|
ynh_print_warn --message="The helper ynh_mkdir_tmp is deprecated."
|
||||||
|
ynh_print_warn --message="You should use 'mktemp -d' instead and manage permissions \
|
||||||
|
properly with chmod/chown."
|
||||||
|
local TMP_DIR=$(mktemp -d)
|
||||||
|
|
||||||
|
# Give rights to other users could be a security risk.
|
||||||
|
# But for retrocompatibility we need it. (This helpers is deprecated)
|
||||||
|
chmod 755 $TMP_DIR
|
||||||
|
echo $TMP_DIR
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove a file or a directory securely
|
||||||
|
#
|
||||||
|
# usage: ynh_secure_remove --file=path_to_remove
|
||||||
|
# | arg: -f, --file - File or directory to remove
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.6.4 or higher.
|
||||||
|
ynh_secure_remove () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=f
|
||||||
|
declare -Ar args_array=( [f]=file= )
|
||||||
|
local file
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
local forbidden_path=" \
|
||||||
|
/var/www \
|
||||||
|
/home/yunohost.app"
|
||||||
|
|
||||||
|
if [ $# -ge 2 ]
|
||||||
|
then
|
||||||
|
ynh_print_warn --message="/!\ Packager ! You provided more than one argument to ynh_secure_remove but it will be ignored... Use this helper with one argument at time."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$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="Avoid deleting $file."
|
||||||
|
else
|
||||||
|
if [ -e "$file" ]
|
||||||
|
then
|
||||||
|
sudo rm -R "$file"
|
||||||
|
else
|
||||||
|
ynh_print_info --message="$file wasn't deleted because it doesn't exist."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Extract a key from a plain command output
|
||||||
|
#
|
||||||
|
# example: yunohost user info tata --output-as plain | ynh_get_plain_key mail
|
||||||
|
#
|
||||||
|
# usage: ynh_get_plain_key key [subkey [subsubkey ...]]
|
||||||
|
# | ret: string - the key's value
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 2.2.4 or higher.
|
||||||
|
ynh_get_plain_key() {
|
||||||
|
local prefix="#"
|
||||||
|
local founded=0
|
||||||
|
local key=$1
|
||||||
|
shift
|
||||||
|
while read line; do
|
||||||
|
if [[ "$founded" == "1" ]] ; then
|
||||||
|
[[ "$line" =~ ^${prefix}[^#] ]] && return
|
||||||
|
echo $line
|
||||||
|
elif [[ "$line" =~ ^${prefix}${key}$ ]]; then
|
||||||
|
if [[ -n "${1:-}" ]]; then
|
||||||
|
prefix+="#"
|
||||||
|
key=$1
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
founded=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Read the value of a key in a ynh manifest file
|
||||||
|
#
|
||||||
|
# usage: ynh_read_manifest manifest key
|
||||||
|
# | arg: -m, --manifest= - Path of the manifest to read
|
||||||
|
# | arg: -k, --key= - Name of the key to find
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.?.? or higher.
|
||||||
|
ynh_read_manifest () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=mk
|
||||||
|
declare -Ar args_array=( [m]=manifest= [k]=manifest_key= )
|
||||||
|
local manifest
|
||||||
|
local manifest_key
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
if [ ! -e "$manifest" ]; then
|
||||||
|
# If the manifest isn't found, try the common place for backup and restore script.
|
||||||
|
manifest="../settings/manifest.json"
|
||||||
|
fi
|
||||||
|
|
||||||
|
jq ".$manifest_key" "$manifest" --raw-output
|
||||||
|
}
|
||||||
|
|
||||||
|
# Read the upstream version from the manifest
|
||||||
|
# The version number in the manifest is defined by <upstreamversion>~ynh<packageversion>
|
||||||
|
# For example : 4.3-2~ynh3
|
||||||
|
# This include the number before ~ynh
|
||||||
|
# In the last example it return 4.3-2
|
||||||
|
#
|
||||||
|
# usage: ynh_app_upstream_version [-m manifest]
|
||||||
|
# | arg: -m, --manifest= - Path of the manifest to read
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.?.? or higher.
|
||||||
|
ynh_app_upstream_version () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=m
|
||||||
|
declare -Ar args_array=( [m]=manifest= )
|
||||||
|
local manifest
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
manifest="${manifest:-../manifest.json}"
|
||||||
|
version_key=$(ynh_read_manifest --manifest="$manifest" --manifest_key="version")
|
||||||
|
echo "${version_key/~ynh*/}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Read package version from the manifest
|
||||||
|
# The version number in the manifest is defined by <upstreamversion>~ynh<packageversion>
|
||||||
|
# For example : 4.3-2~ynh3
|
||||||
|
# This include the number after ~ynh
|
||||||
|
# In the last example it return 3
|
||||||
|
#
|
||||||
|
# usage: ynh_app_package_version [-m manifest]
|
||||||
|
# | arg: -m, --manifest= - Path of the manifest to read
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.?.? or higher.
|
||||||
|
ynh_app_package_version () {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=m
|
||||||
|
declare -Ar args_array=( [m]=manifest= )
|
||||||
|
local manifest
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
manifest="${manifest:-../manifest.json}"
|
||||||
|
version_key=$(ynh_read_manifest --manifest="$manifest" --manifest_key="version")
|
||||||
|
echo "${version_key/*~ynh/}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Checks the app version to upgrade with the existing app version and returns:
|
||||||
|
# - UPGRADE_APP if the upstream app version has changed
|
||||||
|
# - UPGRADE_PACKAGE if only the YunoHost package has changed
|
||||||
|
#
|
||||||
|
# It stops the current script without error if the package is up-to-date
|
||||||
|
#
|
||||||
|
# This helper should be used to avoid an upgrade of an app, or the upstream part
|
||||||
|
# of it, when it's not needed
|
||||||
|
#
|
||||||
|
# To force an upgrade, even if the package is up to date,
|
||||||
|
# you have to set the variable YNH_FORCE_UPGRADE before.
|
||||||
|
# example: sudo YNH_FORCE_UPGRADE=1 yunohost app upgrade MyApp
|
||||||
|
#
|
||||||
|
# usage: ynh_check_app_version_changed
|
||||||
|
#
|
||||||
|
# Requires YunoHost version 3.?.? or higher.
|
||||||
|
ynh_check_app_version_changed () {
|
||||||
|
local force_upgrade=${YNH_FORCE_UPGRADE:-0}
|
||||||
|
local package_check=${PACKAGE_CHECK_EXEC:-0}
|
||||||
|
|
||||||
|
# By default, upstream app version has changed
|
||||||
|
local return_value="UPGRADE_APP"
|
||||||
|
|
||||||
|
local current_version=$(ynh_read_manifest --manifest="/etc/yunohost/apps/$YNH_APP_INSTANCE_NAME/manifest.json" --manifest_key="version" || echo 1.0)
|
||||||
|
local current_upstream_version="$(ynh_app_upstream_version --manifest="/etc/yunohost/apps/$YNH_APP_INSTANCE_NAME/manifest.json")"
|
||||||
|
local update_version=$(ynh_read_manifest --manifest="../manifest.json" --manifest_key="version" || echo 1.0)
|
||||||
|
local update_upstream_version="$(ynh_app_upstream_version)"
|
||||||
|
|
||||||
|
if [ "$current_version" == "$update_version" ] ; then
|
||||||
|
# Complete versions are the same
|
||||||
|
if [ "$force_upgrade" != "0" ]
|
||||||
|
then
|
||||||
|
ynh_print_info --message="Upgrade forced by YNH_FORCE_UPGRADE."
|
||||||
|
unset YNH_FORCE_UPGRADE
|
||||||
|
elif [ "$package_check" != "0" ]
|
||||||
|
then
|
||||||
|
ynh_print_info --message="Upgrade forced for package check."
|
||||||
|
else
|
||||||
|
ynh_die "Up-to-date, nothing to do" 0
|
||||||
|
fi
|
||||||
|
elif [ "$current_upstream_version" == "$update_upstream_version" ] ; then
|
||||||
|
# Upstream versions are the same, only YunoHost package versions differ
|
||||||
|
return_value="UPGRADE_PACKAGE"
|
||||||
|
fi
|
||||||
|
echo $return_value
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue