mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge branch 'dev' of https://github.com/YunoHost/yunohost into dev
This commit is contained in:
commit
1c675cbb74
52 changed files with 260 additions and 312 deletions
|
@ -295,6 +295,9 @@ user:
|
||||||
action_help: List permissions and corresponding accesses
|
action_help: List permissions and corresponding accesses
|
||||||
api: GET /users/permissions
|
api: GET /users/permissions
|
||||||
arguments:
|
arguments:
|
||||||
|
apps:
|
||||||
|
help: Apps to list permission for (all by default)
|
||||||
|
nargs: "*"
|
||||||
-s:
|
-s:
|
||||||
full: --short
|
full: --short
|
||||||
help: Only list permission names
|
help: Only list permission names
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
n_version=7.0.2
|
n_version=7.1.0
|
||||||
n_install_dir="/opt/node_n"
|
n_install_dir="/opt/node_n"
|
||||||
node_version_path="$n_install_dir/n/versions/node"
|
node_version_path="$n_install_dir/n/versions/node"
|
||||||
# N_PREFIX is the directory of n, it needs to be loaded as a environment variable.
|
# N_PREFIX is the directory of n, it needs to be loaded as a environment variable.
|
||||||
|
@ -17,7 +17,7 @@ ynh_install_n () {
|
||||||
ynh_print_info --message="Installation of N - Node.js version management"
|
ynh_print_info --message="Installation of N - Node.js version management"
|
||||||
# Build an app.src for n
|
# Build an app.src for n
|
||||||
echo "SOURCE_URL=https://github.com/tj/n/archive/v${n_version}.tar.gz
|
echo "SOURCE_URL=https://github.com/tj/n/archive/v${n_version}.tar.gz
|
||||||
SOURCE_SUM=fa80a8685f0fb1b4187fc0a1228b44f0ea2f244e063fe8f443b8913ea595af89" > "$YNH_APP_BASEDIR/conf/n.src"
|
SOURCE_SUM=20100f3bc56648cc414717fb7367fcf0e8229dc59a10b0530ccac90042ee0a74" > "$YNH_APP_BASEDIR/conf/n.src"
|
||||||
# Download and extract n
|
# Download and extract n
|
||||||
ynh_setup_source --dest_dir="$n_install_dir/git" --source_id=n
|
ynh_setup_source --dest_dir="$n_install_dir/git" --source_id=n
|
||||||
# Install n
|
# Install n
|
||||||
|
|
|
@ -182,7 +182,7 @@ ynh_permission_exists() {
|
||||||
local permission
|
local permission
|
||||||
ynh_handle_getopts_args "$@"
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
yunohost user permission list --output-as json --quiet \
|
yunohost user permission list "$app" --output-as json --quiet \
|
||||||
| jq -e --arg perm "$app.$permission" '.permissions[$perm]' >/dev/null
|
| jq -e --arg perm "$app.$permission" '.permissions[$perm]' >/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
0
data/hooks/backup/05-conf_ldap
Executable file → Normal file
0
data/hooks/backup/05-conf_ldap
Executable file → Normal file
|
@ -1,17 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Exit hook on subcommand error or unset variable
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
# Source YNH helpers
|
|
||||||
source /usr/share/yunohost/helpers
|
|
||||||
|
|
||||||
# Backup destination
|
|
||||||
backup_dir="${1}/conf/ssh"
|
|
||||||
|
|
||||||
# Backup the configuration
|
|
||||||
if [ -d /etc/ssh/ ]; then
|
|
||||||
ynh_backup "/etc/ssh" "$backup_dir"
|
|
||||||
else
|
|
||||||
echo "SSH is not installed"
|
|
||||||
fi
|
|
|
@ -1,13 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Exit hook on subcommand error or unset variable
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
# Source YNH helpers
|
|
||||||
source /usr/share/yunohost/helpers
|
|
||||||
|
|
||||||
# Backup destination
|
|
||||||
backup_dir="${1}/conf/ssowat"
|
|
||||||
|
|
||||||
# Backup the configuration
|
|
||||||
ynh_backup "/etc/ssowat" "$backup_dir"
|
|
0
data/hooks/backup/17-data_home
Executable file → Normal file
0
data/hooks/backup/17-data_home
Executable file → Normal file
|
@ -1,13 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Exit hook on subcommand error or unset variable
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
# Source YNH helpers
|
|
||||||
source /usr/share/yunohost/helpers
|
|
||||||
|
|
||||||
# Backup destination
|
|
||||||
backup_dir="${1}/conf/ynh/firewall"
|
|
||||||
|
|
||||||
# Backup the configuration
|
|
||||||
ynh_backup "/etc/yunohost/firewall.yml" "${backup_dir}/firewall.yml"
|
|
17
data/hooks/backup/20-conf_ynh_settings
Normal file
17
data/hooks/backup/20-conf_ynh_settings
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Exit hook on subcommand error or unset variable
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# Source YNH helpers
|
||||||
|
source /usr/share/yunohost/helpers
|
||||||
|
|
||||||
|
# Backup destination
|
||||||
|
backup_dir="${1}/conf/ynh"
|
||||||
|
|
||||||
|
# Backup the configuration
|
||||||
|
ynh_backup "/etc/yunohost/firewall.yml" "${backup_dir}/firewall.yml"
|
||||||
|
ynh_backup "/etc/yunohost/current_host" "${backup_dir}/current_host"
|
||||||
|
[ ! -e "/etc/yunohost/settings.json" ] || ynh_backup "/etc/yunohost/settings.json" "${backup_dir}/settings.json"
|
||||||
|
[ ! -d "/etc/yunohost/dyndns" ] || ynh_backup "/etc/yunohost/dyndns" "${backup_dir}/dyndns"
|
||||||
|
[ ! -d "/etc/dkim" ] || ynh_backup "/etc/dkim" "${backup_dir}/dkim"
|
0
data/hooks/backup/21-conf_ynh_certs
Executable file → Normal file
0
data/hooks/backup/21-conf_ynh_certs
Executable file → Normal file
|
@ -1,9 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
source /usr/share/yunohost/helpers
|
|
||||||
ynh_abort_if_errors
|
|
||||||
YNH_CWD="${YNH_BACKUP_DIR%/}/conf/dkim"
|
|
||||||
mkdir -p "$YNH_CWD"
|
|
||||||
cd "$YNH_CWD"
|
|
||||||
|
|
||||||
ynh_backup --src_path="/etc/dkim"
|
|
0
data/hooks/backup/23-data_mail
Executable file → Normal file
0
data/hooks/backup/23-data_mail
Executable file → Normal file
|
@ -1,14 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Exit hook on subcommand error or unset variable
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
# Source YNH helpers
|
|
||||||
source /usr/share/yunohost/helpers
|
|
||||||
|
|
||||||
# Backup destination
|
|
||||||
backup_dir="${1}/conf/xmpp"
|
|
||||||
|
|
||||||
# Backup the configuration
|
|
||||||
ynh_backup /etc/metronome "${backup_dir}/etc"
|
|
||||||
ynh_backup /var/lib/metronome "${backup_dir}/var"
|
|
13
data/hooks/backup/27-data_xmpp
Normal file
13
data/hooks/backup/27-data_xmpp
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Exit hook on subcommand error or unset variable
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# Source YNH helpers
|
||||||
|
source /usr/share/yunohost/helpers
|
||||||
|
|
||||||
|
# Backup destination
|
||||||
|
backup_dir="${1}/data/xmpp"
|
||||||
|
|
||||||
|
ynh_backup /var/lib/metronome "${backup_dir}/var_lib_metronome"
|
||||||
|
ynh_backup /var/xmpp-upload/ "${backup_dir}/var_xmpp-upload"
|
|
@ -1,13 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Exit hook on subcommand error or unset variable
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
# Source YNH helpers
|
|
||||||
source /usr/share/yunohost/helpers
|
|
||||||
|
|
||||||
# Backup destination
|
|
||||||
backup_dir="${1}/conf/nginx"
|
|
||||||
|
|
||||||
# Backup the configuration
|
|
||||||
ynh_backup "/etc/nginx/conf.d" "$backup_dir"
|
|
|
@ -1,13 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Exit hook on subcommand error or unset variable
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
# Source YNH helpers
|
|
||||||
source /usr/share/yunohost/helpers
|
|
||||||
|
|
||||||
# Backup destination
|
|
||||||
backup_dir="${1}/conf/ynh"
|
|
||||||
|
|
||||||
# Backup the configuration
|
|
||||||
ynh_backup "/etc/yunohost/current_host" "${backup_dir}/current_host"
|
|
|
@ -1,10 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
source /usr/share/yunohost/helpers
|
|
||||||
ynh_abort_if_errors
|
|
||||||
YNH_CWD="${YNH_BACKUP_DIR%/}/conf/ynh/dyndns"
|
|
||||||
mkdir -p $YNH_CWD
|
|
||||||
cd "$YNH_CWD"
|
|
||||||
|
|
||||||
# Backup the configuration
|
|
||||||
ynh_exec_warn_less ynh_backup --src_path="/etc/yunohost/dyndns" --not_mandatory
|
|
18
data/hooks/backup/50-conf_manually_modified_files
Normal file
18
data/hooks/backup/50-conf_manually_modified_files
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
source /usr/share/yunohost/helpers
|
||||||
|
ynh_abort_if_errors
|
||||||
|
YNH_CWD="${YNH_BACKUP_DIR%/}/conf/manually_modified_files"
|
||||||
|
mkdir -p "$YNH_CWD"
|
||||||
|
cd "$YNH_CWD"
|
||||||
|
|
||||||
|
yunohost tools shell -c "from yunohost.regenconf import manually_modified_files; print('\n'.join(manually_modified_files()))" > ./manually_modified_files_list
|
||||||
|
|
||||||
|
ynh_backup --src_path="./manually_modified_files_list"
|
||||||
|
|
||||||
|
for file in $(cat ./manually_modified_files_list)
|
||||||
|
do
|
||||||
|
ynh_backup --src_path="$file"
|
||||||
|
done
|
||||||
|
|
||||||
|
ynh_backup --src_path="/etc/ssowat/conf.json.persistent"
|
|
@ -1,61 +1,54 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
backup_dir="${1}/conf/ldap"
|
backup_dir="${1}/conf/ldap"
|
||||||
|
|
||||||
if [[ $EUID -ne 0 ]]; then
|
systemctl stop slapd
|
||||||
|
|
||||||
# We need to execute this script as root, since the ldap
|
# Create a directory for backup
|
||||||
# service will be shut down during the operation (and sudo
|
TMPDIR="/tmp/$(date +%s)"
|
||||||
# won't be available)
|
mkdir -p "$TMPDIR"
|
||||||
/bin/bash $(readlink -f $0) $1
|
|
||||||
|
|
||||||
else
|
die() {
|
||||||
|
state=$1
|
||||||
|
error=$2
|
||||||
|
|
||||||
service slapd stop || true
|
# Restore saved configuration and database
|
||||||
|
[[ $state -ge 1 ]] \
|
||||||
|
&& (rm -rf /etc/ldap/slapd.d &&
|
||||||
|
mv "${TMPDIR}/slapd.d" /etc/ldap/slapd.d)
|
||||||
|
[[ $state -ge 2 ]] \
|
||||||
|
&& (rm -rf /var/lib/ldap &&
|
||||||
|
mv "${TMPDIR}/ldap" /var/lib/ldap)
|
||||||
|
chown -R openldap: /etc/ldap/slapd.d /var/lib/ldap
|
||||||
|
|
||||||
# Create a directory for backup
|
systemctl start slapd
|
||||||
TMPDIR="/tmp/$(date +%s)"
|
|
||||||
mkdir -p "$TMPDIR"
|
|
||||||
|
|
||||||
die() {
|
|
||||||
state=$1
|
|
||||||
error=$2
|
|
||||||
|
|
||||||
# Restore saved configuration and database
|
|
||||||
[[ $state -ge 1 ]] \
|
|
||||||
&& (rm -rf /etc/ldap/slapd.d &&
|
|
||||||
mv "${TMPDIR}/slapd.d" /etc/ldap/slapd.d)
|
|
||||||
[[ $state -ge 2 ]] \
|
|
||||||
&& (rm -rf /var/lib/ldap &&
|
|
||||||
mv "${TMPDIR}/ldap" /var/lib/ldap)
|
|
||||||
chown -R openldap: /etc/ldap/slapd.d /var/lib/ldap
|
|
||||||
|
|
||||||
service slapd start
|
|
||||||
rm -rf "$TMPDIR"
|
|
||||||
|
|
||||||
# Print an error message and exit
|
|
||||||
printf "%s" "$error" 1>&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Restore the configuration
|
|
||||||
mv /etc/ldap/slapd.d "$TMPDIR"
|
|
||||||
mkdir -p /etc/ldap/slapd.d
|
|
||||||
cp -a "${backup_dir}/ldap.conf" /etc/ldap/ldap.conf
|
|
||||||
cp -a "${backup_dir}/slapd.ldif" /etc/ldap/slapd.ldif
|
|
||||||
# Legacy thing but we need it to force the regen-conf in case of it exist
|
|
||||||
cp -a "${backup_dir}/slapd.conf" /etc/ldap/slapd.conf
|
|
||||||
slapadd -F /etc/ldap/slapd.d -b cn=config \
|
|
||||||
-l "${backup_dir}/cn=config.master.ldif" \
|
|
||||||
|| die 1 "Unable to restore LDAP configuration"
|
|
||||||
chown -R openldap: /etc/ldap/slapd.d
|
|
||||||
|
|
||||||
# Restore the database
|
|
||||||
mv /var/lib/ldap "$TMPDIR"
|
|
||||||
mkdir -p /var/lib/ldap
|
|
||||||
slapadd -F /etc/ldap/slapd.d -b dc=yunohost,dc=org \
|
|
||||||
-l "${backup_dir}/dc=yunohost-dc=org.ldif" \
|
|
||||||
|| die 2 "Unable to restore LDAP database"
|
|
||||||
chown -R openldap: /var/lib/ldap
|
|
||||||
|
|
||||||
service slapd start
|
|
||||||
rm -rf "$TMPDIR"
|
rm -rf "$TMPDIR"
|
||||||
fi
|
|
||||||
|
# Print an error message and exit
|
||||||
|
printf "%s" "$error" 1>&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Restore the configuration
|
||||||
|
mv /etc/ldap/slapd.d "$TMPDIR"
|
||||||
|
mkdir -p /etc/ldap/slapd.d
|
||||||
|
cp -a "${backup_dir}/ldap.conf" /etc/ldap/ldap.conf
|
||||||
|
cp -a "${backup_dir}/slapd.ldif" /etc/ldap/slapd.ldif
|
||||||
|
# Legacy thing but we need it to force the regen-conf in case of it exist
|
||||||
|
[ ! -e "${backup_dir}/slapd.conf" ] \
|
||||||
|
|| cp -a "${backup_dir}/slapd.conf" /etc/ldap/slapd.conf
|
||||||
|
slapadd -F /etc/ldap/slapd.d -b cn=config \
|
||||||
|
-l "${backup_dir}/cn=config.master.ldif" \
|
||||||
|
|| die 1 "Unable to restore LDAP configuration"
|
||||||
|
chown -R openldap: /etc/ldap/slapd.d
|
||||||
|
|
||||||
|
# Restore the database
|
||||||
|
mv /var/lib/ldap "$TMPDIR"
|
||||||
|
mkdir -p /var/lib/ldap
|
||||||
|
slapadd -F /etc/ldap/slapd.d -b dc=yunohost,dc=org \
|
||||||
|
-l "${backup_dir}/dc=yunohost-dc=org.ldif" \
|
||||||
|
|| die 2 "Unable to restore LDAP database"
|
||||||
|
chown -R openldap: /var/lib/ldap
|
||||||
|
|
||||||
|
systemctl start slapd
|
||||||
|
rm -rf "$TMPDIR"
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
backup_dir="$1/conf/ssh"
|
|
||||||
|
|
||||||
if [ -d /etc/ssh/ ]; then
|
|
||||||
cp -a $backup_dir/. /etc/ssh
|
|
||||||
service ssh restart
|
|
||||||
else
|
|
||||||
echo "SSH is not installed"
|
|
||||||
fi
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
backup_dir="$1/conf/ssowat"
|
|
||||||
|
|
||||||
cp -a $backup_dir/. /etc/ssowat
|
|
|
@ -1,4 +0,0 @@
|
||||||
backup_dir="$1/conf/ynh/firewall"
|
|
||||||
|
|
||||||
cp -a $backup_dir/. /etc/yunohost
|
|
||||||
yunohost firewall reload
|
|
7
data/hooks/restore/20-conf_ynh_settings
Normal file
7
data/hooks/restore/20-conf_ynh_settings
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
backup_dir="$1/conf/ynh"
|
||||||
|
|
||||||
|
cp -a "${backup_dir}/current_host" /etc/yunohost/current_host
|
||||||
|
cp -a "${backup_dir}/firewall.yml" /etc/yunohost/firewall.yml
|
||||||
|
[ ! -e "${backup_dir}/settings.json" ] || cp -a "${backup_dir}/settings.json" "/etc/yunohost/settings.json"
|
||||||
|
[ ! -d "${backup_dir}/dyndns" ] || cp -raT "${backup_dir}/dyndns" "/etc/yunohost/dyndns"
|
||||||
|
[ ! -d "${backup_dir}/dkim" ] || cp -raT "${backup_dir}/dkim" "/etc/dkim"
|
|
@ -3,5 +3,3 @@ backup_dir="$1/conf/ynh/certs"
|
||||||
mkdir -p /etc/yunohost/certs/
|
mkdir -p /etc/yunohost/certs/
|
||||||
|
|
||||||
cp -a $backup_dir/. /etc/yunohost/certs/
|
cp -a $backup_dir/. /etc/yunohost/certs/
|
||||||
service nginx reload
|
|
||||||
service metronome reload
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
backup_dir="$1/conf/dkim"
|
|
||||||
|
|
||||||
cp -a $backup_dir/etc/dkim/. /etc/dkim
|
|
||||||
|
|
||||||
chown -R root:root /etc/dkim
|
|
||||||
chown _rspamd:root /etc/dkim
|
|
||||||
chown _rspamd:root /etc/dkim/*.mail.key
|
|
|
@ -2,7 +2,3 @@ backup_dir="$1/data/mail"
|
||||||
|
|
||||||
cp -a $backup_dir/. /var/mail/ || echo 'No mail found'
|
cp -a $backup_dir/. /var/mail/ || echo 'No mail found'
|
||||||
chown -R vmail:mail /var/mail/
|
chown -R vmail:mail /var/mail/
|
||||||
|
|
||||||
# Restart services to use migrated certs
|
|
||||||
service postfix restart
|
|
||||||
service dovecot restart
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
backup_dir="$1/conf/xmpp"
|
|
||||||
|
|
||||||
cp -a $backup_dir/etc/. /etc/metronome
|
|
||||||
cp -a $backup_dir/var/. /var/lib/metronome
|
|
||||||
|
|
||||||
# Restart to apply new conf and certs
|
|
||||||
service metronome restart
|
|
4
data/hooks/restore/27-data_xmpp
Normal file
4
data/hooks/restore/27-data_xmpp
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
backup_dir="$1/data/xmpp"
|
||||||
|
|
||||||
|
cp -a $backup_dir/var_lib_metronome/. /var/lib/metronome
|
||||||
|
cp -a $backup_dir/var_xmpp-upload/. /var/xmpp-upload
|
|
@ -1,7 +0,0 @@
|
||||||
backup_dir="$1/conf/nginx"
|
|
||||||
|
|
||||||
# Copy all conf except apps specific conf located in DOMAIN.d
|
|
||||||
find $backup_dir/ -mindepth 1 -maxdepth 1 -name '*.d' -or -exec cp -a {} /etc/nginx/conf.d/ \;
|
|
||||||
|
|
||||||
# Restart to use new conf and certs
|
|
||||||
service nginx restart
|
|
|
@ -1,3 +0,0 @@
|
||||||
backup_dir="$1/conf/ynh"
|
|
||||||
|
|
||||||
cp -a "${backup_dir}/current_host" /etc/yunohost/current_host
|
|
|
@ -1,9 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
source /usr/share/yunohost/helpers
|
|
||||||
ynh_abort_if_errors
|
|
||||||
YNH_CWD="${YNH_BACKUP_DIR%/}/conf/ynh/dyndns"
|
|
||||||
cd "$YNH_CWD"
|
|
||||||
|
|
||||||
# Restore file if exists
|
|
||||||
ynh_restore_file --origin_path="/etc/yunohost/dyndns" --not_mandatory
|
|
13
data/hooks/restore/50-conf_manually_modified_files
Normal file
13
data/hooks/restore/50-conf_manually_modified_files
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
source /usr/share/yunohost/helpers
|
||||||
|
ynh_abort_if_errors
|
||||||
|
YNH_CWD="${YNH_BACKUP_DIR%/}/conf/manually_modified_files"
|
||||||
|
cd "$YNH_CWD"
|
||||||
|
|
||||||
|
for file in $(cat ./manually_modified_files_list)
|
||||||
|
do
|
||||||
|
ynh_restore_file --origin_path="$file" --not_mandatory
|
||||||
|
done
|
||||||
|
|
||||||
|
ynh_restore_file --origin_path="/etc/ssowat/conf.json.persistent" --not_mandatory
|
|
@ -6,6 +6,6 @@ location /yunohost/admin/ {
|
||||||
default_type text/html;
|
default_type text/html;
|
||||||
index index.html;
|
index index.html;
|
||||||
|
|
||||||
more_set_headers "Content-Security-Policy: upgrade-insecure-requests; default-src 'self'; connect-src 'self' https://raw.githubusercontent.com https://paste.yunohost.org wss://$host; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-eval'; object-src 'none';";
|
more_set_headers "Content-Security-Policy: upgrade-insecure-requests; default-src 'self'; connect-src 'self' https://raw.githubusercontent.com https://paste.yunohost.org wss://$host; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-eval'; object-src 'none'; img-src 'self' data:;";
|
||||||
more_set_headers "Content-Security-Policy-Report-Only:";
|
more_set_headers "Content-Security-Policy-Report-Only:";
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,12 @@ smtpd_tls_loglevel=1
|
||||||
|
|
||||||
# -- TLS for outgoing connections
|
# -- TLS for outgoing connections
|
||||||
# Use TLS if this is supported by the remote SMTP server, otherwise use plaintext.
|
# Use TLS if this is supported by the remote SMTP server, otherwise use plaintext.
|
||||||
|
{% if relay_port == "465" %}
|
||||||
|
smtp_tls_wrappermode = yes
|
||||||
|
smtp_tls_security_level = encrypt
|
||||||
|
{% else %}
|
||||||
smtp_tls_security_level = may
|
smtp_tls_security_level = may
|
||||||
|
{% endif %}
|
||||||
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
|
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
|
||||||
smtp_tls_exclude_ciphers = aNULL, MD5, DES, ADH, RC4, 3DES
|
smtp_tls_exclude_ciphers = aNULL, MD5, DES, ADH, RC4, 3DES
|
||||||
smtp_tls_mandatory_ciphers= high
|
smtp_tls_mandatory_ciphers= high
|
||||||
|
|
|
@ -327,7 +327,7 @@
|
||||||
"regenconf_failed": "No s'ha pogut regenerar la configuració per la/les categoria/es : {categories}",
|
"regenconf_failed": "No s'ha pogut regenerar la configuració per la/les categoria/es : {categories}",
|
||||||
"regenconf_pending_applying": "Aplicació de la configuració pendent per la categoria «{category}»...",
|
"regenconf_pending_applying": "Aplicació de la configuració pendent per la categoria «{category}»...",
|
||||||
"restore_already_installed_app": "Una aplicació amb la ID «{app:s}» ja està instal·lada",
|
"restore_already_installed_app": "Una aplicació amb la ID «{app:s}» ja està instal·lada",
|
||||||
"restore_app_failed": "No s'ha pogut restaurar {app:s}",
|
"app_restore_failed": "No s'ha pogut restaurar {app:s}: {error:s}",
|
||||||
"restore_cleaning_failed": "No s'ha pogut netejar el directori temporal de restauració",
|
"restore_cleaning_failed": "No s'ha pogut netejar el directori temporal de restauració",
|
||||||
"restore_complete": "Restauració completada",
|
"restore_complete": "Restauració completada",
|
||||||
"restore_confirm_yunohost_installed": "Esteu segur de voler restaurar un sistema ja instal·lat? [{answers:s}]",
|
"restore_confirm_yunohost_installed": "Esteu segur de voler restaurar un sistema ja instal·lat? [{answers:s}]",
|
||||||
|
|
|
@ -96,7 +96,7 @@
|
||||||
"port_already_closed": "Der Port {port:d} wurde bereits für {ip_version:s} Verbindungen geschlossen",
|
"port_already_closed": "Der Port {port:d} wurde bereits für {ip_version:s} Verbindungen geschlossen",
|
||||||
"port_already_opened": "Der Port {port:d} wird bereits von {ip_version:s} benutzt",
|
"port_already_opened": "Der Port {port:d} wird bereits von {ip_version:s} benutzt",
|
||||||
"restore_already_installed_app": "Es ist bereits eine App mit der ID '{app:s}' installiet",
|
"restore_already_installed_app": "Es ist bereits eine App mit der ID '{app:s}' installiet",
|
||||||
"restore_app_failed": "'{app:s}' konnte nicht wiederhergestellt werden",
|
"restore_app_failed": "'{app:s}' konnte nicht wiederhergestellt werden: {error:s}",
|
||||||
"restore_cleaning_failed": "Das temporäre Dateiverzeichnis für Systemrestaurierung konnte nicht gelöscht werden",
|
"restore_cleaning_failed": "Das temporäre Dateiverzeichnis für Systemrestaurierung konnte nicht gelöscht werden",
|
||||||
"restore_complete": "Vollständig wiederhergestellt",
|
"restore_complete": "Vollständig wiederhergestellt",
|
||||||
"restore_confirm_yunohost_installed": "Möchtest du die Wiederherstellung wirklich starten? [{answers:s}]",
|
"restore_confirm_yunohost_installed": "Möchtest du die Wiederherstellung wirklich starten? [{answers:s}]",
|
||||||
|
|
|
@ -44,6 +44,8 @@
|
||||||
"app_requirements_checking": "Checking required packages for {app}...",
|
"app_requirements_checking": "Checking required packages for {app}...",
|
||||||
"app_requirements_unmeet": "Requirements are not met for {app}, the package {pkgname} ({version}) must be {spec}",
|
"app_requirements_unmeet": "Requirements are not met for {app}, the package {pkgname} ({version}) must be {spec}",
|
||||||
"app_remove_after_failed_install": "Removing the app following the installation failure...",
|
"app_remove_after_failed_install": "Removing the app following the installation failure...",
|
||||||
|
"app_restore_failed": "Could not restore {app:s}: {error:s}",
|
||||||
|
"app_restore_script_failed": "An error occured inside the app restore script",
|
||||||
"app_sources_fetch_failed": "Could not fetch sources files, is the URL correct?",
|
"app_sources_fetch_failed": "Could not fetch sources files, is the URL correct?",
|
||||||
"app_start_install": "Installing {app}...",
|
"app_start_install": "Installing {app}...",
|
||||||
"app_start_remove": "Removing {app}...",
|
"app_start_remove": "Removing {app}...",
|
||||||
|
@ -524,7 +526,6 @@
|
||||||
"regex_with_only_domain": "You can't use a regex for domain, only for path",
|
"regex_with_only_domain": "You can't use a regex for domain, only for path",
|
||||||
"restore_already_installed_app": "An app with the ID '{app:s}' is already installed",
|
"restore_already_installed_app": "An app with the ID '{app:s}' is already installed",
|
||||||
"restore_already_installed_apps": "The following apps can't be restored because they are already installed: {apps}",
|
"restore_already_installed_apps": "The following apps can't be restored because they are already installed: {apps}",
|
||||||
"restore_app_failed": "Could not restore {app:s}",
|
|
||||||
"restore_backup_too_old": "This backup archive can not be restored because it comes from a too-old YunoHost version.",
|
"restore_backup_too_old": "This backup archive can not be restored because it comes from a too-old YunoHost version.",
|
||||||
"restore_cleaning_failed": "Could not clean up the temporary restoration directory",
|
"restore_cleaning_failed": "Could not clean up the temporary restoration directory",
|
||||||
"restore_complete": "Restoration completed",
|
"restore_complete": "Restoration completed",
|
||||||
|
|
|
@ -479,7 +479,7 @@
|
||||||
"service_restarted": "Servo '{service:s}' rekomencis",
|
"service_restarted": "Servo '{service:s}' rekomencis",
|
||||||
"pattern_username": "Devas esti minuskulaj literoj kaj minuskloj nur",
|
"pattern_username": "Devas esti minuskulaj literoj kaj minuskloj nur",
|
||||||
"extracting": "Eltirante…",
|
"extracting": "Eltirante…",
|
||||||
"restore_app_failed": "Ne povis restarigi la programon '{app:s}'",
|
"app_restore_failed": "Ne povis restarigi la programon '{app:s}': {error:s}",
|
||||||
"yunohost_configured": "YunoHost nun estas agordita",
|
"yunohost_configured": "YunoHost nun estas agordita",
|
||||||
"certmanager_self_ca_conf_file_not_found": "Ne povis trovi agorddosieron por mem-subskriba aŭtoritato (dosiero: {file:s})",
|
"certmanager_self_ca_conf_file_not_found": "Ne povis trovi agorddosieron por mem-subskriba aŭtoritato (dosiero: {file:s})",
|
||||||
"log_app_remove": "Forigu la aplikon '{}'",
|
"log_app_remove": "Forigu la aplikon '{}'",
|
||||||
|
|
|
@ -107,7 +107,7 @@
|
||||||
"port_already_closed": "El puerto {port:d} ya está cerrado para las conexiones {ip_version:s}",
|
"port_already_closed": "El puerto {port:d} ya está cerrado para las conexiones {ip_version:s}",
|
||||||
"port_already_opened": "El puerto {port:d} ya está abierto para las conexiones {ip_version:s}",
|
"port_already_opened": "El puerto {port:d} ya está abierto para las conexiones {ip_version:s}",
|
||||||
"restore_already_installed_app": "Una aplicación con el ID «{app:s}» ya está instalada",
|
"restore_already_installed_app": "Una aplicación con el ID «{app:s}» ya está instalada",
|
||||||
"restore_app_failed": "No se pudo restaurar la aplicación «{app:s}»",
|
"app_restore_failed": "No se pudo restaurar la aplicación «{app:s}»: {error:s}",
|
||||||
"restore_cleaning_failed": "No se pudo limpiar el directorio temporal de restauración",
|
"restore_cleaning_failed": "No se pudo limpiar el directorio temporal de restauración",
|
||||||
"restore_complete": "Restaurada",
|
"restore_complete": "Restaurada",
|
||||||
"restore_confirm_yunohost_installed": "¿Realmente desea restaurar un sistema ya instalado? [{answers:s}]",
|
"restore_confirm_yunohost_installed": "¿Realmente desea restaurar un sistema ya instalado? [{answers:s}]",
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
{
|
{
|
||||||
"password_too_simple_1": "Pasahitzak gutxienez 8 karaktere izan behar ditu"
|
"password_too_simple_1": "Pasahitzak gutxienez 8 karaktere izan behar ditu"
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@
|
||||||
"port_already_closed": "Le port {port:d} est déjà fermé pour les connexions {ip_version:s}",
|
"port_already_closed": "Le port {port:d} est déjà fermé pour les connexions {ip_version:s}",
|
||||||
"port_already_opened": "Le port {port:d} est déjà ouvert pour les connexions {ip_version:s}",
|
"port_already_opened": "Le port {port:d} est déjà ouvert pour les connexions {ip_version:s}",
|
||||||
"restore_already_installed_app": "Une application est déjà installée avec l’identifiant '{app:s}'",
|
"restore_already_installed_app": "Une application est déjà installée avec l’identifiant '{app:s}'",
|
||||||
"restore_app_failed": "Impossible de restaurer '{app:s}'",
|
"app_restore_failed": "Impossible de restaurer '{app:s}': {error:s}",
|
||||||
"restore_cleaning_failed": "Impossible de nettoyer le dossier temporaire de restauration",
|
"restore_cleaning_failed": "Impossible de nettoyer le dossier temporaire de restauration",
|
||||||
"restore_complete": "Restauration terminée",
|
"restore_complete": "Restauration terminée",
|
||||||
"restore_confirm_yunohost_installed": "Voulez-vous vraiment restaurer un système déjà installé ? [{answers:s}]",
|
"restore_confirm_yunohost_installed": "Voulez-vous vraiment restaurer un système déjà installé ? [{answers:s}]",
|
||||||
|
|
|
@ -120,7 +120,7 @@
|
||||||
"pattern_username": "Caratteri minuscoli alfanumerici o trattini bassi soli",
|
"pattern_username": "Caratteri minuscoli alfanumerici o trattini bassi soli",
|
||||||
"port_already_closed": "La porta {port:d} è già chiusa per le connessioni {ip_version:s}",
|
"port_already_closed": "La porta {port:d} è già chiusa per le connessioni {ip_version:s}",
|
||||||
"restore_already_installed_app": "Un'applicazione con l'ID '{app:s}' è già installata",
|
"restore_already_installed_app": "Un'applicazione con l'ID '{app:s}' è già installata",
|
||||||
"restore_app_failed": "Impossibile ripristinare l'applicazione '{app:s}'",
|
"app_restore_failed": "Impossibile ripristinare l'applicazione '{app:s}': {error:s}",
|
||||||
"restore_cleaning_failed": "Impossibile pulire la directory temporanea di ripristino",
|
"restore_cleaning_failed": "Impossibile pulire la directory temporanea di ripristino",
|
||||||
"restore_complete": "Ripristino completo",
|
"restore_complete": "Ripristino completo",
|
||||||
"restore_confirm_yunohost_installed": "Sei sicuro di volere ripristinare un sistema già installato? {answers:s}",
|
"restore_confirm_yunohost_installed": "Sei sicuro di volere ripristinare un sistema già installato? {answers:s}",
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
"pattern_password": "Wachtwoord moet tenminste 3 karakters lang zijn",
|
"pattern_password": "Wachtwoord moet tenminste 3 karakters lang zijn",
|
||||||
"port_already_closed": "Poort {port:d} is al gesloten voor {ip_version:s} verbindingen",
|
"port_already_closed": "Poort {port:d} is al gesloten voor {ip_version:s} verbindingen",
|
||||||
"port_already_opened": "Poort {port:d} is al open voor {ip_version:s} verbindingen",
|
"port_already_opened": "Poort {port:d} is al open voor {ip_version:s} verbindingen",
|
||||||
"restore_app_failed": "De app '{app:s}' kon niet worden terug gezet",
|
"app_restore_failed": "De app '{app:s}' kon niet worden terug gezet: {error:s}",
|
||||||
"restore_hook_unavailable": "De herstel-hook '{part:s}' is niet beschikbaar op dit systeem",
|
"restore_hook_unavailable": "De herstel-hook '{part:s}' is niet beschikbaar op dit systeem",
|
||||||
"service_add_failed": "Kan service '{service:s}' niet toevoegen",
|
"service_add_failed": "Kan service '{service:s}' niet toevoegen",
|
||||||
"service_already_started": "Service '{service:s}' draait al",
|
"service_already_started": "Service '{service:s}' draait al",
|
||||||
|
|
|
@ -170,7 +170,7 @@
|
||||||
"port_already_closed": "Lo pòrt {port:d} es ja tampat per las connexions {ip_version:s}",
|
"port_already_closed": "Lo pòrt {port:d} es ja tampat per las connexions {ip_version:s}",
|
||||||
"port_already_opened": "Lo pòrt {port:d} es ja dubèrt per las connexions {ip_version:s}",
|
"port_already_opened": "Lo pòrt {port:d} es ja dubèrt per las connexions {ip_version:s}",
|
||||||
"restore_already_installed_app": "Una aplicacion es ja installada amb l’id « {app:s} »",
|
"restore_already_installed_app": "Una aplicacion es ja installada amb l’id « {app:s} »",
|
||||||
"restore_app_failed": "Impossible de restaurar l’aplicacion « {app:s} »",
|
"app_restore_failed": "Impossible de restaurar l’aplicacion « {app:s} »: {error:s}",
|
||||||
"backup_ask_for_copying_if_needed": "Volètz far una salvagarda en utilizant {size:s} Mo temporàriament ? (Aqueste biais de far es emplegat perque unes fichièrs an pas pogut èsser preparats amb un metòde mai eficaç.)",
|
"backup_ask_for_copying_if_needed": "Volètz far una salvagarda en utilizant {size:s} Mo temporàriament ? (Aqueste biais de far es emplegat perque unes fichièrs an pas pogut èsser preparats amb un metòde mai eficaç.)",
|
||||||
"yunohost_not_installed": "YunoHost es pas installat o corrèctament installat. Mercés d’executar « yunohost tools postinstall »",
|
"yunohost_not_installed": "YunoHost es pas installat o corrèctament installat. Mercés d’executar « yunohost tools postinstall »",
|
||||||
"backup_output_directory_forbidden": "Causissètz un repertòri de destinacion deferent. Las salvagardas pòdon pas se realizar dins los repertòris bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var ou /home/yunohost.backup/archives",
|
"backup_output_directory_forbidden": "Causissètz un repertòri de destinacion deferent. Las salvagardas pòdon pas se realizar dins los repertòris bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var ou /home/yunohost.backup/archives",
|
||||||
|
|
|
@ -194,7 +194,7 @@ def app_info(app, full=False):
|
||||||
)
|
)
|
||||||
|
|
||||||
local_manifest = _get_manifest_of_app(os.path.join(APPS_SETTING_PATH, app))
|
local_manifest = _get_manifest_of_app(os.path.join(APPS_SETTING_PATH, app))
|
||||||
permissions = user_permission_list(full=True, absolute_urls=True)["permissions"]
|
permissions = user_permission_list(full=True, absolute_urls=True, apps=[app])["permissions"]
|
||||||
|
|
||||||
settings = _get_app_settings(app)
|
settings = _get_app_settings(app)
|
||||||
|
|
||||||
|
@ -229,9 +229,7 @@ def app_info(app, full=False):
|
||||||
local_manifest.get("multi_instance", False)
|
local_manifest.get("multi_instance", False)
|
||||||
)
|
)
|
||||||
|
|
||||||
ret["permissions"] = {
|
ret["permissions"] = permissions
|
||||||
p: i for p, i in permissions.items() if p.startswith(app + ".")
|
|
||||||
}
|
|
||||||
ret["label"] = permissions.get(app + ".main", {}).get("label")
|
ret["label"] = permissions.get(app + ".main", {}).get("label")
|
||||||
|
|
||||||
if not ret["label"]:
|
if not ret["label"]:
|
||||||
|
@ -1435,7 +1433,7 @@ def app_setting(app, key, value=None, delete=False):
|
||||||
permission_url,
|
permission_url,
|
||||||
)
|
)
|
||||||
|
|
||||||
permissions = user_permission_list(full=True)["permissions"]
|
permissions = user_permission_list(full=True, apps=[app])["permissions"]
|
||||||
permission_name = "%s.legacy_%s_uris" % (app, key.split("_")[0])
|
permission_name = "%s.legacy_%s_uris" % (app, key.split("_")[0])
|
||||||
permission = permissions.get(permission_name)
|
permission = permissions.get(permission_name)
|
||||||
|
|
||||||
|
|
|
@ -1392,7 +1392,6 @@ class RestoreManager:
|
||||||
self.targets.set_result("apps", app_instance_name, "Warning")
|
self.targets.set_result("apps", app_instance_name, "Warning")
|
||||||
return
|
return
|
||||||
|
|
||||||
logger.debug(m18n.n("restore_running_app_script", app=app_instance_name))
|
|
||||||
try:
|
try:
|
||||||
# Restore app settings
|
# Restore app settings
|
||||||
app_settings_new_path = os.path.join(
|
app_settings_new_path = os.path.join(
|
||||||
|
@ -1401,7 +1400,7 @@ class RestoreManager:
|
||||||
app_scripts_new_path = os.path.join(app_settings_new_path, "scripts")
|
app_scripts_new_path = os.path.join(app_settings_new_path, "scripts")
|
||||||
shutil.copytree(app_settings_in_archive, app_settings_new_path)
|
shutil.copytree(app_settings_in_archive, app_settings_new_path)
|
||||||
filesystem.chmod(app_settings_new_path, 0o400, 0o400, True)
|
filesystem.chmod(app_settings_new_path, 0o400, 0o400, True)
|
||||||
filesystem.chown(app_scripts_new_path, "admin", None, True)
|
filesystem.chown(app_scripts_new_path, "root", None, True)
|
||||||
|
|
||||||
# Copy the app scripts to a writable temporary folder
|
# Copy the app scripts to a writable temporary folder
|
||||||
# FIXME : use 'install -Dm555' or something similar to what's done
|
# FIXME : use 'install -Dm555' or something similar to what's done
|
||||||
|
@ -1409,7 +1408,7 @@ class RestoreManager:
|
||||||
tmp_folder_for_app_restore = tempfile.mkdtemp(prefix="restore")
|
tmp_folder_for_app_restore = tempfile.mkdtemp(prefix="restore")
|
||||||
copytree(app_scripts_in_archive, tmp_folder_for_app_restore)
|
copytree(app_scripts_in_archive, tmp_folder_for_app_restore)
|
||||||
filesystem.chmod(tmp_folder_for_app_restore, 0o550, 0o550, True)
|
filesystem.chmod(tmp_folder_for_app_restore, 0o550, 0o550, True)
|
||||||
filesystem.chown(tmp_folder_for_app_restore, "admin", None, True)
|
filesystem.chown(tmp_folder_for_app_restore, "root", None, True)
|
||||||
restore_script = os.path.join(tmp_folder_for_app_restore, "restore")
|
restore_script = os.path.join(tmp_folder_for_app_restore, "restore")
|
||||||
|
|
||||||
# Restore permissions
|
# Restore permissions
|
||||||
|
@ -1454,81 +1453,111 @@ class RestoreManager:
|
||||||
os.remove("%s/permissions.yml" % app_settings_new_path)
|
os.remove("%s/permissions.yml" % app_settings_new_path)
|
||||||
|
|
||||||
_tools_migrations_run_before_app_restore(backup_version=self.info["from_yunohost_version"], app_id=app_instance_name)
|
_tools_migrations_run_before_app_restore(backup_version=self.info["from_yunohost_version"], app_id=app_instance_name)
|
||||||
|
|
||||||
# Prepare env. var. to pass to script
|
|
||||||
env_dict = _make_environment_for_app_script(app_instance_name)
|
|
||||||
env_dict.update(
|
|
||||||
{
|
|
||||||
"YNH_BACKUP_DIR": self.work_dir,
|
|
||||||
"YNH_BACKUP_CSV": os.path.join(self.work_dir, "backup.csv"),
|
|
||||||
"YNH_APP_BACKUP_DIR": os.path.join(
|
|
||||||
self.work_dir, "apps", app_instance_name, "backup"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
operation_logger.extra["env"] = env_dict
|
|
||||||
operation_logger.flush()
|
|
||||||
|
|
||||||
# Execute app restore script
|
|
||||||
hook_exec(
|
|
||||||
restore_script,
|
|
||||||
chdir=app_backup_in_archive,
|
|
||||||
raise_on_error=True,
|
|
||||||
env=env_dict,
|
|
||||||
)[0]
|
|
||||||
except Exception:
|
except Exception:
|
||||||
msg = m18n.n("restore_app_failed", app=app_instance_name)
|
import traceback
|
||||||
|
error = m18n.n("unexpected_error", error="\n" + traceback.format_exc())
|
||||||
|
msg = m18n.n("app_restore_failed", app=app_instance_name, error=error)
|
||||||
logger.error(msg)
|
logger.error(msg)
|
||||||
operation_logger.error(msg)
|
operation_logger.error(msg)
|
||||||
|
|
||||||
if msettings.get("interface") != "api":
|
|
||||||
dump_app_log_extract_for_debugging(operation_logger)
|
|
||||||
|
|
||||||
self.targets.set_result("apps", app_instance_name, "Error")
|
self.targets.set_result("apps", app_instance_name, "Error")
|
||||||
|
|
||||||
remove_script = os.path.join(app_scripts_in_archive, "remove")
|
# Cleanup
|
||||||
|
|
||||||
# Setup environment for remove script
|
|
||||||
env_dict_remove = _make_environment_for_app_script(app_instance_name)
|
|
||||||
|
|
||||||
operation_logger = OperationLogger(
|
|
||||||
"remove_on_failed_restore",
|
|
||||||
[("app", app_instance_name)],
|
|
||||||
env=env_dict_remove,
|
|
||||||
)
|
|
||||||
operation_logger.start()
|
|
||||||
|
|
||||||
# Execute remove script
|
|
||||||
if hook_exec(remove_script, env=env_dict_remove)[0] != 0:
|
|
||||||
msg = m18n.n("app_not_properly_removed", app=app_instance_name)
|
|
||||||
logger.warning(msg)
|
|
||||||
operation_logger.error(msg)
|
|
||||||
else:
|
|
||||||
operation_logger.success()
|
|
||||||
|
|
||||||
# Cleaning app directory
|
|
||||||
shutil.rmtree(app_settings_new_path, ignore_errors=True)
|
shutil.rmtree(app_settings_new_path, ignore_errors=True)
|
||||||
|
shutil.rmtree(tmp_folder_for_app_restore, ignore_errors=True)
|
||||||
|
|
||||||
# Remove all permission in LDAP for this app
|
return
|
||||||
for permission_name in user_permission_list()["permissions"].keys():
|
|
||||||
if permission_name.startswith(app_instance_name + "."):
|
|
||||||
permission_delete(permission_name, force=True)
|
|
||||||
|
|
||||||
# TODO Cleaning app hooks
|
logger.debug(m18n.n("restore_running_app_script", app=app_instance_name))
|
||||||
else:
|
|
||||||
self.targets.set_result("apps", app_instance_name, "Success")
|
# Prepare env. var. to pass to script
|
||||||
operation_logger.success()
|
env_dict = _make_environment_for_app_script(app_instance_name)
|
||||||
|
env_dict.update(
|
||||||
|
{
|
||||||
|
"YNH_BACKUP_DIR": self.work_dir,
|
||||||
|
"YNH_BACKUP_CSV": os.path.join(self.work_dir, "backup.csv"),
|
||||||
|
"YNH_APP_BACKUP_DIR": os.path.join(
|
||||||
|
self.work_dir, "apps", app_instance_name, "backup"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
operation_logger.extra["env"] = env_dict
|
||||||
|
operation_logger.flush()
|
||||||
|
|
||||||
|
# Execute the app install script
|
||||||
|
restore_failed = True
|
||||||
|
try:
|
||||||
|
restore_retcode = hook_exec(
|
||||||
|
restore_script,
|
||||||
|
chdir=app_backup_in_archive,
|
||||||
|
env=env_dict,
|
||||||
|
)[0]
|
||||||
|
# "Common" app restore failure : the script failed and returned exit code != 0
|
||||||
|
restore_failed = True if restore_retcode != 0 else False
|
||||||
|
if restore_failed:
|
||||||
|
error = m18n.n("app_restore_script_failed")
|
||||||
|
logger.error(m18n.n("app_restore_failed", app=app_instance_name, error=error))
|
||||||
|
failure_message_with_debug_instructions = operation_logger.error(error)
|
||||||
|
if msettings.get("interface") != "api":
|
||||||
|
dump_app_log_extract_for_debugging(operation_logger)
|
||||||
|
# Script got manually interrupted ... N.B. : KeyboardInterrupt does not inherit from Exception
|
||||||
|
except (KeyboardInterrupt, EOFError):
|
||||||
|
error = m18n.n("operation_interrupted")
|
||||||
|
logger.error(m18n.n("app_restore_failed", app=app_instance_name, error=error))
|
||||||
|
failure_message_with_debug_instructions = operation_logger.error(error)
|
||||||
|
# Something wrong happened in Yunohost's code (most probably hook_exec)
|
||||||
|
except Exception:
|
||||||
|
import traceback
|
||||||
|
error = m18n.n("unexpected_error", error="\n" + traceback.format_exc())
|
||||||
|
logger.error(m18n.n("app_restore_failed", app=app_instance_name, error=error))
|
||||||
|
failure_message_with_debug_instructions = operation_logger.error(error)
|
||||||
finally:
|
finally:
|
||||||
# Cleaning temporary scripts directory
|
# Cleaning temporary scripts directory
|
||||||
shutil.rmtree(tmp_folder_for_app_restore, ignore_errors=True)
|
shutil.rmtree(tmp_folder_for_app_restore, ignore_errors=True)
|
||||||
|
|
||||||
|
if not restore_failed:
|
||||||
|
self.targets.set_result("apps", app_instance_name, "Success")
|
||||||
|
operation_logger.success()
|
||||||
|
else:
|
||||||
|
|
||||||
|
self.targets.set_result("apps", app_instance_name, "Error")
|
||||||
|
|
||||||
|
remove_script = os.path.join(app_scripts_in_archive, "remove")
|
||||||
|
|
||||||
|
# Setup environment for remove script
|
||||||
|
env_dict_remove = _make_environment_for_app_script(app_instance_name)
|
||||||
|
|
||||||
|
remove_operation_logger = OperationLogger(
|
||||||
|
"remove_on_failed_restore",
|
||||||
|
[("app", app_instance_name)],
|
||||||
|
env=env_dict_remove,
|
||||||
|
)
|
||||||
|
remove_operation_logger.start()
|
||||||
|
|
||||||
|
# Execute remove script
|
||||||
|
if hook_exec(remove_script, env=env_dict_remove)[0] != 0:
|
||||||
|
msg = m18n.n("app_not_properly_removed", app=app_instance_name)
|
||||||
|
logger.warning(msg)
|
||||||
|
remove_operation_logger.error(msg)
|
||||||
|
else:
|
||||||
|
remove_operation_logger.success()
|
||||||
|
|
||||||
|
# Cleaning app directory
|
||||||
|
shutil.rmtree(app_settings_new_path, ignore_errors=True)
|
||||||
|
|
||||||
|
# Remove all permission in LDAP for this app
|
||||||
|
for permission_name in user_permission_list()["permissions"].keys():
|
||||||
|
if permission_name.startswith(app_instance_name + "."):
|
||||||
|
permission_delete(permission_name, force=True)
|
||||||
|
|
||||||
|
# TODO Cleaning app hooks
|
||||||
|
|
||||||
|
logger.error(failure_message_with_debug_instructions)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Backup methods #
|
# Backup methods #
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
class BackupMethod(object):
|
class BackupMethod(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -260,7 +260,7 @@ def dyndns_update(
|
||||||
ok, result = dig(dyn_host, "A")
|
ok, result = dig(dyn_host, "A")
|
||||||
dyn_host_ip = result[0] if ok == "ok" and len(result) else None
|
dyn_host_ip = result[0] if ok == "ok" and len(result) else None
|
||||||
if not dyn_host_ip:
|
if not dyn_host_ip:
|
||||||
raise YunohostError("Failed to resolve %s" % dyn_host)
|
raise YunohostError("Failed to resolve %s" % dyn_host, raw_msg=True)
|
||||||
|
|
||||||
ok, result = dig(domain, rdtype, resolvers=[dyn_host_ip])
|
ok, result = dig(domain, rdtype, resolvers=[dyn_host_ip])
|
||||||
if ok == "ok":
|
if ok == "ok":
|
||||||
|
|
|
@ -188,18 +188,19 @@ def firewall_list(raw=False, by_ip_version=False, list_forwarded=False):
|
||||||
for i in ["ipv4", "ipv6"]:
|
for i in ["ipv4", "ipv6"]:
|
||||||
f = firewall[i]
|
f = firewall[i]
|
||||||
# Combine TCP and UDP ports
|
# Combine TCP and UDP ports
|
||||||
ports[i] = sorted(set(f["TCP"]) | set(f["UDP"]))
|
ports[i] = sorted(set(f["TCP"]) | set(f["UDP"]), key=lambda p: int(p.split(':')[0]) if isinstance(p, str) else p)
|
||||||
|
|
||||||
if not by_ip_version:
|
if not by_ip_version:
|
||||||
# Combine IPv4 and IPv6 ports
|
# Combine IPv4 and IPv6 ports
|
||||||
ports = sorted(set(ports["ipv4"]) | set(ports["ipv6"]))
|
ports = sorted(set(ports["ipv4"]) | set(ports["ipv6"]), key=lambda p: int(p.split(':')[0]) if isinstance(p, str) else p)
|
||||||
|
|
||||||
# Format returned dict
|
# Format returned dict
|
||||||
ret = {"opened_ports": ports}
|
ret = {"opened_ports": ports}
|
||||||
if list_forwarded:
|
if list_forwarded:
|
||||||
# Combine TCP and UDP forwarded ports
|
# Combine TCP and UDP forwarded ports
|
||||||
ret["forwarded_ports"] = sorted(
|
ret["forwarded_ports"] = sorted(
|
||||||
set(firewall["uPnP"]["TCP"]) | set(firewall["uPnP"]["UDP"])
|
set(firewall["uPnP"]["TCP"]) | set(firewall["uPnP"]["UDP"]),
|
||||||
|
key=lambda p: int(p.split(':')[0]) if isinstance(p, str) else p
|
||||||
)
|
)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
|
@ -414,7 +414,7 @@ class RedactingFormatter(Formatter):
|
||||||
# This matches stuff like db_pwd=the_secret or admin_password=other_secret
|
# This matches stuff like db_pwd=the_secret or admin_password=other_secret
|
||||||
# (the secret part being at least 3 chars to avoid catching some lines like just "db_pwd=")
|
# (the secret part being at least 3 chars to avoid catching some lines like just "db_pwd=")
|
||||||
# Some names like "key" or "manifest_key" are ignored, used in helpers like ynh_app_setting_set or ynh_read_manifest
|
# Some names like "key" or "manifest_key" are ignored, used in helpers like ynh_app_setting_set or ynh_read_manifest
|
||||||
match = re.search(r'(pwd|pass|password|secret\w*|\w+key|token)=(\S{3,})$', record.strip())
|
match = re.search(r'(pwd|pass|password|passphrase|secret\w*|\w+key|token)=(\S{3,})$', record.strip())
|
||||||
if match and match.group(2) not in self.data_to_redact and match.group(1) not in ["key", "manifest_key"]:
|
if match and match.group(2) not in self.data_to_redact and match.group(1) not in ["key", "manifest_key"]:
|
||||||
self.data_to_redact.append(match.group(2))
|
self.data_to_redact.append(match.group(2))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
@ -46,7 +46,7 @@ SYSTEM_PERMS = ["mail", "xmpp", "sftp", "ssh"]
|
||||||
|
|
||||||
|
|
||||||
def user_permission_list(
|
def user_permission_list(
|
||||||
short=False, full=False, ignore_system_perms=False, absolute_urls=False
|
short=False, full=False, ignore_system_perms=False, absolute_urls=False, apps=[]
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
List permissions and corresponding accesses
|
List permissions and corresponding accesses
|
||||||
|
@ -74,7 +74,9 @@ def user_permission_list(
|
||||||
)
|
)
|
||||||
|
|
||||||
# Parse / organize information to be outputed
|
# Parse / organize information to be outputed
|
||||||
apps = sorted(_installed_apps())
|
if apps:
|
||||||
|
ignore_system_perms = True
|
||||||
|
apps = apps if apps else sorted(_installed_apps())
|
||||||
apps_base_path = {
|
apps_base_path = {
|
||||||
app: app_setting(app, "domain") + app_setting(app, "path")
|
app: app_setting(app, "domain") + app_setting(app, "path")
|
||||||
for app in apps
|
for app in apps
|
||||||
|
@ -85,11 +87,14 @@ def user_permission_list(
|
||||||
for infos in permissions_infos:
|
for infos in permissions_infos:
|
||||||
|
|
||||||
name = infos["cn"][0]
|
name = infos["cn"][0]
|
||||||
if ignore_system_perms and name.split(".")[0] in SYSTEM_PERMS:
|
|
||||||
continue
|
|
||||||
|
|
||||||
app = name.split(".")[0]
|
app = name.split(".")[0]
|
||||||
|
|
||||||
|
if app in SYSTEM_PERMS:
|
||||||
|
if ignore_system_perms:
|
||||||
|
continue
|
||||||
|
elif app not in apps:
|
||||||
|
continue
|
||||||
|
|
||||||
perm = {}
|
perm = {}
|
||||||
perm["allowed"] = [
|
perm["allowed"] = [
|
||||||
_ldap_path_extract(p, "cn") for p in infos.get("groupPermission", [])
|
_ldap_path_extract(p, "cn") for p in infos.get("groupPermission", [])
|
||||||
|
|
|
@ -413,7 +413,7 @@ def test_backup_with_different_output_directory(mocker):
|
||||||
# Create the backup
|
# Create the backup
|
||||||
with message(mocker, "backup_created"):
|
with message(mocker, "backup_created"):
|
||||||
backup_create(
|
backup_create(
|
||||||
system=["conf_ssh"],
|
system=["conf_ynh_settings"],
|
||||||
apps=None,
|
apps=None,
|
||||||
output_directory="/opt/test_backup_output_directory",
|
output_directory="/opt/test_backup_output_directory",
|
||||||
name="backup",
|
name="backup",
|
||||||
|
@ -427,7 +427,7 @@ def test_backup_with_different_output_directory(mocker):
|
||||||
archives_info = backup_info(archives[0], with_details=True)
|
archives_info = backup_info(archives[0], with_details=True)
|
||||||
assert archives_info["apps"] == {}
|
assert archives_info["apps"] == {}
|
||||||
assert len(archives_info["system"].keys()) == 1
|
assert len(archives_info["system"].keys()) == 1
|
||||||
assert "conf_ssh" in archives_info["system"].keys()
|
assert "conf_ynh_settings" in archives_info["system"].keys()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.clean_opt_dir
|
@pytest.mark.clean_opt_dir
|
||||||
|
@ -436,7 +436,7 @@ def test_backup_using_copy_method(mocker):
|
||||||
# Create the backup
|
# Create the backup
|
||||||
with message(mocker, "backup_created"):
|
with message(mocker, "backup_created"):
|
||||||
backup_create(
|
backup_create(
|
||||||
system=["conf_nginx"],
|
system=["conf_ynh_settings"],
|
||||||
apps=None,
|
apps=None,
|
||||||
output_directory="/opt/test_backup_output_directory",
|
output_directory="/opt/test_backup_output_directory",
|
||||||
methods=["copy"],
|
methods=["copy"],
|
||||||
|
@ -467,13 +467,13 @@ def test_restore_app_script_failure_handling(monkeypatch, mocker):
|
||||||
def custom_hook_exec(name, *args, **kwargs):
|
def custom_hook_exec(name, *args, **kwargs):
|
||||||
if os.path.basename(name).startswith("restore"):
|
if os.path.basename(name).startswith("restore"):
|
||||||
monkeypatch.undo()
|
monkeypatch.undo()
|
||||||
raise Exception
|
return (1, None)
|
||||||
|
|
||||||
monkeypatch.setattr("yunohost.backup.hook_exec", custom_hook_exec)
|
monkeypatch.setattr("yunohost.backup.hook_exec", custom_hook_exec)
|
||||||
|
|
||||||
assert not _is_installed("wordpress")
|
assert not _is_installed("wordpress")
|
||||||
|
|
||||||
with message(mocker, "restore_app_failed", app="wordpress"):
|
with message(mocker, "app_restore_script_failed"):
|
||||||
with raiseYunohostError(mocker, "restore_nothings_done"):
|
with raiseYunohostError(mocker, "restore_nothings_done"):
|
||||||
backup_restore(
|
backup_restore(
|
||||||
system=None, name=backup_list()["archives"][0], apps=["wordpress"]
|
system=None, name=backup_list()["archives"][0], apps=["wordpress"]
|
||||||
|
@ -675,9 +675,9 @@ def test_backup_binds_are_readonly(mocker, monkeypatch):
|
||||||
def custom_mount_and_backup(self):
|
def custom_mount_and_backup(self):
|
||||||
self._organize_files()
|
self._organize_files()
|
||||||
|
|
||||||
confssh = os.path.join(self.work_dir, "conf/ssh")
|
conf = os.path.join(self.work_dir, "conf/ynh/dkim")
|
||||||
output = subprocess.check_output(
|
output = subprocess.check_output(
|
||||||
"touch %s/test 2>&1 || true" % confssh,
|
"touch %s/test 2>&1 || true" % conf,
|
||||||
shell=True,
|
shell=True,
|
||||||
env={"LANG": "en_US.UTF-8"},
|
env={"LANG": "en_US.UTF-8"},
|
||||||
)
|
)
|
||||||
|
|
|
@ -862,10 +862,10 @@ def user_group_info(groupname):
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
def user_permission_list(short=False, full=False):
|
def user_permission_list(short=False, full=False, apps=[]):
|
||||||
import yunohost.permission
|
import yunohost.permission
|
||||||
|
|
||||||
return yunohost.permission.user_permission_list(short, full, absolute_urls=True)
|
return yunohost.permission.user_permission_list(short, full, absolute_urls=True, apps=apps)
|
||||||
|
|
||||||
|
|
||||||
def user_permission_update(
|
def user_permission_update(
|
||||||
|
|
Loading…
Add table
Reference in a new issue