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
|
||||
api: GET /users/permissions
|
||||
arguments:
|
||||
apps:
|
||||
help: Apps to list permission for (all by default)
|
||||
nargs: "*"
|
||||
-s:
|
||||
full: --short
|
||||
help: Only list permission names
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
n_version=7.0.2
|
||||
n_version=7.1.0
|
||||
n_install_dir="/opt/node_n"
|
||||
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.
|
||||
|
@ -17,7 +17,7 @@ ynh_install_n () {
|
|||
ynh_print_info --message="Installation of N - Node.js version management"
|
||||
# Build an app.src for n
|
||||
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
|
||||
ynh_setup_source --dest_dir="$n_install_dir/git" --source_id=n
|
||||
# Install n
|
||||
|
|
|
@ -182,7 +182,7 @@ ynh_permission_exists() {
|
|||
local permission
|
||||
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
|
||||
}
|
||||
|
||||
|
|
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"
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
systemctl stop slapd
|
||||
|
||||
# We need to execute this script as root, since the ldap
|
||||
# service will be shut down during the operation (and sudo
|
||||
# won't be available)
|
||||
/bin/bash $(readlink -f $0) $1
|
||||
# Create a directory for backup
|
||||
TMPDIR="/tmp/$(date +%s)"
|
||||
mkdir -p "$TMPDIR"
|
||||
|
||||
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
|
||||
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
|
||||
systemctl start slapd
|
||||
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/
|
||||
|
||||
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'
|
||||
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;
|
||||
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:";
|
||||
}
|
||||
|
|
|
@ -54,7 +54,12 @@ smtpd_tls_loglevel=1
|
|||
|
||||
# -- TLS for outgoing connections
|
||||
# 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
|
||||
{% endif %}
|
||||
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
|
||||
smtp_tls_exclude_ciphers = aNULL, MD5, DES, ADH, RC4, 3DES
|
||||
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_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_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_complete": "Restauració completada",
|
||||
"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_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_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_complete": "Vollständig wiederhergestellt",
|
||||
"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_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_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_start_install": "Installing {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",
|
||||
"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_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_cleaning_failed": "Could not clean up the temporary restoration directory",
|
||||
"restore_complete": "Restoration completed",
|
||||
|
|
|
@ -479,7 +479,7 @@
|
|||
"service_restarted": "Servo '{service:s}' rekomencis",
|
||||
"pattern_username": "Devas esti minuskulaj literoj kaj minuskloj nur",
|
||||
"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",
|
||||
"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 '{}'",
|
||||
|
|
|
@ -107,7 +107,7 @@
|
|||
"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}",
|
||||
"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_complete": "Restaurada",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@
|
|||
"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}",
|
||||
"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_complete": "Restauration terminée",
|
||||
"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",
|
||||
"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_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_complete": "Ripristino completo",
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
"service_add_failed": "Kan service '{service:s}' niet toevoegen",
|
||||
"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_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_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ç.)",
|
||||
"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",
|
||||
|
|
|
@ -194,7 +194,7 @@ def app_info(app, full=False):
|
|||
)
|
||||
|
||||
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)
|
||||
|
||||
|
@ -229,9 +229,7 @@ def app_info(app, full=False):
|
|||
local_manifest.get("multi_instance", False)
|
||||
)
|
||||
|
||||
ret["permissions"] = {
|
||||
p: i for p, i in permissions.items() if p.startswith(app + ".")
|
||||
}
|
||||
ret["permissions"] = permissions
|
||||
ret["label"] = permissions.get(app + ".main", {}).get("label")
|
||||
|
||||
if not ret["label"]:
|
||||
|
@ -1435,7 +1433,7 @@ def app_setting(app, key, value=None, delete=False):
|
|||
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 = permissions.get(permission_name)
|
||||
|
||||
|
|
|
@ -1392,7 +1392,6 @@ class RestoreManager:
|
|||
self.targets.set_result("apps", app_instance_name, "Warning")
|
||||
return
|
||||
|
||||
logger.debug(m18n.n("restore_running_app_script", app=app_instance_name))
|
||||
try:
|
||||
# Restore app settings
|
||||
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")
|
||||
shutil.copytree(app_settings_in_archive, app_settings_new_path)
|
||||
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
|
||||
# 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")
|
||||
copytree(app_scripts_in_archive, tmp_folder_for_app_restore)
|
||||
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 permissions
|
||||
|
@ -1454,81 +1453,111 @@ class RestoreManager:
|
|||
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)
|
||||
|
||||
# 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:
|
||||
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)
|
||||
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")
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
# Cleanup
|
||||
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
|
||||
for permission_name in user_permission_list()["permissions"].keys():
|
||||
if permission_name.startswith(app_instance_name + "."):
|
||||
permission_delete(permission_name, force=True)
|
||||
return
|
||||
|
||||
# TODO Cleaning app hooks
|
||||
else:
|
||||
self.targets.set_result("apps", app_instance_name, "Success")
|
||||
operation_logger.success()
|
||||
logger.debug(m18n.n("restore_running_app_script", app=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 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:
|
||||
# Cleaning temporary scripts directory
|
||||
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 #
|
||||
#
|
||||
|
||||
|
||||
class BackupMethod(object):
|
||||
|
||||
"""
|
||||
|
|
|
@ -260,7 +260,7 @@ def dyndns_update(
|
|||
ok, result = dig(dyn_host, "A")
|
||||
dyn_host_ip = result[0] if ok == "ok" and len(result) else None
|
||||
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])
|
||||
if ok == "ok":
|
||||
|
|
|
@ -188,18 +188,19 @@ def firewall_list(raw=False, by_ip_version=False, list_forwarded=False):
|
|||
for i in ["ipv4", "ipv6"]:
|
||||
f = firewall[i]
|
||||
# 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:
|
||||
# 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
|
||||
ret = {"opened_ports": ports}
|
||||
if list_forwarded:
|
||||
# Combine TCP and UDP forwarded ports
|
||||
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
|
||||
|
||||
|
|
|
@ -414,7 +414,7 @@ class RedactingFormatter(Formatter):
|
|||
# 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=")
|
||||
# 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"]:
|
||||
self.data_to_redact.append(match.group(2))
|
||||
except Exception as e:
|
||||
|
|
|
@ -46,7 +46,7 @@ SYSTEM_PERMS = ["mail", "xmpp", "sftp", "ssh"]
|
|||
|
||||
|
||||
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
|
||||
|
@ -74,7 +74,9 @@ def user_permission_list(
|
|||
)
|
||||
|
||||
# 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 = {
|
||||
app: app_setting(app, "domain") + app_setting(app, "path")
|
||||
for app in apps
|
||||
|
@ -85,11 +87,14 @@ def user_permission_list(
|
|||
for infos in permissions_infos:
|
||||
|
||||
name = infos["cn"][0]
|
||||
if ignore_system_perms and name.split(".")[0] in SYSTEM_PERMS:
|
||||
continue
|
||||
|
||||
app = name.split(".")[0]
|
||||
|
||||
if app in SYSTEM_PERMS:
|
||||
if ignore_system_perms:
|
||||
continue
|
||||
elif app not in apps:
|
||||
continue
|
||||
|
||||
perm = {}
|
||||
perm["allowed"] = [
|
||||
_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
|
||||
with message(mocker, "backup_created"):
|
||||
backup_create(
|
||||
system=["conf_ssh"],
|
||||
system=["conf_ynh_settings"],
|
||||
apps=None,
|
||||
output_directory="/opt/test_backup_output_directory",
|
||||
name="backup",
|
||||
|
@ -427,7 +427,7 @@ def test_backup_with_different_output_directory(mocker):
|
|||
archives_info = backup_info(archives[0], with_details=True)
|
||||
assert archives_info["apps"] == {}
|
||||
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
|
||||
|
@ -436,7 +436,7 @@ def test_backup_using_copy_method(mocker):
|
|||
# Create the backup
|
||||
with message(mocker, "backup_created"):
|
||||
backup_create(
|
||||
system=["conf_nginx"],
|
||||
system=["conf_ynh_settings"],
|
||||
apps=None,
|
||||
output_directory="/opt/test_backup_output_directory",
|
||||
methods=["copy"],
|
||||
|
@ -467,13 +467,13 @@ def test_restore_app_script_failure_handling(monkeypatch, mocker):
|
|||
def custom_hook_exec(name, *args, **kwargs):
|
||||
if os.path.basename(name).startswith("restore"):
|
||||
monkeypatch.undo()
|
||||
raise Exception
|
||||
return (1, None)
|
||||
|
||||
monkeypatch.setattr("yunohost.backup.hook_exec", custom_hook_exec)
|
||||
|
||||
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"):
|
||||
backup_restore(
|
||||
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):
|
||||
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(
|
||||
"touch %s/test 2>&1 || true" % confssh,
|
||||
"touch %s/test 2>&1 || true" % conf,
|
||||
shell=True,
|
||||
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
|
||||
|
||||
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(
|
||||
|
|
Loading…
Add table
Reference in a new issue