From 16dba79a3983b979a19de1701773a5440ae9766f Mon Sep 17 00:00:00 2001 From: Kay0u Date: Wed, 17 Nov 2021 00:44:58 +0100 Subject: [PATCH 01/51] fix backup_delete when compress_tar_archives is True --- src/yunohost/backup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/backup.py b/src/yunohost/backup.py index 058813502..f68e59b13 100644 --- a/src/yunohost/backup.py +++ b/src/yunohost/backup.py @@ -2592,7 +2592,7 @@ def backup_delete(name): hook_callback("pre_backup_delete", args=[name]) archive_file = "%s/%s.tar" % (ARCHIVES_PATH, name) - if os.path.exists(archive_file + ".gz"): + if not os.path.exists(archive_file) and os.path.exists(archive_file + ".gz"): archive_file += ".gz" info_file = "%s/%s.info.json" % (ARCHIVES_PATH, name) From dc4341f98cc75baeff03b32777e17045338ec144 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 22 Nov 2021 08:21:54 +0100 Subject: [PATCH 02/51] migrate_to_bullseye: /usr/share/yunohost/yunohost-config/ssl/yunoCA -> /usr/share/yunohost/ssl --- src/yunohost/data_migrations/0021_migrate_to_bullseye.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/yunohost/data_migrations/0021_migrate_to_bullseye.py b/src/yunohost/data_migrations/0021_migrate_to_bullseye.py index db10777bf..aee3bc2d6 100644 --- a/src/yunohost/data_migrations/0021_migrate_to_bullseye.py +++ b/src/yunohost/data_migrations/0021_migrate_to_bullseye.py @@ -77,6 +77,13 @@ class MyMigration(Migration): rm("/etc/mysql/my.cnf", force=True) self.apt_install("mariadb-common --reinstall -o Dpkg::Options::='--force-confmiss'") + # + # /usr/share/yunohost/yunohost-config/ssl/yunoCA -> /usr/share/yunohost/ssl + # + if os.path.exists("/usr/share/yunohost/yunohost-config/ssl/yunoCA"): + os.system("mv /usr/share/yunohost/yunohost-config/ssl/yunoCA /usr/share/yunohost/ssl") + rm("/usr/share/yunohost/yunohost-config", recursive=True, force=True) + # # Main upgrade # From 2bd1df0659588e096a2936f429c53d8dce6e74a0 Mon Sep 17 00:00:00 2001 From: Kayou Date: Tue, 30 Nov 2021 13:10:20 +0100 Subject: [PATCH 03/51] [fix] hook restore multimedia --- data/hooks/restore/18-data_multimedia | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data/hooks/restore/18-data_multimedia b/data/hooks/restore/18-data_multimedia index eb8ef2608..c3c349e7d 100644 --- a/data/hooks/restore/18-data_multimedia +++ b/data/hooks/restore/18-data_multimedia @@ -6,4 +6,6 @@ set -eu # Source YNH helpers source /usr/share/yunohost/helpers -ynh_restore_file --origin_path="/home/yunohost.multimedia" --not_mandatory +backup_dir="data/multimedia" + +ynh_restore_file --origin_path="${backup_dir}" --dest_path="/home/yunohost.multimedia" --not_mandatory From 47f3c00d0c1ef3ce65cd7768b38526cb2b02a9b6 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 3 Dec 2021 01:00:19 +0100 Subject: [PATCH 04/51] helpers apt/php: fix typo spotted by tituspijean --- data/helpers.d/apt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/helpers.d/apt b/data/helpers.d/apt index 2e56e3788..281e17f70 100644 --- a/data/helpers.d/apt +++ b/data/helpers.d/apt @@ -325,7 +325,7 @@ EOF ynh_app_setting_set --app=$app --key=phpversion --value=$specific_php_version # Integrate new php-fpm service in yunohost - yunohost service add php${specific_php_version}-fpm --log "/var/log/php${phpversion}-fpm.log" + yunohost service add php${specific_php_version}-fpm --log "/var/log/php${specific_php_version}-fpm.log" elif grep --quiet 'php' <<< "$dependencies"; then # Store phpversion into the config of this app ynh_app_setting_set --app=$app --key=phpversion --value=$YNH_DEFAULT_PHP_VERSION From 00d535a620ac8c4e5a7dbd7bfbcdb4f7338318cd Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 6 Dec 2021 18:38:49 +0100 Subject: [PATCH 05/51] Stop using /home/yunohost.conf for regenconf / confbackup, /var/cache is fine, prevent confusing /home/yunohost.* folder --- helpers/backup | 6 +++--- hooks/conf_regen/01-yunohost | 7 ++----- src/regenconf.py | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/helpers/backup b/helpers/backup index e4828a10d..01b51d5a1 100644 --- a/helpers/backup +++ b/helpers/backup @@ -226,7 +226,7 @@ with open(sys.argv[1], 'r') as backup_file: # ynh_restore_file -o "conf/nginx.conf" # # 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. +# `/var/cache/yunohost/appconfbackup/`. Otherwise, the existing file is removed. # # if `apps/$app/etc/nginx/conf.d/$domain.d/$app.conf` exists, restore it into # `/etc/nginx/conf.d/$domain.d/$app.conf` @@ -263,7 +263,7 @@ ynh_restore_file() { if [[ -e "${dest_path}" ]]; then # Check if the file/dir size is less than 500 Mo if [[ $(du --summarize --bytes ${dest_path} | cut --delimiter="/" --fields=1) -le "500000000" ]]; then - local backup_file="/home/yunohost.conf/backup/${dest_path}.backup.$(date '+%Y%m%d.%H%M%S')" + local backup_file="/var/cache/yunohost/appconfbackup/${dest_path}.backup.$(date '+%Y%m%d.%H%M%S')" mkdir --parents "$(dirname "$backup_file")" mv "${dest_path}" "$backup_file" # Move the current file or directory else @@ -353,7 +353,7 @@ ynh_backup_if_checksum_is_different() { backup_file_checksum="" if [ -n "$checksum_value" ]; then # Proceed only if a value was stored into the app settings if [ -e $file ] && ! echo "$checksum_value $file" | md5sum --check --status; then # If the checksum is now different - backup_file_checksum="/home/yunohost.conf/backup/$file.backup.$(date '+%Y%m%d.%H%M%S')" + backup_file_checksum="/var/cache/yunohost/appconfbackup/$file.backup.$(date '+%Y%m%d.%H%M%S')" mkdir --parents "$(dirname "$backup_file_checksum")" cp --archive "$file" "$backup_file_checksum" # Backup the current file ynh_print_warn "File $file has been manually modified since the installation or last upgrade. So it has been duplicated in $backup_file_checksum" diff --git a/hooks/conf_regen/01-yunohost b/hooks/conf_regen/01-yunohost index 22929db33..14840e2f1 100755 --- a/hooks/conf_regen/01-yunohost +++ b/hooks/conf_regen/01-yunohost @@ -174,12 +174,12 @@ do_post_regen() { ###################### chmod 750 /home/admin - chmod 750 /home/yunohost.conf chmod 750 /home/yunohost.backup chmod 750 /home/yunohost.backup/archives - chown root:root /home/yunohost.conf + chmod 700 /var/cache/yunohost chown admin:root /home/yunohost.backup chown admin:root /home/yunohost.backup/archives + chown root:root /var/cache/yunohost # NB: x permission for 'others' is important for ssl-cert (and maybe mdns), otherwise slapd will fail to start because can't access the certs chmod 755 /etc/yunohost @@ -195,9 +195,6 @@ do_post_regen() { find /etc/cron.d/yunohost-* -type f -exec chmod 644 {} \; find /etc/cron.*/yunohost-* -type f -exec chown root:root {} \; - chown root:root /var/cache/yunohost - chmod 700 /var/cache/yunohost - setfacl -m g:all_users:--- /var/www setfacl -m g:all_users:--- /var/log/nginx setfacl -m g:all_users:--- /etc/yunohost diff --git a/src/regenconf.py b/src/regenconf.py index afcfb4360..1be62a96f 100644 --- a/src/regenconf.py +++ b/src/regenconf.py @@ -35,7 +35,7 @@ from yunohost.utils.error import YunohostError from yunohost.log import is_unit_operation from yunohost.hook import hook_callback, hook_list -BASE_CONF_PATH = "/home/yunohost.conf" +BASE_CONF_PATH = "/var/cache/yunohost/regenconf" BACKUP_CONF_DIR = os.path.join(BASE_CONF_PATH, "backup") PENDING_CONF_DIR = os.path.join(BASE_CONF_PATH, "pending") REGEN_CONF_FILE = "/etc/yunohost/regenconf.yml" From d1ab1f674eb25f0970ded4698a89aee18f202cec Mon Sep 17 00:00:00 2001 From: ericgaspar Date: Tue, 7 Dec 2021 12:23:22 +0100 Subject: [PATCH 06/51] Update n to 8.0.1 --- data/helpers.d/nodejs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/helpers.d/nodejs b/data/helpers.d/nodejs index e7e61b0c6..962ac2a70 100644 --- a/data/helpers.d/nodejs +++ b/data/helpers.d/nodejs @@ -1,6 +1,6 @@ #!/bin/bash -n_version=8.0.0 +n_version=8.0.1 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. @@ -16,7 +16,7 @@ export N_PREFIX="$n_install_dir" ynh_install_n() { # Build an app.src for n echo "SOURCE_URL=https://github.com/tj/n/archive/v${n_version}.tar.gz -SOURCE_SUM=9e8879dc4f1c4c0fe4e08a108ed6c23046419b6865fe922ca5176ff7998ae6ff" >"$YNH_APP_BASEDIR/conf/n.src" +SOURCE_SUM=8703ae88fd06ce7f2d0f4018d68bfbab7b26859ed86a86ce4b8f25d2110aee2f" >"$YNH_APP_BASEDIR/conf/n.src" # Download and extract n ynh_setup_source --dest_dir="$n_install_dir/git" --source_id=n # Install n From 71a08c09ea5099d7951d8d7badf0ed3bc0a02cf2 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 8 Dec 2021 22:06:46 +0100 Subject: [PATCH 07/51] Update changelog for 4.3.4.2 --- debian/changelog | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/debian/changelog b/debian/changelog index f53b259b6..001ab678a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,14 @@ +yunohost (4.3.4.2) stable; urgency=low + + - [fix] yunomdns: Ignore ipv4 link-local addresses (6854f23c) + - [fix] backup: Fix path for multimedia restore ([#1386](https://github.com/YunoHost/yunohost/pull/1386)) + - [fix] helpers apt/php: typo in extra php-fpm yunohost service integration (47f3c00d) + - [enh] helpers: Update n to 8.0.1 (d1ab1f67) + + Thanks to all contributors <3 ! (ericgaspar, Kayou) + + -- Alexandre Aubin Wed, 08 Dec 2021 22:04:04 +0100 + yunohost (4.3.4.1) stable; urgency=low - [fix] regenconf: Force permission on /etc/resolv.dnsmasq.conf to fix an issue on some setup with umask=027 (5881938c) From b617c799d05fa95e8fb3af85442b59053412f03f Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 8 Dec 2021 22:11:02 +0100 Subject: [PATCH 08/51] migrate_to_bullseye: move /home/yunohost.conf to /var/cache/yunohost/regenconf --- src/yunohost/data_migrations/0021_migrate_to_bullseye.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/yunohost/data_migrations/0021_migrate_to_bullseye.py b/src/yunohost/data_migrations/0021_migrate_to_bullseye.py index aee3bc2d6..b39ef09e8 100644 --- a/src/yunohost/data_migrations/0021_migrate_to_bullseye.py +++ b/src/yunohost/data_migrations/0021_migrate_to_bullseye.py @@ -84,6 +84,13 @@ class MyMigration(Migration): os.system("mv /usr/share/yunohost/yunohost-config/ssl/yunoCA /usr/share/yunohost/ssl") rm("/usr/share/yunohost/yunohost-config", recursive=True, force=True) + # + # /home/yunohost.conf -> /var/cache/yunohost/regenconf + # + if os.path.exists("/home/yunohost.conf"): + os.system("mv /home/yunohost.conf /var/cache/yunohost/regenconf") + rm("/home/yunohost.conf", recursive=True, force=True) + # # Main upgrade # From 83f7721fdd515bd5d3acdd9f5f584c3ee0891a8e Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 9 Dec 2021 16:24:12 +0100 Subject: [PATCH 09/51] [fix] services: small issue when parsing installed php-fpm versions during buster->bullseye migration (or more generally, there could be no php-fpm installed) --- src/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service.py b/src/service.py index b723df407..fb1e15c5f 100644 --- a/src/service.py +++ b/src/service.py @@ -705,7 +705,7 @@ def _get_services(): if os.system(f"dpkg --list | grep -q 'ii *{package}'") != 0: del services[name] - php_fpm_versions = check_output(r"dpkg --list | grep -P 'ii php\d.\d-fpm' | awk '{print $2}' | grep -o -P '\d.\d'") + php_fpm_versions = check_output(r"dpkg --list | grep -P 'ii php\d.\d-fpm' | awk '{print $2}' | grep -o -P '\d.\d' || true") php_fpm_versions = [v for v in php_fpm_versions.split('\n') if v.strip()] for version in php_fpm_versions: services[f"php{version}-fpm"] = { From 107bd854eb338617741847e07a085981140249b7 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 9 Dec 2021 16:47:57 +0100 Subject: [PATCH 10/51] migrate_to_bullseye: fix PHP dependencies issues --- .../data_migrations/0021_migrate_to_bullseye.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/yunohost/data_migrations/0021_migrate_to_bullseye.py b/src/yunohost/data_migrations/0021_migrate_to_bullseye.py index b39ef09e8..6ce963625 100644 --- a/src/yunohost/data_migrations/0021_migrate_to_bullseye.py +++ b/src/yunohost/data_migrations/0021_migrate_to_bullseye.py @@ -108,6 +108,22 @@ class MyMigration(Migration): os.system("apt autoremove --assume-yes") os.system("apt clean --assume-yes") + # Force add sury if it's not there yet + # This is to solve some weird issue with php-common breaking php7.3-common, + # hence breaking many php7.3-deps + # hence triggering some dependency conflict (or foobar-ynh-deps uninstall) + # Adding it there shouldnt be a big deal - Yunohost 11.x does add it + # through its regen conf anyway. + if not os.path.exists("/etc/apt/sources.list.d/extra_php_version.list"): + open("/etc/apt/sources.list.d/extra_php_version.list", "w").write("deb https://packages.sury.org/php/ bullseye main") + os.system('wget --timeout 900 --quiet "https://packages.sury.org/php/apt.gpg" --output-document=- | gpg --dearmor >"/etc/apt/trusted.gpg.d/extra_php_version.gpg"') + + os.system("apt update") + + # Force explicit install of php7.4-fpm to make sure it's ll be there + # during 0022_php73_to_php74_pools migration + self.apt_install("php7.4-fpm -o Dpkg::Options::='--force-confmiss'") + # # Yunohost upgrade # From c4732b776e7420c5b19658d61dc36c787f5cf6c5 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 9 Dec 2021 17:13:06 +0100 Subject: [PATCH 11/51] migrate_to_bullseye: Remove legacy postgresql service record added by helpers, will now be dynamically handled by the core in bullseye --- src/yunohost/data_migrations/0021_migrate_to_bullseye.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/yunohost/data_migrations/0021_migrate_to_bullseye.py b/src/yunohost/data_migrations/0021_migrate_to_bullseye.py index 6ce963625..de53ba8be 100644 --- a/src/yunohost/data_migrations/0021_migrate_to_bullseye.py +++ b/src/yunohost/data_migrations/0021_migrate_to_bullseye.py @@ -15,6 +15,7 @@ from yunohost.utils.packages import ( get_ynh_package_version, _list_upgradable_apt_packages, ) +from yunohost.services import _get_services, _save_services logger = getActionLogger("yunohost.migration") @@ -124,6 +125,13 @@ class MyMigration(Migration): # during 0022_php73_to_php74_pools migration self.apt_install("php7.4-fpm -o Dpkg::Options::='--force-confmiss'") + # Remove legacy postgresql service record added by helpers, + # will now be dynamically handled by the core in bullseye + services = _get_services() + if "postgresql" in services: + del services["postgresql"] + _save_services(services) + # # Yunohost upgrade # From 8abd843fdde7fcec9cc2ae79fbe2f9417ec30725 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 9 Dec 2021 17:31:07 +0100 Subject: [PATCH 12/51] Aaaand typo T_T --- src/yunohost/data_migrations/0021_migrate_to_bullseye.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/data_migrations/0021_migrate_to_bullseye.py b/src/yunohost/data_migrations/0021_migrate_to_bullseye.py index de53ba8be..36e816db1 100644 --- a/src/yunohost/data_migrations/0021_migrate_to_bullseye.py +++ b/src/yunohost/data_migrations/0021_migrate_to_bullseye.py @@ -15,7 +15,7 @@ from yunohost.utils.packages import ( get_ynh_package_version, _list_upgradable_apt_packages, ) -from yunohost.services import _get_services, _save_services +from yunohost.service import _get_services, _save_services logger = getActionLogger("yunohost.migration") From 6cc7978b4a285496371e47d9e0cff8d6ed0b7600 Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Thu, 9 Dec 2021 19:18:07 +0000 Subject: [PATCH 13/51] [CI] Format code with Black --- .../0021_migrate_to_bullseye.py | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/yunohost/data_migrations/0021_migrate_to_bullseye.py b/src/yunohost/data_migrations/0021_migrate_to_bullseye.py index 36e816db1..f97ab16da 100644 --- a/src/yunohost/data_migrations/0021_migrate_to_bullseye.py +++ b/src/yunohost/data_migrations/0021_migrate_to_bullseye.py @@ -25,6 +25,7 @@ N_CURRENT_YUNOHOST = 4 N_NEXT_DEBAN = 11 N_NEXT_YUNOHOST = 11 + class MyMigration(Migration): "Upgrade the system to Debian Bullseye and Yunohost 11.x" @@ -76,13 +77,17 @@ class MyMigration(Migration): _force_clear_hashes(["/etc/mysql/my.cnf"]) rm("/etc/mysql/mariadb.cnf", force=True) rm("/etc/mysql/my.cnf", force=True) - self.apt_install("mariadb-common --reinstall -o Dpkg::Options::='--force-confmiss'") + self.apt_install( + "mariadb-common --reinstall -o Dpkg::Options::='--force-confmiss'" + ) # # /usr/share/yunohost/yunohost-config/ssl/yunoCA -> /usr/share/yunohost/ssl # if os.path.exists("/usr/share/yunohost/yunohost-config/ssl/yunoCA"): - os.system("mv /usr/share/yunohost/yunohost-config/ssl/yunoCA /usr/share/yunohost/ssl") + os.system( + "mv /usr/share/yunohost/yunohost-config/ssl/yunoCA /usr/share/yunohost/ssl" + ) rm("/usr/share/yunohost/yunohost-config", recursive=True, force=True) # @@ -116,8 +121,12 @@ class MyMigration(Migration): # Adding it there shouldnt be a big deal - Yunohost 11.x does add it # through its regen conf anyway. if not os.path.exists("/etc/apt/sources.list.d/extra_php_version.list"): - open("/etc/apt/sources.list.d/extra_php_version.list", "w").write("deb https://packages.sury.org/php/ bullseye main") - os.system('wget --timeout 900 --quiet "https://packages.sury.org/php/apt.gpg" --output-document=- | gpg --dearmor >"/etc/apt/trusted.gpg.d/extra_php_version.gpg"') + open("/etc/apt/sources.list.d/extra_php_version.list", "w").write( + "deb https://packages.sury.org/php/ bullseye main" + ) + os.system( + 'wget --timeout 900 --quiet "https://packages.sury.org/php/apt.gpg" --output-document=- | gpg --dearmor >"/etc/apt/trusted.gpg.d/extra_php_version.gpg"' + ) os.system("apt update") @@ -205,10 +214,10 @@ class MyMigration(Migration): message = m18n.n("migration_0021_general_warning") # FIXME: re-enable this message with updated topic link once we release the migration as stable - #message = ( + # message = ( # "N.B.: This migration has been tested by the community over the last few months but has only been declared stable recently. If your server hosts critical services and if you are not too confident with debugging possible issues, we recommend you to wait a little bit more while we gather more feedback and polish things up. If on the other hand you are relatively confident with debugging small issues that may arise, you are encouraged to run this migration ;)! You can read about remaining known issues and feedback from the community here: https://forum.yunohost.org/t/12195\n\n" # + message - #) + # ) if problematic_apps: message += "\n\n" + m18n.n( @@ -285,7 +294,6 @@ class MyMigration(Migration): call_async_output(cmd, callbacks, shell=True) - def patch_yunohost_conflicts(self): # # This is a super dirty hack to remove the conflicts from yunohost's debian/control file @@ -305,6 +313,8 @@ class MyMigration(Migration): # We want to keep conflicting with apache/bind9 tho new_conflicts = "Conflicts: apache2, bind9" - command = f"sed -i /var/lib/dpkg/status -e 's@{conflicts}@{new_conflicts}@g'" + command = ( + f"sed -i /var/lib/dpkg/status -e 's@{conflicts}@{new_conflicts}@g'" + ) logger.debug(f"Running: {command}") os.system(command) From 0fc209acfbc6dbcb4d56ceb7618153ee34f1aac6 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 13 Dec 2021 18:19:32 +0100 Subject: [PATCH 14/51] [fix] helpers logrorate: remove permission tweak .. code was not working as expected. To be re-addressed some day ... --- data/helpers.d/logrotate | 5 ----- 1 file changed, 5 deletions(-) diff --git a/data/helpers.d/logrotate b/data/helpers.d/logrotate index 80b761711..6f9726beb 100644 --- a/data/helpers.d/logrotate +++ b/data/helpers.d/logrotate @@ -90,11 +90,6 @@ $logfile { EOF mkdir --parents $(dirname "$logfile") # Create the log directory, if not exist cat ${app}-logrotate | $customtee /etc/logrotate.d/$app >/dev/null # Append this config to the existing config file, or replace the whole config file (depending on $customtee) - - if ynh_user_exists --username="$app"; then - chown $app:$app "$logfile" - chmod o-rwx "$logfile" - fi } # Remove the app's logrotate config. From cc1230c5de25aa3c70cdb364bdad2278c2b6ef74 Mon Sep 17 00:00:00 2001 From: liimee Date: Mon, 15 Nov 2021 10:40:19 +0000 Subject: [PATCH 15/51] Translated using Weblate (Indonesian) Currently translated at 7.9% (56 of 705 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/id/ --- locales/id.json | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/locales/id.json b/locales/id.json index c9778dd5f..08e09fe8b 100644 --- a/locales/id.json +++ b/locales/id.json @@ -42,5 +42,17 @@ "app_start_install": "Memasang {app}...", "app_start_remove": "Menghapus {app}...", "app_manifest_install_ask_password": "Pilih kata sandi administrasi untuk aplikasi ini", - "app_upgrade_several_apps": "Aplikasi-aplikasi berikut akan diperbarui: {apps}" -} \ No newline at end of file + "app_upgrade_several_apps": "Aplikasi-aplikasi berikut akan diperbarui: {apps}", + "backup_app_failed": "Tidak dapat mencadangkan {app}", + "backup_archive_name_exists": "Arsip cadangan dengan nama ini sudah ada.", + "backup_created": "Cadangan dibuat", + "backup_creation_failed": "Tidak dapat membuat arsip cadangan", + "backup_delete_error": "Tidak dapat menghapus '{path}'", + "backup_deleted": "Cadangan dihapus", + "diagnosis_apps_issue": "Sebuah masalah ditemukan pada aplikasi {app}", + "backup_applying_method_tar": "Membuat arsip TAR cadangan...", + "backup_method_tar_finished": "Arsip TAR cadanagan dibuat", + "backup_nothings_done": "Tak ada yang harus disimpan", + "certmanager_cert_install_success": "Sertifikat Let's Encrypt sekarang sudah terpasang pada domain '{domain}'", + "backup_mount_archive_for_restore": "Menyiapkan arsip untuk pemulihan..." +} From fbf85fa0ba486262e107ac982684b1a7d3e4afba Mon Sep 17 00:00:00 2001 From: Ilya Date: Wed, 17 Nov 2021 20:03:22 +0000 Subject: [PATCH 16/51] Translated using Weblate (Russian) Currently translated at 14.4% (102 of 705 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/ru/ --- locales/ru.json | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/locales/ru.json b/locales/ru.json index 58bd1846d..f38f703fc 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -73,5 +73,32 @@ "user_unknown": "Неизвестный пользователь: {user}", "yunohost_already_installed": "YunoHost уже установлен", "yunohost_configured": "Теперь YunoHost настроен", - "upgrading_packages": "Обновление пакетов..." -} \ No newline at end of file + "upgrading_packages": "Обновление пакетов...", + "app_requirements_unmeet": "Необходимые требования для {app} не выполнены, пакет {pkgname} ({version}) должен быть {spec}", + "app_make_default_location_already_used": "Невозможно сделать '{app}' приложением по умолчанию на домене, '{domain}' уже используется '{other_app}'", + "app_config_unable_to_apply": "Не удалось применить значения панели конфигурации.", + "app_config_unable_to_read": "Не удалось прочитать значения панели конфигурации.", + "app_install_failed": "Невозможно установить {app}: {error}", + "apps_catalog_init_success": "Система каталога приложений инициализирована!", + "backup_abstract_method": "Этот метод резервного копирования еще не реализован", + "backup_actually_backuping": "Создание резервного архива из собранных файлов...", + "backup_applying_method_custom": "Вызов пользовательского метода резервного копирования {method}'...", + "backup_archive_app_not_found": "Не удалось найти {app} в резервной копии", + "backup_applying_method_tar": "Создание резервной копии в TAR-архиве...", + "backup_archive_broken_link": "Не удалось получить доступ к резервной копии (неправильная ссылка {path})", + "apps_catalog_failed_to_download": "Невозможно загрузить каталог приложений {apps_catalog}: {error}", + "apps_catalog_obsolete_cache": "Кэш каталога приложений пуст или устарел.", + "backup_archive_cant_retrieve_info_json": "Не удалось загрузить информацию об архиве '{archive}'... info.json не может быть получен (или не является корректным json).", + "app_packaging_format_not_supported": "Это приложение не может быть установлено, поскольку его формат не поддерживается вашей версией YunoHost. Возможно, вам следует обновить систему.", + "app_restore_failed": "Не удалось восстановить {app}: {error}", + "app_restore_script_failed": "Произошла ошибка внутри сценария восстановления приложения", + "ask_user_domain": "Домен, используемый для адреса электронной почты пользователя и учетной записи XMPP", + "app_not_upgraded": "Не удалось обновить приложение '{failed_app}', и, как следствие, обновление следующих приложений было отменено: {apps}", + "app_start_backup": "Сбор файлов для резервного копирования {app}...", + "app_start_install": "Устанавливается {app}...", + "backup_app_failed": "Не удалось создать резервную копию {app}", + "backup_archive_name_exists": "Резервная копия с таким именем уже существует.", + "backup_archive_name_unknown": "Неизвестный локальный архив резервного копирования с именем '{name}'", + "backup_archive_open_failed": "Не удалось открыть архив резервной копии", + "backup_archive_corrupted": "Похоже, что архив резервной копии '{archive}' поврежден : {error}" +} From 59c27886211229f39d7991ef7e551a40cf0982e5 Mon Sep 17 00:00:00 2001 From: Ilya Date: Thu, 18 Nov 2021 19:32:14 +0000 Subject: [PATCH 17/51] Translated using Weblate (Russian) Currently translated at 24.1% (170 of 705 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/ru/ --- locales/ru.json | 74 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/locales/ru.json b/locales/ru.json index f38f703fc..deb64c70a 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -35,7 +35,7 @@ "domain_dns_conf_is_just_a_recommendation": "Эта страница показывает вам *рекомендуемую* конфигурацию. Она *не* создаёт для вас конфигурацию DNS. Вы должны сами конфигурировать зону вашего DNS у вашего регистратора в соответствии с этой рекомендацией.", "good_practices_about_user_password": "Выберите пароль пользователя длиной не менее 8 символов, хотя рекомендуется использовать более длинные (например, парольную фразу) и / или использовать символы различного типа (прописные, строчные буквы, цифры и специальные символы).", "password_too_simple_3": "Пароль должен содержать не менее 8 символов и содержать цифры, заглавные и строчные буквы и специальные символы", - "upnp_enabled": "UPnP включён", + "upnp_enabled": "UPnP включен", "user_deleted": "Пользователь удалён", "ask_lastname": "Фамилия", "app_action_broke_system": "Это действие, по-видимому, нарушило эти важные службы: {services}", @@ -51,7 +51,7 @@ "ask_password": "Пароль", "app_remove_after_failed_install": "Удаление приложения после сбоя установки...", "app_upgrade_script_failed": "Внутри скрипта обновления приложения произошла ошибка", - "upnp_disabled": "UPnP отключён", + "upnp_disabled": "UPnP отключен", "app_manifest_install_ask_domain": "Выберите домен, в котором должно быть установлено это приложение", "app_manifest_install_ask_path": "Выберите URL путь (часть после домена), по которому должно быть установлено это приложение", "app_manifest_install_ask_admin": "Выберите пользователя администратора для этого приложения", @@ -100,5 +100,73 @@ "backup_archive_name_exists": "Резервная копия с таким именем уже существует.", "backup_archive_name_unknown": "Неизвестный локальный архив резервного копирования с именем '{name}'", "backup_archive_open_failed": "Не удалось открыть архив резервной копии", - "backup_archive_corrupted": "Похоже, что архив резервной копии '{archive}' поврежден : {error}" + "backup_archive_corrupted": "Похоже, что архив резервной копии '{archive}' поврежден : {error}", + "certmanager_cert_install_success_selfsigned": "Самоподписанный сертификат для домена '{domain}' установлен", + "backup_created": "Создана резервная копия", + "config_unknown_filter_key": "Ключ фильтра '{filter_key}' неверен.", + "config_validate_date": "Должна быть правильная дата в формате YYYY-MM-DD", + "config_validate_email": "Должен быть правильный email", + "config_validate_time": "Должно быть правильное время формата HH:MM", + "backup_ask_for_copying_if_needed": "Хотите ли вы временно выполнить резервное копирование с использованием {size}MB? (Этот способ используется, поскольку некоторые файлы не могут быть подготовлены более эффективным методом.)", + "backup_permission": "Разрешить резервное копирование для {app}", + "certmanager_domain_dns_ip_differs_from_public_ip": "DNS-записи для домена '{domain}' отличаются от IP этого сервера. Пожалуйста, проверьте категорию 'DNS-записи' (основные) в диагностике для получения дополнительной информации. Если вы недавно изменили свою A-запись, пожалуйста, подождите, пока она распространится (некоторые программы проверки распространения DNS доступны в интернете). (Если вы знаете, что делаете, используйте '--no-checks', чтобы отключить эти проверки.)", + "certmanager_domain_not_diagnosed_yet": "Для домена {domain} еще нет результатов диагностики. Пожалуйста, перезапустите диагностику для категорий 'DNS-записи' и 'Web', чтобы проверить, готов ли домен к Let's Encrypt. (Или, если вы знаете, что делаете, используйте '--no-checks', чтобы отключить эти проверки.)", + "config_validate_url": "Должна быть правильная ссылка", + "config_version_not_supported": "Версии конфигурационной панели '{version}' не поддерживаются.", + "confirm_app_install_danger": "ОПАСНО! Это приложение все еще является экспериментальным (если не сказать, что оно явно не работает)! Вам не следует устанавливать его, если вы не знаете, что делаете. Если это приложение не будет работать или сломает вашу систему, мы не будем оказывать техническую поддержку... Если вы все равно готовы рискнуть, введите '{answers}'", + "confirm_app_install_thirdparty": "ВАЖНО! Это приложение не входит в каталог приложений YunoHost. Установка сторонних приложений может нарушить целостность и безопасность вашей системы. Вам не следует устанавливать его, если вы не знаете, что делаете. ТЕХНИЧЕСКОЙ ПОДДЕРЖКИ НЕ БУДЕТ, если это приложение не будет работать или сломает вашу систему... Если вы все равно готовы рискнуть, введите '{answers}'", + "config_apply_failed": "Не удалось применить новую конфигурацию: {error}", + "config_cant_set_value_on_section": "Вы не можете установить одно значение на весь раздел конфигурации.", + "config_forbidden_keyword": "Ключевое слово '{keyword}' зарезервировано, вы не можете создать или использовать панель конфигурации с вопросом с таким id.", + "config_no_panel": "Панель конфигурации не найдена.", + "danger": "Опасно:", + "certmanager_warning_subdomain_dns_record": "Субдомен '{subdomain}' не соответствует IP-адресу основного домена '{domain}'. Некоторые функции будут недоступны, пока вы не исправите это и не перегенерируете сертификат.", + "app_argument_password_no_default": "Ошибка при парсинге аргумента пароля '{name}': аргумент пароля не может иметь значение по умолчанию по причинам безопасности", + "custom_app_url_required": "Вы должны указать URL для обновления вашего пользовательского приложения {app}", + "backup_creation_failed": "Не удалось создать резервную копию", + "backup_csv_addition_failed": "Не удалось добавить файлы для резервного копирования в CSV-файл", + "backup_csv_creation_failed": "Не удалось создать CSV-файл, необходимый для восстановления", + "backup_deleted": "Резервная копия удалена", + "backup_delete_error": "Не удалось удалить '{path}'", + "backup_method_copy_finished": "Создание копии бэкапа завершено", + "backup_method_tar_finished": "Создан резервный TAR-архив", + "backup_mount_archive_for_restore": "Подготовка архива для восстановления...", + "backup_method_custom_finished": "Пользовательский метод резервного копирования '{method}' завершен", + "backup_nothings_done": "Нечего сохранять", + "backup_output_directory_required": "Вы должны выбрать каталог для сохранения резервной копии", + "backup_system_part_failed": "Не удалось создать резервную копию системной части '{part}'", + "certmanager_cert_renew_success": "Обновлен сертификат Let's Encrypt для домена '{domain}'", + "certmanager_cert_signing_failed": "Не удалось подписать новый сертификат", + "diagnosis_apps_bad_quality": "В настоящее время это приложение отмечено как неработающее в каталоге приложений YunoHost. Это может быть временной проблемой, пока мэинтейнеры пытаются исправить проблему. Пока что обновление этого приложения отключено.", + "diagnosis_apps_broken": "В настоящее время это приложение отмечено как неработающее в каталоге приложений YunoHost. Это может быть временной проблемой, пока мэинтейнеры пытаются исправить проблему. Пока что обновления для этого приложения отключены.", + "diagnosis_apps_allgood": "Все установленные приложения соблюдают основные правила упаковки", + "diagnosis_apps_issue": "Обнаружена проблема для приложения {app}", + "diagnosis_apps_not_in_app_catalog": "Этого приложения нет в каталоге приложений YunoHost. Если оно было там раньше, а теперь удалено, вам стоит подумать об удалении этого приложения, так как оно больше не получит обновлений и может нарушить целостность и безопасность вашей системы.", + "diagnosis_apps_deprecated_practices": "Установленная версия этого приложения все еще использует некоторые устаревшие пакеты. Вам стоит подумать об обновлении.", + "additional_urls_already_added": "Этот URL '{url}' уже добавлен в дополнительный URL для разрешения '{permission}'", + "additional_urls_already_removed": "Этот URL '{url}' уже удален из дополнительных URL для разрешения '{permission}'", + "app_action_cannot_be_ran_because_required_services_down": "Для выполнения этого действия должны быть запущены следующие службы: {services}. Попробуйте перезапустить их, чтобы продолжить (и, возможно, выяснить, почему они не работают).", + "app_unsupported_remote_type": "Неподдерживаемый удаленный тип, используемый для приложения", + "backup_archive_system_part_not_available": "Системная часть '{часть}' недоступна в этой резервной копии", + "backup_output_directory_not_empty": "Вы должны выбрать пустой каталог для сохранения", + "backup_archive_writing_error": "Не удалось добавить файлы '{source}' (названные в архиве '{dest}') для резервного копирования в архив '{archive}'", + "backup_cant_mount_uncompress_archive": "Не удалось смонтировать несжатый архив как защищенный от записи", + "backup_copying_to_organize_the_archive": "Копирование {size}MB для создания архива", + "backup_couldnt_bind": "Не удалось связать {src} с {dest}.", + "backup_output_directory_forbidden": "Выберите другой каталог для сохранения. Резервные копии не могут быть созданы в подкаталогах /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var или /home/yunohost.backup/archives", + "backup_with_no_backup_script_for_app": "Приложение '{app}' не имеет сценария резервного копирования. Оно будет проигнорировано.", + "certmanager_attempt_to_renew_nonLE_cert": "Сертификат для домена '{domain}' не выпущен Let's Encrypt. Невозможно продлить его автоматически!", + "certmanager_attempt_to_renew_valid_cert": "Срок действия сертификата для домена '{domain}' НЕ истекает! (Вы можете использовать --force, если знаете, что делаете)", + "certmanager_cannot_read_cert": "При попытке открыть текущий сертификат для домена {домен} произошло что-то неправильное (файл: {file}), причина: {reason}", + "certmanager_cert_install_success": "Сертификат Let's Encrypt для домена '{domain}' установлен", + "certmanager_domain_cert_not_selfsigned": "Сертификат для домена {domain} не самоподписанный. Вы уверены, что хотите заменить его? (Для этого используйте '--force'.)", + "certmanager_certificate_fetching_or_enabling_failed": "Попытка использовать новый сертификат для {domain} не сработала...", + "certmanager_domain_http_not_working": "Похоже, домен {domain} не доступен через HTTP. Пожалуйста, проверьте категорию 'Web' в диагностике для получения дополнительной информации. (Если вы знаете, что делаете, используйте '--no-checks', чтобы отключить эти проверки.)", + "certmanager_hit_rate_limit": "Для этого набора доменов {domain} в последнее время было выпущено слишком много сертификатов. Пожалуйста, повторите попытку позже. См. https://letsencrypt.org/docs/rate-limits/ для получения более подробной информации", + "certmanager_no_cert_file": "Не удалось прочитать файл сертификата для домена {domain} (файл: {file})", + "confirm_app_install_warning": "Предупреждение: Это приложение может работать, но пока еще недостаточно интегрировано в YunoHost. Некоторые функции, такие как единая регистрация и резервное копирование/восстановление, могут быть недоступны. Все равно устанавливать? [{answers}] ", + "yunohost_not_installed": "YunoHost установлен неправильно. Пожалуйста, запустите 'yunohost tools postinstall'", + "backup_cleaning_failed": "Не удалось очистить временную папку резервного копирования", + "certmanager_attempt_to_replace_valid_cert": "Вы пытаетесь перезаписать хороший и действительный сертификат для домена {domain}! (Используйте --force для обхода)", + "backup_create_size_estimation": "Архив будет содержать около {размер} данных." } From c27f13230c7e340f1db238e5784506694f3c4658 Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Fri, 19 Nov 2021 13:08:44 +0000 Subject: [PATCH 18/51] Translated using Weblate (German) Currently translated at 91.0% (642 of 705 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/locales/de.json b/locales/de.json index e491c5ac2..4129e7e72 100644 --- a/locales/de.json +++ b/locales/de.json @@ -638,5 +638,16 @@ "diagnosis_apps_issue": "Ein Problem für die App {app} ist aufgetreten", "config_validate_time": "Sollte eine zulässige Zeit wie HH:MM sein", "config_validate_url": "Sollte eine zulässige web URL sein", - "config_version_not_supported": "Konfigurationspanel Versionen '{version}' sind nicht unterstützt." -} \ No newline at end of file + "config_version_not_supported": "Konfigurationspanel Versionen '{version}' sind nicht unterstützt.", + "diagnosis_apps_allgood": "Alle installierten Apps berücksichtigen die grundlegenden Paketierungspraktiken", + "diagnosis_apps_broken": "Diese App ist im YunoHost-Applikationskatalog momentan als defekt gekennzeichnet. Es könnte sich dabei um einen vorübergehendes Problem handeln. Während der Betreuer versucht das Problem zu beheben, ist die Upgrade-Funktion für diese App gesperrt.", + "diagnosis_apps_not_in_app_catalog": "Diese App fehlt im Applikationskatalog von YunoHost oder wird in diesem nicht mehr angezeigt. Sie müssen im Betracht ziehen, sie zu deinstallieren, weil sie keine Aktualisierungen mehr erhält und die Integrität und die Sicherheit Ihres Systems kompromittieren könnte.", + "diagnosis_apps_outdated_ynh_requirement": "Die installierte Version dieser App erfordert nur YunoHost >=2.x, was darauf hinweist, dass die App nicht mehr auf dem Stand der guten Paketierungspraktiken und der empfohlenen Helper ist. Sie sollten wirklich in Betracht ziehen, sie zu aktualisieren.", + "diagnosis_description_apps": "Applikationen", + "config_cant_set_value_on_section": "Sie können nicht einen einzelnen Wert auf einen gesamten Konfigurationsbereich anwenden.", + "diagnosis_apps_deprecated_practices": "Die installierte Version dieser App verwendet immer noch gewisse veraltete Paketierungspraktiken. Sie sollten die App wirklich aktualisieren.", + "app_config_unable_to_apply": "Konnte die Werte des Konfigurations-Panels nicht anwenden.", + "app_config_unable_to_read": "Konnte die Werte des Konfigurations-Panels nicht auslesen.", + "config_unknown_filter_key": "Der Filterschlüssel '{filter_key}' ist inkorrekt.", + "diagnosis_dns_specialusedomain": "Die Domäne {domain} basiert auf einer Top-Level-Domain (TLD) für spezielle Zwecke wie .local oder .test und deshalb wird von ihr nicht erwartet, dass sie echte DNS-Einträge besitzt." +} From da1b0aa041de4c5d43fc280dbf0c594902df4bb8 Mon Sep 17 00:00:00 2001 From: Ilya Date: Fri, 19 Nov 2021 19:47:40 +0000 Subject: [PATCH 19/51] Translated using Weblate (Russian) Currently translated at 26.9% (190 of 705 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/ru/ --- locales/ru.json | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/locales/ru.json b/locales/ru.json index deb64c70a..8fbc3f91b 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -168,5 +168,25 @@ "yunohost_not_installed": "YunoHost установлен неправильно. Пожалуйста, запустите 'yunohost tools postinstall'", "backup_cleaning_failed": "Не удалось очистить временную папку резервного копирования", "certmanager_attempt_to_replace_valid_cert": "Вы пытаетесь перезаписать хороший и действительный сертификат для домена {domain}! (Используйте --force для обхода)", - "backup_create_size_estimation": "Архив будет содержать около {размер} данных." + "backup_create_size_estimation": "Архив будет содержать около {размер} данных.", + "diagnosis_description_regenconf": "Конфигурации системы", + "diagnosis_description_services": "Проверка статусов сервисов", + "config_validate_color": "Должен быть правильный hex цвета RGB", + "diagnosis_basesystem_hardware": "Аппаратная архитектура сервера – {virt} {arch}", + "certmanager_acme_not_configured_for_domain": "Задача ACME не может быть запущена для {domain} прямо сейчас, потому что в его nginx conf отсутствует соответствующий фрагмент кода... Пожалуйста, убедитесь, что конфигурация вашего nginx обновлена, используя `yunohost tools regen-conf nginx --dry-run --with-diff`.", + "diagnosis_basesystem_ynh_single_version": "{package} версия: {version} ({repo})", + "diagnosis_description_mail": "Email", + "diagnosis_basesystem_kernel": "Версия ядра Linux на сервере {kernel_version}", + "diagnosis_description_apps": "Приложения", + "diagnosis_diskusage_low": "В хранилище {mountpoint} (на устройстве {device}) осталось {free} ({free_percent}%) места (из {total}). Будьте осторожны.", + "diagnosis_description_dnsrecords": "DNS записи", + "diagnosis_description_ip": "Интернет-соединение", + "diagnosis_description_basesystem": "Основная система", + "diagnosis_description_web": "Web", + "diagnosis_basesystem_host": "На сервере запущен Debian {debian_version}", + "diagnosis_dns_bad_conf": "Некоторые записи DNS для домена {domain} (категория {category}) отсутствуют или неверны", + "diagnosis_description_systemresources": "Системные ресурсы", + "backup_with_no_restore_script_for_app": "{app} не имеет сценария восстановления, вы не сможете автоматически восстановить это приложение из резервной копии.", + "diagnosis_description_ports": "Открытые порты", + "diagnosis_basesystem_hardware_model": "Модель сервера {model}" } From 10699e5de04a1ef1dde71939a8f105421474e69e Mon Sep 17 00:00:00 2001 From: Boudewijn Date: Wed, 24 Nov 2021 12:48:07 +0000 Subject: [PATCH 20/51] Translated using Weblate (Dutch) Currently translated at 11.4% (81 of 705 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/nl/ --- locales/nl.json | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/locales/nl.json b/locales/nl.json index f5923fa9a..038d18283 100644 --- a/locales/nl.json +++ b/locales/nl.json @@ -1,19 +1,19 @@ { "action_invalid": "Ongeldige actie '{action}'", "admin_password": "Administrator wachtwoord", - "admin_password_changed": "Het administratie wachtwoord werd gewijzigd", + "admin_password_changed": "Het administratie wachtwoord is gewijzigd", "app_already_installed": "{app} is al geïnstalleerd", "app_argument_invalid": "Kies een geldige waarde voor '{name}': {error}", "app_argument_required": "Het '{name}' moet ingevuld worden", - "app_extraction_failed": "Kan installatiebestanden niet uitpakken", + "app_extraction_failed": "Het lukt niet om de installatiebestanden uit te pakken", "app_id_invalid": "Ongeldige app-id", "app_install_files_invalid": "Deze bestanden kunnen niet worden geïnstalleerd", - "app_not_installed": "{app} is niet geïnstalleerd", - "app_removed": "{app} succesvol verwijderd", - "app_sources_fetch_failed": "Kan bronbestanden niet ophalen, klopt de URL?", + "app_not_installed": "Het lukte niet om {app} te vinden in de lijst met geïnstalleerde apps: {all_apps}", + "app_removed": "{app} is verwijderd", + "app_sources_fetch_failed": "Het is niet gelukt bronbestanden op te halen, klopt de URL?", "app_unknown": "Onbekende app", - "app_upgrade_failed": "Kan app {app} niet updaten", - "app_upgraded": "{app} succesvol geüpgraded", + "app_upgrade_failed": "Het is niet gelukt app {app} bij te werken: {error}", + "app_upgraded": "{app} is bijgewerkt", "ask_firstname": "Voornaam", "ask_lastname": "Achternaam", "ask_new_admin_password": "Nieuw administratorwachtwoord", @@ -69,8 +69,8 @@ "user_unknown": "Gebruikersnaam {user} is onbekend", "user_update_failed": "Kan gebruiker niet bijwerken", "yunohost_configured": "YunoHost configuratie is OK", - "admin_password_change_failed": "Wachtwoord kan niet veranderd worden", - "app_argument_choice_invalid": "Ongeldige keuze voor argument '{name}'. Het moet een van de volgende keuzes zijn {choices}", + "admin_password_change_failed": "Wachtwoord wijzigen is niet gelukt", + "app_argument_choice_invalid": "Kiel een geldige waarde voor argument '{name}'; {value}' komt niet voor in de keuzelijst {choices}", "app_not_correctly_installed": "{app} schijnt niet juist geïnstalleerd te zijn", "app_not_properly_removed": "{app} werd niet volledig verwijderd", "app_requirements_checking": "Noodzakelijke pakketten voor {app} aan het controleren...", @@ -98,18 +98,36 @@ "app_install_failed": "Kan {app} niet installeren: {error}", "app_remove_after_failed_install": "Bezig de app te verwijderen na gefaalde installatie...", "app_manifest_install_ask_domain": "Kies het domein waar deze app op geïnstalleerd moet worden", - "app_manifest_install_ask_path": "Kies het pad waar deze app geïnstalleerd moet worden", + "app_manifest_install_ask_path": "Kies het URL-pad (achter het domein) waar deze app geïnstalleerd moet worden", "app_manifest_install_ask_admin": "Kies een administrator voor deze app", "app_change_url_success": "{app} URL is nu {domain}{path}", - "app_full_domain_unavailable": "Sorry, deze app moet op haar eigen domein geïnstalleerd worden, maar andere apps zijn al geïnstalleerd op het domein '{domain}'. U kunt wel een subdomein aan deze app toewijden.", + "app_full_domain_unavailable": "Sorry, deze app moet op haar eigen domein geïnstalleerd worden, maar andere apps zijn al geïnstalleerd op het domein '{domain}'. Een mogelijke oplossing is om een nieuw subdomein toe te voegen, speciaal voor deze app.", "app_install_script_failed": "Er is een fout opgetreden in het installatiescript van de app", "app_location_unavailable": "Deze URL is niet beschikbaar of is in conflict met de al geïnstalleerde app(s):\n{apps}", "app_manifest_install_ask_password": "Kies een administratiewachtwoord voor deze app", "app_manifest_install_ask_is_public": "Moet deze app zichtbaar zijn voor anomieme bezoekers?", "app_not_upgraded": "De app '{failed_app}' kon niet upgraden en daardoor zijn de upgrades van de volgende apps geannuleerd: {apps}", - "app_start_install": "{app} installeren...", - "app_start_remove": "{app} verwijderen...", + "app_start_install": "Bezig met installeren van {app}...", + "app_start_remove": "Bezig met verwijderen van {app}...", "app_start_backup": "Bestanden aan het verzamelen voor de backup van {app}...", "app_start_restore": "{app} herstellen...", - "app_upgrade_several_apps": "De volgende apps zullen worden geüpgraded: {apps}" -} \ No newline at end of file + "app_upgrade_several_apps": "De volgende apps zullen worden geüpgraded: {apps}", + "app_upgrade_script_failed": "Er is een fout opgetreden in het upgradescript van de app", + "apps_already_up_to_date": "Alle apps zijn al bijgewerkt met de nieuwste versie", + "app_restore_script_failed": "Er ging iets mis in het helstelscript van de app", + "app_change_url_identical_domains": "De oude en nieuwe domeinnaam/url_path zijn identiek ('{domain}{path}'), er is niets te doen.", + "app_already_up_to_date": "{app} is al de meest actuele versie", + "app_action_broke_system": "Deze actie lijkt de volgende belangrijke services te hebben kapotgemaakt: {services}", + "app_config_unable_to_apply": "De waarden in het configuratiescherm konden niet toegepast worden.", + "app_config_unable_to_read": "Het is niet gelukt de waarden van het configuratiescherm te lezen.", + "app_argument_password_no_default": "Foutmelding tijdens het lezen van wachtwoordargument '{name}': het wachtwoordargument mag om veiligheidsredenen geen standaardwaarde hebben.", + "app_already_installed_cant_change_url": "Deze app is al geïnstalleerd. De URL kan niet veranderd worden met deze functie. Probeer of dat lukt via `app changeurl`.", + "apps_catalog_init_success": "De app-catalogus is succesvol geinitieerd!", + "apps_catalog_failed_to_download": "Het is niet gelukt de {apps_catalog} app-catalogus te downloaden: {error}", + "app_packaging_format_not_supported": "Deze app kon niet geinstalleerd worden, omdat het pakketformaat niet ondersteund wordt door je Yunohost. Probeer of je Yunohost bijgewerkt kan worden.", + "additional_urls_already_added": "Extra URL '{url:s}' is al toegevoegd in de extra URL voor privilege '{permission:s}'", + "additional_urls_already_removed": "Extra URL '{url}' is al verwijderd in de extra URL voor privilege '{permission}'", + "app_label_deprecated": "Dit commando is vervallen. Gebruik alsjeblieft het nieuwe commando 'yunohost user permission update' om het label van de app te beheren.", + "app_change_url_no_script": "De app '{app_name}' ondersteunt nog geen URL-aanpassingen. Misschien wel na een upgrade.", + "app_upgrade_some_app_failed": "Sommige apps konden niet worden bijgewerkt" +} From 4d8ca7aaad63520ed604d0bd4889287945a6fb20 Mon Sep 17 00:00:00 2001 From: Tymofii Lytvynenko Date: Thu, 25 Nov 2021 00:51:47 +0000 Subject: [PATCH 21/51] Translated using Weblate (Ukrainian) Currently translated at 100.0% (705 of 705 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/uk/ --- locales/uk.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/uk.json b/locales/uk.json index ae59b0274..f45ad8c66 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -376,7 +376,7 @@ "diagnosis_security_vulnerable_to_meltdown": "Схоже, що ви вразливі до критичної вразливості безпеки Meltdown", "diagnosis_rootfstotalspace_critical": "Коренева файлова система має тільки {space}, що дуже тривожно! Скоріше за все, дисковий простір закінчиться дуже скоро! Рекомендовано мати не менше 16 ГБ для кореневої файлової системи.", "diagnosis_rootfstotalspace_warning": "Коренева файлова система має тільки {space}. Можливо це нормально, але будьте обережні, тому що в кінцевому підсумку дисковий простір може швидко закінчитися... Рекомендовано мати не менше 16 ГБ для кореневої файлової системи.", - "diagnosis_regenconf_manually_modified_details": "Можливо це нормально, якщо ви знаєте, що робите! YunoHost перестане оновлювати цей файл автоматично... Але врахуйте, що оновлення YunoHost можуть містити важливі рекомендовані зміни. Якщо ви хочете, ви можете перевірити відмінності за допомогою команди yunohost tools regen-conf {category} --dry-run --with-diff і примусово повернути рекомендовану конфігурацію за допомогою команди yunohost tools regen-conf {category} --force", + "diagnosis_regenconf_manually_modified_details": "Можливо це нормально, якщо ви знаєте, що робите! YunoHost перестане оновлювати цей файл автоматично. Але врахуйте, що оновлення YunoHost можуть містити важливі рекомендовані зміни. Якщо хочете, ви можете перевірити відмінності за допомогою команди yunohost tools regen-conf {category} --dry-run --with-diff і примусово повернути рекомендовану конфігурацію за допомогою команди yunohost tools regen-conf {category} --force", "diagnosis_regenconf_manually_modified": "Конфігураційний файл {file}, схоже, було змінено вручну.", "diagnosis_regenconf_allgood": "Усі конфігураційні файли відповідають рекомендованій конфігурації!", "diagnosis_mail_queue_too_big": "Занадто багато відкладених листів у поштовій черзі (листів: {nb_pending})", @@ -704,4 +704,4 @@ "ldap_attribute_already_exists": "Атрибут LDAP '{attribute}' вже існує зі значенням '{value}'", "domain_dns_push_already_up_to_date": "Записи вже оновлені, нічого не потрібно робити.", "domain_unknown": "Домен '{domain}' є невідомим" -} \ No newline at end of file +} From 77d74eba06f1f0f65c3321db2dbd5d2238600569 Mon Sep 17 00:00:00 2001 From: Valentin von Guttenberg Date: Mon, 29 Nov 2021 15:02:06 +0000 Subject: [PATCH 22/51] Translated using Weblate (German) Currently translated at 100.0% (705 of 705 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 82 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 14 deletions(-) diff --git a/locales/de.json b/locales/de.json index 4129e7e72..d94161151 100644 --- a/locales/de.json +++ b/locales/de.json @@ -4,7 +4,7 @@ "admin_password_change_failed": "Ändern des Passworts nicht möglich", "admin_password_changed": "Das Administrator-Kennwort wurde geändert", "app_already_installed": "{app} ist schon installiert", - "app_argument_choice_invalid": "Wähle einen der folgenden Werte '{choices}' für das Argument '{name}'", + "app_argument_choice_invalid": "Wähle einen gültigen Wert für das Argument '{name}': '{value}' ist nicht unter den verfügbaren Auswahlmöglichkeiten ({choices})", "app_argument_invalid": "Wähle einen gültigen Wert für das Argument '{name}': {error}", "app_argument_required": "Argument '{name}' wird benötigt", "app_extraction_failed": "Installationsdateien konnten nicht entpackt werden", @@ -127,7 +127,7 @@ "user_creation_failed": "Benutzer:in konnte nicht erstellt werden {user}: {error}", "user_deleted": "Benutzer:in gelöscht", "user_deletion_failed": "Benutzer:in konnte nicht gelöscht werden {user}: {error}", - "user_home_creation_failed": "Persönlicher Ordner des Benutzers konnte nicht erstellt werden", + "user_home_creation_failed": "Persönlicher Ordner '{home}' des/der Benutzers:in konnte nicht erstellt werden", "user_unknown": "Unbekannte:r Benutzer:in : {user}", "user_update_failed": "Benutzer:in konnte nicht aktualisiert werden {user}: {error}", "user_updated": "Benutzerinformationen wurden aktualisiert", @@ -279,7 +279,7 @@ "apps_catalog_obsolete_cache": "Der Cache des App-Katalogs ist leer oder veraltet.", "apps_catalog_update_success": "Der Apps-Katalog wurde aktualisiert!", "password_too_simple_1": "Das Passwort muss mindestens 8 Zeichen lang sein", - "diagnosis_everything_ok": "Alles schaut gut aus für {category}!", + "diagnosis_everything_ok": "Alles sieht OK aus für {category}!", "diagnosis_failed": "Kann Diagnose-Ergebnis für die Kategorie '{category}' nicht abrufen: {error}", "diagnosis_ip_connected_ipv4": "Der Server ist mit dem Internet über IPv4 verbunden!", "diagnosis_no_cache": "Kein Diagnose Cache aktuell für die Kategorie '{category}'", @@ -288,7 +288,7 @@ "diagnosis_ip_no_ipv6": "Der Server hat kein funktionierendes IPv6.", "diagnosis_ip_not_connected_at_all": "Der Server scheint überhaupt nicht mit dem Internet verbunden zu sein!?", "diagnosis_failed_for_category": "Diagnose fehlgeschlagen für die Kategorie '{category}': {error}", - "diagnosis_cache_still_valid": "(Der Cache für die Diagnose {category} ist immer noch gültig. Es wird momentan keine neue Diagnose durchgeführt!)", + "diagnosis_cache_still_valid": "(Cache noch gültig für {category} Diagnose. Es wird keine neue Diagnose durchgeführt!)", "diagnosis_cant_run_because_of_dep": "Kann Diagnose für {category} nicht ausführen während wichtige Probleme zu {dep} noch nicht behoben sind.", "diagnosis_found_errors_and_warnings": "Habe {errors} erhebliche(s) Problem(e) (und {warnings} Warnung(en)) in Verbindung mit {category} gefunden!", "diagnosis_ip_broken_dnsresolution": "Domänen-Namens-Auflösung scheint aus einem bestimmten Grund nicht zu funktionieren... Blockiert eine Firewall die DNS Anfragen?", @@ -317,7 +317,7 @@ "diagnosis_domain_expiration_success": "Ihre Domänen sind registriert und werden in nächster Zeit nicht ablaufen.", "diagnosis_domain_not_found_details": "Die Domäne {domain} existiert nicht in der WHOIS-Datenbank oder sie ist abgelaufen!", "diagnosis_domain_expiration_not_found": "Das Ablaufdatum einiger Domains kann nicht überprüft werden", - "diagnosis_dns_try_dyndns_update_force": "Die DNS Konfiguration der Domäne sollte von Yunohost kontrolliert werden. Andernfalls, kannst du mit yunohost dyndns update --force ein Update erzwingen.", + "diagnosis_dns_try_dyndns_update_force": "Die DNS-Konfiguration dieser Domäne sollte automatisch von YunoHost verwaltet werden. Andernfalls könntest Du mittels yunohost dyndns update --force ein Update erzwingen.", "diagnosis_dns_point_to_doc": "Bitte schaue in die Dokumentation unter https://yunohost.org/dns_config wenn du hilfe bei der Konfiguration der DNS Einträge brauchst.", "diagnosis_dns_discrepancy": "Der folgende DNS Eintrag scheint nicht den empfohlenen Einstellungen zu entsprechen:
Typ: {type}
Name: {name}
Aktueller Wert: {current}
Erwarteter Wert: {value}", "diagnosis_dns_missing_record": "Gemäß der empfohlenen DNS-Konfiguration sollten Sie einen DNS-Eintrag mit den folgenden Informationen hinzufügen.
Typ: {type}
Name: {name}
Wert: {value}", @@ -349,7 +349,7 @@ "diagnosis_diskusage_low": "Der Speicher {mountpoint} (auf Gerät {device}) hat nur noch {free} ({free_percent}%) freien Speicherplatz (von insgesamt {total}). Seien Sie vorsichtig.", "diagnosis_ram_low": "Das System hat nur {available} ({available_percent}%) RAM zur Verfügung! (von insgesamt {total}). Seien Sie vorsichtig.", "service_reload_or_restart_failed": "Der Dienst '{service}' konnte nicht erneut geladen oder gestartet werden.\n\nKürzlich erstellte Logs des Dienstes: {logs}", - "diagnosis_domain_expiration_not_found_details": "Die WHOIS Informationen für die Domäne {domain} scheinen keine Informationen über das Ablaufdatum zu enthalten.", + "diagnosis_domain_expiration_not_found_details": "Die WHOIS-Informationen für die Domäne {domain} scheinen keine Informationen über das Ablaufdatum zu enthalten. Stimmt das?", "diagnosis_domain_expiration_warning": "Einige Domänen werden bald ablaufen.", "diagnosis_diskusage_ok": "Der Speicher {mountpoint} (auf Gerät {device}) hat immer noch {free} ({free_percent}%) freien Speicherplatz übrig(von insgesamt {total})!", "diagnosis_ram_ok": "Das System hat immer noch {available} ({available_percent}%) RAM zu Verfügung von {total}.", @@ -375,7 +375,7 @@ "ask_user_domain": "Domäne, welche für die E-Mail-Adresse und den XMPP-Account des Benutzers verwendet werden soll", "app_manifest_install_ask_is_public": "Soll diese Applikation für anonyme Benutzer:innen sichtbar sein?", "app_manifest_install_ask_admin": "Wählen Sie einen Administrator für diese Applikation", - "app_manifest_install_ask_path": "Wählen Sie den Pfad, in welchem die Applikation installiert werden soll", + "app_manifest_install_ask_path": "Wählen Sie den URL-Pfad (nach der Domäne), unter dem die Applikation installiert werden soll", "diagnosis_mail_blacklist_listed_by": "Ihre IP-Adresse oder Domäne {item} ist auf der Blacklist auf {blacklist_name}", "diagnosis_mail_blacklist_ok": "Die IP-Adressen und die Domänen, welche von diesem Server verwendet werden, scheinen nicht auf einer Blacklist zu sein", "diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "Aktueller Reverse-DNS-Eintrag: {rdns_domain}
Erwarteter Wert: {ehlo_domain}", @@ -428,7 +428,7 @@ "app_label_deprecated": "Dieser Befehl ist veraltet! Bitte nutzen Sie den neuen Befehl 'yunohost user permission update' um das Applabel zu verwalten.", "diagnosis_http_hairpinning_issue_details": "Das ist wahrscheinlich aufgrund Ihrer ISP Box / Router. Als Konsequenz können Personen von ausserhalb Ihres Netzwerkes aber nicht von innerhalb Ihres lokalen Netzwerkes (wie wahrscheinlich Sie selber?) wie gewohnt auf Ihren Server zugreifen, wenn Sie ihre Domäne oder Ihre öffentliche IP verwenden. Sie können die Situation wahrscheinlich verbessern, indem Sie ein einen Blick in https://yunohost.org/dns_local_network werfen", "diagnosis_http_nginx_conf_not_up_to_date": "Jemand hat anscheinend die Konfiguration von Nginx manuell geändert. Diese Änderung verhindert, dass YunoHost eine Diagnose durchführen kann, wenn er via HTTP erreichbar ist.", - "diagnosis_http_bad_status_code": "Anscheinend beantwortet ein anderes Gerät als Ihr Server die Anfrage (Vielleicht ihr Internetrouter).
1. Die häufigste Ursache ist, dass Port 80 (und 443) nicht richtig auf Ihren Server weitergeleitet wird.
2. Bei komplexeren Setups: Vergewissern Sie sich, dass keine Firewall und keine Reverse-Proxy interferieren.", + "diagnosis_http_bad_status_code": "Es sieht so aus als ob ein anderes Gerät (vielleicht dein Router/Modem) anstelle deines Servers antwortet.
1. Der häufigste Grund hierfür ist, dass Port 80 (und 443) nicht korrekt zu deinem Server weiterleiten.
2. Bei komplexeren Setups: prüfe ob deine Firewall oder Reverse-Proxy die Verbindung stören.", "diagnosis_never_ran_yet": "Sie haben kürzlich einen neuen YunoHost-Server installiert aber es gibt davon noch keinen Diagnosereport. Sie sollten eine Diagnose anstossen. Sie können das entweder vom Webadmin aus oder in der Kommandozeile machen. In der Kommandozeile verwenden Sie dafür den Befehl 'yunohost diagnosis run'.", "diagnosis_http_nginx_conf_not_up_to_date_details": "Um dieses Problem zu beheben, geben Sie in der Kommandozeile yunohost tools regen-conf nginx --dry-run --with-diff ein. Dieses Tool zeigt ihnen den Unterschied an. Wenn Sie damit einverstanden sind, können Sie mit yunohost tools regen-conf nginx --force die Änderungen übernehmen.", "diagnosis_backports_in_sources_list": "Sie haben anscheinend apt (den Paketmanager) für das Backports-Repository konfiguriert. Wir raten strikte davon ab, Pakete aus dem Backports-Repository zu installieren. Diese würden wahrscheinlich zu Instabilitäten und Konflikten führen. Es sei denn, Sie wissen was Sie tun.", @@ -606,7 +606,7 @@ "server_shutdown_confirm": "Der Server wird sofort heruntergefahren, sind Sie sicher? [{answers}]", "server_shutdown": "Der Server wird heruntergefahren", "root_password_replaced_by_admin_password": "Ihr Root Passwort wurde durch Ihr Admin Passwort ersetzt.", - "show_tile_cant_be_enabled_for_regex": "Momentan können Sie 'show_tile' nicht aktivieren, weil die URL für die Berechtigung '{permission}' ein regulärer Ausdruck ist", + "show_tile_cant_be_enabled_for_regex": "Du kannst 'show_tile' momentan nicht aktivieren, weil die URL für die Berechtigung '{permission}' ein regulärer Ausdruck ist", "show_tile_cant_be_enabled_for_url_not_defined": "Momentan können Sie 'show_tile' nicht aktivieren, weil Sie zuerst eine URL für die Berechtigung '{permission}' definieren müssen", "tools_upgrade_regular_packages_failed": "Konnte für die folgenden Pakete das Upgrade nicht durchführen: {packages_list}", "tools_upgrade_regular_packages": "Momentan werden Upgrades für das System (YunoHost-unabhängige) Pakete durchgeführt...", @@ -628,11 +628,11 @@ "disk_space_not_sufficient_update": "Es ist nicht genügend Speicherplatz frei, um diese Applikation zu aktuallisieren", "disk_space_not_sufficient_install": "Es ist nicht genügend Speicherplatz frei, um diese Applikation zu installieren", "danger": "Warnung:", - "diagnosis_apps_bad_quality": "Diese App ist im YunoHost App Katalog momentan als kaputt gekennzeichnet. Dies mag ein temporäres Problem darstellen, das von den Maintainern versucht wird zu beheben. In der Zwischenzeit ist das Upgrade dieser App nicht möglich.", - "config_apply_failed": "Die neue Konfiguration umzusetzen ist fehlgeschlagen: {error}", + "diagnosis_apps_bad_quality": "Diese App ist im YunoHost-Applikationskatalog momentan als defekt gekennzeichnet. Es könnte sich dabei um einen vorübergehendes Problem handeln. Während der/die Betreuer:in versucht das Problem zu beheben, ist die Upgrade-Funktion für diese App gesperrt.", + "config_apply_failed": "Anwenden der neuen Konfiguration fehlgeschlagen: {error}", "config_validate_date": "Sollte ein zulässiges Datum in folgendem Format sein: YYYY-MM-DD", "config_validate_email": "Sollte eine zulässige eMail sein", - "config_forbidden_keyword": "Das Keyword '{keyword}' ist reserviert. Mit dieser id kannst du keine Konfigurationspanel erstellen", + "config_forbidden_keyword": "Das Schlüsselwort '{keyword}' ist reserviert. Du kannst kein Konfigurationspanel mit einer Frage erstellen, die diese ID verwendet.", "config_no_panel": "Kein Konfigurationspanel gefunden.", "config_validate_color": "Sollte eine zulässige RGB hexadezimal Farbe sein", "diagnosis_apps_issue": "Ein Problem für die App {app} ist aufgetreten", @@ -640,7 +640,7 @@ "config_validate_url": "Sollte eine zulässige web URL sein", "config_version_not_supported": "Konfigurationspanel Versionen '{version}' sind nicht unterstützt.", "diagnosis_apps_allgood": "Alle installierten Apps berücksichtigen die grundlegenden Paketierungspraktiken", - "diagnosis_apps_broken": "Diese App ist im YunoHost-Applikationskatalog momentan als defekt gekennzeichnet. Es könnte sich dabei um einen vorübergehendes Problem handeln. Während der Betreuer versucht das Problem zu beheben, ist die Upgrade-Funktion für diese App gesperrt.", + "diagnosis_apps_broken": "Diese App ist im YunoHost-Applikationskatalog momentan als defekt gekennzeichnet. Es könnte sich dabei um einen vorübergehendes Problem handeln. Während der/die Betreuer:in versucht das Problem zu beheben, ist die Upgrade-Funktion für diese App gesperrt.", "diagnosis_apps_not_in_app_catalog": "Diese App fehlt im Applikationskatalog von YunoHost oder wird in diesem nicht mehr angezeigt. Sie müssen im Betracht ziehen, sie zu deinstallieren, weil sie keine Aktualisierungen mehr erhält und die Integrität und die Sicherheit Ihres Systems kompromittieren könnte.", "diagnosis_apps_outdated_ynh_requirement": "Die installierte Version dieser App erfordert nur YunoHost >=2.x, was darauf hinweist, dass die App nicht mehr auf dem Stand der guten Paketierungspraktiken und der empfohlenen Helper ist. Sie sollten wirklich in Betracht ziehen, sie zu aktualisieren.", "diagnosis_description_apps": "Applikationen", @@ -649,5 +649,59 @@ "app_config_unable_to_apply": "Konnte die Werte des Konfigurations-Panels nicht anwenden.", "app_config_unable_to_read": "Konnte die Werte des Konfigurations-Panels nicht auslesen.", "config_unknown_filter_key": "Der Filterschlüssel '{filter_key}' ist inkorrekt.", - "diagnosis_dns_specialusedomain": "Die Domäne {domain} basiert auf einer Top-Level-Domain (TLD) für spezielle Zwecke wie .local oder .test und deshalb wird von ihr nicht erwartet, dass sie echte DNS-Einträge besitzt." + "diagnosis_dns_specialusedomain": "Die Domäne {domain} basiert auf einer Top-Level-Domain (TLD) für spezielle Zwecke wie .local oder .test und deshalb wird von ihr nicht erwartet, dass sie echte DNS-Einträge besitzt.", + "ldap_server_down": "LDAP-Server kann nicht erreicht werden", + "diagnosis_http_special_use_tld": "Die Domäne {domain} basiert auf einer Top-Level-Domäne (TLD) für besondere Zwecke wie .local oder .test und wird daher voraussichtlich nicht außerhalb des lokalen Netzwerks zugänglich sein.", + "domain_dns_push_managed_in_parent_domain": "Die automatische DNS-Konfiguration wird von der übergeordneten Domäne {parent_domain} verwaltet.", + "domain_dns_push_already_up_to_date": "Die Einträge sind auf dem neuesten Stand, es gibt nichts zu tun.", + "domain_config_auth_token": "Authentifizierungstoken", + "domain_config_auth_key": "Authentifizierungsschlüssel", + "domain_config_auth_secret": "Authentifizierungsgeheimnis", + "domain_config_api_protocol": "API-Protokoll", + "domain_unknown": "Domäne '{domain}' unbekannt", + "ldap_server_is_down_restart_it": "Der LDAP-Dienst ist nicht erreichbar, versuche ihn neu zu starten...", + "user_import_bad_file": "Deine CSV-Datei ist nicht korrekt formatiert und wird daher ignoriert, um einen möglichen Datenverlust zu vermeiden", + "global_settings_setting_security_experimental_enabled": "Aktiviere experimentelle Sicherheitsfunktionen (nur aktivieren, wenn Du weißt was Du tust!)", + "global_settings_setting_security_nginx_redirect_to_https": "HTTP-Anfragen standardmäßig auf HTTPs umleiten (NICHT AUSSCHALTEN, sofern Du nicht weißt was Du tust!)", + "user_import_missing_columns": "Die folgenden Spalten fehlen: {columns}", + "user_import_nothing_to_do": "Es muss kein:e Benutzer:in importiert werden", + "user_import_partial_failed": "Der Import von Benutzer:innen ist teilweise fehlgeschlagen", + "user_import_bad_line": "Ungültige Zeile {line}: {details}", + "other_available_options": "… und {n} weitere verfügbare Optionen, die nicht angezeigt werden", + "domain_dns_conf_special_use_tld": "Diese Domäne basiert auf einer Top-Level-Domäne (TLD) für besondere Zwecke wie .local oder .test und wird daher vermutlich keine eigenen DNS-Einträge haben.", + "domain_dns_registrar_managed_in_parent_domain": "Diese Domäne ist eine Unterdomäne von {parent_domain_link}. Die Konfiguration des DNS-Registrars sollte auf der Konfigurationsseite von {parent_domain} verwaltet werden.", + "domain_dns_registrar_not_supported": "YunoHost konnte den Registrar, der diese Domäne verwaltet, nicht automatisch erkennen. Du solltest die DNS-Einträge, wie unter https://yunohost.org/dns beschrieben, manuell konfigurieren.", + "domain_dns_registrar_supported": "YunoHost hat automatisch erkannt, dass diese Domäne von dem Registrar **{registrar}** verwaltet wird. Wenn Du möchtest, konfiguriert YunoHost diese DNS-Zone automatisch, wenn Du die entsprechenden API-Zugangsdaten zur Verfügung stellst. Auf dieser Seite erfährst Du, wie Du deine API-Anmeldeinformationen erhältst: https://yunohost.org/registar_api_{registrar}. (Du kannst deine DNS-Einträge auch, wie unter https://yunohost.org/dns beschrieben, manuell konfigurieren)", + "service_not_reloading_because_conf_broken": "Der Dienst '{Name}' wird nicht neu geladen/gestartet, da seine Konfiguration fehlerhaft ist: {Fehler}", + "user_import_failed": "Der Import von Benutzer:innen ist komplett fehlgeschlagen", + "domain_dns_push_failed_to_list": "Auflistung der aktuellen Einträge über die API des Registrars fehlgeschlagen: {error}", + "domain_dns_pushing": "DNS-Einträge übertragen…", + "domain_dns_push_record_failed": "{action} für Eintrag {type}/{name} fehlgeschlagen: {error}", + "domain_dns_push_success": "DNS-Einträge aktualisiert!", + "domain_dns_push_failed": "Die Aktualisierung der DNS-Einträge ist leider gescheitert.", + "domain_dns_push_partial_failure": "DNS-Einträge teilweise aktualisiert: einige Warnungen/Fehler wurden gemeldet.", + "domain_config_features_disclaimer": "Bisher hat das Aktivieren/Deaktivieren von Mail- oder XMPP-Funktionen nur Auswirkungen auf die empfohlene und automatische DNS-Konfiguration, nicht auf die Systemkonfigurationen!", + "domain_config_mail_in": "Eingehende E-Mails", + "domain_config_mail_out": "Ausgehende E-Mails", + "domain_config_xmpp": "Instant Messaging (XMPP)", + "log_app_config_set": "Konfiguration auf die Applikation '{}' anwenden", + "log_user_import": "Benutzer:innen importieren", + "diagnosis_high_number_auth_failures": "In letzter Zeit gab es eine verdächtig hohe Anzahl von Authentifizierungsfehlern. Stelle sicher, dass fail2ban läuft und korrekt konfiguriert ist, oder verwende einen benutzerdefinierten Port für SSH, wie unter https://yunohost.org/security beschrieben.", + "domain_dns_registrar_yunohost": "Dies ist eine nohost.me / nohost.st / ynh.fr Domäne, ihre DNS-Konfiguration wird daher automatisch von YunoHost ohne weitere Konfiguration übernommen. (siehe Befehl 'yunohost dyndns update')", + "domain_config_auth_entrypoint": "API-Einstiegspunkt", + "domain_config_auth_application_key": "Anwendungsschlüssel", + "domain_config_auth_application_secret": "Geheimer Anwendungsschlüssel", + "domain_config_auth_consumer_key": "Consumer-Schlüssel", + "invalid_number_min": "Muss größer sein als {min}", + "invalid_number_max": "Muss kleiner sein als {max}", + "invalid_password": "Ungültiges Passwort", + "ldap_attribute_already_exists": "LDAP-Attribut '{attribute}' existiert bereits mit dem Wert '{value}'", + "user_import_success": "Benutzer:innen erfolgreich importiert", + "domain_registrar_is_not_configured": "Der DNS-Registrar ist noch nicht für die Domäne '{domain}' konfiguriert.", + "domain_dns_push_not_applicable": "Die automatische DNS-Konfiguration ist nicht auf die Domäne {domain} anwendbar. Konfiguriere die DNS-Einträge manuell, wie unter https://yunohost.org/dns_config beschrieben.", + "domain_dns_registrar_experimental": "Bislang wurde die Schnittstelle zur API von **{registrar}** noch nicht außreichend von der YunoHost-Community getestet und geprüft. Der Support ist **sehr experimentell** – sei vorsichtig!", + "domain_dns_push_failed_to_authenticate": "Die Authentifizierung bei der API des Registrars für die Domäne '{domain}' ist fehlgeschlagen. Wahrscheinlich sind die Anmeldedaten falsch? (Fehler: {error})", + "log_domain_config_set": "Konfiguration für die Domäne '{}' aktualisieren", + "log_domain_dns_push": "DNS-Einträge für die Domäne '{}' übertragen", + "service_description_yunomdns": "Ermöglicht es dir, deinen Server über 'yunohost.local' in deinem lokalen Netzwerk zu erreichen" } From b6250c0094aba4aac8f1a51a517f9314b6cd8519 Mon Sep 17 00:00:00 2001 From: Colin Wawrik Date: Mon, 29 Nov 2021 18:25:18 +0000 Subject: [PATCH 23/51] Translated using Weblate (German) Currently translated at 100.0% (705 of 705 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index d94161151..f1b7ec2cc 100644 --- a/locales/de.json +++ b/locales/de.json @@ -427,7 +427,7 @@ "additional_urls_already_removed": "Zusätzliche URL '{url}' bereits entfernt in der zusätzlichen URL für Berechtigung '{permission}'", "app_label_deprecated": "Dieser Befehl ist veraltet! Bitte nutzen Sie den neuen Befehl 'yunohost user permission update' um das Applabel zu verwalten.", "diagnosis_http_hairpinning_issue_details": "Das ist wahrscheinlich aufgrund Ihrer ISP Box / Router. Als Konsequenz können Personen von ausserhalb Ihres Netzwerkes aber nicht von innerhalb Ihres lokalen Netzwerkes (wie wahrscheinlich Sie selber?) wie gewohnt auf Ihren Server zugreifen, wenn Sie ihre Domäne oder Ihre öffentliche IP verwenden. Sie können die Situation wahrscheinlich verbessern, indem Sie ein einen Blick in https://yunohost.org/dns_local_network werfen", - "diagnosis_http_nginx_conf_not_up_to_date": "Jemand hat anscheinend die Konfiguration von Nginx manuell geändert. Diese Änderung verhindert, dass YunoHost eine Diagnose durchführen kann, wenn er via HTTP erreichbar ist.", + "diagnosis_http_nginx_conf_not_up_to_date": "Die Konfiguration von Nginx scheint manuell geändert worden zu sein. Dies hindert YunoHost daran festzustellen, ob es über HTTP erreichbar ist.", "diagnosis_http_bad_status_code": "Es sieht so aus als ob ein anderes Gerät (vielleicht dein Router/Modem) anstelle deines Servers antwortet.
1. Der häufigste Grund hierfür ist, dass Port 80 (und 443) nicht korrekt zu deinem Server weiterleiten.
2. Bei komplexeren Setups: prüfe ob deine Firewall oder Reverse-Proxy die Verbindung stören.", "diagnosis_never_ran_yet": "Sie haben kürzlich einen neuen YunoHost-Server installiert aber es gibt davon noch keinen Diagnosereport. Sie sollten eine Diagnose anstossen. Sie können das entweder vom Webadmin aus oder in der Kommandozeile machen. In der Kommandozeile verwenden Sie dafür den Befehl 'yunohost diagnosis run'.", "diagnosis_http_nginx_conf_not_up_to_date_details": "Um dieses Problem zu beheben, geben Sie in der Kommandozeile yunohost tools regen-conf nginx --dry-run --with-diff ein. Dieses Tool zeigt ihnen den Unterschied an. Wenn Sie damit einverstanden sind, können Sie mit yunohost tools regen-conf nginx --force die Änderungen übernehmen.", From c3ef8ad3c7b6aab121b80a5726c643ea6b9c2532 Mon Sep 17 00:00:00 2001 From: Valentin von Guttenberg Date: Mon, 29 Nov 2021 18:26:05 +0000 Subject: [PATCH 24/51] Translated using Weblate (German) Currently translated at 100.0% (705 of 705 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index f1b7ec2cc..aa0413ba8 100644 --- a/locales/de.json +++ b/locales/de.json @@ -427,7 +427,7 @@ "additional_urls_already_removed": "Zusätzliche URL '{url}' bereits entfernt in der zusätzlichen URL für Berechtigung '{permission}'", "app_label_deprecated": "Dieser Befehl ist veraltet! Bitte nutzen Sie den neuen Befehl 'yunohost user permission update' um das Applabel zu verwalten.", "diagnosis_http_hairpinning_issue_details": "Das ist wahrscheinlich aufgrund Ihrer ISP Box / Router. Als Konsequenz können Personen von ausserhalb Ihres Netzwerkes aber nicht von innerhalb Ihres lokalen Netzwerkes (wie wahrscheinlich Sie selber?) wie gewohnt auf Ihren Server zugreifen, wenn Sie ihre Domäne oder Ihre öffentliche IP verwenden. Sie können die Situation wahrscheinlich verbessern, indem Sie ein einen Blick in https://yunohost.org/dns_local_network werfen", - "diagnosis_http_nginx_conf_not_up_to_date": "Die Konfiguration von Nginx scheint manuell geändert worden zu sein. Dies hindert YunoHost daran festzustellen, ob es über HTTP erreichbar ist.", + "diagnosis_http_nginx_conf_not_up_to_date": "Die Konfiguration von Nginx scheint für diese Domäne manuell geändert worden zu sein. Dies hindert YunoHost daran festzustellen, ob es über HTTP erreichbar ist.", "diagnosis_http_bad_status_code": "Es sieht so aus als ob ein anderes Gerät (vielleicht dein Router/Modem) anstelle deines Servers antwortet.
1. Der häufigste Grund hierfür ist, dass Port 80 (und 443) nicht korrekt zu deinem Server weiterleiten.
2. Bei komplexeren Setups: prüfe ob deine Firewall oder Reverse-Proxy die Verbindung stören.", "diagnosis_never_ran_yet": "Sie haben kürzlich einen neuen YunoHost-Server installiert aber es gibt davon noch keinen Diagnosereport. Sie sollten eine Diagnose anstossen. Sie können das entweder vom Webadmin aus oder in der Kommandozeile machen. In der Kommandozeile verwenden Sie dafür den Befehl 'yunohost diagnosis run'.", "diagnosis_http_nginx_conf_not_up_to_date_details": "Um dieses Problem zu beheben, geben Sie in der Kommandozeile yunohost tools regen-conf nginx --dry-run --with-diff ein. Dieses Tool zeigt ihnen den Unterschied an. Wenn Sie damit einverstanden sind, können Sie mit yunohost tools regen-conf nginx --force die Änderungen übernehmen.", From 7c8ded3275e4702d97f2c30f78c47eddfb11d050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Gaspar?= Date: Fri, 10 Dec 2021 11:16:05 +0000 Subject: [PATCH 25/51] Translated using Weblate (French) Currently translated at 100.0% (719 of 719 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/locales/fr.json b/locales/fr.json index 07bdcfad3..e6827df56 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -416,7 +416,7 @@ "diagnosis_ip_weird_resolvconf": "La résolution DNS semble fonctionner, mais il semble que vous utilisez un /etc/resolv.conf personnalisé.", "diagnosis_ip_weird_resolvconf_details": "Le fichier /etc/resolv.conf doit être un lien symbolique vers /etc/resolvconf/run/resolv.conf lui-même pointant vers 127.0.0.1 (dnsmasq). Si vous souhaitez configurer manuellement les résolveurs DNS, veuillez modifier /etc/resolv.dnsmasq.conf.", "diagnosis_dns_missing_record": "Selon la configuration DNS recommandée, vous devez ajouter un enregistrement DNS
Type : {type}
Nom : {name}
Valeur : {value}", - "diagnosis_diskusage_ok": "L'espace de stockage {mountpoint} (sur le périphérique {device}) a encore {free} ({free_percent}%) espace restant (sur {total}) !", + "diagnosis_diskusage_ok": "L'espace de stockage {mountpoint} (sur le périphérique {device}) a encore {free} ({free_percent}%) d'espace restant (sur {total}) !", "diagnosis_ram_ok": "Le système dispose encore de {available} ({available_percent}%) de RAM sur {total}.", "diagnosis_regenconf_allgood": "Tous les fichiers de configuration sont conformes à la configuration recommandée !", "diagnosis_security_vulnerable_to_meltdown": "Vous semblez vulnérable à la vulnérabilité de sécurité critique de Meltdown", @@ -442,9 +442,9 @@ "diagnosis_dns_bad_conf": "Certains enregistrements DNS sont manquants ou incorrects pour le domaine {domain} (catégorie {category})", "diagnosis_dns_discrepancy": "Cet enregistrement DNS ne semble pas correspondre à la configuration recommandée :
Type : {type}
Nom : {name}
La valeur actuelle est : {current}
La valeur attendue est : {value}", "diagnosis_services_bad_status": "Le service {service} est {status} :-(", - "diagnosis_diskusage_verylow": "L'espace de stockage {mountpoint} (sur l'appareil {device}) ne dispose que de {free} ({free_percent}%) espace restant (sur {total}). Vous devriez vraiment envisager de nettoyer de l'espace !", - "diagnosis_diskusage_low": "L'espace de stockage {mountpoint} (sur l'appareil {device}) ne dispose que de {free} ({free_percent}%) espace restant (sur {total}). Faites attention.", - "diagnosis_ram_verylow": "Le système ne dispose plus que de {available} ({available_percent}%)! (sur {total})", + "diagnosis_diskusage_verylow": "L'espace de stockage {mountpoint} (sur l'appareil {device}) ne dispose que de {free} ({free_percent}%) d'espace restant (sur {total}). Vous devriez vraiment envisager de nettoyer de l'espace !", + "diagnosis_diskusage_low": "L'espace de stockage {mountpoint} (sur l'appareil {device}) ne dispose que de {free} ({free_percent}%) d'espace restant (sur {total}). Faites attention.", + "diagnosis_ram_verylow": "Le système ne dispose plus que de {available} ({available_percent}%) de RAM ! (sur {total})", "diagnosis_ram_low": "Le système n'a plus de {available} ({available_percent}%) RAM sur {total}. Faites attention.", "diagnosis_swap_none": "Le système n'a aucun espace de swap. Vous devriez envisager d'ajouter au moins {recommended} de swap pour éviter les situations où le système manque de mémoire.", "diagnosis_swap_notsomuch": "Le système ne dispose que de {total} de swap. Vous devez envisager d'avoir au moins {recommended} pour éviter les situations où le système manque de mémoire.", @@ -547,7 +547,7 @@ "diagnosis_swap_tip": "Merci d'être prudent et conscient que si vous hébergez une partition SWAP sur une carte SD ou un disque SSD, cela risque de réduire drastiquement l'espérance de vie du périphérique.", "restore_already_installed_apps": "Les applications suivantes ne peuvent pas être restaurées car elles sont déjà installées : {apps}", "regenconf_need_to_explicitly_specify_ssh": "La configuration de ssh a été modifiée manuellement. Vous devez explicitement indiquer la mention --force à \"ssh\" pour appliquer les changements.", - "migration_0015_cleaning_up": "Nettoyage du cache et des paquets qui ne sont plus nécessaires ...", + "migration_0015_cleaning_up": "Nettoyage du cache et des paquets qui ne sont plus nécessaires...", "migration_0015_specific_upgrade": "Démarrage de la mise à jour des paquets du système qui doivent être mis à jour séparément...", "migration_0015_modified_files": "Veuillez noter que les fichiers suivants ont été modifiés manuellement et pourraient être écrasés à la suite de la mise à niveau : {manually_modified_files}", "migration_0015_problematic_apps_warning": "Veuillez noter que des applications qui peuvent poser problèmes ont été détectées. Il semble qu'elles n'aient pas été installées à partir du catalogue d'applications YunoHost, ou bien qu'elles ne soient pas signalées comme \"fonctionnelles\". Par conséquent, il n'est pas possible de garantir que les applications suivantes fonctionneront encore après la mise à niveau : {problematic_apps}", @@ -703,5 +703,19 @@ "domain_dns_conf_special_use_tld": "Ce domaine est basé sur un domaine de premier niveau (TLD) à usage spécial tel que .local ou .test et ne devrait donc pas avoir d'enregistrements DNS réels.", "other_available_options": "... et {n} autres options disponibles non affichées", "domain_config_auth_consumer_key": "Consumer key", - "domain_unknown": "Domaine '{domain}' inconnu" -} \ No newline at end of file + "domain_unknown": "Domaine '{domain}' inconnu", + "migration_0021_start": "Démarrage de la migration vers Bullseye", + "migration_0021_patching_sources_list": "Mise à jour du fichier sources.lists...", + "migration_0021_main_upgrade": "Démarrage de la mise à niveau générale...", + "migration_0021_still_on_buster_after_main_upgrade": "Quelque chose s'est mal passé lors de la mise à niveau, le système semble toujours être sous Debian Buster", + "migration_0021_yunohost_upgrade": "Démarrage de la mise à jour du noyau YunoHost...", + "migration_0021_not_enough_free_space": "L'espace libre est très faible dans /var/ ! Vous devriez avoir au moins 1 Go de libre pour effectuer cette migration.", + "migration_0021_system_not_fully_up_to_date": "Votre système n'est pas entièrement à jour. Veuillez effectuer une mise à jour normale avant de lancer la migration vers Bullseye.", + "migration_0021_general_warning": "Veuillez noter que cette migration est une opération délicate. L'équipe YunoHost a fait de son mieux pour la revérifier et la tester, mais la migration pourrait quand même casser des éléments du système ou de ses applications.\n\nIl est donc recommandé :\n - de faire une sauvegarde de toute donnée ou application critique. Plus d'informations ici https://yunohost.org/backup ;\n - d'être patient après le lancement de la migration. Selon votre connexion internet et votre matériel, la mise à niveau peut prendre jusqu'à quelques heures.", + "migration_0021_problematic_apps_warning": "Veuillez noter que des applications qui peuvent poser problèmes ont été détectées. Il semble qu'elles n'aient pas été installées à partir du catalogue d'applications YunoHost, ou bien qu'elles ne soient pas signalées comme \\\"fonctionnelles\\\". Par conséquent, il n'est pas possible de garantir que les applications suivantes fonctionneront encore après la mise à niveau : {problematic_apps}", + "migration_0021_modified_files": "Veuillez noter que les fichiers suivants ont été modifiés manuellement et pourraient être écrasés à la suite de la mise à niveau : {manually_modified_files}", + "migration_0021_cleaning_up": "Nettoyage du cache et des paquets qui ne sont plus nécessaires...", + "migration_0021_patch_yunohost_conflicts": "Application du correctif pour contourner le problème de conflit...", + "migration_0021_not_buster": "La distribution Debian actuelle n'est pas Buster !", + "migration_description_0021_migrate_to_bullseye": "Mise à niveau du système vers Debian Bullseye et YunoHost 11.x" +} From 05c69ed9fac93d285e8313c83b89347dae4b90bc Mon Sep 17 00:00:00 2001 From: Tymofii-Lytvynenko Date: Fri, 10 Dec 2021 23:55:58 +0000 Subject: [PATCH 26/51] Translated using Weblate (Ukrainian) Currently translated at 100.0% (719 of 719 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/uk/ --- locales/uk.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/locales/uk.json b/locales/uk.json index f45ad8c66..25fa1d551 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -703,5 +703,19 @@ "domain_dns_pushing": "Передання записів DNS...", "ldap_attribute_already_exists": "Атрибут LDAP '{attribute}' вже існує зі значенням '{value}'", "domain_dns_push_already_up_to_date": "Записи вже оновлені, нічого не потрібно робити.", - "domain_unknown": "Домен '{domain}' є невідомим" + "domain_unknown": "Домен '{domain}' є невідомим", + "migration_0021_start": "Початок міграції на Bullseye", + "migration_0021_patching_sources_list": "Виправлення sources.lists...", + "migration_0021_main_upgrade": "Початок основного оновлення...", + "migration_0021_yunohost_upgrade": "Початок оновлення ядра YunoHost...", + "migration_0021_not_buster": "Поточний дистрибутив Debian не є Buster!", + "migration_0021_problematic_apps_warning": "Зверніть увагу, що були виявлені наступні, ймовірно проблемні встановлені застосунки. Схоже, що вони не були встановлені з каталогу застосунків YunoHost або не зазначені як «робочі». Отже, не можна гарантувати, що вони будуть працювати після оновлення: {problematic_apps}", + "migration_0021_modified_files": "Зверніть увагу, що такі файли були змінені вручну і можуть бути перезаписані після оновлення: {manually_modified_files}", + "migration_0021_cleaning_up": "Очищення кеш-пам'яті і пакетів, які більше не потрібні...", + "migration_0021_patch_yunohost_conflicts": "Застосування виправлення для вирішення проблеми конфлікту...", + "migration_0021_still_on_buster_after_main_upgrade": "Щось пішло не так під час основного оновлення, здається, що система все ще працює на Debian Buster", + "migration_0021_not_enough_free_space": "Вільного місця в /var/ досить мало! У вас повинно бути не менше 1 ГБ вільного місця, щоб запустити цю міграцію.", + "migration_0021_system_not_fully_up_to_date": "Ваша система не повністю оновлена. Будь ласка, виконайте регулярне оновлення перед запуском міграції на Bullseye.", + "migration_0021_general_warning": "Будь ласка, зверніть увагу, що ця міграція є делікатною операцією. Команда YunoHost зробила все можливе, щоб перевірити і протестувати її, але міграція все ще може порушити частину системи або її застосунків.\n\nТому рекомендовано:\n - Виконати резервне копіювання всіх важливих даних або застосунків. Подробиці на сайті https://yunohost.org/backup; \n - Наберіться терпіння після запуску міграції: В залежності від вашого з'єднання з Інтернетом і апаратного забезпечення, оновлення може зайняти до декількох годин.", + "migration_description_0021_migrate_to_bullseye": "Оновлення системи до Debian Bullseye і YunoHost 11.x" } From e84bd3a1c11d2cca3ba3d65f3580d25a83d6a29e Mon Sep 17 00:00:00 2001 From: Moutonjr Geoff Date: Fri, 17 Dec 2021 11:23:00 +0100 Subject: [PATCH 27/51] Message stays compliant in each locale with --apps deprecation --- locales/de.json | 2 +- locales/eo.json | 2 +- locales/es.json | 2 +- locales/eu.json | 2 +- locales/fr.json | 4 ++-- locales/oc.json | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/locales/de.json b/locales/de.json index e491c5ac2..49e312a08 100644 --- a/locales/de.json +++ b/locales/de.json @@ -613,7 +613,7 @@ "tools_upgrade_cant_unhold_critical_packages": "Konnte für die kritischen Pakete das Flag 'hold' nicht aufheben...", "tools_upgrade_cant_hold_critical_packages": "Konnte für die kritischen Pakete das Flag 'hold' nicht setzen...", "tools_upgrade_cant_both": "Kann das Upgrade für das System und die Applikation nicht gleichzeitig durchführen", - "tools_upgrade_at_least_one": "Bitte geben Sie '--apps' oder '--system' an", + "tools_upgrade_at_least_one": "Bitte geben Sie 'apps' oder 'system' an", "this_action_broke_dpkg": "Diese Aktion hat unkonfigurierte Pakete verursacht, welche durch dpkg/apt (die Paketverwaltungen dieses Systems) zurückgelassen wurden... Sie können versuchen dieses Problem zu lösen, indem Sie 'sudo apt install --fix-broken' und/oder 'sudo dpkg --configure -a' ausführen.", "update_apt_cache_failed": "Kann den Cache von APT (Debians Paketmanager) nicht aktualisieren. Hier ist ein Auszug aus den sources.list-Zeilen, die helfen könnten, das Problem zu identifizieren:\n{sourceslist}", "tools_upgrade_special_packages_completed": "YunoHost-Paketupdate beendet.\nDrücke [Enter], um zurück zur Kommandoziele zu kommen", diff --git a/locales/eo.json b/locales/eo.json index 49040b768..5139ec98d 100644 --- a/locales/eo.json +++ b/locales/eo.json @@ -234,7 +234,7 @@ "service_stop_failed": "Ne povis maldaŭrigi la servon '{service}'\n\nLastatempaj servaj protokoloj: {logs}", "unbackup_app": "App '{app}' ne konserviĝos", "updating_apt_cache": "Akirante haveblajn ĝisdatigojn por sistemaj pakoj…", - "tools_upgrade_at_least_one": "Bonvolu specifi '--apps' aŭ '--system'", + "tools_upgrade_at_least_one": "Bonvolu specifi 'apps' aŭ 'system'", "service_already_stopped": "La servo '{service}' jam ĉesis", "tools_upgrade_cant_both": "Ne eblas ĝisdatigi ambaŭ sistemon kaj programojn samtempe", "restore_extracting": "Eltirante bezonatajn dosierojn el la ar theivo…", diff --git a/locales/es.json b/locales/es.json index d6382c262..8e64fbcec 100644 --- a/locales/es.json +++ b/locales/es.json @@ -211,7 +211,7 @@ "tools_upgrade_cant_unhold_critical_packages": "No se pudo liberar los paquetes críticos…", "tools_upgrade_cant_hold_critical_packages": "No se pudieron retener los paquetes críticos…", "tools_upgrade_cant_both": "No se puede actualizar el sistema y las aplicaciones al mismo tiempo", - "tools_upgrade_at_least_one": "Especifique «--apps», o «--system»", + "tools_upgrade_at_least_one": "Especifique «apps», o «system»", "this_action_broke_dpkg": "Esta acción rompió dpkg/APT(los gestores de paquetes del sistema)… Puede tratar de solucionar este problema conectando mediante SSH y ejecutando `sudo dpkg --configure -a`.", "service_reloaded_or_restarted": "El servicio '{service}' fue recargado o reiniciado", "service_reload_or_restart_failed": "No se pudo recargar o reiniciar el servicio «{service}»\n\nRegistro de servicios recientes:{logs}", diff --git a/locales/eu.json b/locales/eu.json index 21c23260c..b5e880ce4 100644 --- a/locales/eu.json +++ b/locales/eu.json @@ -527,7 +527,7 @@ "service_restarted": "'{service}' zerbitzua berrabiarazi da", "service_start_failed": "Ezin izan da '{service}' zerbitzua abiarazi\n\nZerbitzuen azken erregistroak: {logs}", "ssowat_conf_updated": "SSOwat ezarpenak eguneratu dira", - "tools_upgrade_at_least_one": "Mesedez, zehaztu '--apps' edo '--system'", + "tools_upgrade_at_least_one": "Mesedez, zehaztu 'apps' edo 'system'", "tools_upgrade_cant_both": "Ezin dira sistema eta aplikazioak une berean eguneratu", "update_apt_cache_failed": "Ezin da APT Debian-en pakete kudeatzailearen cachea eguneratu. Hemen dituzu sources.list fitxategiaren lerroak, arazoa identifikatzeko baliagarria izan dezakezuna:\n{sourceslist}", "update_apt_cache_warning": "Zerbaitek huts egin du APT Debian-en pakete kudeatzailearen cachea eguneratzean. Hemen dituzu sources.list fitxategiaren lerroak, arazoa identifikatzeko baliagarria izan dezakezuna:\n{sourceslist}", diff --git a/locales/fr.json b/locales/fr.json index 07bdcfad3..c3cae1342 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -339,7 +339,7 @@ "regenconf_failed": "Impossible de régénérer la configuration pour la ou les catégorie(s) : '{categories}'", "regenconf_pending_applying": "Applique la configuration en attente pour la catégorie '{category}'...", "service_regen_conf_is_deprecated": "'yunohost service regen-conf' est obsolète ! Veuillez plutôt utiliser 'yunohost tools regen-conf' à la place.", - "tools_upgrade_at_least_one": "Veuillez spécifier '--apps' ou '--system'", + "tools_upgrade_at_least_one": "Veuillez spécifier 'apps' ou 'system'", "tools_upgrade_cant_both": "Impossible de mettre à niveau le système et les applications en même temps", "tools_upgrade_cant_hold_critical_packages": "Impossibilité d'ajouter le drapeau 'hold' pour les paquets critiques...", "tools_upgrade_regular_packages": "Mise à jour des paquets du système (non liés a YunoHost)...", @@ -704,4 +704,4 @@ "other_available_options": "... et {n} autres options disponibles non affichées", "domain_config_auth_consumer_key": "Consumer key", "domain_unknown": "Domaine '{domain}' inconnu" -} \ No newline at end of file +} diff --git a/locales/oc.json b/locales/oc.json index 9de7944c5..a90298f18 100644 --- a/locales/oc.json +++ b/locales/oc.json @@ -341,7 +341,7 @@ "service_reload_or_restart_failed": "Impossible de recargar o reaviar lo servici « {service} »\n\nJornal d’audit recent : {logs}", "regenconf_file_kept_back": "S’espèra que lo fichièr de configuracion « {conf} » siá suprimit per regen-conf (categoria {category} mas es estat mantengut.", "this_action_broke_dpkg": "Aquesta accion a copat dpkg/apt (los gestionaris de paquets del sistèma)… Podètz ensajar de resòlver aqueste problèma en vos connectant amb SSH e executant « sudo dpkg --configure -a ».", - "tools_upgrade_at_least_one": "Especificatz --apps O --system", + "tools_upgrade_at_least_one": "Especificatz apps O system", "tools_upgrade_cant_unhold_critical_packages": "Se pòt pas quitar de manténer los paquets critics…", "tools_upgrade_regular_packages": "Actualizacion dels paquets « normals » (pas ligats a YunoHost)…", "tools_upgrade_special_packages": "Actualizacion dels paquets « especials » (ligats a YunoHost)…", From 4315045e4aae87966d6dd64343ca47e98b257361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20M?= Date: Fri, 17 Dec 2021 13:41:53 +0000 Subject: [PATCH 28/51] Translated using Weblate (Galician) Currently translated at 100.0% (719 of 719 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/gl/ --- locales/gl.json | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/locales/gl.json b/locales/gl.json index ac41200a6..308cba961 100644 --- a/locales/gl.json +++ b/locales/gl.json @@ -703,5 +703,19 @@ "domain_dns_push_managed_in_parent_domain": "A función de rexistro DNS automático está xestionada polo dominio nai {parent_domain}.", "ldap_attribute_already_exists": "Xa existe o atributo LDAP '{attribute}' con valor '{value}'", "log_domain_config_set": "Actualizar configuración para o dominio '{}'", - "domain_unknown": "Dominio '{domain}' descoñecido" -} \ No newline at end of file + "domain_unknown": "Dominio '{domain}' descoñecido", + "migration_0021_start": "Comezando a migración a Bullseye", + "migration_0021_patching_sources_list": "Actualizando sources.list...", + "migration_0021_main_upgrade": "Iniciando a actualización principal...", + "migration_0021_still_on_buster_after_main_upgrade": "Algo fallou durante a actualización principal, o sistema semlla que aínda está en Debian Buster", + "migration_0021_yunohost_upgrade": "Iniciando actualización compoñente core de YunoHost...", + "migration_0021_not_buster": "A distribución Debian actual non é Buster!", + "migration_0021_not_enough_free_space": "Queda pouco espazo en /var/! Deberías ter polo menos 1GB libre para facer a migración.", + "migration_0021_problematic_apps_warning": "Detectamos que están instaladas estas app que poderían ser problemáticas. Semella que non foron instaladas desde o catálogo YunoHost, ou non están marcadas como que 'funcionan'. Así, non podemos garantir que seguiran funcionando ben tras a migración: {problematic_apps}", + "migration_0021_modified_files": "Ten en conta que os seguintes ficheiros semella que foron editados manualmente e poderían ser sobrescritos durante a migración: {manually_modified_files}", + "migration_0021_cleaning_up": "Limpando a caché e os paquetes que xa non son precisos...", + "migration_0021_patch_yunohost_conflicts": "Solucionando os problemas e conflitos...", + "migration_description_0021_migrate_to_bullseye": "Actualizar o sistema a Debian Bullseye e YunoHost 11.x", + "migration_0021_system_not_fully_up_to_date": "O teu sistema non está completamente actualizado. Fai unha actualización normal antes de executar a migración a Bullseye.", + "migration_0021_general_warning": "Ten en conta que a migración é unha operación delicada. O equipo de YunoHost fixo todo o que puido para revisalo e probalo, pero aínda así poderían acontecer fallos no sistema ou apps.\n\nAsí as cousas, é recomendable:\n - Facer unha copia de apoio dos datos e apps importantes. Máis info en https://yunohost.org/backup;\n - Ter paciencia unha vez inicias a migración: dependendo da túa conexión a internet e hardware, podería levarlle varias horas completar o proceso." +} From 4decdfc07c64818519df8228ad7b578f9e2d636d Mon Sep 17 00:00:00 2001 From: tituspijean Date: Tue, 21 Dec 2021 10:32:19 +0100 Subject: [PATCH 29/51] Fix typo in deleting superfluous question keys Co-authored-by: jacen05 --- src/yunohost/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index f6d940da8..ece44f172 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -1997,7 +1997,7 @@ def _set_default_ask_questions(arguments): if "example" in arg: del arg["example"] if "default" in arg: - del arg["domain"] + del arg["default"] return arguments From 4fc6db6317a6126d51f8eb34a706f538a6195c1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Alberto=20Gonz=C3=A1lez?= Date: Wed, 22 Dec 2021 19:52:53 +0000 Subject: [PATCH 30/51] Translated using Weblate (Spanish) Currently translated at 83.0% (597 of 719 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/es/ --- locales/es.json | 92 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 30 deletions(-) diff --git a/locales/es.json b/locales/es.json index 8e64fbcec..4afa56996 100644 --- a/locales/es.json +++ b/locales/es.json @@ -51,7 +51,7 @@ "domain_dyndns_already_subscribed": "Ya se ha suscrito a un dominio de DynDNS", "domain_dyndns_root_unknown": "Dominio raíz de DynDNS desconocido", "domain_exists": "El dominio ya existe", - "domain_uninstall_app_first": "Estas aplicaciones están todavía instaladas en tu dominio:\n{apps}\n\nPor favor desinstálalas utilizando yunohost app remove the_app_id o cambialas a otro dominio usando yunohost app change-url the_app_id antes de continuar con el borrado del dominio.", + "domain_uninstall_app_first": "Estas aplicaciones siguen instaladas en tu dominio:\n{apps}\n\nPor favor desinstálalas con el comando 'yunohost app remove the_app_id' o cámbialas a otro dominio usando /etc/resolv.conf no apunta a 127.0.0.1.", "diagnosis_dns_missing_record": "Según la configuración DNS recomendada, deberías añadir un registro DNS\ntipo: {type}\nnombre: {name}\nvalor: {value}", - "diagnosis_diskusage_low": "El almacenamiento {mountpoint} (en dispositivo {device}) solo tiene {free} ({free_percent}%) de espacio disponible. Ten cuidado.", - "diagnosis_services_bad_status_tip": "Puedes intentar reiniciar el servicio, y si no funciona, echar un vistazo a los logs del servicio usando 'yunohost service log {service}' o a través de la sección 'Servicios' en webadmin.", + "diagnosis_diskusage_low": "El almacenamiento {mountpoint} (en el dispositivo {device}) solo tiene {free} ({free_percent}%) de espacio disponible (de {total}). Ten cuidado.", + "diagnosis_services_bad_status_tip": "Puedes intentar reiniciar el servicio, y si no funciona, echar un vistazo a los logs del serviciode la administración web (desde la línea de comandos puedes hacerlo con yunohost service restart {service} y yunohost service log {service}).", "diagnosis_ip_connected_ipv6": "¡El servidor está conectado a internet a través de IPv6!", "diagnosis_ip_no_ipv6": "El servidor no cuenta con IPv6 funcional.", "diagnosis_ip_dnsresolution_working": "¡DNS no está funcionando!", @@ -441,8 +441,8 @@ "diagnosis_dns_bad_conf": "Algunos registros DNS faltan o están mal cofigurados para el dominio {domain} (categoría {category})", "diagnosis_dns_discrepancy": "El siguiente registro DNS parace que no sigue la configuración recomendada
Tipo: {type}
Nombre: {name}
Valor Actual: {current}
Valor esperado: {value}", "diagnosis_services_bad_status": "El servicio {service} está {status} :(", - "diagnosis_diskusage_verylow": "El almacenamiento {mountpoint} (en el dispositivo {device}) sólo tiene {free} ({free_percent}%) de espacio disponible. Deberías considerar la posibilidad de limpiar algo de espacio.", - "diagnosis_diskusage_ok": "¡El almacenamiento {mountpoint} (en el dispositivo {device}) todavía tiene {free} ({free_percent}%) de espacio libre!", + "diagnosis_diskusage_verylow": "El almacenamiento {mountpoint}(en el dispositivo {device}) sólo tiene {free} ({free_percent}%) de espacio disponible(de {total}). ¡Deberías limpiar algo de espacio!", + "diagnosis_diskusage_ok": "¡El almacenamiento {mountpoint} (en el dispositivo {device}) todavía tiene {free} ({free_percent}%) de espacio libre (de {total})!", "diagnosis_services_conf_broken": "¡Mala configuración para el servicio {service}!", "diagnosis_services_running": "¡El servicio {service} está en ejecución!", "diagnosis_failed": "Error al obtener el resultado del diagnóstico para la categoría '{category}': {error}", @@ -455,7 +455,7 @@ "diagnosis_swap_notsomuch": "Al sistema le queda solamente {total} de espacio de intercambio. Considera agregar al menos {recommended} para evitar que el sistema se quede sin memoria.", "diagnosis_mail_outgoing_port_25_blocked": "El puerto de salida 25 parece estar bloqueado. Intenta desbloquearlo con el panel de configuración de tu proveedor de servicios de Internet (o proveedor de halbergue). Mientras tanto, el servidor no podrá enviar correos electrónicos a otros servidores.", "diagnosis_regenconf_allgood": "Todos los archivos de configuración están en linea con la configuración recomendada!", - "diagnosis_regenconf_manually_modified": "El archivo de configuración {file} parece que ha sido modificado manualmente.", + "diagnosis_regenconf_manually_modified": "El archivo de configuración {file} parece que ha sido modificado manualmente.", "diagnosis_regenconf_manually_modified_details": "¡Esto probablemente esta BIEN si sabes lo que estás haciendo! YunoHost dejará de actualizar este fichero automáticamente... Pero ten en cuenta que las actualizaciones de YunoHost pueden contener importantes cambios que están recomendados. Si quieres puedes comprobar las diferencias mediante yunohost tools regen-conf {category} --dry-run --with-diff o puedes forzar el volver a las opciones recomendadas mediante el comando yunohost tools regen-conf {category} --force", "diagnosis_security_vulnerable_to_meltdown": "Pareces vulnerable a el colapso de vulnerabilidad critica de seguridad", "diagnosis_description_basesystem": "Sistema de base", @@ -504,11 +504,11 @@ "diagnosis_domain_expiration_not_found_details": "¿Parece que la información de WHOIS para el dominio {domain} no contiene información sobre la fecha de expiración?", "diagnosis_domain_not_found_details": "¡El dominio {domain} no existe en la base de datos WHOIS o ha expirado!", "diagnosis_domain_expiration_not_found": "No se pudo revisar la fecha de expiración para algunos dominios", - "diagnosis_dns_try_dyndns_update_force": "La configuración DNS de este dominio debería ser administrada automáticamente por Yunohost. Si no es el caso, puede intentar forzar una actualización ejecutando yunohost dyndns update --force.", + "diagnosis_dns_try_dyndns_update_force": "La configuración DNS de este dominio debería ser administrada automáticamente por YunoHost. Si no es el caso, puedes intentar forzar una actualización mediante yunohost dyndns update --force.", "diagnosis_ip_local": "IP Local: {local}", "diagnosis_ip_no_ipv6_tip": "Tener IPv6 funcionando no es obligatorio para que su servidor funcione, pero es mejor para la salud del Internet en general. IPv6 debería ser configurado automáticamente por el sistema o su proveedor si está disponible. De otra manera, es posible que tenga que configurar varias cosas manualmente, tal y como se explica en esta documentación https://yunohost.org/#/ipv6. Si no puede habilitar IPv6 o si parece demasiado técnico, puede ignorar esta advertencia con toda seguridad.", "diagnosis_display_tip": "Para ver los problemas encontrados, puede ir a la sección de diagnóstico del webadmin, o ejecutar 'yunohost diagnosis show --issues --human-readable' en la línea de comandos.", - "diagnosis_package_installed_from_sury_details": "Algunos paquetes fueron accidentalmente instalados de un repositorio de terceros llamado Sury. El equipo Yunohost ha mejorado la estrategia para manejar estos pquetes, pero es posible que algunas instalaciones con aplicaciones de PHP7.3 en Stretch puedan tener algunas inconsistencias. Para solucionar esta situación, debería intentar ejecutar el siguiente comando: {cmd_to_fix}", + "diagnosis_package_installed_from_sury_details": "Algunos paquetes fueron accidentalmente instalados de un repositorio de terceros llamado Sury. El equipo YunoHost ha mejorado la estrategia para manejar estos paquetes, pero es posible que algunas configuraciones que han instalado aplicaciones PHP7.3 al tiempo que presentes en Stretch tienen algunas inconsistencias. Para solucionar esta situación, deberías intentar ejecutar el siguiente comando: {cmd_to_fix}", "diagnosis_package_installed_from_sury": "Algunos paquetes del sistema deberían ser devueltos a una versión anterior", "certmanager_domain_not_diagnosed_yet": "Aún no hay resultado del diagnóstico para el dominio {domain}. Por favor ejecute el diagnóstico para las categorías 'Registros DNS' y 'Web' en la sección de diagnóstico para verificar si el dominio está listo para Let's Encrypt. (O si sabe lo que está haciendo, utilice '--no-checks' para deshabilitar esos chequeos.)", "backup_archive_corrupted": "Parece que el archivo de respaldo '{archive}' está corrupto : {error}", @@ -571,7 +571,7 @@ "diagnosis_mail_ehlo_bad_answer_details": "Podría ser debido a otra máquina en lugar de tu servidor.", "diagnosis_mail_ehlo_bad_answer": "Un servicio que no es SMTP respondió en el puerto 25 mediante IPv{ipversion}", "diagnosis_mail_ehlo_unreachable_details": "No pudo abrirse la conexión en el puerto 25 de tu servidor mediante IPv{ipversion}. Parece que no se puede contactar.
1. La causa más común en estos casos suele ser que el puerto 25 no está correctamente redireccionado a tu servidor.
2. También deberías asegurarte que el servicio postfix está en marcha.
3. En casos más complejos: asegurate que no estén interfiriendo ni el firewall ni el reverse-proxy.", - "diagnosis_mail_ehlo_unreachable": "El servidor de correo SMTP no puede contactarse desde el exterior mediante IPv{ipversion}. No puede recibir correos", + "diagnosis_mail_ehlo_unreachable": "El servidor de correo SMTP no puede contactarse desde el exterior mediante IPv{ipversion}. No puede recibir correos.", "diagnosis_mail_ehlo_ok": "¡El servidor de correo SMTP puede contactarse desde el exterior por lo que puede recibir correos!", "diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Algunos proveedores de internet no le permitirán desbloquear el puerto 25 porque no les importa la Neutralidad de la Red.
- Algunos proporcionan una alternativa usando un relay como servidor de correo lo que implica que el relay podrá espiar tu trafico de correo.
- Una alternativa buena para la privacidad es utilizar una VPN *con una IP pública dedicada* para evitar estas limitaciones. Mira en https://yunohost.org/#/vpn_advantage
- Otra alternativa es cambiar de proveedor de inteernet a uno más amable con la Neutralidad de la Red", "diagnosis_backports_in_sources_list": "Parece que apt (el gestor de paquetes) está configurado para usar el repositorio backports. A menos que realmente sepas lo que estás haciendo, desaconsejamos absolutamente instalar paquetes desde backports, ya que pueden provocar comportamientos intestables o conflictos en el sistema.", @@ -583,5 +583,37 @@ "app_config_unable_to_apply": "No se pudieron aplicar los valores del panel configuración.", "app_config_unable_to_read": "No se pudieron leer los valores del panel configuración.", "backup_create_size_estimation": "El archivo contendrá aproximadamente {size} de datos.", - "config_cant_set_value_on_section": "No puede establecer un único valor en una sección de configuración completa." -} \ No newline at end of file + "config_cant_set_value_on_section": "No puede establecer un único valor en una sección de configuración completa.", + "diagnosis_http_special_use_tld": "Le dominio {domain} está basado en un dominio de primer nivel (TLD) de uso especial, como un .local o .test y no debería estar expuesto fuera de la red local.", + "domain_dns_push_failed": "La actualización de las entradas DNS ha fallado.", + "domain_dns_push_partial_failure": "Entradas DNS actualizadas parcialmente: algunas advertencias/errores reportados.", + "domain_unknown": "Dominio '{domain}' desconocido", + "diagnosis_high_number_auth_failures": "Ultimamente ha habido un gran número de errores de autenticación. Asegúrate de que Fail2Ban está ejecutándose y correctamente configurado, o usa un puerto SSH personalizado como se explica en https://yunohost.org/security.", + "diagnosis_sshd_config_inconsistent": "Parece que el puerto SSH ha sido modificado manualmente en /etc/ssh/sshd_config. Desde YunoHost 4.2, hay un nuevo parámetro global 'security.ssh.port' disponible para evitar modificar manualmente la configuración.", + "diagnosis_sshd_config_inconsistent_details": "Por favor ejecuta yunohost settings set security.ssh.port -v TU_PUERTO_SSH para definir el puerto SSH, y comprueba yunohost tools regen-conf ssh --dry-run --with-diff y yunohost tools regen-conf ssh --force para resetear tu configuración a las recomendaciones de YunoHost.", + "config_forbidden_keyword": "'{keyword}' es una palabra reservada, no puedes crear ni usar un panel de configuración con una pregunta que use esta id.", + "config_no_panel": "No se ha encontrado ningún panel de configuración.", + "config_unknown_filter_key": "La clave de filtrado '{filter_key}' es incorrecta.", + "config_validate_color": "Debe ser un valor hexadecimal RGB correcto", + "danger": "Peligro:", + "diagnosis_apps_issue": "Se ha detectado un problema con la aplicación {app}", + "diagnosis_description_apps": "Aplicaciones", + "diagnosis_rootfstotalspace_critical": "¡El sistema de ficheros raíz solo tiene un total de {space}! ¡Vas a quedarte sin espacio rápidamente! Se recomienda tener al menos 16GB para ese sistema de ficheros.", + "diagnosis_rootfstotalspace_warning": "¡El sistema de ficheros raíz solo tiene un total de {space}! Podría ser suficiente, pero cuidado, puedes rellenarlo rápidamente… Se recomienda tener al menos 16GB para el sistema de ficheros raíz.", + "diagnosis_apps_allgood": "Todas las aplicaciones instaladas respetan las prácticas básicas de empaquetado", + "config_validate_date": "Debe ser una fecha válida en formato AAAA-MM-DD", + "config_validate_email": "Debe ser una dirección de correo correcta", + "config_validate_time": "Debe ser una hora valida en formato HH:MM", + "config_validate_url": "Debe ser una URL válida", + "config_version_not_supported": "Las versiones del panel de configuración '{version}' no están soportadas.", + "domain_remove_confirm_apps_removal": "La supresión de este dominio también eliminará las siguientes aplicaciones:\n{apps}\n\n¿Seguro? [{answers}]", + "domain_registrar_is_not_configured": "El registrador aún no ha configurado el dominio {domain}.", + "diagnosis_apps_not_in_app_catalog": "Esta aplicación se encuentra ausente o ya no figura en el catálogo de aplicaciones de YunoHost. Deberías considerar desinstalarla ya que no recibirá actualizaciones y podría comprometer la integridad y seguridad de tu sistema.", + "disk_space_not_sufficient_install": "No hay espacio libre suficiente para instalar esta aplicación", + "disk_space_not_sufficient_update": "No hay espacio libre suficiente para actualizar esta aplicación", + "diagnosis_dns_specialusedomain": "El dominio {domain} se basa en un dominio de primer nivel (TLD) de usos especiales como .local o .test y no debería tener entradas DNS reales.", + "diagnosis_apps_bad_quality": "Esta aplicación está etiquetada como defectuosa en el catálogo de aplicaciones YunoHost. Podría ser un problema temporal mientras las personas responsables corrigen el asunto. Mientras tanto, la actualización de esta aplicación está desactivada.", + "diagnosis_apps_broken": "Esta aplicación está etiquetada como defectuosa en el catálogo de aplicaciones YunoHost. Podría ser un problema temporal mientras las personas responsables corrigen el asunto. Mientras tanto, la actualización de esta aplicación está desactivada.", + "diagnosis_apps_deprecated_practices": "La versión instalada de esta aplicación usa aún prácticas de empaquetado obsoletas. Deberías actualizarla.", + "diagnosis_apps_outdated_ynh_requirement": "La versión instalada de esta aplicación solo necesita YunoHost >= 2.x, lo que indica que no está al día con la buena praxis de ayudas y empaquetado recomendadas. Deberías actualizarla." +} From ad56275801bccbfa0c0b5acf2e47df999ff798b9 Mon Sep 17 00:00:00 2001 From: Laurent Peuch Date: Fri, 24 Dec 2021 01:16:41 +0100 Subject: [PATCH 31/51] [mod] run pyupgrade on source code --- data/hooks/diagnosis/00-basesystem.py | 4 +-- data/hooks/diagnosis/10-ip.py | 4 +-- data/hooks/diagnosis/50-systemresources.py | 8 ++--- doc/generate_helper_doc.py | 2 +- src/yunohost/app.py | 10 +++--- src/yunohost/app_catalog.py | 2 +- src/yunohost/backup.py | 14 ++++---- src/yunohost/certificate.py | 34 +++++++++--------- .../data_migrations/0015_migrate_to_buster.py | 8 ++--- src/yunohost/diagnosis.py | 16 ++++----- src/yunohost/dns.py | 2 +- src/yunohost/dyndns.py | 10 +++--- src/yunohost/hook.py | 6 ++-- src/yunohost/log.py | 2 +- src/yunohost/permission.py | 8 ++--- src/yunohost/regenconf.py | 2 +- src/yunohost/service.py | 8 ++--- src/yunohost/settings.py | 2 +- src/yunohost/tests/test_app_catalog.py | 2 +- src/yunohost/tests/test_app_config.py | 2 +- src/yunohost/tests/test_apps.py | 8 ++--- src/yunohost/tests/test_appurl.py | 8 ++--- src/yunohost/tests/test_backuprestore.py | 4 +-- src/yunohost/tests/test_changeurl.py | 2 +- src/yunohost/tests/test_permission.py | 20 +++++------ src/yunohost/tests/test_questions.py | 2 +- src/yunohost/tests/test_user-group.py | 2 +- src/yunohost/tools.py | 2 +- src/yunohost/user.py | 12 +++---- src/yunohost/utils/network.py | 4 +-- src/yunohost/utils/yunopaste.py | 2 +- src/yunohost/vendor/acme_tiny/acme_tiny.py | 36 +++++++++---------- tests/test_translation_format_consistency.py | 6 ++-- 33 files changed, 126 insertions(+), 128 deletions(-) diff --git a/data/hooks/diagnosis/00-basesystem.py b/data/hooks/diagnosis/00-basesystem.py index b472a2d32..8b7b888e3 100644 --- a/data/hooks/diagnosis/00-basesystem.py +++ b/data/hooks/diagnosis/00-basesystem.py @@ -42,7 +42,7 @@ class BaseSystemDiagnoser(Diagnoser): elif os.path.exists("/sys/devices/virtual/dmi/id/sys_vendor"): model = read_file("/sys/devices/virtual/dmi/id/sys_vendor").strip() if os.path.exists("/sys/devices/virtual/dmi/id/product_name"): - model = "%s %s" % ( + model = "{} {}".format( model, read_file("/sys/devices/virtual/dmi/id/product_name").strip(), ) @@ -116,7 +116,7 @@ class BaseSystemDiagnoser(Diagnoser): bad_sury_packages = list(self.bad_sury_packages()) if bad_sury_packages: cmd_to_fix = "apt install --allow-downgrades " + " ".join( - ["%s=%s" % (package, version) for package, version in bad_sury_packages] + ["{}={}".format(package, version) for package, version in bad_sury_packages] ) yield dict( meta={"test": "packages_from_sury"}, diff --git a/data/hooks/diagnosis/10-ip.py b/data/hooks/diagnosis/10-ip.py index 408019668..486e37e3e 100644 --- a/data/hooks/diagnosis/10-ip.py +++ b/data/hooks/diagnosis/10-ip.py @@ -167,7 +167,7 @@ class IPDiagnoser(Diagnoser): assert ( resolvers != [] - ), "Uhoh, need at least one IPv%s DNS resolver in %s ..." % ( + ), "Uhoh, need at least one IPv{} DNS resolver in {} ...".format( protocol, resolver_file, ) @@ -221,7 +221,7 @@ class IPDiagnoser(Diagnoser): return download_text(url, timeout=30).strip() except Exception as e: self.logger_debug( - "Could not get public IPv%s : %s" % (str(protocol), str(e)) + "Could not get public IPv{} : {}".format(str(protocol), str(e)) ) return None diff --git a/data/hooks/diagnosis/50-systemresources.py b/data/hooks/diagnosis/50-systemresources.py index a662e392e..4deb607f4 100644 --- a/data/hooks/diagnosis/50-systemresources.py +++ b/data/hooks/diagnosis/50-systemresources.py @@ -132,7 +132,7 @@ class SystemResourcesDiagnoser(Diagnoser): d for d in disk_partitions if d.mountpoint in ["/", "/var"] ] main_space = sum( - [psutil.disk_usage(d.mountpoint).total for d in main_disk_partitions] + psutil.disk_usage(d.mountpoint).total for d in main_disk_partitions ) if main_space < 10 * GB: yield dict( @@ -156,7 +156,7 @@ class SystemResourcesDiagnoser(Diagnoser): kills_count = self.recent_kills_by_oom_reaper() if kills_count: kills_summary = "\n".join( - ["%s (x%s)" % (proc, count) for proc, count in kills_count] + ["{} (x{})".format(proc, count) for proc, count in kills_count] ) yield dict( @@ -202,9 +202,9 @@ def human_size(bytes_): # Adapted from https://stackoverflow.com/a/1094933 for unit in ["", "ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]: if abs(bytes_) < 1024.0: - return "%s %sB" % (round_(bytes_), unit) + return "{} {}B".format(round_(bytes_), unit) bytes_ /= 1024.0 - return "%s %sB" % (round_(bytes_), "Yi") + return "{} {}B".format(round_(bytes_), "Yi") def round_(n): diff --git a/doc/generate_helper_doc.py b/doc/generate_helper_doc.py index f2d5bf444..689904a8a 100644 --- a/doc/generate_helper_doc.py +++ b/doc/generate_helper_doc.py @@ -107,7 +107,7 @@ class Parser: else: # We're getting out of a comment bloc, we should find # the name of the function - assert len(line.split()) >= 1, "Malformed line %s in %s" % ( + assert len(line.split()) >= 1, "Malformed line {} in {}".format( i, self.filename, ) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index ece44f172..f47efd9d7 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -122,7 +122,7 @@ def app_list(full=False, installed=False, filter=None): try: app_info_dict = app_info(app_id, full=full) except Exception as e: - logger.error("Failed to read info for %s : %s" % (app_id, e)) + logger.error("Failed to read info for {} : {}".format(app_id, e)) continue app_info_dict["id"] = app_id out.append(app_info_dict) @@ -1219,7 +1219,7 @@ def app_setting(app, key, value=None, delete=False): ) permissions = user_permission_list(full=True, apps=[app])["permissions"] - permission_name = "%s.legacy_%s_uris" % (app, key.split("_")[0]) + permission_name = "{}.legacy_{}_uris".format(app, key.split("_")[0]) permission = permissions.get(permission_name) # GET @@ -1562,7 +1562,7 @@ def app_action_run(operation_logger, app, action, args=None): shutil.rmtree(tmp_workdir_for_app) if retcode not in action_declaration.get("accepted_return_codes", [0]): - msg = "Error while executing action '%s' of app '%s': return code %s" % ( + msg = "Error while executing action '{}' of app '{}': return code {}".format( action, app, retcode, @@ -1989,7 +1989,7 @@ def _set_default_ask_questions(arguments): for question in questions_with_default ): # The key is for example "app_manifest_install_ask_domain" - key = "app_manifest_%s_ask_%s" % (script_name, arg["name"]) + key = "app_manifest_{}_ask_{}".format(script_name, arg["name"]) arg["ask"] = m18n.n(key) # Also it in fact doesn't make sense for any of those questions to have an example value nor a default value... @@ -2397,7 +2397,7 @@ def _make_environment_for_app_script( env_dict["YNH_APP_BASEDIR"] = workdir for arg_name, arg_value in args.items(): - env_dict["YNH_%s%s" % (args_prefix, arg_name.upper())] = str(arg_value) + env_dict["YNH_{}{}".format(args_prefix, arg_name.upper())] = str(arg_value) return env_dict diff --git a/src/yunohost/app_catalog.py b/src/yunohost/app_catalog.py index e4ffa1db6..96a006704 100644 --- a/src/yunohost/app_catalog.py +++ b/src/yunohost/app_catalog.py @@ -217,7 +217,7 @@ def _load_apps_catalog(): ) except Exception as e: raise YunohostError( - "Unable to read cache for apps_catalog %s : %s" % (cache_file, e), + "Unable to read cache for apps_catalog {} : {}".format(cache_file, e), raw_msg=True, ) diff --git a/src/yunohost/backup.py b/src/yunohost/backup.py index f68e59b13..03721be0c 100644 --- a/src/yunohost/backup.py +++ b/src/yunohost/backup.py @@ -2380,7 +2380,7 @@ def backup_list(with_info=False, human_readable=False): # Get local archives sorted according to last modification time # (we do a realpath() to resolve symlinks) archives = glob("%s/*.tar.gz" % ARCHIVES_PATH) + glob("%s/*.tar" % ARCHIVES_PATH) - archives = set([os.path.realpath(archive) for archive in archives]) + archives = {os.path.realpath(archive) for archive in archives} archives = sorted(archives, key=lambda x: os.path.getctime(x)) # Extract only filename without the extension @@ -2420,7 +2420,7 @@ def backup_download(name): ) return - archive_file = "%s/%s.tar" % (ARCHIVES_PATH, name) + archive_file = "{}/{}.tar".format(ARCHIVES_PATH, name) # Check file exist (even if it's a broken symlink) if not os.path.lexists(archive_file): @@ -2462,7 +2462,7 @@ def backup_info(name, with_details=False, human_readable=False): elif name.endswith(".tar"): name = name[: -len(".tar")] - archive_file = "%s/%s.tar" % (ARCHIVES_PATH, name) + archive_file = "{}/{}.tar".format(ARCHIVES_PATH, name) # Check file exist (even if it's a broken symlink) if not os.path.lexists(archive_file): @@ -2480,7 +2480,7 @@ def backup_info(name, with_details=False, human_readable=False): "backup_archive_broken_link", path=archive_file ) - info_file = "%s/%s.info.json" % (ARCHIVES_PATH, name) + info_file = "{}/{}.info.json".format(ARCHIVES_PATH, name) if not os.path.exists(info_file): tar = tarfile.open( @@ -2591,10 +2591,10 @@ def backup_delete(name): hook_callback("pre_backup_delete", args=[name]) - archive_file = "%s/%s.tar" % (ARCHIVES_PATH, name) + archive_file = "{}/{}.tar".format(ARCHIVES_PATH, name) if not os.path.exists(archive_file) and os.path.exists(archive_file + ".gz"): archive_file += ".gz" - info_file = "%s/%s.info.json" % (ARCHIVES_PATH, name) + info_file = "{}/{}.info.json".format(ARCHIVES_PATH, name) files_to_delete = [archive_file, info_file] @@ -2693,5 +2693,5 @@ def binary_to_human(n, customary=False): for s in reversed(symbols): if n >= prefix[s]: value = float(n) / prefix[s] - return "%.1f%s" % (value, s) + return "{:.1f}{}".format(value, s) return "%s" % n diff --git a/src/yunohost/certificate.py b/src/yunohost/certificate.py index 2679b2429..e4dc7d350 100644 --- a/src/yunohost/certificate.py +++ b/src/yunohost/certificate.py @@ -143,7 +143,7 @@ def _certificate_install_selfsigned(domain_list, force=False): # Paths of files and folder we'll need date_tag = datetime.utcnow().strftime("%Y%m%d.%H%M%S") - new_cert_folder = "%s/%s-history/%s-selfsigned" % ( + new_cert_folder = "{}/{}-history/{}-selfsigned".format( CERT_FOLDER, domain, date_tag, @@ -300,7 +300,7 @@ def _certificate_install_letsencrypt( try: _fetch_and_enable_new_certificate(domain, staging, no_checks=no_checks) except Exception as e: - msg = "Certificate installation for %s failed !\nException: %s" % ( + msg = "Certificate installation for {} failed !\nException: {}".format( domain, e, ) @@ -457,20 +457,20 @@ def _email_renewing_failed(domain, exception_message, stack=""): logs = _tail(50, "/var/log/yunohost/yunohost-cli.log") text = """ -An attempt for renewing the certificate for domain %s failed with the following +An attempt for renewing the certificate for domain {} failed with the following error : -%s -%s +{} +{} Here's the tail of /var/log/yunohost/yunohost-cli.log, which might help to investigate : -%s +{} -- Certificate Manager -""" % ( +""".format( domain, exception_message, stack, @@ -478,12 +478,12 @@ investigate : ) message = """\ -From: %s -To: %s -Subject: %s +From: {} +To: {} +Subject: {} -%s -""" % ( +{} +""".format( from_, to_, subject_, @@ -532,7 +532,7 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False): # Prepare certificate signing request logger.debug("Prepare key and certificate signing request (CSR) for %s...", domain) - domain_key_file = "%s/%s.pem" % (TMP_FOLDER, domain) + domain_key_file = "{}/{}.pem".format(TMP_FOLDER, domain) _generate_key(domain_key_file) _set_permissions(domain_key_file, "root", "ssl-cert", 0o640) @@ -541,7 +541,7 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False): # Sign the certificate logger.debug("Now using ACME Tiny to sign the certificate...") - domain_csr_file = "%s/%s.csr" % (TMP_FOLDER, domain) + domain_csr_file = "{}/{}.csr".format(TMP_FOLDER, domain) if staging: certification_authority = STAGING_CERTIFICATION_AUTHORITY @@ -580,7 +580,7 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False): else: folder_flag = "letsencrypt" - new_cert_folder = "%s/%s-history/%s-%s" % ( + new_cert_folder = "{}/{}-history/{}-{}".format( CERT_FOLDER, domain, date_tag, @@ -642,7 +642,7 @@ def _prepare_certificate_signing_request(domain, key_file, output_folder): csr.add_extensions( [ crypto.X509Extension( - "subjectAltName".encode("utf8"), + b"subjectAltName", False, ("DNS:" + subdomain).encode("utf8"), ) @@ -844,7 +844,7 @@ def _backup_current_cert(domain): cert_folder_domain = os.path.join(CERT_FOLDER, domain) date_tag = datetime.utcnow().strftime("%Y%m%d.%H%M%S") - backup_folder = "%s-backups/%s" % (cert_folder_domain, date_tag) + backup_folder = "{}-backups/{}".format(cert_folder_domain, date_tag) shutil.copytree(cert_folder_domain, backup_folder) diff --git a/src/yunohost/data_migrations/0015_migrate_to_buster.py b/src/yunohost/data_migrations/0015_migrate_to_buster.py index 4f2d4caf8..626dd682a 100644 --- a/src/yunohost/data_migrations/0015_migrate_to_buster.py +++ b/src/yunohost/data_migrations/0015_migrate_to_buster.py @@ -269,14 +269,14 @@ class MyMigration(Migration): % default_crt ) - os.system("mv %s %s.old" % (default_crt, default_crt)) - os.system("mv %s %s.old" % (default_key, default_key)) + os.system("mv {} {}.old".format(default_crt, default_crt)) + os.system("mv {} {}.old".format(default_key, default_key)) ret = os.system("/usr/share/yunohost/hooks/conf_regen/02-ssl init") if ret != 0 or not os.path.exists(default_crt): logger.error("Upgrading the certificate failed ... reverting") - os.system("mv %s.old %s" % (default_crt, default_crt)) - os.system("mv %s.old %s" % (default_key, default_key)) + os.system("mv {}.old {}".format(default_crt, default_crt)) + os.system("mv {}.old {}".format(default_key, default_key)) signatures = {cert: check_output(cmd % cert) for cert in active_certs} diff --git a/src/yunohost/diagnosis.py b/src/yunohost/diagnosis.py index 4ac5e2731..dfe58685e 100644 --- a/src/yunohost/diagnosis.py +++ b/src/yunohost/diagnosis.py @@ -640,7 +640,7 @@ class Diagnoser: elif ipversion == 6: socket.getaddrinfo = getaddrinfo_ipv6_only - url = "https://%s/%s" % (DIAGNOSIS_SERVER, uri) + url = "https://{}/{}".format(DIAGNOSIS_SERVER, uri) try: r = requests.post(url, json=data, timeout=timeout) finally: @@ -679,7 +679,7 @@ def _email_diagnosis_issues(): from yunohost.domain import _get_maindomain maindomain = _get_maindomain() - from_ = "diagnosis@%s (Automatic diagnosis on %s)" % (maindomain, maindomain) + from_ = "diagnosis@{} (Automatic diagnosis on {})".format(maindomain, maindomain) to_ = "root" subject_ = "Issues found by automatic diagnosis on %s" % maindomain @@ -692,16 +692,16 @@ def _email_diagnosis_issues(): content = _dump_human_readable_reports(issues) message = """\ -From: %s -To: %s -Subject: %s +From: {} +To: {} +Subject: {} -%s +{} --- -%s -""" % ( +{} +""".format( from_, to_, subject_, diff --git a/src/yunohost/dns.py b/src/yunohost/dns.py index 534ade918..23c641a35 100644 --- a/src/yunohost/dns.py +++ b/src/yunohost/dns.py @@ -762,7 +762,7 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge= changes = {"delete": [], "update": [], "create": [], "unchanged": []} type_and_names = sorted( - set([(r["type"], r["name"]) for r in current_records + wanted_records]) + {(r["type"], r["name"]) for r in current_records + wanted_records} ) comparison = { type_and_name: {"current": [], "wanted": []} for type_and_name in type_and_names diff --git a/src/yunohost/dyndns.py b/src/yunohost/dyndns.py index 4f4dc1d1f..63bb3180f 100644 --- a/src/yunohost/dyndns.py +++ b/src/yunohost/dyndns.py @@ -151,7 +151,7 @@ def dyndns_subscribe(operation_logger, domain=None, key=None): try: error = json.loads(r.text)["error"] except Exception: - error = 'Server error, code: %s. (Message: "%s")' % (r.status_code, r.text) + error = 'Server error, code: {}. (Message: "{}")'.format(r.status_code, r.text) raise YunohostError("dyndns_registration_failed", error=error) # Yunohost regen conf will add the dyndns cron job if a private key exists @@ -196,7 +196,7 @@ def dyndns_update( # If key is not given, pick the first file we find with the domain given elif key is None: - keys = glob.glob("/etc/yunohost/dyndns/K{0}.+*.private".format(domain)) + keys = glob.glob("/etc/yunohost/dyndns/K{}.+*.private".format(domain)) if not keys: raise YunohostValidationError("dyndns_key_not_found") @@ -263,14 +263,14 @@ def dyndns_update( return None raise YunohostError( - "Failed to resolve %s for %s" % (rdtype, domain), raw_msg=True + "Failed to resolve {} for {}".format(rdtype, domain), raw_msg=True ) old_ipv4 = resolve_domain(domain, "A") old_ipv6 = resolve_domain(domain, "AAAA") - logger.debug("Old IPv4/v6 are (%s, %s)" % (old_ipv4, old_ipv6)) - logger.debug("Requested IPv4/v6 are (%s, %s)" % (ipv4, ipv6)) + logger.debug("Old IPv4/v6 are ({}, {})".format(old_ipv4, old_ipv6)) + logger.debug("Requested IPv4/v6 are ({}, {})".format(ipv4, ipv6)) # no need to update if (not force and not dry_run) and (old_ipv4 == ipv4 and old_ipv6 == ipv6): diff --git a/src/yunohost/hook.py b/src/yunohost/hook.py index 98b624f12..c5ff8b0cd 100644 --- a/src/yunohost/hook.py +++ b/src/yunohost/hook.py @@ -156,7 +156,7 @@ def hook_list(action, list_by="name", show_info=False): try: d[priority].add(name) except KeyError: - d[priority] = set([name]) + d[priority] = {name} elif list_by == "name" or list_by == "folder": if show_info: @@ -197,7 +197,7 @@ def hook_list(action, list_by="name", show_info=False): or (f.startswith("__") and f.endswith("__")) ): continue - path = "%s%s/%s" % (folder, action, f) + path = "{}{}/{}".format(folder, action, f) priority, name = _extract_filename_parts(f) _append_hook(d, priority, name, path) @@ -407,7 +407,7 @@ def _hook_exec_bash(path, args, chdir, env, user, return_format, loggers): if not chdir: # use the script directory as current one chdir, cmd_script = os.path.split(path) - cmd_script = "./{0}".format(cmd_script) + cmd_script = "./{}".format(cmd_script) else: cmd_script = path diff --git a/src/yunohost/log.py b/src/yunohost/log.py index 0e534f9f8..cb11c7112 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -544,7 +544,7 @@ class OperationLogger(object): # We use proc.open_files() to list files opened / actively used by this proc # We only keep files matching a recent yunohost operation log active_logs = sorted( - [f.path for f in proc.open_files() if f.path in recent_operation_logs], + (f.path for f in proc.open_files() if f.path in recent_operation_logs), key=os.path.getctime, reverse=True, ) diff --git a/src/yunohost/permission.py b/src/yunohost/permission.py index 1856046d6..04c170a32 100644 --- a/src/yunohost/permission.py +++ b/src/yunohost/permission.py @@ -139,7 +139,7 @@ def user_permission_list( continue main_perm_label = permissions[main_perm_name]["label"] infos["sublabel"] = infos["label"] - infos["label"] = "%s (%s)" % (main_perm_label, infos["label"]) + infos["label"] = "{} ({})".format(main_perm_label, infos["label"]) if short: permissions = list(permissions.keys()) @@ -664,13 +664,11 @@ def permission_sync_to_user(): currently_allowed_users = set(permission_infos["corresponding_users"]) # These are the users that should be allowed because they are member of a group that is allowed for this permission ... - should_be_allowed_users = set( - [ + should_be_allowed_users = { user for group in permission_infos["allowed"] for user in groups[group]["members"] - ] - ) + } # Note that a LDAP operation with the same value that is in LDAP crash SLAP. # So we need to check before each ldap operation that we really change something in LDAP diff --git a/src/yunohost/regenconf.py b/src/yunohost/regenconf.py index 1beef8a44..224fb8bc5 100644 --- a/src/yunohost/regenconf.py +++ b/src/yunohost/regenconf.py @@ -640,7 +640,7 @@ def _process_regen_conf(system_conf, new_conf=None, save=True): if save: backup_path = os.path.join( BACKUP_CONF_DIR, - "{0}-{1}".format( + "{}-{}".format( system_conf.lstrip("/"), datetime.utcnow().strftime("%Y%m%d.%H%M%S") ), ) diff --git a/src/yunohost/service.py b/src/yunohost/service.py index f200d08c0..f47f67a3c 100644 --- a/src/yunohost/service.py +++ b/src/yunohost/service.py @@ -625,7 +625,7 @@ def _run_service_command(action, service): % (action, ", ".join(possible_actions)) ) - cmd = "systemctl %s %s" % (action, service) + cmd = "systemctl {} {}".format(action, service) need_lock = services[service].get("need_lock", False) and action in [ "start", @@ -673,7 +673,7 @@ def _give_lock(action, service, p): else: systemctl_PID_name = "ControlPID" - cmd_get_son_PID = "systemctl show %s -p %s" % (service, systemctl_PID_name) + cmd_get_son_PID = "systemctl show {} -p {}".format(service, systemctl_PID_name) son_PID = 0 # As long as we did not found the PID and that the command is still running while son_PID == 0 and p.poll() is None: @@ -687,7 +687,7 @@ def _give_lock(action, service, p): if son_PID != 0: # Append the PID to the lock file logger.debug( - "Giving a lock to PID %s for service %s !" % (str(son_PID), service) + "Giving a lock to PID {} for service {} !".format(str(son_PID), service) ) append_to_file(MOULINETTE_LOCK, "\n%s" % str(son_PID)) @@ -865,7 +865,7 @@ def _get_journalctl_logs(service, number="all"): systemd_service = services.get(service, {}).get("actual_systemd_service", service) try: return check_output( - "journalctl --no-hostname --no-pager -u {0} -n{1}".format( + "journalctl --no-hostname --no-pager -u {} -n{}".format( systemd_service, number ) ) diff --git a/src/yunohost/settings.py b/src/yunohost/settings.py index d59b41a58..77d0d2705 100644 --- a/src/yunohost/settings.py +++ b/src/yunohost/settings.py @@ -224,7 +224,7 @@ def settings_set(key, value): try: trigger_post_change_hook(key, old_value, value) except Exception as e: - logger.error("Post-change hook for setting %s failed : %s" % (key, e)) + logger.error("Post-change hook for setting {} failed : {}".format(key, e)) raise diff --git a/src/yunohost/tests/test_app_catalog.py b/src/yunohost/tests/test_app_catalog.py index 8423b868e..e9ecb1c12 100644 --- a/src/yunohost/tests/test_app_catalog.py +++ b/src/yunohost/tests/test_app_catalog.py @@ -132,7 +132,7 @@ def test_apps_catalog_update_nominal(mocker): catalog = app_catalog(with_categories=True) assert "apps" in catalog - assert set(catalog["apps"].keys()) == set(["foo", "bar"]) + assert set(catalog["apps"].keys()) == {"foo", "bar"} assert "categories" in catalog assert [c["id"] for c in catalog["categories"]] == ["yolo", "swag"] diff --git a/src/yunohost/tests/test_app_config.py b/src/yunohost/tests/test_app_config.py index 0eb813672..8de03bfd5 100644 --- a/src/yunohost/tests/test_app_config.py +++ b/src/yunohost/tests/test_app_config.py @@ -70,7 +70,7 @@ def legacy_app(request): app_install( os.path.join(get_test_apps_dir(), "legacy_app_ynh"), - args="domain=%s&path=%s&is_public=%s" % (main_domain, "/", 1), + args="domain={}&path={}&is_public={}".format(main_domain, "/", 1), force=True, ) diff --git a/src/yunohost/tests/test_apps.py b/src/yunohost/tests/test_apps.py index 22e18ec9a..2a808b5bd 100644 --- a/src/yunohost/tests/test_apps.py +++ b/src/yunohost/tests/test_apps.py @@ -111,7 +111,7 @@ def secondary_domain(request): def app_expected_files(domain, app): - yield "/etc/nginx/conf.d/%s.d/%s.conf" % (domain, app) + yield "/etc/nginx/conf.d/{}.d/{}.conf".format(domain, app) if app.startswith("legacy_app"): yield "/var/www/%s/index.html" % app yield "/etc/yunohost/apps/%s/settings.yml" % app @@ -152,7 +152,7 @@ def install_legacy_app(domain, path, public=True): app_install( os.path.join(get_test_apps_dir(), "legacy_app_ynh"), - args="domain=%s&path=%s&is_public=%s" % (domain, path, 1 if public else 0), + args="domain={}&path={}&is_public={}".format(domain, path, 1 if public else 0), force=True, ) @@ -170,7 +170,7 @@ def install_break_yo_system(domain, breakwhat): app_install( os.path.join(get_test_apps_dir(), "break_yo_system_ynh"), - args="domain=%s&breakwhat=%s" % (domain, breakwhat), + args="domain={}&breakwhat={}".format(domain, breakwhat), force=True, ) @@ -338,7 +338,7 @@ def test_legacy_app_failed_remove(mocker, secondary_domain): # The remove script runs with set -eu and attempt to remove this # file without -f, so will fail if it's not there ;) - os.remove("/etc/nginx/conf.d/%s.d/%s.conf" % (secondary_domain, "legacy_app")) + os.remove("/etc/nginx/conf.d/{}.d/{}.conf".format(secondary_domain, "legacy_app")) # TODO / FIXME : can't easily validate that 'app_not_properly_removed' # is triggered for weird reasons ... diff --git a/src/yunohost/tests/test_appurl.py b/src/yunohost/tests/test_appurl.py index 00bfe5c58..c036ae28a 100644 --- a/src/yunohost/tests/test_appurl.py +++ b/src/yunohost/tests/test_appurl.py @@ -99,7 +99,7 @@ def test_registerurl(): app_install( os.path.join(get_test_apps_dir(), "register_url_app_ynh"), - args="domain=%s&path=%s" % (maindomain, "/urlregisterapp"), + args="domain={}&path={}".format(maindomain, "/urlregisterapp"), force=True, ) @@ -109,7 +109,7 @@ def test_registerurl(): with pytest.raises(YunohostError): app_install( os.path.join(get_test_apps_dir(), "register_url_app_ynh"), - args="domain=%s&path=%s" % (maindomain, "/urlregisterapp"), + args="domain={}&path={}".format(maindomain, "/urlregisterapp"), force=True, ) @@ -119,7 +119,7 @@ def test_registerurl_baddomain(): with pytest.raises(YunohostError): app_install( os.path.join(get_test_apps_dir(), "register_url_app_ynh"), - args="domain=%s&path=%s" % ("yolo.swag", "/urlregisterapp"), + args="domain={}&path={}".format("yolo.swag", "/urlregisterapp"), force=True, ) @@ -234,7 +234,7 @@ def test_normalize_permission_path_with_unknown_domain(): def test_normalize_permission_path_conflicting_path(): app_install( os.path.join(get_test_apps_dir(), "register_url_app_ynh"), - args="domain=%s&path=%s" % (maindomain, "/url/registerapp"), + args="domain={}&path={}".format(maindomain, "/url/registerapp"), force=True, ) diff --git a/src/yunohost/tests/test_backuprestore.py b/src/yunohost/tests/test_backuprestore.py index 6e2c3b514..bfed5082a 100644 --- a/src/yunohost/tests/test_backuprestore.py +++ b/src/yunohost/tests/test_backuprestore.py @@ -139,7 +139,7 @@ def app_is_installed(app): # These are files we know should be installed by the app app_files = [] - app_files.append("/etc/nginx/conf.d/%s.d/%s.conf" % (maindomain, app)) + app_files.append("/etc/nginx/conf.d/{}.d/{}.conf".format(maindomain, app)) app_files.append("/var/www/%s/index.html" % app) app_files.append("/etc/importantfile") @@ -214,7 +214,7 @@ def install_app(app, path, additionnal_args=""): app_install( os.path.join(get_test_apps_dir(), app), - args="domain=%s&path=%s%s" % (maindomain, path, additionnal_args), + args="domain={}&path={}{}".format(maindomain, path, additionnal_args), force=True, ) diff --git a/src/yunohost/tests/test_changeurl.py b/src/yunohost/tests/test_changeurl.py index e375bd9f0..04cb4a1a9 100644 --- a/src/yunohost/tests/test_changeurl.py +++ b/src/yunohost/tests/test_changeurl.py @@ -26,7 +26,7 @@ def teardown_function(function): def install_changeurl_app(path): app_install( os.path.join(get_test_apps_dir(), "change_url_app_ynh"), - args="domain=%s&path=%s" % (maindomain, path), + args="domain={}&path={}".format(maindomain, path), force=True, ) diff --git a/src/yunohost/tests/test_permission.py b/src/yunohost/tests/test_permission.py index 00799d0fd..01b62f2a8 100644 --- a/src/yunohost/tests/test_permission.py +++ b/src/yunohost/tests/test_permission.py @@ -347,7 +347,7 @@ def check_permission_for_apps(): # {"bar", "foo"} # and compare this to the list of installed apps ... - app_perms_prefix = set(p.split(".")[0] for p in app_perms) + app_perms_prefix = {p.split(".")[0] for p in app_perms} assert set(_installed_apps()) == app_perms_prefix @@ -398,7 +398,7 @@ def test_permission_list(): assert res["wiki.main"]["allowed"] == ["all_users"] assert res["blog.main"]["allowed"] == ["alice"] assert res["blog.api"]["allowed"] == ["visitors"] - assert set(res["wiki.main"]["corresponding_users"]) == set(["alice", "bob"]) + assert set(res["wiki.main"]["corresponding_users"]) == {"alice", "bob"} assert res["blog.main"]["corresponding_users"] == ["alice"] assert res["blog.api"]["corresponding_users"] == [] assert res["wiki.main"]["url"] == "/" @@ -442,7 +442,7 @@ def test_permission_create_main(mocker): res = user_permission_list(full=True)["permissions"] assert "site.main" in res assert res["site.main"]["allowed"] == ["all_users"] - assert set(res["site.main"]["corresponding_users"]) == set(["alice", "bob"]) + assert set(res["site.main"]["corresponding_users"]) == {"alice", "bob"} assert res["site.main"]["protected"] is False @@ -630,8 +630,8 @@ def test_permission_add_group(mocker): user_permission_update("wiki.main", add="alice") res = user_permission_list(full=True)["permissions"] - assert set(res["wiki.main"]["allowed"]) == set(["all_users", "alice"]) - assert set(res["wiki.main"]["corresponding_users"]) == set(["alice", "bob"]) + assert set(res["wiki.main"]["allowed"]) == {"all_users", "alice"} + assert set(res["wiki.main"]["corresponding_users"]) == {"alice", "bob"} def test_permission_remove_group(mocker): @@ -680,7 +680,7 @@ def test_permission_reset(mocker): res = user_permission_list(full=True)["permissions"] assert res["blog.main"]["allowed"] == ["all_users"] - assert set(res["blog.main"]["corresponding_users"]) == set(["alice", "bob"]) + assert set(res["blog.main"]["corresponding_users"]) == {"alice", "bob"} def test_permission_reset_idempotency(): @@ -690,7 +690,7 @@ def test_permission_reset_idempotency(): res = user_permission_list(full=True)["permissions"] assert res["blog.main"]["allowed"] == ["all_users"] - assert set(res["blog.main"]["corresponding_users"]) == set(["alice", "bob"]) + assert set(res["blog.main"]["corresponding_users"]) == {"alice", "bob"} def test_permission_change_label(mocker): @@ -1013,9 +1013,9 @@ def test_permission_app_install(): assert res["permissions_app.dev"]["url"] == "/dev" assert res["permissions_app.main"]["allowed"] == ["all_users"] - assert set(res["permissions_app.main"]["corresponding_users"]) == set( - ["alice", "bob"] - ) + assert set(res["permissions_app.main"]["corresponding_users"]) == { + "alice", "bob" + } assert res["permissions_app.admin"]["allowed"] == ["alice"] assert res["permissions_app.admin"]["corresponding_users"] == ["alice"] diff --git a/src/yunohost/tests/test_questions.py b/src/yunohost/tests/test_questions.py index c21ff8c40..5917d32d4 100644 --- a/src/yunohost/tests/test_questions.py +++ b/src/yunohost/tests/test_questions.py @@ -1977,7 +1977,7 @@ def test_question_file_from_api(): from base64 import b64encode - b64content = b64encode("helloworld".encode()) + b64content = b64encode(b"helloworld") questions = [ { "name": "some_file", diff --git a/src/yunohost/tests/test_user-group.py b/src/yunohost/tests/test_user-group.py index d65366a9a..e561118e0 100644 --- a/src/yunohost/tests/test_user-group.py +++ b/src/yunohost/tests/test_user-group.py @@ -281,7 +281,7 @@ def test_update_group_add_user(mocker): user_group_update("dev", add=["bob"]) group_res = user_group_list()["groups"] - assert set(group_res["dev"]["members"]) == set(["alice", "bob"]) + assert set(group_res["dev"]["members"]) == {"alice", "bob"} def test_update_group_add_user_already_in(mocker): diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index fb9839814..87c962499 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -224,7 +224,7 @@ def tools_postinstall( disk_partitions = sorted(psutil.disk_partitions(), key=lambda k: k.mountpoint) main_disk_partitions = [d for d in disk_partitions if d.mountpoint in ["/", "/var"]] main_space = sum( - [psutil.disk_usage(d.mountpoint).total for d in main_disk_partitions] + psutil.disk_usage(d.mountpoint).total for d in main_disk_partitions ) GB = 1024 ** 3 if not force_diskspace and main_space < 10 * GB: diff --git a/src/yunohost/user.py b/src/yunohost/user.py index c9f70e152..6a924add3 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -97,7 +97,7 @@ def user_list(fields=None): and values[0].strip() == "/bin/false", } - attrs = set(["uid"]) + attrs = {"uid"} users = {} if not fields: @@ -215,7 +215,7 @@ def user_create( uid_guid_found = uid not in all_uid and uid not in all_gid # Adapt values for LDAP - fullname = "%s %s" % (firstname, lastname) + fullname = "{} {}".format(firstname, lastname) attr_dict = { "objectClass": [ @@ -333,8 +333,8 @@ def user_delete(operation_logger, username, purge=False, from_import=False): subprocess.call(["nscd", "-i", "passwd"]) if purge: - subprocess.call(["rm", "-rf", "/home/{0}".format(username)]) - subprocess.call(["rm", "-rf", "/var/mail/{0}".format(username)]) + subprocess.call(["rm", "-rf", "/home/{}".format(username)]) + subprocess.call(["rm", "-rf", "/var/mail/{}".format(username)]) hook_callback("post_user_delete", args=[username, purge]) @@ -1334,9 +1334,9 @@ def user_ssh_remove_key(username, key): def _convertSize(num, suffix=""): for unit in ["K", "M", "G", "T", "P", "E", "Z"]: if abs(num) < 1024.0: - return "%3.1f%s%s" % (num, unit, suffix) + return "{:3.1f}{}{}".format(num, unit, suffix) num /= 1024.0 - return "%.1f%s%s" % (num, "Yi", suffix) + return "{:.1f}{}{}".format(num, "Yi", suffix) def _hash_user_password(password): diff --git a/src/yunohost/utils/network.py b/src/yunohost/utils/network.py index 4474af14f..fd70e4d4b 100644 --- a/src/yunohost/utils/network.py +++ b/src/yunohost/utils/network.py @@ -44,7 +44,7 @@ def get_public_ip(protocol=4): ): ip = read_file(cache_file).strip() ip = ip if ip else None # Empty file (empty string) means there's no IP - logger.debug("Reusing IPv%s from cache: %s" % (protocol, ip)) + logger.debug("Reusing IPv{} from cache: {}".format(protocol, ip)) else: ip = get_public_ip_from_remote_server(protocol) logger.debug("IP fetched: %s" % ip) @@ -87,7 +87,7 @@ def get_public_ip_from_remote_server(protocol=4): try: return download_text(url, timeout=30).strip() except Exception as e: - logger.debug("Could not get public IPv%s : %s" % (str(protocol), str(e))) + logger.debug("Could not get public IPv{} : {}".format(str(protocol), str(e))) return None diff --git a/src/yunohost/utils/yunopaste.py b/src/yunohost/utils/yunopaste.py index 0c3e3c998..35e829991 100644 --- a/src/yunohost/utils/yunopaste.py +++ b/src/yunohost/utils/yunopaste.py @@ -49,7 +49,7 @@ def yunopaste(data): raw_msg=True, ) - return "%s/raw/%s" % (paste_server, url) + return "{}/raw/{}".format(paste_server, url) def anonymize(data): diff --git a/src/yunohost/vendor/acme_tiny/acme_tiny.py b/src/yunohost/vendor/acme_tiny/acme_tiny.py index 3c13d13ec..0d2534df9 100644 --- a/src/yunohost/vendor/acme_tiny/acme_tiny.py +++ b/src/yunohost/vendor/acme_tiny/acme_tiny.py @@ -38,7 +38,7 @@ def get_crt( ) out, err = proc.communicate(cmd_input) if proc.returncode != 0: - raise IOError("{0}\n{1}".format(err_msg, err)) + raise IOError("{}\n{}".format(err_msg, err)) return out # helper function - make request and automatically parse json response @@ -74,7 +74,7 @@ def get_crt( raise IndexError(resp_data) # allow 100 retrys for bad nonces if code not in [200, 201, 204]: raise ValueError( - "{0}:\nUrl: {1}\nData: {2}\nResponse Code: {3}\nResponse: {4}".format( + "{}:\nUrl: {}\nData: {}\nResponse Code: {}\nResponse: {}".format( err_msg, url, data, code, resp_data ) ) @@ -89,7 +89,7 @@ def get_crt( {"jwk": jwk} if acct_headers is None else {"kid": acct_headers["Location"]} ) protected64 = _b64(json.dumps(protected).encode("utf8")) - protected_input = "{0}.{1}".format(protected64, payload64).encode("utf8") + protected_input = "{}.{}".format(protected64, payload64).encode("utf8") out = _cmd( ["openssl", "dgst", "-sha256", "-sign", account_key], stdin=subprocess.PIPE, @@ -125,8 +125,8 @@ def get_crt( pub_hex, pub_exp = re.search( pub_pattern, out.decode("utf8"), re.MULTILINE | re.DOTALL ).groups() - pub_exp = "{0:x}".format(int(pub_exp)) - pub_exp = "0{0}".format(pub_exp) if len(pub_exp) % 2 else pub_exp + pub_exp = "{:x}".format(int(pub_exp)) + pub_exp = "0{}".format(pub_exp) if len(pub_exp) % 2 else pub_exp alg = "RS256" jwk = { "e": _b64(binascii.unhexlify(pub_exp.encode("utf-8"))), @@ -140,9 +140,9 @@ def get_crt( log.info("Parsing CSR...") out = _cmd( ["openssl", "req", "-in", csr, "-noout", "-text"], - err_msg="Error loading {0}".format(csr), + err_msg="Error loading {}".format(csr), ) - domains = set([]) + domains = set() common_name = re.search(r"Subject:.*? CN\s?=\s?([^\s,;/]+)", out.decode("utf8")) if common_name is not None: domains.add(common_name.group(1)) @@ -155,7 +155,7 @@ def get_crt( for san in subject_alt_names.group(1).split(", "): if san.startswith("DNS:"): domains.add(san[4:]) - log.info("Found domains: {0}".format(", ".join(domains))) + log.info("Found domains: {}".format(", ".join(domains))) # get the ACME directory of urls log.info("Getting directory...") @@ -178,7 +178,7 @@ def get_crt( {"contact": contact}, "Error updating contact details", ) - log.info("Updated contact details:\n{0}".format("\n".join(account["contact"]))) + log.info("Updated contact details:\n{}".format("\n".join(account["contact"]))) # create a new order log.info("Creating new order...") @@ -194,46 +194,46 @@ def get_crt( auth_url, None, "Error getting challenges" ) domain = authorization["identifier"]["value"] - log.info("Verifying {0}...".format(domain)) + log.info("Verifying {}...".format(domain)) # find the http-01 challenge and write the challenge file challenge = [c for c in authorization["challenges"] if c["type"] == "http-01"][ 0 ] token = re.sub(r"[^A-Za-z0-9_\-]", "_", challenge["token"]) - keyauthorization = "{0}.{1}".format(token, thumbprint) + keyauthorization = "{}.{}".format(token, thumbprint) wellknown_path = os.path.join(acme_dir, token) with open(wellknown_path, "w") as wellknown_file: wellknown_file.write(keyauthorization) # check that the file is in place try: - wellknown_url = "http://{0}/.well-known/acme-challenge/{1}".format( + wellknown_url = "http://{}/.well-known/acme-challenge/{}".format( domain, token ) assert disable_check or _do_request(wellknown_url)[0] == keyauthorization except (AssertionError, ValueError) as e: raise ValueError( - "Wrote file to {0}, but couldn't download {1}: {2}".format( + "Wrote file to {}, but couldn't download {}: {}".format( wellknown_path, wellknown_url, e ) ) # say the challenge is done _send_signed_request( - challenge["url"], {}, "Error submitting challenges: {0}".format(domain) + challenge["url"], {}, "Error submitting challenges: {}".format(domain) ) authorization = _poll_until_not( auth_url, ["pending"], - "Error checking challenge status for {0}".format(domain), + "Error checking challenge status for {}".format(domain), ) if authorization["status"] != "valid": raise ValueError( - "Challenge did not pass for {0}: {1}".format(domain, authorization) + "Challenge did not pass for {}: {}".format(domain, authorization) ) os.remove(wellknown_path) - log.info("{0} verified!".format(domain)) + log.info("{} verified!".format(domain)) # finalize the order with the csr log.info("Signing certificate...") @@ -251,7 +251,7 @@ def get_crt( "Error checking order status", ) if order["status"] != "valid": - raise ValueError("Order failed: {0}".format(order)) + raise ValueError("Order failed: {}".format(order)) # download the certificate certificate_pem, _, _ = _send_signed_request( diff --git a/tests/test_translation_format_consistency.py b/tests/test_translation_format_consistency.py index 86d1c3279..bfd0e3ae4 100644 --- a/tests/test_translation_format_consistency.py +++ b/tests/test_translation_format_consistency.py @@ -26,10 +26,10 @@ def find_inconsistencies(locale_file): # Then we check that every "{stuff}" (for python's .format()) # should also be in the translated string, otherwise the .format # will trigger an exception! - subkeys_in_ref = set(k[0] for k in re.findall(r"{(\w+)(:\w)?}", string)) - subkeys_in_this_locale = set( + subkeys_in_ref = {k[0] for k in re.findall(r"{(\w+)(:\w)?}", string)} + subkeys_in_this_locale = { k[0] for k in re.findall(r"{(\w+)(:\w)?}", this_locale[key]) - ) + } if any(k not in subkeys_in_ref for k in subkeys_in_this_locale): yield """\n From 77058ab356316809b0474ee64cff189fe2b64583 Mon Sep 17 00:00:00 2001 From: Laurent Peuch Date: Fri, 24 Dec 2021 01:16:52 +0100 Subject: [PATCH 32/51] [mod] stop using old style class --- src/yunohost/backup.py | 4 ++-- src/yunohost/log.py | 2 +- src/yunohost/tools.py | 2 +- src/yunohost/utils/config.py | 2 +- src/yunohost/utils/password.py | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/yunohost/backup.py b/src/yunohost/backup.py index 03721be0c..458d7655f 100644 --- a/src/yunohost/backup.py +++ b/src/yunohost/backup.py @@ -80,7 +80,7 @@ MB_ALLOWED_TO_ORGANIZE = 10 logger = getActionLogger("yunohost.backup") -class BackupRestoreTargetsManager(object): +class BackupRestoreTargetsManager: """ BackupRestoreTargetsManager manage the targets @@ -1570,7 +1570,7 @@ class RestoreManager: # # Backup methods # # -class BackupMethod(object): +class BackupMethod: """ BackupMethod is an abstract class that represents a way to backup and diff --git a/src/yunohost/log.py b/src/yunohost/log.py index cb11c7112..d28a35e18 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -469,7 +469,7 @@ class RedactingFormatter(Formatter): ) -class OperationLogger(object): +class OperationLogger: """ Instances of this class represents unit operation done on the ynh instance. diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index 87c962499..679b4d16e 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -1107,7 +1107,7 @@ def _tools_migrations_run_before_app_restore(backup_version, app_id): raise -class Migration(object): +class Migration: # Those are to be implemented by daughter classes diff --git a/src/yunohost/utils/config.py b/src/yunohost/utils/config.py index 5d1d1f9d2..e3b09f870 100644 --- a/src/yunohost/utils/config.py +++ b/src/yunohost/utils/config.py @@ -678,7 +678,7 @@ class ConfigPanel: yield (panel, section, option) -class Question(object): +class Question: hide_user_input_in_prompt = False pattern: Optional[Dict] = None diff --git a/src/yunohost/utils/password.py b/src/yunohost/utils/password.py index 188850183..9fff5ece7 100644 --- a/src/yunohost/utils/password.py +++ b/src/yunohost/utils/password.py @@ -51,7 +51,7 @@ def assert_password_is_strong_enough(profile, password): PasswordValidator(profile).validate(password) -class PasswordValidator(object): +class PasswordValidator: def __init__(self, profile): """ Initialize a password validator. From a615528c7f9f60ee7b4d2838242389455ace0b9b Mon Sep 17 00:00:00 2001 From: Kay0u Date: Sat, 25 Dec 2021 17:32:50 +0100 Subject: [PATCH 33/51] remove double quote around a variable --- data/hooks/diagnosis/12-dnsrecords.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/hooks/diagnosis/12-dnsrecords.py b/data/hooks/diagnosis/12-dnsrecords.py index 7e681484d..cedd3891e 100644 --- a/data/hooks/diagnosis/12-dnsrecords.py +++ b/data/hooks/diagnosis/12-dnsrecords.py @@ -136,7 +136,7 @@ class DNSRecordsDiagnoser(Diagnoser): # If status is okay and there's actually no expected records # (e.g. XMPP disabled) # then let's not yield any diagnosis line - if not records and "status" == "SUCCESS": + if not records and status == "SUCCESS": continue output = dict( From c4b83459b81c0bfc67882155e967ab9c645436e3 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Sat, 25 Dec 2021 18:20:12 +0100 Subject: [PATCH 34/51] add lgtm/code quality badge --- .lgtm.yml | 4 ++++ README.md | 1 + 2 files changed, 5 insertions(+) create mode 100644 .lgtm.yml diff --git a/.lgtm.yml b/.lgtm.yml new file mode 100644 index 000000000..8fd57e49e --- /dev/null +++ b/.lgtm.yml @@ -0,0 +1,4 @@ +extraction: + python: + python_setup: + version: "3" \ No newline at end of file diff --git a/README.md b/README.md index df3a4bb9f..969651eee 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ ![Version](https://img.shields.io/github/v/tag/yunohost/yunohost?label=version&sort=semver) [![Build status](https://shields.io/gitlab/pipeline/yunohost/yunohost/dev)](https://gitlab.com/yunohost/yunohost/-/pipelines) ![Test coverage](https://img.shields.io/gitlab/coverage/yunohost/yunohost/dev) +[![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/YunoHost/yunohost.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/YunoHost/yunohost/context:python) [![GitHub license](https://img.shields.io/github/license/YunoHost/yunohost)](https://github.com/YunoHost/yunohost/blob/dev/LICENSE) [![Mastodon Follow](https://img.shields.io/mastodon/follow/28084)](https://mastodon.social/@yunohost) From 7112deb16738dd11f5b9fa134dde5dbc178fc18e Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 27 Dec 2021 14:59:08 +0100 Subject: [PATCH 35/51] f-string all the things! --- data/hooks/diagnosis/00-basesystem.py | 8 ++- data/hooks/diagnosis/10-ip.py | 11 ++-- data/hooks/diagnosis/50-systemresources.py | 8 +-- src/yunohost/app.py | 17 +++--- src/yunohost/app_catalog.py | 2 +- src/yunohost/backup.py | 10 ++-- src/yunohost/certificate.py | 60 ++++++---------------- src/yunohost/dyndns.py | 10 ++-- src/yunohost/hook.py | 4 +- src/yunohost/permission.py | 3 +- src/yunohost/regenconf.py | 9 ++-- src/yunohost/service.py | 12 ++--- src/yunohost/settings.py | 2 +- src/yunohost/user.py | 8 +-- src/yunohost/utils/network.py | 4 +- 15 files changed, 66 insertions(+), 102 deletions(-) diff --git a/data/hooks/diagnosis/00-basesystem.py b/data/hooks/diagnosis/00-basesystem.py index 8b7b888e3..99241c55f 100644 --- a/data/hooks/diagnosis/00-basesystem.py +++ b/data/hooks/diagnosis/00-basesystem.py @@ -42,10 +42,8 @@ class BaseSystemDiagnoser(Diagnoser): elif os.path.exists("/sys/devices/virtual/dmi/id/sys_vendor"): model = read_file("/sys/devices/virtual/dmi/id/sys_vendor").strip() if os.path.exists("/sys/devices/virtual/dmi/id/product_name"): - model = "{} {}".format( - model, - read_file("/sys/devices/virtual/dmi/id/product_name").strip(), - ) + product_name = read_file("/sys/devices/virtual/dmi/id/product_name").strip() + model = f"{model} {product_name}" hardware["data"]["model"] = model hardware["details"] = ["diagnosis_basesystem_hardware_model"] @@ -116,7 +114,7 @@ class BaseSystemDiagnoser(Diagnoser): bad_sury_packages = list(self.bad_sury_packages()) if bad_sury_packages: cmd_to_fix = "apt install --allow-downgrades " + " ".join( - ["{}={}".format(package, version) for package, version in bad_sury_packages] + [f"{package}={version}" for package, version in bad_sury_packages] ) yield dict( meta={"test": "packages_from_sury"}, diff --git a/data/hooks/diagnosis/10-ip.py b/data/hooks/diagnosis/10-ip.py index 486e37e3e..1c6c5a4b3 100644 --- a/data/hooks/diagnosis/10-ip.py +++ b/data/hooks/diagnosis/10-ip.py @@ -167,10 +167,7 @@ class IPDiagnoser(Diagnoser): assert ( resolvers != [] - ), "Uhoh, need at least one IPv{} DNS resolver in {} ...".format( - protocol, - resolver_file, - ) + ), f"Uhoh, need at least one IPv{protocol} DNS resolver in {resolver_file} ..." # So let's try to ping the first 4~5 resolvers (shuffled) # If we succesfully ping any of them, we conclude that we are indeed connected @@ -220,9 +217,9 @@ class IPDiagnoser(Diagnoser): try: return download_text(url, timeout=30).strip() except Exception as e: - self.logger_debug( - "Could not get public IPv{} : {}".format(str(protocol), str(e)) - ) + protocol = str(protocol) + e = str(e) + self.logger_debug(f"Could not get public IPv{protocol} : {e}") return None diff --git a/data/hooks/diagnosis/50-systemresources.py b/data/hooks/diagnosis/50-systemresources.py index 4deb607f4..bdea0ea16 100644 --- a/data/hooks/diagnosis/50-systemresources.py +++ b/data/hooks/diagnosis/50-systemresources.py @@ -156,7 +156,7 @@ class SystemResourcesDiagnoser(Diagnoser): kills_count = self.recent_kills_by_oom_reaper() if kills_count: kills_summary = "\n".join( - ["{} (x{})".format(proc, count) for proc, count in kills_count] + [f"{proc} (x{count})" for proc, count in kills_count] ) yield dict( @@ -202,9 +202,11 @@ def human_size(bytes_): # Adapted from https://stackoverflow.com/a/1094933 for unit in ["", "ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]: if abs(bytes_) < 1024.0: - return "{} {}B".format(round_(bytes_), unit) + bytes_ = round_(bytes_) + return f"{bytes_} {unit}B" bytes_ /= 1024.0 - return "{} {}B".format(round_(bytes_), "Yi") + bytes_ = round_(bytes_) + return f"{bytes_} YiB" def round_(n): diff --git a/src/yunohost/app.py b/src/yunohost/app.py index f47efd9d7..d5e57d6cf 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -122,7 +122,7 @@ def app_list(full=False, installed=False, filter=None): try: app_info_dict = app_info(app_id, full=full) except Exception as e: - logger.error("Failed to read info for {} : {}".format(app_id, e)) + logger.error(f"Failed to read info for {app_id} : {e}") continue app_info_dict["id"] = app_id out.append(app_info_dict) @@ -1219,7 +1219,8 @@ def app_setting(app, key, value=None, delete=False): ) permissions = user_permission_list(full=True, apps=[app])["permissions"] - permission_name = "{}.legacy_{}_uris".format(app, key.split("_")[0]) + key_ = key.split("_")[0] + permission_name = f"{app}.legacy_{key_}_uris" permission = permissions.get(permission_name) # GET @@ -1562,11 +1563,7 @@ def app_action_run(operation_logger, app, action, args=None): shutil.rmtree(tmp_workdir_for_app) if retcode not in action_declaration.get("accepted_return_codes", [0]): - msg = "Error while executing action '{}' of app '{}': return code {}".format( - action, - app, - retcode, - ) + msg = f"Error while executing action '{action}' of app '{app}': return code {retcode}" operation_logger.error(msg) raise YunohostError(msg, raw_msg=True) @@ -1989,7 +1986,8 @@ def _set_default_ask_questions(arguments): for question in questions_with_default ): # The key is for example "app_manifest_install_ask_domain" - key = "app_manifest_{}_ask_{}".format(script_name, arg["name"]) + arg_name = arg["name"] + key = f"app_manifest_{script_name}_ask_{arg_name}" arg["ask"] = m18n.n(key) # Also it in fact doesn't make sense for any of those questions to have an example value nor a default value... @@ -2397,7 +2395,8 @@ def _make_environment_for_app_script( env_dict["YNH_APP_BASEDIR"] = workdir for arg_name, arg_value in args.items(): - env_dict["YNH_{}{}".format(args_prefix, arg_name.upper())] = str(arg_value) + arg_name_upper = arg_name.upper() + env_dict[f"YNH_{args_prefix}{arg_name_upper}"] = str(arg_value) return env_dict diff --git a/src/yunohost/app_catalog.py b/src/yunohost/app_catalog.py index 96a006704..0f0e1ae46 100644 --- a/src/yunohost/app_catalog.py +++ b/src/yunohost/app_catalog.py @@ -217,7 +217,7 @@ def _load_apps_catalog(): ) except Exception as e: raise YunohostError( - "Unable to read cache for apps_catalog {} : {}".format(cache_file, e), + f"Unable to read cache for apps_catalog {cache_file} : {e}", raw_msg=True, ) diff --git a/src/yunohost/backup.py b/src/yunohost/backup.py index 458d7655f..ebfb23ab0 100644 --- a/src/yunohost/backup.py +++ b/src/yunohost/backup.py @@ -2420,7 +2420,7 @@ def backup_download(name): ) return - archive_file = "{}/{}.tar".format(ARCHIVES_PATH, name) + archive_file = f"{ARCHIVES_PATH}/{name}.tar" # Check file exist (even if it's a broken symlink) if not os.path.lexists(archive_file): @@ -2462,7 +2462,7 @@ def backup_info(name, with_details=False, human_readable=False): elif name.endswith(".tar"): name = name[: -len(".tar")] - archive_file = "{}/{}.tar".format(ARCHIVES_PATH, name) + archive_file = f"{ARCHIVES_PATH}/{name}.tar" # Check file exist (even if it's a broken symlink) if not os.path.lexists(archive_file): @@ -2480,7 +2480,7 @@ def backup_info(name, with_details=False, human_readable=False): "backup_archive_broken_link", path=archive_file ) - info_file = "{}/{}.info.json".format(ARCHIVES_PATH, name) + info_file = f"{ARCHIVES_PATH}/{name}.info.json" if not os.path.exists(info_file): tar = tarfile.open( @@ -2591,10 +2591,10 @@ def backup_delete(name): hook_callback("pre_backup_delete", args=[name]) - archive_file = "{}/{}.tar".format(ARCHIVES_PATH, name) + archive_file = f"{ARCHIVES_PATH}/{name}.tar" if not os.path.exists(archive_file) and os.path.exists(archive_file + ".gz"): archive_file += ".gz" - info_file = "{}/{}.info.json".format(ARCHIVES_PATH, name) + info_file = f"{ARCHIVES_PATH}/{name}.info.json" files_to_delete = [archive_file, info_file] diff --git a/src/yunohost/certificate.py b/src/yunohost/certificate.py index e4dc7d350..79e3ae092 100644 --- a/src/yunohost/certificate.py +++ b/src/yunohost/certificate.py @@ -143,11 +143,7 @@ def _certificate_install_selfsigned(domain_list, force=False): # Paths of files and folder we'll need date_tag = datetime.utcnow().strftime("%Y%m%d.%H%M%S") - new_cert_folder = "{}/{}-history/{}-selfsigned".format( - CERT_FOLDER, - domain, - date_tag, - ) + new_cert_folder = f"{CERT_FOLDER}/{domain}-history/{date_tag}-selfsigned" conf_template = os.path.join(SSL_DIR, "openssl.cnf") @@ -300,10 +296,7 @@ def _certificate_install_letsencrypt( try: _fetch_and_enable_new_certificate(domain, staging, no_checks=no_checks) except Exception as e: - msg = "Certificate installation for {} failed !\nException: {}".format( - domain, - e, - ) + msg = f"Certificate installation for {domain} failed !\nException: {e}" logger.error(msg) operation_logger.error(msg) if no_checks: @@ -456,39 +449,25 @@ def _email_renewing_failed(domain, exception_message, stack=""): subject_ = "Certificate renewing attempt for %s failed!" % domain logs = _tail(50, "/var/log/yunohost/yunohost-cli.log") - text = """ -An attempt for renewing the certificate for domain {} failed with the following + message = f"""\ +From: {from_} +To: {to_} +Subject: {subject_} + + +An attempt for renewing the certificate for domain {domain} failed with the following error : -{} -{} +{exception_message} +{stack} Here's the tail of /var/log/yunohost/yunohost-cli.log, which might help to investigate : -{} +{logs} -- Certificate Manager - -""".format( - domain, - exception_message, - stack, - logs, - ) - - message = """\ -From: {} -To: {} -Subject: {} - -{} -""".format( - from_, - to_, - subject_, - text, - ) +""" import smtplib @@ -532,7 +511,7 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False): # Prepare certificate signing request logger.debug("Prepare key and certificate signing request (CSR) for %s...", domain) - domain_key_file = "{}/{}.pem".format(TMP_FOLDER, domain) + domain_key_file = f"{TMP_FOLDER}/{domain}.pem" _generate_key(domain_key_file) _set_permissions(domain_key_file, "root", "ssl-cert", 0o640) @@ -541,7 +520,7 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False): # Sign the certificate logger.debug("Now using ACME Tiny to sign the certificate...") - domain_csr_file = "{}/{}.csr".format(TMP_FOLDER, domain) + domain_csr_file = f"{TMP_FOLDER}/{domain}.csr" if staging: certification_authority = STAGING_CERTIFICATION_AUTHORITY @@ -580,12 +559,7 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False): else: folder_flag = "letsencrypt" - new_cert_folder = "{}/{}-history/{}-{}".format( - CERT_FOLDER, - domain, - date_tag, - folder_flag, - ) + new_cert_folder = f"{CERT_FOLDER}/{domain}-history/{date_tag}-{folder_flag}" os.makedirs(new_cert_folder) @@ -844,7 +818,7 @@ def _backup_current_cert(domain): cert_folder_domain = os.path.join(CERT_FOLDER, domain) date_tag = datetime.utcnow().strftime("%Y%m%d.%H%M%S") - backup_folder = "{}-backups/{}".format(cert_folder_domain, date_tag) + backup_folder = f"{cert_folder_domain}-backups/{date_tag}" shutil.copytree(cert_folder_domain, backup_folder) diff --git a/src/yunohost/dyndns.py b/src/yunohost/dyndns.py index 63bb3180f..8748c1c00 100644 --- a/src/yunohost/dyndns.py +++ b/src/yunohost/dyndns.py @@ -151,7 +151,7 @@ def dyndns_subscribe(operation_logger, domain=None, key=None): try: error = json.loads(r.text)["error"] except Exception: - error = 'Server error, code: {}. (Message: "{}")'.format(r.status_code, r.text) + error = f'Server error, code: {r.status_code}. (Message: "{r.text}")' raise YunohostError("dyndns_registration_failed", error=error) # Yunohost regen conf will add the dyndns cron job if a private key exists @@ -196,7 +196,7 @@ def dyndns_update( # If key is not given, pick the first file we find with the domain given elif key is None: - keys = glob.glob("/etc/yunohost/dyndns/K{}.+*.private".format(domain)) + keys = glob.glob(f"/etc/yunohost/dyndns/K{domain}.+*.private") if not keys: raise YunohostValidationError("dyndns_key_not_found") @@ -263,14 +263,14 @@ def dyndns_update( return None raise YunohostError( - "Failed to resolve {} for {}".format(rdtype, domain), raw_msg=True + f"Failed to resolve {rdtype} for {domain}", raw_msg=True ) old_ipv4 = resolve_domain(domain, "A") old_ipv6 = resolve_domain(domain, "AAAA") - logger.debug("Old IPv4/v6 are ({}, {})".format(old_ipv4, old_ipv6)) - logger.debug("Requested IPv4/v6 are ({}, {})".format(ipv4, ipv6)) + logger.debug(f"Old IPv4/v6 are ({old_ipv4}, {old_ipv6})") + logger.debug(f"Requested IPv4/v6 are ({ipv4}, {ipv6})") # no need to update if (not force and not dry_run) and (old_ipv4 == ipv4 and old_ipv6 == ipv6): diff --git a/src/yunohost/hook.py b/src/yunohost/hook.py index c5ff8b0cd..7b03b2e9b 100644 --- a/src/yunohost/hook.py +++ b/src/yunohost/hook.py @@ -197,7 +197,7 @@ def hook_list(action, list_by="name", show_info=False): or (f.startswith("__") and f.endswith("__")) ): continue - path = "{}{}/{}".format(folder, action, f) + path = f"{folder}{action}/{f}" priority, name = _extract_filename_parts(f) _append_hook(d, priority, name, path) @@ -407,7 +407,7 @@ def _hook_exec_bash(path, args, chdir, env, user, return_format, loggers): if not chdir: # use the script directory as current one chdir, cmd_script = os.path.split(path) - cmd_script = "./{}".format(cmd_script) + cmd_script = f"./{cmd_script}" else: cmd_script = path diff --git a/src/yunohost/permission.py b/src/yunohost/permission.py index 04c170a32..9a46cad27 100644 --- a/src/yunohost/permission.py +++ b/src/yunohost/permission.py @@ -139,7 +139,8 @@ def user_permission_list( continue main_perm_label = permissions[main_perm_name]["label"] infos["sublabel"] = infos["label"] - infos["label"] = "{} ({})".format(main_perm_label, infos["label"]) + label_ = infos["label"] + infos["label"] = f"{main_perm_label} ({label_})" if short: permissions = list(permissions.keys()) diff --git a/src/yunohost/regenconf.py b/src/yunohost/regenconf.py index 224fb8bc5..adec5508d 100644 --- a/src/yunohost/regenconf.py +++ b/src/yunohost/regenconf.py @@ -638,12 +638,9 @@ def _process_regen_conf(system_conf, new_conf=None, save=True): """ if save: - backup_path = os.path.join( - BACKUP_CONF_DIR, - "{}-{}".format( - system_conf.lstrip("/"), datetime.utcnow().strftime("%Y%m%d.%H%M%S") - ), - ) + system_conf_ = system_conf.lstrip("/") + now_ = datetime.utcnow().strftime("%Y%m%d.%H%M%S") + backup_path = os.path.join(BACKUP_CONF_DIR, f"{system_conf_}-{now_}") backup_dir = os.path.dirname(backup_path) if not os.path.isdir(backup_dir): diff --git a/src/yunohost/service.py b/src/yunohost/service.py index f47f67a3c..4f453dfe9 100644 --- a/src/yunohost/service.py +++ b/src/yunohost/service.py @@ -625,7 +625,7 @@ def _run_service_command(action, service): % (action, ", ".join(possible_actions)) ) - cmd = "systemctl {} {}".format(action, service) + cmd = f"systemctl {action} {service}" need_lock = services[service].get("need_lock", False) and action in [ "start", @@ -673,7 +673,7 @@ def _give_lock(action, service, p): else: systemctl_PID_name = "ControlPID" - cmd_get_son_PID = "systemctl show {} -p {}".format(service, systemctl_PID_name) + cmd_get_son_PID = f"systemctl show {service} -p {systemctl_PID_name}" son_PID = 0 # As long as we did not found the PID and that the command is still running while son_PID == 0 and p.poll() is None: @@ -686,9 +686,7 @@ def _give_lock(action, service, p): # If we found a PID if son_PID != 0: # Append the PID to the lock file - logger.debug( - "Giving a lock to PID {} for service {} !".format(str(son_PID), service) - ) + logger.debug(f"Giving a lock to PID {son_PID} for service {service} !") append_to_file(MOULINETTE_LOCK, "\n%s" % str(son_PID)) return son_PID @@ -865,9 +863,7 @@ def _get_journalctl_logs(service, number="all"): systemd_service = services.get(service, {}).get("actual_systemd_service", service) try: return check_output( - "journalctl --no-hostname --no-pager -u {} -n{}".format( - systemd_service, number - ) + f"journalctl --no-hostname --no-pager -u {systemd_service} -n{number}" ) except Exception: import traceback diff --git a/src/yunohost/settings.py b/src/yunohost/settings.py index 77d0d2705..eddb30764 100644 --- a/src/yunohost/settings.py +++ b/src/yunohost/settings.py @@ -224,7 +224,7 @@ def settings_set(key, value): try: trigger_post_change_hook(key, old_value, value) except Exception as e: - logger.error("Post-change hook for setting {} failed : {}".format(key, e)) + logger.error(f"Post-change hook for setting {key} failed : {e}") raise diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 6a924add3..78fda8d09 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -166,7 +166,7 @@ def user_create( # On affiche les differents domaines possibles Moulinette.display(m18n.n("domains_available")) for domain in domain_list()["domains"]: - Moulinette.display("- {}".format(domain)) + Moulinette.display(f"- {domain}") maindomain = _get_maindomain() domain = Moulinette.prompt( @@ -215,7 +215,7 @@ def user_create( uid_guid_found = uid not in all_uid and uid not in all_gid # Adapt values for LDAP - fullname = "{} {}".format(firstname, lastname) + fullname = f"{firstname} {lastname}" attr_dict = { "objectClass": [ @@ -333,8 +333,8 @@ def user_delete(operation_logger, username, purge=False, from_import=False): subprocess.call(["nscd", "-i", "passwd"]) if purge: - subprocess.call(["rm", "-rf", "/home/{}".format(username)]) - subprocess.call(["rm", "-rf", "/var/mail/{}".format(username)]) + subprocess.call(["rm", "-rf", f"/home/{username}"]) + subprocess.call(["rm", "-rf", f"/var/mail/{username}"]) hook_callback("post_user_delete", args=[username, purge]) diff --git a/src/yunohost/utils/network.py b/src/yunohost/utils/network.py index fd70e4d4b..c4dc8723e 100644 --- a/src/yunohost/utils/network.py +++ b/src/yunohost/utils/network.py @@ -44,7 +44,7 @@ def get_public_ip(protocol=4): ): ip = read_file(cache_file).strip() ip = ip if ip else None # Empty file (empty string) means there's no IP - logger.debug("Reusing IPv{} from cache: {}".format(protocol, ip)) + logger.debug(f"Reusing IPv{protocol} from cache: {ip}") else: ip = get_public_ip_from_remote_server(protocol) logger.debug("IP fetched: %s" % ip) @@ -87,7 +87,7 @@ def get_public_ip_from_remote_server(protocol=4): try: return download_text(url, timeout=30).strip() except Exception as e: - logger.debug("Could not get public IPv{} : {}".format(str(protocol), str(e))) + logger.debug(f"Could not get public IPv{protocol} : {e}")) return None From 377ccd8acf73d2a01757f66fdbedb5a97a15cbee Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 27 Dec 2021 15:19:48 +0100 Subject: [PATCH 36/51] Typo /o\ --- src/yunohost/utils/network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/utils/network.py b/src/yunohost/utils/network.py index c4dc8723e..28dcb204c 100644 --- a/src/yunohost/utils/network.py +++ b/src/yunohost/utils/network.py @@ -87,7 +87,7 @@ def get_public_ip_from_remote_server(protocol=4): try: return download_text(url, timeout=30).strip() except Exception as e: - logger.debug(f"Could not get public IPv{protocol} : {e}")) + logger.debug(f"Could not get public IPv{protocol} : {e}") return None From bd04779e402e63cce2ffb819aee96fb8a8436bc6 Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Mon, 27 Dec 2021 15:31:00 +0000 Subject: [PATCH 37/51] [CI] Reformat / remove stale translated strings --- locales/de.json | 4 ++-- locales/es.json | 2 +- locales/fr.json | 2 +- locales/gl.json | 2 +- locales/id.json | 2 +- locales/nl.json | 2 +- locales/ru.json | 8 ++++---- locales/uk.json | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/locales/de.json b/locales/de.json index 85d566266..537621f99 100644 --- a/locales/de.json +++ b/locales/de.json @@ -672,7 +672,7 @@ "domain_dns_registrar_managed_in_parent_domain": "Diese Domäne ist eine Unterdomäne von {parent_domain_link}. Die Konfiguration des DNS-Registrars sollte auf der Konfigurationsseite von {parent_domain} verwaltet werden.", "domain_dns_registrar_not_supported": "YunoHost konnte den Registrar, der diese Domäne verwaltet, nicht automatisch erkennen. Du solltest die DNS-Einträge, wie unter https://yunohost.org/dns beschrieben, manuell konfigurieren.", "domain_dns_registrar_supported": "YunoHost hat automatisch erkannt, dass diese Domäne von dem Registrar **{registrar}** verwaltet wird. Wenn Du möchtest, konfiguriert YunoHost diese DNS-Zone automatisch, wenn Du die entsprechenden API-Zugangsdaten zur Verfügung stellst. Auf dieser Seite erfährst Du, wie Du deine API-Anmeldeinformationen erhältst: https://yunohost.org/registar_api_{registrar}. (Du kannst deine DNS-Einträge auch, wie unter https://yunohost.org/dns beschrieben, manuell konfigurieren)", - "service_not_reloading_because_conf_broken": "Der Dienst '{Name}' wird nicht neu geladen/gestartet, da seine Konfiguration fehlerhaft ist: {Fehler}", + "service_not_reloading_because_conf_broken": "Der Dienst '{name}' wird nicht neu geladen/gestartet, da seine Konfiguration fehlerhaft ist: {errors}", "user_import_failed": "Der Import von Benutzer:innen ist komplett fehlgeschlagen", "domain_dns_push_failed_to_list": "Auflistung der aktuellen Einträge über die API des Registrars fehlgeschlagen: {error}", "domain_dns_pushing": "DNS-Einträge übertragen…", @@ -704,4 +704,4 @@ "log_domain_config_set": "Konfiguration für die Domäne '{}' aktualisieren", "log_domain_dns_push": "DNS-Einträge für die Domäne '{}' übertragen", "service_description_yunomdns": "Ermöglicht es dir, deinen Server über 'yunohost.local' in deinem lokalen Netzwerk zu erreichen" -} +} \ No newline at end of file diff --git a/locales/es.json b/locales/es.json index 4afa56996..22493ec11 100644 --- a/locales/es.json +++ b/locales/es.json @@ -616,4 +616,4 @@ "diagnosis_apps_broken": "Esta aplicación está etiquetada como defectuosa en el catálogo de aplicaciones YunoHost. Podría ser un problema temporal mientras las personas responsables corrigen el asunto. Mientras tanto, la actualización de esta aplicación está desactivada.", "diagnosis_apps_deprecated_practices": "La versión instalada de esta aplicación usa aún prácticas de empaquetado obsoletas. Deberías actualizarla.", "diagnosis_apps_outdated_ynh_requirement": "La versión instalada de esta aplicación solo necesita YunoHost >= 2.x, lo que indica que no está al día con la buena praxis de ayudas y empaquetado recomendadas. Deberías actualizarla." -} +} \ No newline at end of file diff --git a/locales/fr.json b/locales/fr.json index 2d70f2cab..cc7088c19 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -718,4 +718,4 @@ "migration_0021_patch_yunohost_conflicts": "Application du correctif pour contourner le problème de conflit...", "migration_0021_not_buster": "La distribution Debian actuelle n'est pas Buster !", "migration_description_0021_migrate_to_bullseye": "Mise à niveau du système vers Debian Bullseye et YunoHost 11.x" -} +} \ No newline at end of file diff --git a/locales/gl.json b/locales/gl.json index 308cba961..3c577b935 100644 --- a/locales/gl.json +++ b/locales/gl.json @@ -718,4 +718,4 @@ "migration_description_0021_migrate_to_bullseye": "Actualizar o sistema a Debian Bullseye e YunoHost 11.x", "migration_0021_system_not_fully_up_to_date": "O teu sistema non está completamente actualizado. Fai unha actualización normal antes de executar a migración a Bullseye.", "migration_0021_general_warning": "Ten en conta que a migración é unha operación delicada. O equipo de YunoHost fixo todo o que puido para revisalo e probalo, pero aínda así poderían acontecer fallos no sistema ou apps.\n\nAsí as cousas, é recomendable:\n - Facer unha copia de apoio dos datos e apps importantes. Máis info en https://yunohost.org/backup;\n - Ter paciencia unha vez inicias a migración: dependendo da túa conexión a internet e hardware, podería levarlle varias horas completar o proceso." -} +} \ No newline at end of file diff --git a/locales/id.json b/locales/id.json index 08e09fe8b..47aff8b2e 100644 --- a/locales/id.json +++ b/locales/id.json @@ -55,4 +55,4 @@ "backup_nothings_done": "Tak ada yang harus disimpan", "certmanager_cert_install_success": "Sertifikat Let's Encrypt sekarang sudah terpasang pada domain '{domain}'", "backup_mount_archive_for_restore": "Menyiapkan arsip untuk pemulihan..." -} +} \ No newline at end of file diff --git a/locales/nl.json b/locales/nl.json index 038d18283..1c3e2083d 100644 --- a/locales/nl.json +++ b/locales/nl.json @@ -130,4 +130,4 @@ "app_label_deprecated": "Dit commando is vervallen. Gebruik alsjeblieft het nieuwe commando 'yunohost user permission update' om het label van de app te beheren.", "app_change_url_no_script": "De app '{app_name}' ondersteunt nog geen URL-aanpassingen. Misschien wel na een upgrade.", "app_upgrade_some_app_failed": "Sommige apps konden niet worden bijgewerkt" -} +} \ No newline at end of file diff --git a/locales/ru.json b/locales/ru.json index 8fbc3f91b..9c857f7a6 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -147,7 +147,7 @@ "additional_urls_already_removed": "Этот URL '{url}' уже удален из дополнительных URL для разрешения '{permission}'", "app_action_cannot_be_ran_because_required_services_down": "Для выполнения этого действия должны быть запущены следующие службы: {services}. Попробуйте перезапустить их, чтобы продолжить (и, возможно, выяснить, почему они не работают).", "app_unsupported_remote_type": "Неподдерживаемый удаленный тип, используемый для приложения", - "backup_archive_system_part_not_available": "Системная часть '{часть}' недоступна в этой резервной копии", + "backup_archive_system_part_not_available": "Системная часть '{part}' недоступна в этой резервной копии", "backup_output_directory_not_empty": "Вы должны выбрать пустой каталог для сохранения", "backup_archive_writing_error": "Не удалось добавить файлы '{source}' (названные в архиве '{dest}') для резервного копирования в архив '{archive}'", "backup_cant_mount_uncompress_archive": "Не удалось смонтировать несжатый архив как защищенный от записи", @@ -157,7 +157,7 @@ "backup_with_no_backup_script_for_app": "Приложение '{app}' не имеет сценария резервного копирования. Оно будет проигнорировано.", "certmanager_attempt_to_renew_nonLE_cert": "Сертификат для домена '{domain}' не выпущен Let's Encrypt. Невозможно продлить его автоматически!", "certmanager_attempt_to_renew_valid_cert": "Срок действия сертификата для домена '{domain}' НЕ истекает! (Вы можете использовать --force, если знаете, что делаете)", - "certmanager_cannot_read_cert": "При попытке открыть текущий сертификат для домена {домен} произошло что-то неправильное (файл: {file}), причина: {reason}", + "certmanager_cannot_read_cert": "При попытке открыть текущий сертификат для домена {domain} произошло что-то неправильное (файл: {file}), причина: {reason}", "certmanager_cert_install_success": "Сертификат Let's Encrypt для домена '{domain}' установлен", "certmanager_domain_cert_not_selfsigned": "Сертификат для домена {domain} не самоподписанный. Вы уверены, что хотите заменить его? (Для этого используйте '--force'.)", "certmanager_certificate_fetching_or_enabling_failed": "Попытка использовать новый сертификат для {domain} не сработала...", @@ -168,7 +168,7 @@ "yunohost_not_installed": "YunoHost установлен неправильно. Пожалуйста, запустите 'yunohost tools postinstall'", "backup_cleaning_failed": "Не удалось очистить временную папку резервного копирования", "certmanager_attempt_to_replace_valid_cert": "Вы пытаетесь перезаписать хороший и действительный сертификат для домена {domain}! (Используйте --force для обхода)", - "backup_create_size_estimation": "Архив будет содержать около {размер} данных.", + "backup_create_size_estimation": "Архив будет содержать около {size} данных.", "diagnosis_description_regenconf": "Конфигурации системы", "diagnosis_description_services": "Проверка статусов сервисов", "config_validate_color": "Должен быть правильный hex цвета RGB", @@ -189,4 +189,4 @@ "backup_with_no_restore_script_for_app": "{app} не имеет сценария восстановления, вы не сможете автоматически восстановить это приложение из резервной копии.", "diagnosis_description_ports": "Открытые порты", "diagnosis_basesystem_hardware_model": "Модель сервера {model}" -} +} \ No newline at end of file diff --git a/locales/uk.json b/locales/uk.json index 25fa1d551..e997d6bf4 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -718,4 +718,4 @@ "migration_0021_system_not_fully_up_to_date": "Ваша система не повністю оновлена. Будь ласка, виконайте регулярне оновлення перед запуском міграції на Bullseye.", "migration_0021_general_warning": "Будь ласка, зверніть увагу, що ця міграція є делікатною операцією. Команда YunoHost зробила все можливе, щоб перевірити і протестувати її, але міграція все ще може порушити частину системи або її застосунків.\n\nТому рекомендовано:\n - Виконати резервне копіювання всіх важливих даних або застосунків. Подробиці на сайті https://yunohost.org/backup; \n - Наберіться терпіння після запуску міграції: В залежності від вашого з'єднання з Інтернетом і апаратного забезпечення, оновлення може зайняти до декількох годин.", "migration_description_0021_migrate_to_bullseye": "Оновлення системи до Debian Bullseye і YunoHost 11.x" -} +} \ No newline at end of file From 76abbf03d75c20705f85157b86ea18b45dda10f7 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 29 Dec 2021 00:35:42 +0100 Subject: [PATCH 38/51] diagnosis: bump treshold for suspiciously high number of auth failure because too many people getting report about it idk --- data/hooks/diagnosis/00-basesystem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/hooks/diagnosis/00-basesystem.py b/data/hooks/diagnosis/00-basesystem.py index b472a2d32..d003c2670 100644 --- a/data/hooks/diagnosis/00-basesystem.py +++ b/data/hooks/diagnosis/00-basesystem.py @@ -133,7 +133,7 @@ class BaseSystemDiagnoser(Diagnoser): summary="diagnosis_backports_in_sources_list", ) - if self.number_of_recent_auth_failure() > 500: + if self.number_of_recent_auth_failure() > 750: yield dict( meta={"test": "high_number_auth_failure"}, status="WARNING", From 76b9838bfd2c1e2871d74fa1bdcb307c79928c6f Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 29 Dec 2021 01:06:45 +0100 Subject: [PATCH 39/51] Tmp removal of bullseye migration for small release --- .../0021_migrate_to_bullseye.py | 320 ------------------ 1 file changed, 320 deletions(-) delete mode 100644 src/yunohost/data_migrations/0021_migrate_to_bullseye.py diff --git a/src/yunohost/data_migrations/0021_migrate_to_bullseye.py b/src/yunohost/data_migrations/0021_migrate_to_bullseye.py deleted file mode 100644 index f97ab16da..000000000 --- a/src/yunohost/data_migrations/0021_migrate_to_bullseye.py +++ /dev/null @@ -1,320 +0,0 @@ -import glob -import os - -from moulinette import m18n -from yunohost.utils.error import YunohostError -from moulinette.utils.log import getActionLogger -from moulinette.utils.process import check_output, call_async_output -from moulinette.utils.filesystem import read_file, rm - -from yunohost.tools import Migration, tools_update, tools_upgrade -from yunohost.app import unstable_apps -from yunohost.regenconf import manually_modified_files, _force_clear_hashes -from yunohost.utils.filesystem import free_space_in_directory -from yunohost.utils.packages import ( - get_ynh_package_version, - _list_upgradable_apt_packages, -) -from yunohost.service import _get_services, _save_services - -logger = getActionLogger("yunohost.migration") - -N_CURRENT_DEBIAN = 10 -N_CURRENT_YUNOHOST = 4 - -N_NEXT_DEBAN = 11 -N_NEXT_YUNOHOST = 11 - - -class MyMigration(Migration): - - "Upgrade the system to Debian Bullseye and Yunohost 11.x" - - mode = "manual" - - def run(self): - - self.check_assertions() - - logger.info(m18n.n("migration_0021_start")) - - # - # Add new apt .deb signing key - # - - new_apt_key = "https://forge.yunohost.org/yunohost_bullseye.asc" - check_output(f"wget -O- {new_apt_key} -q | apt-key add -qq -") - - # - # Patch sources.list - # - logger.info(m18n.n("migration_0021_patching_sources_list")) - self.patch_apt_sources_list() - tools_update(target="system") - - # Tell libc6 it's okay to restart system stuff during the upgrade - os.system( - "echo 'libc6 libraries/restart-without-asking boolean true' | debconf-set-selections" - ) - - # Don't send an email to root about the postgresql migration. It should be handled automatically after. - os.system( - "echo 'postgresql-common postgresql-common/obsolete-major seen true' | debconf-set-selections" - ) - - # - # Patch yunohost conflicts - # - logger.info(m18n.n("migration_0021_patch_yunohost_conflicts")) - - self.patch_yunohost_conflicts() - - # - # Specific tweaking to get rid of custom my.cnf and use debian's default one - # (my.cnf is actually a symlink to mariadb.cnf) - # - - _force_clear_hashes(["/etc/mysql/my.cnf"]) - rm("/etc/mysql/mariadb.cnf", force=True) - rm("/etc/mysql/my.cnf", force=True) - self.apt_install( - "mariadb-common --reinstall -o Dpkg::Options::='--force-confmiss'" - ) - - # - # /usr/share/yunohost/yunohost-config/ssl/yunoCA -> /usr/share/yunohost/ssl - # - if os.path.exists("/usr/share/yunohost/yunohost-config/ssl/yunoCA"): - os.system( - "mv /usr/share/yunohost/yunohost-config/ssl/yunoCA /usr/share/yunohost/ssl" - ) - rm("/usr/share/yunohost/yunohost-config", recursive=True, force=True) - - # - # /home/yunohost.conf -> /var/cache/yunohost/regenconf - # - if os.path.exists("/home/yunohost.conf"): - os.system("mv /home/yunohost.conf /var/cache/yunohost/regenconf") - rm("/home/yunohost.conf", recursive=True, force=True) - - # - # Main upgrade - # - logger.info(m18n.n("migration_0021_main_upgrade")) - - apps_packages = self.get_apps_equivs_packages() - self.hold(apps_packages) - tools_upgrade(target="system", allow_yunohost_upgrade=False) - - if self.debian_major_version() == N_CURRENT_DEBIAN: - raise YunohostError("migration_0021_still_on_buster_after_main_upgrade") - - # Clean the mess - logger.info(m18n.n("migration_0021_cleaning_up")) - os.system("apt autoremove --assume-yes") - os.system("apt clean --assume-yes") - - # Force add sury if it's not there yet - # This is to solve some weird issue with php-common breaking php7.3-common, - # hence breaking many php7.3-deps - # hence triggering some dependency conflict (or foobar-ynh-deps uninstall) - # Adding it there shouldnt be a big deal - Yunohost 11.x does add it - # through its regen conf anyway. - if not os.path.exists("/etc/apt/sources.list.d/extra_php_version.list"): - open("/etc/apt/sources.list.d/extra_php_version.list", "w").write( - "deb https://packages.sury.org/php/ bullseye main" - ) - os.system( - 'wget --timeout 900 --quiet "https://packages.sury.org/php/apt.gpg" --output-document=- | gpg --dearmor >"/etc/apt/trusted.gpg.d/extra_php_version.gpg"' - ) - - os.system("apt update") - - # Force explicit install of php7.4-fpm to make sure it's ll be there - # during 0022_php73_to_php74_pools migration - self.apt_install("php7.4-fpm -o Dpkg::Options::='--force-confmiss'") - - # Remove legacy postgresql service record added by helpers, - # will now be dynamically handled by the core in bullseye - services = _get_services() - if "postgresql" in services: - del services["postgresql"] - _save_services(services) - - # - # Yunohost upgrade - # - logger.info(m18n.n("migration_0021_yunohost_upgrade")) - self.unhold(apps_packages) - tools_upgrade(target="system") - - def debian_major_version(self): - # The python module "platform" and lsb_release are not reliable because - # on some setup, they may still return Release=9 even after upgrading to - # buster ... (Apparently this is related to OVH overriding some stuff - # with /etc/lsb-release for instance -_-) - # Instead, we rely on /etc/os-release which should be the raw info from - # the distribution... - return int( - check_output( - "grep VERSION_ID /etc/os-release | head -n 1 | tr '\"' ' ' | cut -d ' ' -f2" - ) - ) - - def yunohost_major_version(self): - return int(get_ynh_package_version("yunohost")["version"].split(".")[0]) - - def check_assertions(self): - - # Be on buster (10.x) and yunohost 4.x - # NB : we do both check to cover situations where the upgrade crashed - # in the middle and debian version could be > 9.x but yunohost package - # would still be in 3.x... - if ( - not self.debian_major_version() == N_CURRENT_DEBIAN - and not self.yunohost_major_version() == N_CURRENT_YUNOHOST - ): - raise YunohostError("migration_0021_not_buster") - - # Have > 1 Go free space on /var/ ? - if free_space_in_directory("/var/") / (1024 ** 3) < 1.0: - raise YunohostError("migration_0021_not_enough_free_space") - - # Check system is up to date - # (but we don't if 'bullseye' is already in the sources.list ... - # which means maybe a previous upgrade crashed and we're re-running it) - if " bullseye " not in read_file("/etc/apt/sources.list"): - tools_update(target="system") - upgradable_system_packages = list(_list_upgradable_apt_packages()) - if upgradable_system_packages: - raise YunohostError("migration_0021_system_not_fully_up_to_date") - - @property - def disclaimer(self): - - # Avoid having a super long disclaimer + uncessary check if we ain't - # on buster / yunohost 4.x anymore - # NB : we do both check to cover situations where the upgrade crashed - # in the middle and debian version could be >= 10.x but yunohost package - # would still be in 4.x... - if ( - not self.debian_major_version() == N_CURRENT_DEBIAN - and not self.yunohost_major_version() == N_CURRENT_YUNOHOST - ): - return None - - # Get list of problematic apps ? I.e. not official or community+working - problematic_apps = unstable_apps() - problematic_apps = "".join(["\n - " + app for app in problematic_apps]) - - # Manually modified files ? (c.f. yunohost service regen-conf) - modified_files = manually_modified_files() - modified_files = "".join(["\n - " + f for f in modified_files]) - - message = m18n.n("migration_0021_general_warning") - - # FIXME: re-enable this message with updated topic link once we release the migration as stable - # message = ( - # "N.B.: This migration has been tested by the community over the last few months but has only been declared stable recently. If your server hosts critical services and if you are not too confident with debugging possible issues, we recommend you to wait a little bit more while we gather more feedback and polish things up. If on the other hand you are relatively confident with debugging small issues that may arise, you are encouraged to run this migration ;)! You can read about remaining known issues and feedback from the community here: https://forum.yunohost.org/t/12195\n\n" - # + message - # ) - - if problematic_apps: - message += "\n\n" + m18n.n( - "migration_0021_problematic_apps_warning", - problematic_apps=problematic_apps, - ) - - if modified_files: - message += "\n\n" + m18n.n( - "migration_0021_modified_files", manually_modified_files=modified_files - ) - - return message - - def patch_apt_sources_list(self): - - sources_list = glob.glob("/etc/apt/sources.list.d/*.list") - sources_list.append("/etc/apt/sources.list") - - # This : - # - replace single 'buster' occurence by 'bulleye' - # - comments lines containing "backports" - # - replace 'buster/updates' by 'bullseye/updates' (or same with -) - # Special note about the security suite: - # https://www.debian.org/releases/bullseye/amd64/release-notes/ch-information.en.html#security-archive - for f in sources_list: - command = ( - f"sed -i {f} " - "-e 's@ buster @ bullseye @g' " - "-e '/backports/ s@^#*@#@' " - "-e 's@ buster/updates @ bullseye-security @g' " - "-e 's@ buster-@ bullseye-@g' " - ) - os.system(command) - - def get_apps_equivs_packages(self): - - command = ( - "dpkg --get-selections" - " | grep -v deinstall" - " | awk '{print $1}'" - " | { grep 'ynh-deps$' || true; }" - ) - - output = check_output(command) - - return output.split("\n") if output else [] - - def hold(self, packages): - for package in packages: - os.system("apt-mark hold {}".format(package)) - - def unhold(self, packages): - for package in packages: - os.system("apt-mark unhold {}".format(package)) - - def apt_install(self, cmd): - def is_relevant(line): - return "Reading database ..." not in line.rstrip() - - callbacks = ( - lambda l: logger.info("+ " + l.rstrip() + "\r") - if is_relevant(l) - else logger.debug(l.rstrip() + "\r"), - lambda l: logger.warning(l.rstrip()), - ) - - cmd = ( - "LC_ALL=C DEBIAN_FRONTEND=noninteractive APT_LISTCHANGES_FRONTEND=none apt install --quiet -o=Dpkg::Use-Pty=0 --fix-broken --assume-yes " - + cmd - ) - - logger.debug("Running: %s" % cmd) - - call_async_output(cmd, callbacks, shell=True) - - def patch_yunohost_conflicts(self): - # - # This is a super dirty hack to remove the conflicts from yunohost's debian/control file - # Those conflicts are there to prevent mistakenly upgrading critical packages - # such as dovecot, postfix, nginx, openssl, etc... usually related to mistakenly - # using backports etc. - # - # The hack consists in savagely removing the conflicts directly in /var/lib/dpkg/status - # - - # We only patch the conflict if we're on yunohost 4.x - if self.yunohost_major_version() != N_CURRENT_YUNOHOST: - return - - conflicts = check_output("dpkg-query -s yunohost | grep '^Conflicts:'").strip() - if conflicts: - # We want to keep conflicting with apache/bind9 tho - new_conflicts = "Conflicts: apache2, bind9" - - command = ( - f"sed -i /var/lib/dpkg/status -e 's@{conflicts}@{new_conflicts}@g'" - ) - logger.debug(f"Running: {command}") - os.system(command) From 509ba1e8a28e0be598aa0617eda06669b7b0f1d8 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 29 Dec 2021 01:07:09 +0100 Subject: [PATCH 40/51] Update changelog for 4.3.5 --- debian/changelog | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/debian/changelog b/debian/changelog index 001ab678a..49227f946 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,19 @@ +yunohost (4.3.5) stable; urgency=low + + - [fix] backup: bug in backup_delete when compress_tar_archives is True ([#1381](https://github.com/YunoHost/yunohost/pull/1381)) + - [fix] helpers logrorate: remove permission tweak .. code was not working as expected. To be re-addressed some day ... (0fc209ac) + - [fix] i18n: consistency for deprecation for --apps in 'yunohost tools update/upgrade' ([#1392](https://github.com/YunoHost/yunohost/pull/1392)) + - [fix] apps: typo when deleting superfluous question keys ([#1393](https://github.com/YunoHost/yunohost/pull/1393)) + - [fix] diagnosis: typo in dns record diagnoser (a615528c) + - [fix] diagnosis: tweak treshold for suspiciously high number of auth failure because too many people getting report about it idk (76abbf03) + - [enh] quality: apply pyupgrade ([#1395](https://github.com/YunoHost/yunohost/pull/1395)) + - [enh] quality: add lgtm/code quality badge ([#1396](https://github.com/YunoHost/yunohost/pull/1396)) + - [i18n] Translations updated for Dutch, French, Galician, German, Indonesian, Russian, Spanish, Ukrainian + + Thanks to all contributors <3 ! (Boudewijn, Bram, Christian Wehrli, Colin Wawrik, Éric Gaspar, Ilya, José M, Juan Alberto González, Kay0u, liimee, Moutonjr Geoff, tituspijean, Tymofii Lytvynenko, Valentin von Guttenberg) + + -- Alexandre Aubin Wed, 29 Dec 2021 01:01:33 +0100 + yunohost (4.3.4.2) stable; urgency=low - [fix] yunomdns: Ignore ipv4 link-local addresses (6854f23c) From 2f38639a2ed61c7b1195fc3f9cf7a1dfee84c60c Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 29 Dec 2021 01:07:34 +0100 Subject: [PATCH 41/51] Revert "Tmp removal of bullseye migration for small release" This reverts commit 76b9838bfd2c1e2871d74fa1bdcb307c79928c6f. --- .../0021_migrate_to_bullseye.py | 320 ++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 src/yunohost/data_migrations/0021_migrate_to_bullseye.py diff --git a/src/yunohost/data_migrations/0021_migrate_to_bullseye.py b/src/yunohost/data_migrations/0021_migrate_to_bullseye.py new file mode 100644 index 000000000..f97ab16da --- /dev/null +++ b/src/yunohost/data_migrations/0021_migrate_to_bullseye.py @@ -0,0 +1,320 @@ +import glob +import os + +from moulinette import m18n +from yunohost.utils.error import YunohostError +from moulinette.utils.log import getActionLogger +from moulinette.utils.process import check_output, call_async_output +from moulinette.utils.filesystem import read_file, rm + +from yunohost.tools import Migration, tools_update, tools_upgrade +from yunohost.app import unstable_apps +from yunohost.regenconf import manually_modified_files, _force_clear_hashes +from yunohost.utils.filesystem import free_space_in_directory +from yunohost.utils.packages import ( + get_ynh_package_version, + _list_upgradable_apt_packages, +) +from yunohost.service import _get_services, _save_services + +logger = getActionLogger("yunohost.migration") + +N_CURRENT_DEBIAN = 10 +N_CURRENT_YUNOHOST = 4 + +N_NEXT_DEBAN = 11 +N_NEXT_YUNOHOST = 11 + + +class MyMigration(Migration): + + "Upgrade the system to Debian Bullseye and Yunohost 11.x" + + mode = "manual" + + def run(self): + + self.check_assertions() + + logger.info(m18n.n("migration_0021_start")) + + # + # Add new apt .deb signing key + # + + new_apt_key = "https://forge.yunohost.org/yunohost_bullseye.asc" + check_output(f"wget -O- {new_apt_key} -q | apt-key add -qq -") + + # + # Patch sources.list + # + logger.info(m18n.n("migration_0021_patching_sources_list")) + self.patch_apt_sources_list() + tools_update(target="system") + + # Tell libc6 it's okay to restart system stuff during the upgrade + os.system( + "echo 'libc6 libraries/restart-without-asking boolean true' | debconf-set-selections" + ) + + # Don't send an email to root about the postgresql migration. It should be handled automatically after. + os.system( + "echo 'postgresql-common postgresql-common/obsolete-major seen true' | debconf-set-selections" + ) + + # + # Patch yunohost conflicts + # + logger.info(m18n.n("migration_0021_patch_yunohost_conflicts")) + + self.patch_yunohost_conflicts() + + # + # Specific tweaking to get rid of custom my.cnf and use debian's default one + # (my.cnf is actually a symlink to mariadb.cnf) + # + + _force_clear_hashes(["/etc/mysql/my.cnf"]) + rm("/etc/mysql/mariadb.cnf", force=True) + rm("/etc/mysql/my.cnf", force=True) + self.apt_install( + "mariadb-common --reinstall -o Dpkg::Options::='--force-confmiss'" + ) + + # + # /usr/share/yunohost/yunohost-config/ssl/yunoCA -> /usr/share/yunohost/ssl + # + if os.path.exists("/usr/share/yunohost/yunohost-config/ssl/yunoCA"): + os.system( + "mv /usr/share/yunohost/yunohost-config/ssl/yunoCA /usr/share/yunohost/ssl" + ) + rm("/usr/share/yunohost/yunohost-config", recursive=True, force=True) + + # + # /home/yunohost.conf -> /var/cache/yunohost/regenconf + # + if os.path.exists("/home/yunohost.conf"): + os.system("mv /home/yunohost.conf /var/cache/yunohost/regenconf") + rm("/home/yunohost.conf", recursive=True, force=True) + + # + # Main upgrade + # + logger.info(m18n.n("migration_0021_main_upgrade")) + + apps_packages = self.get_apps_equivs_packages() + self.hold(apps_packages) + tools_upgrade(target="system", allow_yunohost_upgrade=False) + + if self.debian_major_version() == N_CURRENT_DEBIAN: + raise YunohostError("migration_0021_still_on_buster_after_main_upgrade") + + # Clean the mess + logger.info(m18n.n("migration_0021_cleaning_up")) + os.system("apt autoremove --assume-yes") + os.system("apt clean --assume-yes") + + # Force add sury if it's not there yet + # This is to solve some weird issue with php-common breaking php7.3-common, + # hence breaking many php7.3-deps + # hence triggering some dependency conflict (or foobar-ynh-deps uninstall) + # Adding it there shouldnt be a big deal - Yunohost 11.x does add it + # through its regen conf anyway. + if not os.path.exists("/etc/apt/sources.list.d/extra_php_version.list"): + open("/etc/apt/sources.list.d/extra_php_version.list", "w").write( + "deb https://packages.sury.org/php/ bullseye main" + ) + os.system( + 'wget --timeout 900 --quiet "https://packages.sury.org/php/apt.gpg" --output-document=- | gpg --dearmor >"/etc/apt/trusted.gpg.d/extra_php_version.gpg"' + ) + + os.system("apt update") + + # Force explicit install of php7.4-fpm to make sure it's ll be there + # during 0022_php73_to_php74_pools migration + self.apt_install("php7.4-fpm -o Dpkg::Options::='--force-confmiss'") + + # Remove legacy postgresql service record added by helpers, + # will now be dynamically handled by the core in bullseye + services = _get_services() + if "postgresql" in services: + del services["postgresql"] + _save_services(services) + + # + # Yunohost upgrade + # + logger.info(m18n.n("migration_0021_yunohost_upgrade")) + self.unhold(apps_packages) + tools_upgrade(target="system") + + def debian_major_version(self): + # The python module "platform" and lsb_release are not reliable because + # on some setup, they may still return Release=9 even after upgrading to + # buster ... (Apparently this is related to OVH overriding some stuff + # with /etc/lsb-release for instance -_-) + # Instead, we rely on /etc/os-release which should be the raw info from + # the distribution... + return int( + check_output( + "grep VERSION_ID /etc/os-release | head -n 1 | tr '\"' ' ' | cut -d ' ' -f2" + ) + ) + + def yunohost_major_version(self): + return int(get_ynh_package_version("yunohost")["version"].split(".")[0]) + + def check_assertions(self): + + # Be on buster (10.x) and yunohost 4.x + # NB : we do both check to cover situations where the upgrade crashed + # in the middle and debian version could be > 9.x but yunohost package + # would still be in 3.x... + if ( + not self.debian_major_version() == N_CURRENT_DEBIAN + and not self.yunohost_major_version() == N_CURRENT_YUNOHOST + ): + raise YunohostError("migration_0021_not_buster") + + # Have > 1 Go free space on /var/ ? + if free_space_in_directory("/var/") / (1024 ** 3) < 1.0: + raise YunohostError("migration_0021_not_enough_free_space") + + # Check system is up to date + # (but we don't if 'bullseye' is already in the sources.list ... + # which means maybe a previous upgrade crashed and we're re-running it) + if " bullseye " not in read_file("/etc/apt/sources.list"): + tools_update(target="system") + upgradable_system_packages = list(_list_upgradable_apt_packages()) + if upgradable_system_packages: + raise YunohostError("migration_0021_system_not_fully_up_to_date") + + @property + def disclaimer(self): + + # Avoid having a super long disclaimer + uncessary check if we ain't + # on buster / yunohost 4.x anymore + # NB : we do both check to cover situations where the upgrade crashed + # in the middle and debian version could be >= 10.x but yunohost package + # would still be in 4.x... + if ( + not self.debian_major_version() == N_CURRENT_DEBIAN + and not self.yunohost_major_version() == N_CURRENT_YUNOHOST + ): + return None + + # Get list of problematic apps ? I.e. not official or community+working + problematic_apps = unstable_apps() + problematic_apps = "".join(["\n - " + app for app in problematic_apps]) + + # Manually modified files ? (c.f. yunohost service regen-conf) + modified_files = manually_modified_files() + modified_files = "".join(["\n - " + f for f in modified_files]) + + message = m18n.n("migration_0021_general_warning") + + # FIXME: re-enable this message with updated topic link once we release the migration as stable + # message = ( + # "N.B.: This migration has been tested by the community over the last few months but has only been declared stable recently. If your server hosts critical services and if you are not too confident with debugging possible issues, we recommend you to wait a little bit more while we gather more feedback and polish things up. If on the other hand you are relatively confident with debugging small issues that may arise, you are encouraged to run this migration ;)! You can read about remaining known issues and feedback from the community here: https://forum.yunohost.org/t/12195\n\n" + # + message + # ) + + if problematic_apps: + message += "\n\n" + m18n.n( + "migration_0021_problematic_apps_warning", + problematic_apps=problematic_apps, + ) + + if modified_files: + message += "\n\n" + m18n.n( + "migration_0021_modified_files", manually_modified_files=modified_files + ) + + return message + + def patch_apt_sources_list(self): + + sources_list = glob.glob("/etc/apt/sources.list.d/*.list") + sources_list.append("/etc/apt/sources.list") + + # This : + # - replace single 'buster' occurence by 'bulleye' + # - comments lines containing "backports" + # - replace 'buster/updates' by 'bullseye/updates' (or same with -) + # Special note about the security suite: + # https://www.debian.org/releases/bullseye/amd64/release-notes/ch-information.en.html#security-archive + for f in sources_list: + command = ( + f"sed -i {f} " + "-e 's@ buster @ bullseye @g' " + "-e '/backports/ s@^#*@#@' " + "-e 's@ buster/updates @ bullseye-security @g' " + "-e 's@ buster-@ bullseye-@g' " + ) + os.system(command) + + def get_apps_equivs_packages(self): + + command = ( + "dpkg --get-selections" + " | grep -v deinstall" + " | awk '{print $1}'" + " | { grep 'ynh-deps$' || true; }" + ) + + output = check_output(command) + + return output.split("\n") if output else [] + + def hold(self, packages): + for package in packages: + os.system("apt-mark hold {}".format(package)) + + def unhold(self, packages): + for package in packages: + os.system("apt-mark unhold {}".format(package)) + + def apt_install(self, cmd): + def is_relevant(line): + return "Reading database ..." not in line.rstrip() + + callbacks = ( + lambda l: logger.info("+ " + l.rstrip() + "\r") + if is_relevant(l) + else logger.debug(l.rstrip() + "\r"), + lambda l: logger.warning(l.rstrip()), + ) + + cmd = ( + "LC_ALL=C DEBIAN_FRONTEND=noninteractive APT_LISTCHANGES_FRONTEND=none apt install --quiet -o=Dpkg::Use-Pty=0 --fix-broken --assume-yes " + + cmd + ) + + logger.debug("Running: %s" % cmd) + + call_async_output(cmd, callbacks, shell=True) + + def patch_yunohost_conflicts(self): + # + # This is a super dirty hack to remove the conflicts from yunohost's debian/control file + # Those conflicts are there to prevent mistakenly upgrading critical packages + # such as dovecot, postfix, nginx, openssl, etc... usually related to mistakenly + # using backports etc. + # + # The hack consists in savagely removing the conflicts directly in /var/lib/dpkg/status + # + + # We only patch the conflict if we're on yunohost 4.x + if self.yunohost_major_version() != N_CURRENT_YUNOHOST: + return + + conflicts = check_output("dpkg-query -s yunohost | grep '^Conflicts:'").strip() + if conflicts: + # We want to keep conflicting with apache/bind9 tho + new_conflicts = "Conflicts: apache2, bind9" + + command = ( + f"sed -i /var/lib/dpkg/status -e 's@{conflicts}@{new_conflicts}@g'" + ) + logger.debug(f"Running: {command}") + os.system(command) From 94bf107838ee97fd2a544a1036c6410daa6a89e4 Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Wed, 29 Dec 2021 00:44:22 +0000 Subject: [PATCH 42/51] [CI] Format code with Black --- data/hooks/diagnosis/00-basesystem.py | 4 +++- src/yunohost/dyndns.py | 4 +--- src/yunohost/permission.py | 6 +++--- src/yunohost/tests/test_permission.py | 4 +--- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/data/hooks/diagnosis/00-basesystem.py b/data/hooks/diagnosis/00-basesystem.py index a60070b5a..e30efc7fc 100644 --- a/data/hooks/diagnosis/00-basesystem.py +++ b/data/hooks/diagnosis/00-basesystem.py @@ -42,7 +42,9 @@ class BaseSystemDiagnoser(Diagnoser): elif os.path.exists("/sys/devices/virtual/dmi/id/sys_vendor"): model = read_file("/sys/devices/virtual/dmi/id/sys_vendor").strip() if os.path.exists("/sys/devices/virtual/dmi/id/product_name"): - product_name = read_file("/sys/devices/virtual/dmi/id/product_name").strip() + product_name = read_file( + "/sys/devices/virtual/dmi/id/product_name" + ).strip() model = f"{model} {product_name}" hardware["data"]["model"] = model hardware["details"] = ["diagnosis_basesystem_hardware_model"] diff --git a/src/yunohost/dyndns.py b/src/yunohost/dyndns.py index 8748c1c00..ebf04c008 100644 --- a/src/yunohost/dyndns.py +++ b/src/yunohost/dyndns.py @@ -262,9 +262,7 @@ def dyndns_update( else: return None - raise YunohostError( - f"Failed to resolve {rdtype} for {domain}", raw_msg=True - ) + raise YunohostError(f"Failed to resolve {rdtype} for {domain}", raw_msg=True) old_ipv4 = resolve_domain(domain, "A") old_ipv6 = resolve_domain(domain, "AAAA") diff --git a/src/yunohost/permission.py b/src/yunohost/permission.py index 9a46cad27..e87715e63 100644 --- a/src/yunohost/permission.py +++ b/src/yunohost/permission.py @@ -666,9 +666,9 @@ def permission_sync_to_user(): # These are the users that should be allowed because they are member of a group that is allowed for this permission ... should_be_allowed_users = { - user - for group in permission_infos["allowed"] - for user in groups[group]["members"] + user + for group in permission_infos["allowed"] + for user in groups[group]["members"] } # Note that a LDAP operation with the same value that is in LDAP crash SLAP. diff --git a/src/yunohost/tests/test_permission.py b/src/yunohost/tests/test_permission.py index 01b62f2a8..9c059f0e4 100644 --- a/src/yunohost/tests/test_permission.py +++ b/src/yunohost/tests/test_permission.py @@ -1013,9 +1013,7 @@ def test_permission_app_install(): assert res["permissions_app.dev"]["url"] == "/dev" assert res["permissions_app.main"]["allowed"] == ["all_users"] - assert set(res["permissions_app.main"]["corresponding_users"]) == { - "alice", "bob" - } + assert set(res["permissions_app.main"]["corresponding_users"]) == {"alice", "bob"} assert res["permissions_app.admin"]["allowed"] == ["alice"] assert res["permissions_app.admin"]["corresponding_users"] == ["alice"] From de149975d2c235fe29beba1eee4108d5c9f5532d Mon Sep 17 00:00:00 2001 From: Kay0u Date: Wed, 29 Dec 2021 22:40:54 +0100 Subject: [PATCH 43/51] Remove unused variable --- data/hooks/diagnosis/12-dnsrecords.py | 1 - 1 file changed, 1 deletion(-) diff --git a/data/hooks/diagnosis/12-dnsrecords.py b/data/hooks/diagnosis/12-dnsrecords.py index cedd3891e..554576f79 100644 --- a/data/hooks/diagnosis/12-dnsrecords.py +++ b/data/hooks/diagnosis/12-dnsrecords.py @@ -56,7 +56,6 @@ class DNSRecordsDiagnoser(Diagnoser): def check_domain(self, domain, is_main_domain): if is_special_use_tld(domain): - categories = [] yield dict( meta={"domain": domain}, data={}, From f92c88aff7abdd9812a32592e0dd7fa052937b58 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Wed, 29 Dec 2021 22:41:57 +0100 Subject: [PATCH 44/51] remove unused lines --- src/yunohost/app.py | 1 - src/yunohost/dns.py | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index d5e57d6cf..bf41f163d 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -1033,7 +1033,6 @@ def app_remove(operation_logger, app, purge=False): remove_script = f"{tmp_workdir_for_app}/scripts/remove" env_dict = {} - app_id, app_instance_nb = _parse_app_instance_name(app) env_dict = _make_environment_for_app_script(app, workdir=tmp_workdir_for_app) env_dict["YNH_APP_PURGE"] = str(1 if purge else 0) diff --git a/src/yunohost/dns.py b/src/yunohost/dns.py index 23c641a35..492b285c0 100644 --- a/src/yunohost/dns.py +++ b/src/yunohost/dns.py @@ -857,7 +857,6 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge= ignored = "" if action == "create": - old_content = record.get("old_content", "(None)")[:30] new_content = record.get("content", "(None)")[:30] return f"{name:>20} [{t:^5}] {new_content:^30} {ignored}" elif action == "update": @@ -867,7 +866,7 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge= f"{name:>20} [{t:^5}] {old_content:^30} -> {new_content:^30} {ignored}" ) elif action == "unchanged": - old_content = new_content = record.get("content", "(None)")[:30] + old_content = record.get("content", "(None)")[:30] return f"{name:>20} [{t:^5}] {old_content:^30}" else: old_content = record.get("content", "(None)")[:30] From 2cc09aca91c97ae2bfbda9d224a93cd422b206ae Mon Sep 17 00:00:00 2001 From: Kay0u Date: Wed, 29 Dec 2021 22:45:25 +0100 Subject: [PATCH 45/51] some improvements --- .../0016_php70_to_php73_pools.py | 12 +++---- src/yunohost/service.py | 2 +- src/yunohost/tools.py | 34 ++++++++----------- 3 files changed, 22 insertions(+), 26 deletions(-) diff --git a/src/yunohost/data_migrations/0016_php70_to_php73_pools.py b/src/yunohost/data_migrations/0016_php70_to_php73_pools.py index fed96c9c8..570e63ea4 100644 --- a/src/yunohost/data_migrations/0016_php70_to_php73_pools.py +++ b/src/yunohost/data_migrations/0016_php70_to_php73_pools.py @@ -38,11 +38,11 @@ class MyMigration(Migration): # Ignore the "www.conf" (default stuff, probably don't want to touch it ?) php70_pool_files = [f for f in php70_pool_files if f != "www.conf"] - for f in php70_pool_files: + for pf in php70_pool_files: # Copy the files to the php7.3 pool - src = "{}/{}".format(PHP70_POOLS, f) - dest = "{}/{}".format(PHP73_POOLS, f) + src = "{}/{}".format(PHP70_POOLS, pf) + dest = "{}/{}".format(PHP73_POOLS, pf) copy2(src, dest) # Replace the socket prefix if it's found @@ -56,17 +56,17 @@ class MyMigration(Migration): c = "sed -i '1i {}' {}".format(MIGRATION_COMMENT, dest) os.system(c) - app_id = os.path.basename(f)[: -len(".conf")] + app_id = os.path.basename(pf)[: -len(".conf")] if _is_installed(app_id): _patch_legacy_php_versions_in_settings( "/etc/yunohost/apps/%s/" % app_id ) nginx_conf_files = glob.glob("/etc/nginx/conf.d/*.d/%s.conf" % app_id) - for f in nginx_conf_files: + for nf in nginx_conf_files: # Replace the socket prefix if it's found c = "sed -i -e 's@{}@{}@g' {}".format( - PHP70_SOCKETS_PREFIX, PHP73_SOCKETS_PREFIX, f + PHP70_SOCKETS_PREFIX, PHP73_SOCKETS_PREFIX, nf ) os.system(c) diff --git a/src/yunohost/service.py b/src/yunohost/service.py index 4f453dfe9..8a7b146b1 100644 --- a/src/yunohost/service.py +++ b/src/yunohost/service.py @@ -587,7 +587,7 @@ def service_regen_conf( if name not in services.keys(): raise YunohostValidationError("service_unknown", service=name) - if names is []: + if names == []: names = list(services.keys()) logger.warning(m18n.n("service_regen_conf_is_deprecated")) diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index 679b4d16e..a0411c69e 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -236,28 +236,24 @@ def tools_postinstall( # If this is a nohost.me/noho.st, actually check for availability if not ignore_dyndns and is_yunohost_dyndns_domain(domain): - # (Except if the user explicitly said he/she doesn't care about dyndns) - if ignore_dyndns: - dyndns = False # Check if the domain is available... - else: - try: - available = _dyndns_available(domain) - # If an exception is thrown, most likely we don't have internet - # connectivity or something. Assume that this domain isn't manageable - # and inform the user that we could not contact the dyndns host server. - except Exception: - logger.warning( - m18n.n( - "dyndns_provider_unreachable", provider="dyndns.yunohost.org" - ) + try: + available = _dyndns_available(domain) + # If an exception is thrown, most likely we don't have internet + # connectivity or something. Assume that this domain isn't manageable + # and inform the user that we could not contact the dyndns host server. + except Exception: + logger.warning( + m18n.n( + "dyndns_provider_unreachable", provider="dyndns.yunohost.org" ) + ) - if available: - dyndns = True - # If not, abort the postinstall - else: - raise YunohostValidationError("dyndns_unavailable", domain=domain) + if available: + dyndns = True + # If not, abort the postinstall + else: + raise YunohostValidationError("dyndns_unavailable", domain=domain) else: dyndns = False From bbe0486935615779925b4a11ba239395a095f33d Mon Sep 17 00:00:00 2001 From: Kay0u Date: Thu, 30 Dec 2021 00:08:49 +0100 Subject: [PATCH 46/51] Trying to fix some lgtm warnings --- src/yunohost/app.py | 7 ++- src/yunohost/certificate.py | 52 +++++++++---------- .../data_migrations/0018_xtable_to_nftable.py | 6 ++- src/yunohost/domain.py | 20 +++---- src/yunohost/regenconf.py | 5 +- src/yunohost/tools.py | 2 +- src/yunohost/user.py | 24 ++++----- src/yunohost/utils/config.py | 5 +- 8 files changed, 66 insertions(+), 55 deletions(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index bf41f163d..ca56be232 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -627,7 +627,7 @@ def app_upgrade(app=[], url=None, file=None, force=False, no_safety_backup=False if upgrade_failed or broke_the_system: # display this if there are remaining apps - if apps[number + 1 :]: + if apps[number + 1:]: not_upgraded_apps = apps[number:] logger.error( m18n.n( @@ -1626,9 +1626,12 @@ class AppConfigPanel(ConfigPanel): error=message, ) - def _call_config_script(self, action, env={}): + def _call_config_script(self, action, env=None): from yunohost.hook import hook_exec + if env is None: + env = {} + # Add default config script if needed config_script = os.path.join( APPS_SETTING_PATH, self.entity, "scripts", "config" diff --git a/src/yunohost/certificate.py b/src/yunohost/certificate.py index 79e3ae092..2f3676202 100644 --- a/src/yunohost/certificate.py +++ b/src/yunohost/certificate.py @@ -70,28 +70,28 @@ PRODUCTION_CERTIFICATION_AUTHORITY = "https://acme-v02.api.letsencrypt.org" # -def certificate_status(domain_list, full=False): +def certificate_status(domains, full=False): """ Print the status of certificate for given domains (all by default) Keyword argument: - domain_list -- Domains to be checked + domains -- Domains to be checked full -- Display more info about the certificates """ - import yunohost.domain + from yunohost.domain import domain_list, _assert_domain_exists # If no domains given, consider all yunohost domains - if domain_list == []: - domain_list = yunohost.domain.domain_list()["domains"] + if domains == []: + domains = domain_list()["domains"] # Else, validate that yunohost knows the domains given else: - for domain in domain_list: - yunohost.domain._assert_domain_exists(domain) + for domain in domains: + _assert_domain_exists(domain) certificates = {} - for domain in domain_list: + for domain in domains: status = _get_status(domain) if not full: @@ -239,28 +239,28 @@ def _certificate_install_selfsigned(domain_list, force=False): def _certificate_install_letsencrypt( - domain_list, force=False, no_checks=False, staging=False + domains, force=False, no_checks=False, staging=False ): - import yunohost.domain + from yunohost.domain import domain_list, _assert_domain_exists if not os.path.exists(ACCOUNT_KEY_FILE): _generate_account_key() # If no domains given, consider all yunohost domains with self-signed # certificates - if domain_list == []: - for domain in yunohost.domain.domain_list()["domains"]: + if domains == []: + for domain in domain_list()["domains"]: status = _get_status(domain) if status["CA_type"]["code"] != "self-signed": continue - domain_list.append(domain) + domains.append(domain) # Else, validate that yunohost knows the domains given else: - for domain in domain_list: - yunohost.domain._assert_domain_exists(domain) + for domain in domains: + _assert_domain_exists(domain) # Is it self-signed? status = _get_status(domain) @@ -275,7 +275,7 @@ def _certificate_install_letsencrypt( ) # Actual install steps - for domain in domain_list: + for domain in domains: if not no_checks: try: @@ -311,25 +311,25 @@ def _certificate_install_letsencrypt( def certificate_renew( - domain_list, force=False, no_checks=False, email=False, staging=False + domains, force=False, no_checks=False, email=False, staging=False ): """ Renew Let's Encrypt certificate for given domains (all by default) Keyword argument: - domain_list -- Domains for which to renew the certificates + domains -- Domains for which to renew the certificates force -- Ignore the validity threshold (15 days) no-check -- Disable some checks about the reachability of web server before attempting the renewing email -- Emails root if some renewing failed """ - import yunohost.domain + from yunohost.domain import domain_list, _assert_domain_exists # If no domains given, consider all yunohost domains with Let's Encrypt # certificates - if domain_list == []: - for domain in yunohost.domain.domain_list()["domains"]: + if domains == []: + for domain in domain_list()["domains"]: # Does it have a Let's Encrypt cert? status = _get_status(domain) @@ -347,17 +347,17 @@ def certificate_renew( ) continue - domain_list.append(domain) + domains.append(domain) - if len(domain_list) == 0 and not email: + if len(domains) == 0 and not email: logger.info("No certificate needs to be renewed.") # Else, validate the domain list given else: - for domain in domain_list: + for domain in domains: # Is it in Yunohost domain list? - yunohost.domain._assert_domain_exists(domain) + _assert_domain_exists(domain) status = _get_status(domain) @@ -385,7 +385,7 @@ def certificate_renew( ) # Actual renew steps - for domain in domain_list: + for domain in domains: if not no_checks: try: diff --git a/src/yunohost/data_migrations/0018_xtable_to_nftable.py b/src/yunohost/data_migrations/0018_xtable_to_nftable.py index 94b47d944..374620f2f 100644 --- a/src/yunohost/data_migrations/0018_xtable_to_nftable.py +++ b/src/yunohost/data_migrations/0018_xtable_to_nftable.py @@ -41,7 +41,8 @@ class MyMigration(Migration): ) # For some reason if we don't do this, iptables-legacy-save is empty ? self.runcmd("iptables-legacy-save > %s" % self.backup_rules_ipv4) assert ( - open(self.backup_rules_ipv4).read().strip() + os.path.exists(self.backup_rules_ipv4) and + os.stat(self.backup_rules_ipv4).st_size > 0 ), "Uhoh backup of legacy ipv4 rules is empty !?" if self.do_ipv6 and not os.path.exists(self.backup_rules_ipv6): self.runcmd( @@ -49,7 +50,8 @@ class MyMigration(Migration): ) # For some reason if we don't do this, iptables-legacy-save is empty ? self.runcmd("ip6tables-legacy-save > %s" % self.backup_rules_ipv6) assert ( - open(self.backup_rules_ipv6).read().strip() + os.path.exists(self.backup_rules_ipv6) and + os.stat(self.backup_rules_ipv6).st_size > 0 ), "Uhoh backup of legacy ipv6 rules is empty !?" # We inject the legacy rules (iptables-legacy) into the new iptable (just "iptables") diff --git a/src/yunohost/domain.py b/src/yunohost/domain.py index 0bd84ea82..d1ea45a08 100644 --- a/src/yunohost/domain.py +++ b/src/yunohost/domain.py @@ -507,17 +507,17 @@ def _set_domain_settings(domain: str, settings: dict) -> None: def domain_cert_status(domain_list, full=False): - import yunohost.certificate + from yunohost.certificate import certificate_status - return yunohost.certificate.certificate_status(domain_list, full) + return certificate_status(domain_list, full) def domain_cert_install( domain_list, force=False, no_checks=False, self_signed=False, staging=False ): - import yunohost.certificate + from yunohost.certificate import certificate_install - return yunohost.certificate.certificate_install( + return certificate_install( domain_list, force, no_checks, self_signed, staging ) @@ -525,9 +525,9 @@ def domain_cert_install( def domain_cert_renew( domain_list, force=False, no_checks=False, email=False, staging=False ): - import yunohost.certificate + from yunohost.certificate import certificate_renew - return yunohost.certificate.certificate_renew( + return certificate_renew( domain_list, force, no_checks, email, staging ) @@ -537,12 +537,12 @@ def domain_dns_conf(domain): def domain_dns_suggest(domain): - import yunohost.dns + from yunohost.dns import domain_dns_suggest - return yunohost.dns.domain_dns_suggest(domain) + return domain_dns_suggest(domain) def domain_dns_push(domain, dry_run, force, purge): - import yunohost.dns + from yunohost.dns import domain_dns_push - return yunohost.dns.domain_dns_push(domain, dry_run, force, purge) + return domain_dns_push(domain, dry_run, force, purge) diff --git a/src/yunohost/regenconf.py b/src/yunohost/regenconf.py index adec5508d..4b697cd84 100644 --- a/src/yunohost/regenconf.py +++ b/src/yunohost/regenconf.py @@ -48,7 +48,7 @@ logger = log.getActionLogger("yunohost.regenconf") @is_unit_operation([("names", "configuration")]) def regen_conf( operation_logger, - names=[], + names=None, with_diff=False, force=False, dry_run=False, @@ -66,6 +66,9 @@ def regen_conf( """ + if names is None: + names = [] + result = {} # Return the list of pending conf diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index a0411c69e..6dd4032e9 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -1130,7 +1130,7 @@ class Migration: def description(self): return m18n.n("migration_description_%s" % self.id) - def ldap_migration(run): + def ldap_migration(self, run): def func(self): # Backup LDAP before the migration diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 78fda8d09..a27fffbee 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -1263,25 +1263,25 @@ def user_group_remove(groupname, usernames, force=False, sync_perm=True): def user_permission_list(short=False, full=False, apps=[]): - import yunohost.permission + from yunohost.permission import user_permission_list - return yunohost.permission.user_permission_list( + return user_permission_list( short, full, absolute_urls=True, apps=apps ) def user_permission_update(permission, label=None, show_tile=None, sync_perm=True): - import yunohost.permission + from yunohost.permission import user_permission_update - return yunohost.permission.user_permission_update( + return user_permission_update( permission, label=label, show_tile=show_tile, sync_perm=sync_perm ) def user_permission_add(permission, names, protected=None, force=False, sync_perm=True): - import yunohost.permission + from yunohost.permission import user_permission_update - return yunohost.permission.user_permission_update( + return user_permission_update( permission, add=names, protected=protected, force=force, sync_perm=sync_perm ) @@ -1289,23 +1289,23 @@ def user_permission_add(permission, names, protected=None, force=False, sync_per def user_permission_remove( permission, names, protected=None, force=False, sync_perm=True ): - import yunohost.permission + from yunohost.permission import user_permission_update - return yunohost.permission.user_permission_update( + return user_permission_update( permission, remove=names, protected=protected, force=force, sync_perm=sync_perm ) def user_permission_reset(permission, sync_perm=True): - import yunohost.permission + from yunohost.permission import user_permission_reset - return yunohost.permission.user_permission_reset(permission, sync_perm=sync_perm) + return user_permission_reset(permission, sync_perm=sync_perm) def user_permission_info(permission): - import yunohost.permission + from yunohost.permission import user_permission_info - return yunohost.permission.user_permission_info(permission) + return user_permission_info(permission) # diff --git a/src/yunohost/utils/config.py b/src/yunohost/utils/config.py index e3b09f870..5b286a92b 100644 --- a/src/yunohost/utils/config.py +++ b/src/yunohost/utils/config.py @@ -52,7 +52,10 @@ CONFIG_PANEL_VERSION_SUPPORTED = 1.0 # Those js-like evaluate functions are used to eval safely visible attributes # The goal is to evaluate in the same way than js simple-evaluate # https://github.com/shepherdwind/simple-evaluate -def evaluate_simple_ast(node, context={}): +def evaluate_simple_ast(node, context=None): + if context is None: + context = {} + operators = { ast.Not: op.not_, ast.Mult: op.mul, From 7cb96c6652eeb6eb1e6a2e37fda26e9d396abfd9 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Thu, 30 Dec 2021 00:25:54 +0100 Subject: [PATCH 47/51] fix ldap_migration decorator --- src/yunohost/tools.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index 6dd4032e9..79c558b2d 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -1130,7 +1130,8 @@ class Migration: def description(self): return m18n.n("migration_description_%s" % self.id) - def ldap_migration(self, run): + @staticmethod + def ldap_migration(run): def func(self): # Backup LDAP before the migration From c177a6797e5fa09f7b6c4db1b056e56eadad19c5 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Wed, 29 Dec 2021 22:40:54 +0100 Subject: [PATCH 48/51] Remove unused variable --- data/hooks/diagnosis/12-dnsrecords.py | 1 - 1 file changed, 1 deletion(-) diff --git a/data/hooks/diagnosis/12-dnsrecords.py b/data/hooks/diagnosis/12-dnsrecords.py index cedd3891e..554576f79 100644 --- a/data/hooks/diagnosis/12-dnsrecords.py +++ b/data/hooks/diagnosis/12-dnsrecords.py @@ -56,7 +56,6 @@ class DNSRecordsDiagnoser(Diagnoser): def check_domain(self, domain, is_main_domain): if is_special_use_tld(domain): - categories = [] yield dict( meta={"domain": domain}, data={}, From acd96f1382b68fe23dc3ea72a807257ddecdf058 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Wed, 29 Dec 2021 22:41:57 +0100 Subject: [PATCH 49/51] remove unused lines --- src/yunohost/app.py | 1 - src/yunohost/dns.py | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index d5e57d6cf..bf41f163d 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -1033,7 +1033,6 @@ def app_remove(operation_logger, app, purge=False): remove_script = f"{tmp_workdir_for_app}/scripts/remove" env_dict = {} - app_id, app_instance_nb = _parse_app_instance_name(app) env_dict = _make_environment_for_app_script(app, workdir=tmp_workdir_for_app) env_dict["YNH_APP_PURGE"] = str(1 if purge else 0) diff --git a/src/yunohost/dns.py b/src/yunohost/dns.py index 23c641a35..492b285c0 100644 --- a/src/yunohost/dns.py +++ b/src/yunohost/dns.py @@ -857,7 +857,6 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge= ignored = "" if action == "create": - old_content = record.get("old_content", "(None)")[:30] new_content = record.get("content", "(None)")[:30] return f"{name:>20} [{t:^5}] {new_content:^30} {ignored}" elif action == "update": @@ -867,7 +866,7 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge= f"{name:>20} [{t:^5}] {old_content:^30} -> {new_content:^30} {ignored}" ) elif action == "unchanged": - old_content = new_content = record.get("content", "(None)")[:30] + old_content = record.get("content", "(None)")[:30] return f"{name:>20} [{t:^5}] {old_content:^30}" else: old_content = record.get("content", "(None)")[:30] From ef44abae6e7e557855f0ece47e5fa4725ed97c14 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Wed, 29 Dec 2021 22:45:25 +0100 Subject: [PATCH 50/51] some improvements --- .../0016_php70_to_php73_pools.py | 12 +++---- src/yunohost/service.py | 2 +- src/yunohost/tools.py | 34 ++++++++----------- 3 files changed, 22 insertions(+), 26 deletions(-) diff --git a/src/yunohost/data_migrations/0016_php70_to_php73_pools.py b/src/yunohost/data_migrations/0016_php70_to_php73_pools.py index fed96c9c8..570e63ea4 100644 --- a/src/yunohost/data_migrations/0016_php70_to_php73_pools.py +++ b/src/yunohost/data_migrations/0016_php70_to_php73_pools.py @@ -38,11 +38,11 @@ class MyMigration(Migration): # Ignore the "www.conf" (default stuff, probably don't want to touch it ?) php70_pool_files = [f for f in php70_pool_files if f != "www.conf"] - for f in php70_pool_files: + for pf in php70_pool_files: # Copy the files to the php7.3 pool - src = "{}/{}".format(PHP70_POOLS, f) - dest = "{}/{}".format(PHP73_POOLS, f) + src = "{}/{}".format(PHP70_POOLS, pf) + dest = "{}/{}".format(PHP73_POOLS, pf) copy2(src, dest) # Replace the socket prefix if it's found @@ -56,17 +56,17 @@ class MyMigration(Migration): c = "sed -i '1i {}' {}".format(MIGRATION_COMMENT, dest) os.system(c) - app_id = os.path.basename(f)[: -len(".conf")] + app_id = os.path.basename(pf)[: -len(".conf")] if _is_installed(app_id): _patch_legacy_php_versions_in_settings( "/etc/yunohost/apps/%s/" % app_id ) nginx_conf_files = glob.glob("/etc/nginx/conf.d/*.d/%s.conf" % app_id) - for f in nginx_conf_files: + for nf in nginx_conf_files: # Replace the socket prefix if it's found c = "sed -i -e 's@{}@{}@g' {}".format( - PHP70_SOCKETS_PREFIX, PHP73_SOCKETS_PREFIX, f + PHP70_SOCKETS_PREFIX, PHP73_SOCKETS_PREFIX, nf ) os.system(c) diff --git a/src/yunohost/service.py b/src/yunohost/service.py index 4f453dfe9..8a7b146b1 100644 --- a/src/yunohost/service.py +++ b/src/yunohost/service.py @@ -587,7 +587,7 @@ def service_regen_conf( if name not in services.keys(): raise YunohostValidationError("service_unknown", service=name) - if names is []: + if names == []: names = list(services.keys()) logger.warning(m18n.n("service_regen_conf_is_deprecated")) diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index 679b4d16e..a0411c69e 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -236,28 +236,24 @@ def tools_postinstall( # If this is a nohost.me/noho.st, actually check for availability if not ignore_dyndns and is_yunohost_dyndns_domain(domain): - # (Except if the user explicitly said he/she doesn't care about dyndns) - if ignore_dyndns: - dyndns = False # Check if the domain is available... - else: - try: - available = _dyndns_available(domain) - # If an exception is thrown, most likely we don't have internet - # connectivity or something. Assume that this domain isn't manageable - # and inform the user that we could not contact the dyndns host server. - except Exception: - logger.warning( - m18n.n( - "dyndns_provider_unreachable", provider="dyndns.yunohost.org" - ) + try: + available = _dyndns_available(domain) + # If an exception is thrown, most likely we don't have internet + # connectivity or something. Assume that this domain isn't manageable + # and inform the user that we could not contact the dyndns host server. + except Exception: + logger.warning( + m18n.n( + "dyndns_provider_unreachable", provider="dyndns.yunohost.org" ) + ) - if available: - dyndns = True - # If not, abort the postinstall - else: - raise YunohostValidationError("dyndns_unavailable", domain=domain) + if available: + dyndns = True + # If not, abort the postinstall + else: + raise YunohostValidationError("dyndns_unavailable", domain=domain) else: dyndns = False From 270c2eb9c0a7154680b3672689416613ed158a7f Mon Sep 17 00:00:00 2001 From: Kay0u Date: Thu, 30 Dec 2021 00:08:49 +0100 Subject: [PATCH 51/51] Trying to fix some lgtm warnings --- src/yunohost/app.py | 7 ++- src/yunohost/certificate.py | 52 +++++++++---------- .../data_migrations/0018_xtable_to_nftable.py | 6 ++- src/yunohost/domain.py | 20 +++---- src/yunohost/regenconf.py | 5 +- src/yunohost/tools.py | 2 +- src/yunohost/user.py | 24 ++++----- src/yunohost/utils/config.py | 5 +- 8 files changed, 66 insertions(+), 55 deletions(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index bf41f163d..ca56be232 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -627,7 +627,7 @@ def app_upgrade(app=[], url=None, file=None, force=False, no_safety_backup=False if upgrade_failed or broke_the_system: # display this if there are remaining apps - if apps[number + 1 :]: + if apps[number + 1:]: not_upgraded_apps = apps[number:] logger.error( m18n.n( @@ -1626,9 +1626,12 @@ class AppConfigPanel(ConfigPanel): error=message, ) - def _call_config_script(self, action, env={}): + def _call_config_script(self, action, env=None): from yunohost.hook import hook_exec + if env is None: + env = {} + # Add default config script if needed config_script = os.path.join( APPS_SETTING_PATH, self.entity, "scripts", "config" diff --git a/src/yunohost/certificate.py b/src/yunohost/certificate.py index 79e3ae092..2f3676202 100644 --- a/src/yunohost/certificate.py +++ b/src/yunohost/certificate.py @@ -70,28 +70,28 @@ PRODUCTION_CERTIFICATION_AUTHORITY = "https://acme-v02.api.letsencrypt.org" # -def certificate_status(domain_list, full=False): +def certificate_status(domains, full=False): """ Print the status of certificate for given domains (all by default) Keyword argument: - domain_list -- Domains to be checked + domains -- Domains to be checked full -- Display more info about the certificates """ - import yunohost.domain + from yunohost.domain import domain_list, _assert_domain_exists # If no domains given, consider all yunohost domains - if domain_list == []: - domain_list = yunohost.domain.domain_list()["domains"] + if domains == []: + domains = domain_list()["domains"] # Else, validate that yunohost knows the domains given else: - for domain in domain_list: - yunohost.domain._assert_domain_exists(domain) + for domain in domains: + _assert_domain_exists(domain) certificates = {} - for domain in domain_list: + for domain in domains: status = _get_status(domain) if not full: @@ -239,28 +239,28 @@ def _certificate_install_selfsigned(domain_list, force=False): def _certificate_install_letsencrypt( - domain_list, force=False, no_checks=False, staging=False + domains, force=False, no_checks=False, staging=False ): - import yunohost.domain + from yunohost.domain import domain_list, _assert_domain_exists if not os.path.exists(ACCOUNT_KEY_FILE): _generate_account_key() # If no domains given, consider all yunohost domains with self-signed # certificates - if domain_list == []: - for domain in yunohost.domain.domain_list()["domains"]: + if domains == []: + for domain in domain_list()["domains"]: status = _get_status(domain) if status["CA_type"]["code"] != "self-signed": continue - domain_list.append(domain) + domains.append(domain) # Else, validate that yunohost knows the domains given else: - for domain in domain_list: - yunohost.domain._assert_domain_exists(domain) + for domain in domains: + _assert_domain_exists(domain) # Is it self-signed? status = _get_status(domain) @@ -275,7 +275,7 @@ def _certificate_install_letsencrypt( ) # Actual install steps - for domain in domain_list: + for domain in domains: if not no_checks: try: @@ -311,25 +311,25 @@ def _certificate_install_letsencrypt( def certificate_renew( - domain_list, force=False, no_checks=False, email=False, staging=False + domains, force=False, no_checks=False, email=False, staging=False ): """ Renew Let's Encrypt certificate for given domains (all by default) Keyword argument: - domain_list -- Domains for which to renew the certificates + domains -- Domains for which to renew the certificates force -- Ignore the validity threshold (15 days) no-check -- Disable some checks about the reachability of web server before attempting the renewing email -- Emails root if some renewing failed """ - import yunohost.domain + from yunohost.domain import domain_list, _assert_domain_exists # If no domains given, consider all yunohost domains with Let's Encrypt # certificates - if domain_list == []: - for domain in yunohost.domain.domain_list()["domains"]: + if domains == []: + for domain in domain_list()["domains"]: # Does it have a Let's Encrypt cert? status = _get_status(domain) @@ -347,17 +347,17 @@ def certificate_renew( ) continue - domain_list.append(domain) + domains.append(domain) - if len(domain_list) == 0 and not email: + if len(domains) == 0 and not email: logger.info("No certificate needs to be renewed.") # Else, validate the domain list given else: - for domain in domain_list: + for domain in domains: # Is it in Yunohost domain list? - yunohost.domain._assert_domain_exists(domain) + _assert_domain_exists(domain) status = _get_status(domain) @@ -385,7 +385,7 @@ def certificate_renew( ) # Actual renew steps - for domain in domain_list: + for domain in domains: if not no_checks: try: diff --git a/src/yunohost/data_migrations/0018_xtable_to_nftable.py b/src/yunohost/data_migrations/0018_xtable_to_nftable.py index 94b47d944..374620f2f 100644 --- a/src/yunohost/data_migrations/0018_xtable_to_nftable.py +++ b/src/yunohost/data_migrations/0018_xtable_to_nftable.py @@ -41,7 +41,8 @@ class MyMigration(Migration): ) # For some reason if we don't do this, iptables-legacy-save is empty ? self.runcmd("iptables-legacy-save > %s" % self.backup_rules_ipv4) assert ( - open(self.backup_rules_ipv4).read().strip() + os.path.exists(self.backup_rules_ipv4) and + os.stat(self.backup_rules_ipv4).st_size > 0 ), "Uhoh backup of legacy ipv4 rules is empty !?" if self.do_ipv6 and not os.path.exists(self.backup_rules_ipv6): self.runcmd( @@ -49,7 +50,8 @@ class MyMigration(Migration): ) # For some reason if we don't do this, iptables-legacy-save is empty ? self.runcmd("ip6tables-legacy-save > %s" % self.backup_rules_ipv6) assert ( - open(self.backup_rules_ipv6).read().strip() + os.path.exists(self.backup_rules_ipv6) and + os.stat(self.backup_rules_ipv6).st_size > 0 ), "Uhoh backup of legacy ipv6 rules is empty !?" # We inject the legacy rules (iptables-legacy) into the new iptable (just "iptables") diff --git a/src/yunohost/domain.py b/src/yunohost/domain.py index 0bd84ea82..d1ea45a08 100644 --- a/src/yunohost/domain.py +++ b/src/yunohost/domain.py @@ -507,17 +507,17 @@ def _set_domain_settings(domain: str, settings: dict) -> None: def domain_cert_status(domain_list, full=False): - import yunohost.certificate + from yunohost.certificate import certificate_status - return yunohost.certificate.certificate_status(domain_list, full) + return certificate_status(domain_list, full) def domain_cert_install( domain_list, force=False, no_checks=False, self_signed=False, staging=False ): - import yunohost.certificate + from yunohost.certificate import certificate_install - return yunohost.certificate.certificate_install( + return certificate_install( domain_list, force, no_checks, self_signed, staging ) @@ -525,9 +525,9 @@ def domain_cert_install( def domain_cert_renew( domain_list, force=False, no_checks=False, email=False, staging=False ): - import yunohost.certificate + from yunohost.certificate import certificate_renew - return yunohost.certificate.certificate_renew( + return certificate_renew( domain_list, force, no_checks, email, staging ) @@ -537,12 +537,12 @@ def domain_dns_conf(domain): def domain_dns_suggest(domain): - import yunohost.dns + from yunohost.dns import domain_dns_suggest - return yunohost.dns.domain_dns_suggest(domain) + return domain_dns_suggest(domain) def domain_dns_push(domain, dry_run, force, purge): - import yunohost.dns + from yunohost.dns import domain_dns_push - return yunohost.dns.domain_dns_push(domain, dry_run, force, purge) + return domain_dns_push(domain, dry_run, force, purge) diff --git a/src/yunohost/regenconf.py b/src/yunohost/regenconf.py index adec5508d..4b697cd84 100644 --- a/src/yunohost/regenconf.py +++ b/src/yunohost/regenconf.py @@ -48,7 +48,7 @@ logger = log.getActionLogger("yunohost.regenconf") @is_unit_operation([("names", "configuration")]) def regen_conf( operation_logger, - names=[], + names=None, with_diff=False, force=False, dry_run=False, @@ -66,6 +66,9 @@ def regen_conf( """ + if names is None: + names = [] + result = {} # Return the list of pending conf diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index a0411c69e..6dd4032e9 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -1130,7 +1130,7 @@ class Migration: def description(self): return m18n.n("migration_description_%s" % self.id) - def ldap_migration(run): + def ldap_migration(self, run): def func(self): # Backup LDAP before the migration diff --git a/src/yunohost/user.py b/src/yunohost/user.py index 78fda8d09..a27fffbee 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -1263,25 +1263,25 @@ def user_group_remove(groupname, usernames, force=False, sync_perm=True): def user_permission_list(short=False, full=False, apps=[]): - import yunohost.permission + from yunohost.permission import user_permission_list - return yunohost.permission.user_permission_list( + return user_permission_list( short, full, absolute_urls=True, apps=apps ) def user_permission_update(permission, label=None, show_tile=None, sync_perm=True): - import yunohost.permission + from yunohost.permission import user_permission_update - return yunohost.permission.user_permission_update( + return user_permission_update( permission, label=label, show_tile=show_tile, sync_perm=sync_perm ) def user_permission_add(permission, names, protected=None, force=False, sync_perm=True): - import yunohost.permission + from yunohost.permission import user_permission_update - return yunohost.permission.user_permission_update( + return user_permission_update( permission, add=names, protected=protected, force=force, sync_perm=sync_perm ) @@ -1289,23 +1289,23 @@ def user_permission_add(permission, names, protected=None, force=False, sync_per def user_permission_remove( permission, names, protected=None, force=False, sync_perm=True ): - import yunohost.permission + from yunohost.permission import user_permission_update - return yunohost.permission.user_permission_update( + return user_permission_update( permission, remove=names, protected=protected, force=force, sync_perm=sync_perm ) def user_permission_reset(permission, sync_perm=True): - import yunohost.permission + from yunohost.permission import user_permission_reset - return yunohost.permission.user_permission_reset(permission, sync_perm=sync_perm) + return user_permission_reset(permission, sync_perm=sync_perm) def user_permission_info(permission): - import yunohost.permission + from yunohost.permission import user_permission_info - return yunohost.permission.user_permission_info(permission) + return user_permission_info(permission) # diff --git a/src/yunohost/utils/config.py b/src/yunohost/utils/config.py index e3b09f870..5b286a92b 100644 --- a/src/yunohost/utils/config.py +++ b/src/yunohost/utils/config.py @@ -52,7 +52,10 @@ CONFIG_PANEL_VERSION_SUPPORTED = 1.0 # Those js-like evaluate functions are used to eval safely visible attributes # The goal is to evaluate in the same way than js simple-evaluate # https://github.com/shepherdwind/simple-evaluate -def evaluate_simple_ast(node, context={}): +def evaluate_simple_ast(node, context=None): + if context is None: + context = {} + operators = { ast.Not: op.not_, ast.Mult: op.mul,