From d2113b243ebc4f5ac3ffcce34e821f47bea27ba1 Mon Sep 17 00:00:00 2001 From: selfhoster1312 Date: Tue, 15 Aug 2023 15:35:36 +0200 Subject: [PATCH 001/113] Add information in yunohost app install --help --- share/actionsmap.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/actionsmap.yml b/share/actionsmap.yml index 48e12ba0f..0c3301874 100644 --- a/share/actionsmap.yml +++ b/share/actionsmap.yml @@ -934,14 +934,14 @@ app: help: Custom name for the app -a: full: --args - help: Serialized arguments for app script (i.e. "domain=domain.tld&path=/path") + help: Serialized arguments for app script (i.e. "domain=domain.tld&path=/path&init_main_permission=visitors") -n: full: --no-remove-on-failure help: Debug option to avoid removing the app on a failed installation action: store_true -f: full: --force - help: Do not ask confirmation if the app is not safe to use (low quality, experimental or 3rd party) + help: Do not ask confirmation if the app is not safe to use (low quality, experimental or 3rd party), or when the app displays a post-install notification action: store_true ### app_remove() From 0d88978c2a31e967570b04e14ab747956b2fb9b5 Mon Sep 17 00:00:00 2001 From: massyas Date: Wed, 16 Aug 2023 17:25:23 +0200 Subject: [PATCH 002/113] Fix typo in app_upgrade argument help --- share/actionsmap.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/actionsmap.yml b/share/actionsmap.yml index 0c3301874..e44a72125 100644 --- a/share/actionsmap.yml +++ b/share/actionsmap.yml @@ -980,7 +980,7 @@ app: action: store_true -c: full: --continue-on-failure - help: Continue to upgrade apps event if one or more upgrade failed + help: Continue to upgrade apps even if one or more upgrade failed action: store_true ### app_change_url() From d716746f281957fec6054744a13ce499420e76e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20M?= Date: Wed, 19 Jul 2023 12:09:22 +0000 Subject: [PATCH 003/113] Translated using Weblate (Galician) Currently translated at 100.0% (780 of 780 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/gl/ --- locales/gl.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/gl.json b/locales/gl.json index 1926f6148..93f73b528 100644 --- a/locales/gl.json +++ b/locales/gl.json @@ -612,7 +612,7 @@ "domain_config_auth_consumer_key": "Chave consumidora", "log_domain_dns_push": "Enviar rexistros DNS para o dominio '{}'", "other_available_options": "... e outras {n} opcións dispoñibles non mostradas", - "domain_dns_registrar_yunohost": "Este dominio un dos de nohost.me / nohost.st / ynh.fr e a configuración DNS xestionaa directamente YunoHost se máis requisitos. (mira o comando 'yunohost dyndns update')", + "domain_dns_registrar_yunohost": "Este dominio é un dos de nohost.me / nohost.st / ynh.fr e a configuración DNS xestionaa directamente YunoHost sen máis requisitos. (mira o comando 'yunohost dyndns update')", "domain_dns_registrar_supported": "YunoHost detectou automáticamente que este dominio está xestionado pola rexistradora **{registrar}**. Se queres, YunoHost pode configurar automáticamente as súas zonas DNS, se proporcionas as credenciais de acceso á API. Podes ver a documentación sobre como obter as credenciais da API nesta páxina: https://yunohost.org/registrar_api_{registrar}. (Tamén podes configurar manualmente os rexistros DNS seguindo a documentación en https://yunohost.org/dns )", "domain_dns_push_partial_failure": "Actualización parcial dos rexistros DNS: informouse dalgúns avisos/erros.", "domain_config_auth_token": "Token de autenticación", @@ -654,7 +654,7 @@ "global_settings_setting_admin_strength": "Fortaleza do contrasinal de Admin", "global_settings_setting_user_strength": "Fortaleza do contrasinal da usuaria", "global_settings_setting_postfix_compatibility_help": "Compromiso entre compatibilidade e seguridade para o servidor Postfix. Aféctalle ao cifrado (e outros aspectos da seguridade)", - "global_settings_setting_ssh_compatibility_help": "Compromiso entre compatibilidade e seguridade para o servidor SSH. Aféctalle ao cifrado (e outros aspectos da seguridade)", + "global_settings_setting_ssh_compatibility_help": "Compromiso entre compatibilidade e seguridade para o servidor SSH. Aféctalle ao cifrado (e outros aspectos da seguridade). Le https://infosec.mozilla.org/guidelines/openssh for more info.", "global_settings_setting_ssh_password_authentication_help": "Permitir autenticación con contrasinal para SSH", "global_settings_setting_ssh_port": "Porto SSH", "global_settings_setting_webadmin_allowlist_help": "Enderezos IP con permiso para acceder á webadmin. Separados por vírgulas.", From 9fdbc5532f8f5144602f3430e2f9ef07f96dbc0e Mon Sep 17 00:00:00 2001 From: Suleyman Harmandar Date: Sat, 22 Jul 2023 05:45:21 +0000 Subject: [PATCH 004/113] Translated using Weblate (Turkish) Currently translated at 2.5% (20 of 780 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/tr/ --- locales/tr.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/locales/tr.json b/locales/tr.json index 1af0ffd54..3c15591f3 100644 --- a/locales/tr.json +++ b/locales/tr.json @@ -15,5 +15,10 @@ "additional_urls_already_added": "Ek URL '{url}' zaten '{permission}' izni için ek URL'ye eklendi", "additional_urls_already_removed": "Ek URL '{url}', '{permission}' izni için ek URL'de zaten kaldırıldı", "app_action_cannot_be_ran_because_required_services_down": "Bu eylemi gerçekleştirmek için şu servisler çalışıyor olmalıdır: {services}. Devam etmek için onları yeniden başlatın (ve muhtemelen neden çalışmadığını araştırın).", - "app_arch_not_supported": "Bu uygulama yalnızca {required} işlemci mimarisi üzerine kurulabilir ancak sunucunuzun işlemci mimarisi {current}." -} \ No newline at end of file + "app_arch_not_supported": "Bu uygulama yalnızca {required} işlemci mimarisi üzerine kurulabilir ancak sunucunuzun işlemci mimarisi {current}.", + "app_argument_choice_invalid": "'{name}'' için geçerli bir değer giriniz '{value}' mevcut seçimlerin arasında değil ({choices})", + "app_change_url_failed": "{app}: {error} için url değiştirilemedi", + "app_argument_required": "'{name}' değeri gerekli", + "app_argument_invalid": "'{name}': {error} için geçerli bir değer giriniz", + "app_argument_password_no_default": "'{name}': çözümlenirken bir hata meydana geldi. Parola argümanı güvenlik nedeniyle varsayılan değer alamaz" +} From 5eecfcae6755c517cdc73943a981544d11f3d094 Mon Sep 17 00:00:00 2001 From: Kuba Bazan Date: Sun, 23 Jul 2023 22:20:41 +0000 Subject: [PATCH 005/113] Translated using Weblate (Polish) Currently translated at 34.8% (272 of 780 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/pl/ --- locales/pl.json | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/locales/pl.json b/locales/pl.json index 52f2de3ca..78d295f61 100644 --- a/locales/pl.json +++ b/locales/pl.json @@ -103,7 +103,7 @@ "backup_applying_method_custom": "Wywołuję niestandardową metodę tworzenia kopii zapasowych '{method}'...", "app_remove_after_failed_install": "Usuwanie aplikacji po niepowodzeniu instalacji...", "app_upgrade_script_failed": "Wystąpił błąd w skrypcie aktualizacji aplikacji", - "apps_catalog_init_success": "Zainicjowano system katalogu aplikacji!", + "apps_catalog_init_success": "System katalogu aplikacji został zainicjowany!", "apps_catalog_obsolete_cache": "Pamięć podręczna katalogu aplikacji jest pusta lub przestarzała.", "app_extraction_failed": "Nie można wyodrębnić plików instalacyjnych", "app_packaging_format_not_supported": "Ta aplikacja nie może zostać zainstalowana, ponieważ jej format opakowania nie jest obsługiwany przez twoją wersję YunoHost. Prawdopodobnie powinieneś rozważyć aktualizację swojego systemu.", @@ -183,7 +183,7 @@ "app_failed_to_download_asset": "Nie udało się pobrać zasobu '{source_id}' ({url}) dla {app}: {out}", "backup_with_no_backup_script_for_app": "Aplikacja '{app}' nie posiada skryptu kopii zapasowej. Ignorowanie.", "backup_with_no_restore_script_for_app": "Aplikacja {app} nie posiada skryptu przywracania, co oznacza, że nie będzie można automatycznie przywrócić kopii zapasowej tej aplikacji.", - "certmanager_acme_not_configured_for_domain": "Wyzwanie ACME nie może zostać uruchomione dla domeny {domain}, ponieważ jej konfiguracja nginx nie zawiera odpowiedniego fragmentu kodu... Upewnij się, że konfiguracja nginx jest aktualna, używając polecenia yunohost tools regen-conf nginx --dry-run --with-diff.", + "certmanager_acme_not_configured_for_domain": "Wyzwanie ACME nie może być teraz uruchomione dla {domain}, ponieważ jego konfiguracja nginx nie zawiera odpowiedniego fragmentu kodu… Upewnij się, że twoja konfiguracja nginx jest aktualna, używając `yunohost tools regen-conf nginx --dry-run --with-diff`.", "certmanager_domain_dns_ip_differs_from_public_ip": "Rekordy DNS dla domeny '{domain}' różnią się od adresu IP tego serwera. Sprawdź kategorię 'Rekordy DNS' (podstawowe) w diagnozie, aby uzyskać więcej informacji. Jeśli niedawno dokonałeś zmiany rekordu A, poczekaj, aż zostanie on zaktualizowany (można skorzystać z narzędzi online do sprawdzania propagacji DNS). (Jeśli wiesz, co robisz, użyj opcji '--no-checks', aby wyłączyć te sprawdzania.)", "confirm_app_install_danger": "UWAGA! Ta aplikacja jest wciąż w fazie eksperymentalnej (jeśli nie działa jawnie)! Prawdopodobnie NIE powinieneś jej instalować, chyba że wiesz, co robisz. NIE ZOSTANIE udzielone wsparcie, jeśli ta aplikacja nie będzie działać poprawnie lub spowoduje uszkodzenie systemu... Jeśli mimo to jesteś gotów podjąć to ryzyko, wpisz '{answers}", "confirm_app_install_thirdparty": "UWAGA! Ta aplikacja nie jest częścią katalogu aplikacji YunoHost. Instalowanie aplikacji innych firm może naruszyć integralność i bezpieczeństwo systemu. Prawdopodobnie NIE powinieneś jej instalować, chyba że wiesz, co robisz. NIE ZOSTANIE udzielone wsparcie, jeśli ta aplikacja nie będzie działać poprawnie lub spowoduje uszkodzenie systemu... Jeśli mimo to jesteś gotów podjąć to ryzyko, wpisz '{answers}'", @@ -192,19 +192,19 @@ "config_no_panel": "Nie znaleziono panelu konfiguracji.", "config_unknown_filter_key": "Klucz filtru '{filter_key}' jest niepoprawny.", "config_validate_email": "Proszę podać poprawny adres e-mail", - "backup_hook_unknown": "Nieznany jest hook kopii zapasowej '{hook}'.", + "backup_hook_unknown": "Nieznany jest hook kopii zapasowej '{hook}'", "backup_no_uncompress_archive_dir": "Nie istnieje taki katalog nieskompresowanego archiwum.", - "backup_output_symlink_dir_broken": "Twój katalog archiwum '{path}' to uszkodzony dowiązanie symboliczne. Być może zapomniałeś o ponownym zamontowaniu lub podłączeniu nośnika przechowującego, do którego on wskazuje.", - "backup_system_part_failed": "Nie można wykonać kopii zapasowej części systemu '{part}'", + "backup_output_symlink_dir_broken": "Twój katalog archiwum ‘{path}’ to uszkodzony symlink. Być może zapomniałeś o ponownym zamontowaniu lub podłączeniu nośnika przechowującego, do którego on wskazuje.", + "backup_system_part_failed": "Nie udało się wykonać kopii zapasowej części systemu ‘{part}’", "config_validate_color": "Powinien być poprawnym szesnastkowym kodem koloru RGB.", "config_validate_date": "Data powinna być poprawna w formacie RRRR-MM-DD", "config_validate_time": "Podaj poprawny czas w formacie GG:MM", "certmanager_domain_not_diagnosed_yet": "Nie ma jeszcze wyników diagnozy dla domeny {domain}. Proszę ponownie uruchomić diagnozę dla kategorii 'Rekordy DNS' i 'Strona internetowa' w sekcji diagnozy, aby sprawdzić, czy domena jest gotowa do użycia Let's Encrypt. (Jeśli wiesz, co robisz, użyj opcji '--no-checks', aby wyłączyć te sprawdzania.)", "certmanager_cannot_read_cert": "Wystąpił problem podczas próby otwarcia bieżącego certyfikatu dla domeny {domain} (plik: {file}), przyczyna: {reason}", - "certmanager_no_cert_file": "Nie można odczytać pliku certyfikatu dla domeny {domain} (plik: {file}).", - "certmanager_self_ca_conf_file_not_found": "Nie można znaleźć pliku konfiguracyjnego dla autorytetu samopodpisującego (plik: {file})", - "backup_running_hooks": "Uruchamianie hooków kopii zapasowej...", - "backup_permission": "Uprawnienia kopii zapasowej dla aplikacji {app}", + "certmanager_no_cert_file": "Nie można odczytać pliku certyfikatu dla domeny {domain} (plik: {file})", + "certmanager_self_ca_conf_file_not_found": "Nie można znaleźć pliku konfiguracyjnego dla samodzielnie podpisanego upoważnienia do (file: {file})", + "backup_running_hooks": "Uruchamianie kopii zapasowej hooków...", + "backup_permission": "Uprawnienia do tworzenia kopii zapasowej dla aplikacji {app}", "certmanager_domain_cert_not_selfsigned": "Certyfikat dla domeny {domain} nie jest samopodpisany. Czy na pewno chcesz go zastąpić? (Użyj opcji '--force', aby to zrobić.)", "config_action_disabled": "Nie można uruchomić akcji '{action}', ponieważ jest ona wyłączona. Upewnij się, że spełnione są jej ograniczenia. Pomoc: {help}", "config_action_failed": "Nie udało się uruchomić akcji '{action}': {error}", @@ -214,7 +214,7 @@ "confirm_app_insufficient_ram": "UWAGA! Ta aplikacja wymaga {required} pamięci RAM do zainstalowania/aktualizacji, a obecnie dostępne jest tylko {current}. Nawet jeśli aplikacja mogłaby działać, proces instalacji/aktualizacji wymaga dużej ilości pamięci RAM, więc serwer może się zawiesić i niepowodzenie może być katastrofalne. Jeśli mimo to jesteś gotów podjąć to ryzyko, wpisz '{answers}'", "app_not_upgraded_broken_system": "Aplikacja '{failed_app}' nie powiodła się w procesie aktualizacji i spowodowała uszkodzenie systemu. W rezultacie anulowane zostały aktualizacje następujących aplikacji: {apps}", "app_not_upgraded_broken_system_continue": "Aplikacja '{failed_app}' nie powiodła się w procesie aktualizacji i spowodowała uszkodzenie systemu (parametr --continue-on-failure jest ignorowany). W rezultacie anulowane zostały aktualizacje następujących aplikacji: {apps}", - "certmanager_domain_http_not_working": "Domena {domain} wydaje się niedostępna przez HTTP. Sprawdź kategorię 'Strona internetowa' diagnostyki, aby uzyskać więcej informacji. (Jeśli wiesz, co robisz, użyj opcji '--no-checks', aby wyłączyć te sprawdzania.)", + "certmanager_domain_http_not_working": "Domena {domain} nie wydaje się być dostępna przez HTTP. Sprawdź kategorię 'Strona internetowa' diagnostyki, aby uzyskać więcej informacji. (Jeśli wiesz, co robisz, użyj opcji '--no-checks', aby wyłączyć te sprawdzania.)", "migration_0021_system_not_fully_up_to_date": "Twój system nie jest w pełni zaktualizowany! Proszę, wykonaj zwykłą aktualizację oprogramowania zanim rozpoczniesz migrację na system Bullseye.", "global_settings_setting_smtp_relay_port": "Port przekaźnika SMTP", "domain_config_cert_renew": "Odnów certyfikat Let's Encrypt", @@ -274,5 +274,12 @@ "global_settings_setting_smtp_allow_ipv6_help": "Zezwól na wykorzystywanie IPv7 do odbierania i wysyłania maili", "global_settings_setting_ssh_password_authentication": "Logowanie hasłem", "diagnosis_backports_in_sources_list": "Wygląda na to że apt (menedżer pakietów) został skonfigurowany tak, aby wykorzystywać repozytorium backported. Nie zalecamy wykorzystywania repozytorium backported, ponieważ może powodować problemy ze stabilnością i/lub konflikty z konfiguracją. No chyba, że wiesz co robisz.", - "domain_config_xmpp_help": "Uwaga: niektóre funkcje XMPP będą wymagały aktualizacji rekordów DNS i odnowienia certyfikatu Lets Encrypt w celu ich włączenia" + "domain_config_xmpp_help": "Uwaga: niektóre funkcje XMPP będą wymagały aktualizacji rekordów DNS i odnowienia certyfikatu Lets Encrypt w celu ich włączenia", + "ask_dyndns_recovery_password_explain": "Proszę wybrać hasło odzyskiwania dla swojej domeny DynDNS, na wypadek gdybyś musiał go później zresetować.", + "ask_dyndns_recovery_password_explain_during_unsubscribe": "Proszę wprowadzić hasło odzyskiwania dla tej domeny DynDNS.", + "certmanager_unable_to_parse_self_CA_name": "Nie można spasować nazwy organu samopodpisywanego (pliku: {file})", + "app_corrupt_source": "YunoHost był w stanie pobrać zasób ‘{source_id}’ ({url}) dla {app}, ale zasób nie pasuje do oczekiwanego sumy kontrolnej. Może to oznaczać, że na twoim serwerze wystąpiła tymczasowa awaria sieci, LUB zasób został jakoś zmieniony przez dostawcę usługi (lub złośliwego aktora?) i pakowacze YunoHost muszą zbadać sprawę i zaktualizować manifest aplikacji, aby odzwierciedlić tę zmianę. \nOczekiwana suma kontrolna sha256: {expected_sha256} \nPobrana suma kontrolna sha256: {computed_sha256} \nRozmiar pobranego pliku: {size}”", + "ask_dyndns_recovery_password": "Hasło odzyskiwania DynDNS", + "certmanager_hit_rate_limit": "Zbyt wiele certyfikatów zostało ostatnio wydanych dla tej dokładnej grupy domen {domain}. Spróbuj ponownie później. Zobacz https://letsencrypt.org/docs/rate-limits/ aby uzyskać więcej informacji", + "apps_failed_to_upgrade_line": "\n * {app_id} (aby zobaczyć odpowiedni dziennik, wykonaj ‘yunohost log show {operation_logger_name}’)" } From 927a17cf3046d49023e9cd8ac92be5a02978eb2a Mon Sep 17 00:00:00 2001 From: taco Date: Wed, 2 Aug 2023 18:07:56 +0000 Subject: [PATCH 006/113] Translated using Weblate (Spanish) Currently translated at 95.8% (748 of 780 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/es/ --- locales/es.json | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/locales/es.json b/locales/es.json index 85d7b1f43..5003c305c 100644 --- a/locales/es.json +++ b/locales/es.json @@ -522,8 +522,8 @@ "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 tráfico 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 internet 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.", "diagnosis_basesystem_hardware_model": "El modelo de servidor es {model}", - "additional_urls_already_removed": "La URL adicional '{url}' ya se ha eliminado para el permiso «{permission}»", - "additional_urls_already_added": "La URL adicional '{url}' ya se ha añadido para el permiso «{permission}»", + "additional_urls_already_removed": "URL adicional '{url}' ya eliminada en la URL adicional para permiso «{permission}»", + "additional_urls_already_added": "URL adicional '{url}' ya añadida en la URL adicional para permiso «{permission}»", "config_apply_failed": "Falló la aplicación de la nueva configuración: {error}", "app_restore_script_failed": "Ha ocurrido un error dentro del script de restauración de aplicaciones", "app_config_unable_to_apply": "No se pudieron aplicar los valores del panel configuración.", @@ -747,5 +747,10 @@ "global_settings_setting_smtp_relay_host": "Host de retransmisión SMTP", "migration_0024_rebuild_python_venv_disclaimer_rebuild": "Se intentará reconstruir el virtualenv para las siguientes apps (NB: ¡la operación puede llevar algún tiempo!): {rebuild_apps}", "migration_description_0025_global_settings_to_configpanel": "Migración de la nomenclatura de ajustes globales heredada a la nomenclatura nueva y moderna", - "registrar_infos": "Información sobre el registrador" -} \ No newline at end of file + "registrar_infos": "Información sobre el registrador", + "app_failed_to_download_asset": "Error al descargar el recurso '{source_id}' ({url}) para {app}: {out}", + "app_corrupt_source": "YunoHost ha podido descargar el recurso '{source_id}' ({url}) para {app}, pero no coincide con la suma de comprobación esperada. Esto puede significar que ocurrió un fallo de red en tu servidor, o que el recurso ha sido modificado por el responsable de la aplicación (¿o un actor malicioso?) y los responsables de empaquetar esta aplicación para YunoHost necesitan investigar y actualizar el manifesto de la aplicación para reflejar estos cambios. \n Suma de control sha256 esperada: {expected_sha256}\n Suma de control sha256 descargada: {computed_sha256}\n Tamaño del archivo descargado: {size}", + "app_change_url_failed": "No es possible cambiar la URL para {app}: {error}", + "app_change_url_require_full_domain": "{app} no se puede mover a esta nueva URL porque requiere un dominio completo (es decir, con una ruta = /)", + "app_change_url_script_failed": "Se ha producido un error en el script de modificación de la url" +} From f46dc30783e7b19295f3e5b36c7c85e34832cf5e Mon Sep 17 00:00:00 2001 From: Grzegorz Cichocki Date: Sat, 5 Aug 2023 22:19:12 +0000 Subject: [PATCH 007/113] Translated using Weblate (Polish) Currently translated at 35.0% (273 of 780 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/pl/ --- locales/pl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/pl.json b/locales/pl.json index 78d295f61..17a9fa572 100644 --- a/locales/pl.json +++ b/locales/pl.json @@ -193,7 +193,7 @@ "config_unknown_filter_key": "Klucz filtru '{filter_key}' jest niepoprawny.", "config_validate_email": "Proszę podać poprawny adres e-mail", "backup_hook_unknown": "Nieznany jest hook kopii zapasowej '{hook}'", - "backup_no_uncompress_archive_dir": "Nie istnieje taki katalog nieskompresowanego archiwum.", + "backup_no_uncompress_archive_dir": "Nie istnieje taki katalog nieskompresowanego archiwum", "backup_output_symlink_dir_broken": "Twój katalog archiwum ‘{path}’ to uszkodzony symlink. Być może zapomniałeś o ponownym zamontowaniu lub podłączeniu nośnika przechowującego, do którego on wskazuje.", "backup_system_part_failed": "Nie udało się wykonać kopii zapasowej części systemu ‘{part}’", "config_validate_color": "Powinien być poprawnym szesnastkowym kodem koloru RGB.", From c4b3068d3abf3c4a1518dbd0d4df004441629673 Mon Sep 17 00:00:00 2001 From: Neko Nekowazarashi Date: Tue, 8 Aug 2023 15:12:19 +0000 Subject: [PATCH 008/113] Translated using Weblate (Indonesian) Currently translated at 52.9% (413 of 780 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/id/ --- locales/id.json | 51 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/locales/id.json b/locales/id.json index c6b023102..2cc7c56dc 100644 --- a/locales/id.json +++ b/locales/id.json @@ -391,5 +391,54 @@ "log_letsencrypt_cert_renew": "Memperbarui sertifikat Let's Encrypt '{}'", "log_selfsigned_cert_install": "Memasang sertifikat ditandai sendiri pada domain '{}'", "log_user_permission_reset": "Mengatur ulang izin '{}'", - "domain_config_xmpp": "Pesan Langsung (XMPP)" + "domain_config_xmpp": "Pesan Langsung (XMPP)", + "diagnosis_http_connection_error": "Masalah jaringan: tidak dapat terhubung dengan domain yang diminta, sangat mungkin terputus.", + "dyndns_ip_updated": "IP Anda diperbarui di DynDNS", + "ask_dyndns_recovery_password_explain": "Pilih kata sandi pemulihan untuk domain DynDNS Anda.", + "ask_dyndns_recovery_password": "Kata sandi pemulihan DynDNS", + "backup_output_directory_not_empty": "Anda harus memilih direktori yang kosong", + "service_reload_or_restart_failed": "Tidak dapat memuat atau memulai ulang layanan '{service}'\n\nLog layanan baru-baru ini:{logs}", + "service_reload_failed": "Tidak dapat memuat ulang layanan '{service}'\n\nLog layanan baru-baru ini:{logs}", + "service_start_failed": "Tidak dapat memulai layanan '{service}'\n\nLog layanan baru-baru ini: {logs}", + "diagnosis_apps_deprecated_practices": "Versi aplikasi yang dipasang ini masih menggunakan praktik pengemasan yang lama. Anda lebih baik untuk memperbarui aplikasi tersebut.", + "diagnosis_dns_bad_conf": "Beberapa rekaman DNS untuk domain {domain} ada yang tidak ada atau salah (kategori {category})", + "diagnosis_dns_good_conf": "Rekaman DNS untuk domain {domain} sudah diatur dengan benar (kategori {category})", + "dyndns_unavailable": "Domain '{domain}' tidak tersedia.", + "dyndns_set_recovery_password_denied": "Tidak dapat menyetel kata sandi pemulihan: tidak valid", + "dyndns_set_recovery_password_unknown_domain": "Tidak dapat menyetel kata sandi pemulihan: domain belum terdaftar", + "dyndns_set_recovery_password_invalid_password": "Tidak dapat menyetel kata sandi pemulihan: kata sandi tidak cukup kuat", + "dyndns_set_recovery_password_failed": "Tidak dapat menyetel kata sandi pemulihan: {error}", + "dyndns_set_recovery_password_success": "Kata sandi pemulihan berhasil disetel!", + "file_does_not_exist": "Berkas {path} tidak ada.", + "firewall_reload_failed": "Tidak dapat memuat ulang tembok api", + "firewall_reloaded": "Tembok api dimuat ulang", + "migration_description_0023_postgresql_11_to_13": "Migrasi basis data dari PostgreSQL 11 ke 13", + "service_enabled": "Layanan '{service}' akan secara mandiri dimulai saat pemulaian.", + "service_reloaded_or_restarted": "Layanan {service} dimuat atau dimulai ulang", + "service_stopped": "Layanan '{service}' diberhentikan", + "service_unknown": "Layanan yang tidak diketahui: '{service}'", + "updating_apt_cache": "Mengambil pembaruan yang tersedia untuk paket sistem...", + "group_mailalias_remove": "Alias surel '{mail}' akan dihapus dari kelompok '{group}'", + "migration_description_0021_migrate_to_bullseye": "Peningkatan sistem ke Debian Bullseye dan YunoHost 11.x", + "migration_description_0024_rebuild_python_venv": "Memperbaiki aplikasi Python setelah migrasi Bullseye", + "service_disable_failed": "Tidak dapat membuat layanan '{service}' dimulai saat pemulaian.\n\nLog layanan baru-baru ini:{logs}", + "service_disabled": "Layanan '{service}' tidak akan dimulai kembali saat pemulaian.", + "tools_upgrade_failed": "Tidak dapat memperbarui paket: {packages_list}", + "global_settings_setting_nginx_redirect_to_https": "Paksa HTTPS", + "backup_archive_system_part_not_available": "Segmen '{part}' tidak tersedia di cadangan ini", + "backup_output_directory_forbidden": "Pilih direktori yang berbeda. Cadangan tidak dapat dibuat di /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var, atau subfolder dari /home/yunohost.backup/archives", + "ask_dyndns_recovery_password_explain_during_unsubscribe": "Masukkan kata sandi pemulihan untuk domain DynDNS ini.", + "backup_output_symlink_dir_broken": "Direktori arsip Anda '{path}' rusak penautannya. Mungkin Anda lupa untuk menambatkan ulang atau memasukkan kembali penyimpanan tujuan penautan direktori arsip tersebut.", + "diagnosis_apps_not_in_app_catalog": "Aplikasi ini tidak ada di katalog aplikasi YunoHost. Jika aplikasi ini ada di sana sebelumnya dan dihapus, Anda disarankan untuk melepas aplikasi ini dikarenakan ini tidak akan menerima pembaruan dan mungkin bisa menghancurkan integritas dan keamanan sistem Anda.", + "dyndns_ip_update_failed": "Tidak dapat memperbarui IP Anda di DynDNS", + "service_restarted": "Layanan {service} dimulai ulang", + "service_started": "Layanan '{service}' dimulai", + "service_stop_failed": "Tidak dapat menghentikan layanan '{service}'\n\nLog layanan baru-baru ini: {logs}", + "apps_catalog_failed_to_download": "Tidak dapat mengunduh katalog aplikasi {apps_catalog}: {error}", + "backup_archive_corrupted": "Sepertinya arsip cadangan '{archive}' rusak: {error}", + "diagnosis_found_errors": "{errors} masalah signifikan ditemukan terkait dengan {category}!", + "restore_system_part_failed": "Tidak dapat memulihkan segmen '{part}'", + "service_enable_failed": "Tidak dapat membuat layanan '{service}' dimulai mandiri saat pemulaian.\n\nLog layanan baru-baru ini:{logs}", + "service_not_reloading_because_conf_broken": "Tidak memuat atau memulai ulang layanan '{name}' karena konfigurasinya rusak: {errors}", + "service_reloaded": "Layanan {service} dimuat ulang" } From 576992899cdb4785980dd5916295953593923879 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 16 Aug 2023 19:18:37 +0200 Subject: [PATCH 009/113] apps: allow to use jinja {% if foobar %} blocks in their notifications/doc pages --- src/app.py | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/app.py b/src/app.py index 7f4acdc1a..0b1be18a6 100644 --- a/src/app.py +++ b/src/app.py @@ -186,11 +186,17 @@ def app_info(app, full=False, upgradable=False): ret["from_catalog"] = from_catalog # Hydrate app notifications and doc + rendered_doc = {} for pagename, content_per_lang in ret["manifest"]["doc"].items(): for lang, content in content_per_lang.items(): - ret["manifest"]["doc"][pagename][lang] = _hydrate_app_template( - content, settings - ) + rendered_content = _hydrate_app_template(content, settings) + # Rendered content may be empty because of conditional blocks + if not rendered_content: + continue + if pagename not in rendered_doc: + rendered_doc[pagename] = {} + rendered_doc[pagename][lang] = rendered_content + ret["manifest"]["doc"] = rendered_doc # Filter dismissed notification ret["manifest"]["notifications"] = { @@ -201,9 +207,16 @@ def app_info(app, full=False, upgradable=False): # Hydrate notifications (also filter uneeded post_upgrade notification based on version) for step, notifications in ret["manifest"]["notifications"].items(): + rendered_notifications = {} for name, content_per_lang in notifications.items(): for lang, content in content_per_lang.items(): - notifications[name][lang] = _hydrate_app_template(content, settings) + rendered_content = _hydrate_app_template(content, settings) + if not rendered_content: + continue + if name not in rendered_notifications: + rendered_notifications[name] = {} + rendered_notifications[name][lang] = rendered_content + ret["manifest"]["notifications"][step] = rendered_notifications ret["is_webapp"] = "domain" in settings and "path" in settings @@ -2230,6 +2243,13 @@ def _parse_app_doc_and_notifications(path): def _hydrate_app_template(template, data): + + # Apply jinja for stuff like {% if .. %} blocks, + # but only if there's indeed an if block (to try to reduce overhead or idk) + if "{%" in template: + from jinja2 import Template + template = Template(template).render(**data) + stuff_to_replace = set(re.findall(r"__[A-Z0-9]+?[A-Z0-9_]*?[A-Z0-9]*?__", template)) for stuff in stuff_to_replace: @@ -2238,7 +2258,7 @@ def _hydrate_app_template(template, data): if varname in data: template = template.replace(stuff, str(data[varname])) - return template + return template.strip() def _convert_v1_manifest_to_v2(manifest): @@ -3145,7 +3165,7 @@ def _filter_and_hydrate_notifications(notifications, current_version=None, data= else: return version.parse(name) > version.parse(current_version.split("~")[0]) - return { + out = { # Should we render the markdown maybe? idk name: _hydrate_app_template(_value_for_locale(content_per_lang), data) for name, content_per_lang in notifications.items() @@ -3154,6 +3174,9 @@ def _filter_and_hydrate_notifications(notifications, current_version=None, data= or is_version_more_recent_than_current_version(name, current_version) } + # Filter out empty notifications (notifications may be empty because of if blocks) + return {name:content for name, content in out.items() if content and content.strip()} + def _display_notifications(notifications, force=False): if not notifications: From 32376cf18ffce2cffb54e4adf30856cab39e842c Mon Sep 17 00:00:00 2001 From: Tagada <36127788+Tagadda@users.noreply.github.com> Date: Mon, 21 Aug 2023 16:39:54 +0200 Subject: [PATCH 010/113] Use the existing db_name setting for database provising This should help upgrading an app from packaging v1 when db_name was different from `app` --- src/utils/resources.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/utils/resources.py b/src/utils/resources.py index 60a5f44f6..ba02930c9 100644 --- a/src/utils/resources.py +++ b/src/utils/resources.py @@ -1337,8 +1337,8 @@ class DatabaseAppResource(AppResource): def provision_or_update(self, context: Dict = {}): # This is equivalent to ynh_sanitize_dbid - db_name = self.app.replace("-", "_").replace(".", "_") - db_user = db_name + db_user = self.app.replace("-", "_").replace(".", "_") + db_name = self.get_setting("db_name") || db_user self.set_setting("db_name", db_name) self.set_setting("db_user", db_user) @@ -1372,8 +1372,8 @@ class DatabaseAppResource(AppResource): ) def deprovision(self, context: Dict = {}): - db_name = self.app.replace("-", "_").replace(".", "_") - db_user = db_name + db_user = self.app.replace("-", "_").replace(".", "_") + db_name = self.get_setting("db_name") || db_user if self.dbtype == "mysql": self._run_script( From 07daa68770df82f92c1539228d5d003b9570fa29 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 22 Aug 2023 15:37:47 +0200 Subject: [PATCH 011/113] apps: BACKUP_CORE_ONLY was not set for pre-upgrade safety backups, resulting in unecessarily large pre-upgrade backups --- src/app.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/app.py b/src/app.py index 0b1be18a6..94485b176 100644 --- a/src/app.py +++ b/src/app.py @@ -707,9 +707,17 @@ def app_upgrade( safety_backup_name = f"{app_instance_name}-pre-upgrade2" other_safety_backup_name = f"{app_instance_name}-pre-upgrade1" - backup_create( - name=safety_backup_name, apps=[app_instance_name], system=None - ) + tweaked_backup_core_only = False + if "BACKUP_CORE_ONLY" not in os.environ: + tweaked_backup_core_only = True + os.environ["BACKUP_CORE_ONLY"] = "1" + try: + backup_create( + name=safety_backup_name, apps=[app_instance_name], system=None + ) + finally: + if tweaked_backup_core_only: + del os.environ["BACKUP_CORE_ONLY"] if safety_backup_name in backup_list()["archives"]: # if the backup suceeded, delete old safety backup to save space From ee4d94d3829192029e8ece8d87529a005280eea3 Mon Sep 17 00:00:00 2001 From: Tagada <36127788+Tagadda@users.noreply.github.com> Date: Tue, 22 Aug 2023 17:11:56 +0200 Subject: [PATCH 012/113] Update src/utils/resources.py Co-authored-by: Alexandre Aubin --- src/utils/resources.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/resources.py b/src/utils/resources.py index ba02930c9..fd476d9bd 100644 --- a/src/utils/resources.py +++ b/src/utils/resources.py @@ -1338,7 +1338,7 @@ class DatabaseAppResource(AppResource): def provision_or_update(self, context: Dict = {}): # This is equivalent to ynh_sanitize_dbid db_user = self.app.replace("-", "_").replace(".", "_") - db_name = self.get_setting("db_name") || db_user + db_name = self.get_setting("db_name") or db_user self.set_setting("db_name", db_name) self.set_setting("db_user", db_user) From 73a144fa4623f36f6f4b105801509cd5d183fec1 Mon Sep 17 00:00:00 2001 From: Tagada <36127788+Tagadda@users.noreply.github.com> Date: Tue, 22 Aug 2023 17:12:03 +0200 Subject: [PATCH 013/113] Update src/utils/resources.py Co-authored-by: Alexandre Aubin --- src/utils/resources.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/resources.py b/src/utils/resources.py index fd476d9bd..69b260334 100644 --- a/src/utils/resources.py +++ b/src/utils/resources.py @@ -1373,7 +1373,7 @@ class DatabaseAppResource(AppResource): def deprovision(self, context: Dict = {}): db_user = self.app.replace("-", "_").replace(".", "_") - db_name = self.get_setting("db_name") || db_user + db_name = self.get_setting("db_name") or db_user if self.dbtype == "mysql": self._run_script( From b0fe49ae8390299d022c84b5c824057fc28f7c31 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 22 Aug 2023 17:36:12 +0200 Subject: [PATCH 014/113] configpanels/forms : more edge cases with some questions not implementing some methods/attributes --- src/utils/configpanel.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/utils/configpanel.py b/src/utils/configpanel.py index ee9019303..12024855a 100644 --- a/src/utils/configpanel.py +++ b/src/utils/configpanel.py @@ -160,11 +160,15 @@ class ConfigPanel: result[key] = {"ask": ask} if "current_value" in option: question_class = OPTIONS[option.get("type", OptionType.string)] - result[key]["value"] = question_class.humanize( - option["current_value"], option - ) + if hasattr(question_class, "humanize"): + result[key]["value"] = question_class.humanize( + option["current_value"], option + ) + else: + result[key]["value"] = option["current_value"] + # FIXME: semantics, technically here this is not about a prompt... - if question_class.hide_user_input_in_prompt: + if getattr(question_class, "hide_user_input_in_prompt", None): result[key][ "value" ] = "**************" # Prevent displaying password in `config get` From 0b0514374502bfa3093f71de7777a4a72598e43b Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Fri, 25 Aug 2023 03:23:33 +0200 Subject: [PATCH 015/113] [fix] Diagnosis: reverse DNS check should be case-insensitive #2235 --- src/diagnosers/24-mail.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/diagnosers/24-mail.py b/src/diagnosers/24-mail.py index df14222a5..c7fe9d04b 100644 --- a/src/diagnosers/24-mail.py +++ b/src/diagnosers/24-mail.py @@ -43,7 +43,7 @@ class MyDiagnoser(Diagnoser): dependencies: List[str] = ["ip"] def run(self): - self.ehlo_domain = _get_maindomain() + self.ehlo_domain = _get_maindomain().lower() self.mail_domains = domain_list()["domains"] self.ipversions, self.ips = self.get_ips_checked() @@ -132,7 +132,7 @@ class MyDiagnoser(Diagnoser): summary=summary, details=[summary + "_details"], ) - elif r["helo"] != self.ehlo_domain: + elif r["helo"].lower() != self.ehlo_domain: yield dict( meta={"test": "mail_ehlo", "ipversion": ipversion}, data={"wrong_ehlo": r["helo"], "right_ehlo": self.ehlo_domain}, @@ -185,7 +185,7 @@ class MyDiagnoser(Diagnoser): rdns_domain = "" if len(value) > 0: rdns_domain = value[0][:-1] if value[0].endswith(".") else value[0] - if rdns_domain != self.ehlo_domain: + if rdns_domain.lower() != self.ehlo_domain: details = [ "diagnosis_mail_fcrdns_different_from_ehlo_domain_details" ] + details @@ -194,7 +194,7 @@ class MyDiagnoser(Diagnoser): data={ "ip": ip, "ehlo_domain": self.ehlo_domain, - "rdns_domain": rdns_domain, + "rdns_domain": rdns_domain.lower(), }, status="ERROR", summary="diagnosis_mail_fcrdns_different_from_ehlo_domain", From fde05c0ac2af8c2009be9952f7819604f9d56b6a Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Fri, 25 Aug 2023 20:53:30 +0200 Subject: [PATCH 016/113] [enh] bind heritage in config panel --- helpers/config | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/helpers/config b/helpers/config index 77f118c5f..6c6285cf6 100644 --- a/helpers/config +++ b/helpers/config @@ -108,11 +108,11 @@ _ynh_app_config_apply_one() { else local bind_after="" local bind_key_="$(echo "$bind" | cut -d: -f1)" - bind_key_=${bind_key_:-$short_setting} if [[ "$bind_key_" == *">"* ]]; then bind_after="$(echo "${bind_key_}" | cut -d'>' -f1)" bind_key_="$(echo "${bind_key_}" | cut -d'>' -f2)" fi + bind_key_=${bind_key_:-$short_setting} local bind_file="$(echo "$bind" | cut -d: -f2 | sed s@__INSTALL_DIR__@$install_dir@ | sed s@__FINALPATH__@$final_path@ | sed s/__APP__/$app/)" ynh_backup_if_checksum_is_different --file="$bind_file" @@ -139,15 +139,31 @@ loaded_toml = toml.loads(file_content, _dict=OrderedDict) for panel_name, panel in loaded_toml.items(): if not isinstance(panel, dict): continue + bind_panel = panel.get('bind') for section_name, section in panel.items(): if not isinstance(section, dict): continue + bind_section = section.get('bind', bind_panel) for name, param in section.items(): if not isinstance(param, dict): continue + + bind = param.get('bind') + + if not bind: + if bind_section: + bind = bind_section + else: + bind = 'settings' if param.get('type', 'string') != 'file' else 'null' + elif bind[-1] == ":" and bind_section and ":" in bind_section: + regex, bind_file = bind_section.split(":") + if ">" in bind: + bind = bind + bind_file + else: + bind = regex + bind + bind_file print(';'.join([ name, param.get('type', 'string'), - param.get('bind', 'settings' if param.get('type', 'string') != 'file' else 'null') + bind ])) EOL ) From 79e620ef428629a65b9717092cf4109d158fb168 Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Fri, 25 Aug 2023 21:12:01 +0200 Subject: [PATCH 017/113] [fix] Conflict type file and settings bind mode --- helpers/config | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/helpers/config b/helpers/config index 6c6285cf6..a44582acf 100644 --- a/helpers/config +++ b/helpers/config @@ -153,13 +153,16 @@ for panel_name, panel in loaded_toml.items(): if bind_section: bind = bind_section else: - bind = 'settings' if param.get('type', 'string') != 'file' else 'null' + bind = 'settings' elif bind[-1] == ":" and bind_section and ":" in bind_section: regex, bind_file = bind_section.split(":") if ">" in bind: bind = bind + bind_file else: bind = regex + bind + bind_file + if bind == "settings" and param.get('type', 'string') == 'file': + bind = 'null' + print(';'.join([ name, param.get('type', 'string'), From dcafac1913364e5da690c5c01af8fe62b68bee55 Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Fri, 25 Aug 2023 22:36:33 +0200 Subject: [PATCH 018/113] [fix] Combine bind section regex with bind panel file --- helpers/config | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/helpers/config b/helpers/config index a44582acf..5a41822cc 100644 --- a/helpers/config +++ b/helpers/config @@ -142,7 +142,16 @@ for panel_name, panel in loaded_toml.items(): bind_panel = panel.get('bind') for section_name, section in panel.items(): if not isinstance(section, dict): continue - bind_section = section.get('bind', bind_panel) + bind_section = section.get('bind') + if not bind_section: + bind_section = bind_panel + elif bind_section[-1] == ":" and bind_panel and ":" in bind_panel: + regex, bind_panel_file = bind_panel.split(":") + if ">" in bind_section: + bind_section = bind_section + bind_panel_file + else: + bind_section = regex + bind_section + bind_panel_file + for name, param in section.items(): if not isinstance(param, dict): continue From 65d25710725b06d281630644b80d8d01dfba1bde Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 31 Aug 2023 17:23:21 +0200 Subject: [PATCH 019/113] helpers: add new --group option for ynh_add_fpm_config to customize the Group parameter --- helpers/php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/helpers/php b/helpers/php index c9e5b1cb8..ee3d35cb1 100644 --- a/helpers/php +++ b/helpers/php @@ -70,8 +70,9 @@ YNH_PHP_VERSION=${YNH_PHP_VERSION:-$YNH_DEFAULT_PHP_VERSION} ynh_add_fpm_config() { local _globalphpversion=${phpversion-:} # Declare an array to define the options of this helper. - local legacy_args=vufpd - local -A args_array=([v]=phpversion= [u]=usage= [f]=footprint= [p]=package= [d]=dedicated_service) + local legacy_args=vufpdg + local -A args_array=([v]=phpversion= [u]=usage= [f]=footprint= [p]=package= [d]=dedicated_service [g]=group=) + local group local phpversion local usage local footprint @@ -80,6 +81,7 @@ ynh_add_fpm_config() { # Manage arguments with getopts ynh_handle_getopts_args "$@" package=${package:-} + group=${group:-} # The default behaviour is to use the template. local autogenconf=false @@ -180,12 +182,13 @@ ynh_add_fpm_config() { # Define the values to use for the configuration of PHP. ynh_get_scalable_phpfpm --usage=$usage --footprint=$footprint + local phpfpm_group=$([[ -n "$group" ]] && echo "$group" || echo "$app") local phpfpm_path="$YNH_APP_BASEDIR/conf/php-fpm.conf" echo " [__APP__] user = __APP__ -group = __APP__ +group = __PHPFPM_GROUP__ chdir = __INSTALL_DIR__ From 51d8608b40e2e2acd76a0ce34ceca9dab0cf13d0 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 31 Aug 2023 17:33:08 +0200 Subject: [PATCH 020/113] Update changelog for 11.2.4 --- debian/changelog | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/debian/changelog b/debian/changelog index 586f8387b..610109fcd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,18 @@ +yunohost (11.2.4) stable; urgency=low + + - doc: Improve --help for 'yunohost app install' ([#1702](https://github.com/yunohost/yunohost/pull/1702)) + - helpers: add new --group option for ynh_add_fpm_config to customize the Group parameter (65d25710) + - apps: allow to use jinja {% if foobar %} blocks in their notifications/doc pages (57699289) + - apps: BACKUP_CORE_ONLY was not set for pre-upgrade safety backups, resulting in unecessarily large pre-upgrade backups (07daa687) + - apps: Use the existing db_name setting for database provising to ease v1->v2 transition with specific db_name ([#1704](https://github.com/yunohost/yunohost/pull/1704)) + - configpanels/forms: more edge cases with some questions not implementing some methods/attributes (b0fe49ae) + - diagnosis: reverse DNS check should be case-insensitive #2235 ([#1705](https://github.com/yunohost/yunohost/pull/1705)) + - i18n: Translations updated for Galician, Indonesian, Polish, Spanish, Turkish + + Thanks to all contributors <3 ! (Grzegorz Cichocki, José M, Kuba Bazan, ljf (zamentur), massyas, Neko Nekowazarashi, selfhoster1312, Suleyman Harmandar, taco, Tagada) + + -- Alexandre Aubin Thu, 31 Aug 2023 17:30:21 +0200 + yunohost (11.2.3) stable; urgency=low - apps: fix another case of no attribute 'value' due to config panels/questions refactoring (4fda8ed49) From 6f3b194944502460422d0f06c02a7fd225387f58 Mon Sep 17 00:00:00 2001 From: ljf Date: Sat, 2 Sep 2023 22:47:02 +0200 Subject: [PATCH 021/113] [fix] Avoid char conflict with bind properties --- helpers/config | 4 ++-- src/utils/configpanel.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/helpers/config b/helpers/config index 5a41822cc..fbf7febaa 100644 --- a/helpers/config +++ b/helpers/config @@ -172,7 +172,7 @@ for panel_name, panel in loaded_toml.items(): if bind == "settings" and param.get('type', 'string') == 'file': bind = 'null' - print(';'.join([ + print('|'.join([ name, param.get('type', 'string'), bind @@ -181,7 +181,7 @@ EOL ) for line in $lines; do # Split line into short_setting, type and bind - IFS=';' read short_setting type bind <<<"$line" + IFS='|' read short_setting type bind <<<"$line" binds[${short_setting}]="$bind" types[${short_setting}]="$type" file_hash[${short_setting}]="" diff --git a/src/utils/configpanel.py b/src/utils/configpanel.py index 12024855a..cc93f888f 100644 --- a/src/utils/configpanel.py +++ b/src/utils/configpanel.py @@ -345,14 +345,14 @@ class ConfigPanel: "defaults": {"version": 1.0}, }, "panels": { - "properties": ["name", "services", "actions", "help"], + "properties": ["name", "services", "actions", "help", "bind"], "defaults": { "services": [], "actions": {"apply": {"en": "Apply"}}, }, }, "sections": { - "properties": ["name", "services", "optional", "help", "visible"], + "properties": ["name", "services", "optional", "help", "visible", "bind"], "defaults": { "name": "", "services": [], From ffa8eb38ed43cfee8c278d673c5ec72d009ed5e4 Mon Sep 17 00:00:00 2001 From: ljf Date: Mon, 4 Sep 2023 15:42:12 +0200 Subject: [PATCH 022/113] [enh] Add post_app_restore hook --- src/backup.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/backup.py b/src/backup.py index ce1e8ba2c..7dffce321 100644 --- a/src/backup.py +++ b/src/backup.py @@ -1554,6 +1554,12 @@ class RestoreManager: if not restore_failed: self.targets.set_result("apps", app_instance_name, "Success") operation_logger.success() + + # Call post_app_restore hook + env_dict = _make_environment_for_app_script( + app_instance_name + ) + hook_callback("post_app_restore", env=env_dict) else: self.targets.set_result("apps", app_instance_name, "Error") From 3dfab89c1f4c94115110b17b9a98efdfb0590a55 Mon Sep 17 00:00:00 2001 From: Kayou Date: Thu, 7 Sep 2023 14:59:08 +0200 Subject: [PATCH 023/113] check and re-download a prefetched file that doesn't match the checksum --- helpers/utils | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/helpers/utils b/helpers/utils index 52d7c734f..4694dd724 100644 --- a/helpers/utils +++ b/helpers/utils @@ -244,9 +244,11 @@ ynh_setup_source() { if [ "$src_format" = "docker" ]; then src_platform="${src_platform:-"linux/$YNH_ARCH"}" - elif test -e "$local_src"; then - cp $local_src $src_filename else + if test -e "$local_src"; then + cp $local_src $src_filename + fi + [ -n "$src_url" ] || ynh_die "Couldn't parse SOURCE_URL from $src_file_path ?" # If the file was prefetched but somehow doesn't match the sum, rm and redownload it From 79e41a1e4b9deed01181e8788bb8bec4493e2a32 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Thu, 7 Sep 2023 16:22:16 +0200 Subject: [PATCH 024/113] app.py: fix typo in log statement --- src/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app.py b/src/app.py index 94485b176..627909b70 100644 --- a/src/app.py +++ b/src/app.py @@ -809,7 +809,7 @@ def app_upgrade( and not no_safety_backup ): logger.warning( - "Upgrade failed ... attempting to restore the satefy backup (Yunohost first need to remove the app for this) ..." + "Upgrade failed ... attempting to restore the safety backup (Yunohost first need to remove the app for this) ..." ) app_remove(app_instance_name, force_workdir=extracted_app_folder) From 920fe527f4ef1ca5ffef72bc247497ac09bf5404 Mon Sep 17 00:00:00 2001 From: orhtej2 <2871798+orhtej2@users.noreply.github.com> Date: Thu, 7 Sep 2023 22:14:06 +0200 Subject: [PATCH 025/113] Allow system users to send mails from IPv6 localhost and in no-IP contexts. --- src/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app.py b/src/app.py index 627909b70..df5eecae2 100644 --- a/src/app.py +++ b/src/app.py @@ -3261,7 +3261,7 @@ def regen_mail_app_user_config_for_dovecot_and_postfix(only=None): if dovecot: hashed_password = _hash_user_password(settings["mail_pwd"]) dovecot_passwd.append( - f"{app}:{hashed_password}::::::allow_nets=127.0.0.1/24" + f"{app}:{hashed_password}::::::allow_nets=::1,127.0.0.1/24,local" ) if postfix: mail_user = settings.get("mail_user", app) From df1f3149ea1d2182f212823c69e1ac07d4a3cf72 Mon Sep 17 00:00:00 2001 From: stanislas Date: Tue, 12 Sep 2023 00:37:47 +0200 Subject: [PATCH 026/113] The p value of a DMARC record can take the values none, quarantine or reject The validation is no more about the being similar to the expected config. Now wre check that the value of the p parameter of a DMARC record has the value none, quarantine or reject. No check for other parameters but it could be improved --- src/diagnosers/12-dnsrecords.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/diagnosers/12-dnsrecords.py b/src/diagnosers/12-dnsrecords.py index 196a2e1f9..19becb753 100644 --- a/src/diagnosers/12-dnsrecords.py +++ b/src/diagnosers/12-dnsrecords.py @@ -215,6 +215,11 @@ class MyDiagnoser(Diagnoser): for part in current if not part.startswith("ip4:") and not part.startswith("ip6:") } + if "v=DMARC1" in r["value"]: + for param in current: + key, value = param.split("=") + if key == "p": + return value in ["none", "quarantine", "reject"] return expected == current elif r["type"] == "MX": # For MX, we want to ignore the priority From b54a71b0cf365042e3d6e6f364b64d5608b238e4 Mon Sep 17 00:00:00 2001 From: Florian Date: Tue, 12 Sep 2023 09:02:04 +0300 Subject: [PATCH 027/113] Fix missleading example for ynh_setup_source There shouldn't be any trailing / for folders for ynh_setup_source --- helpers/utils | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpers/utils b/helpers/utils index 4694dd724..8b28000d6 100644 --- a/helpers/utils +++ b/helpers/utils @@ -75,7 +75,7 @@ fi # usage: ynh_setup_source --dest_dir=dest_dir [--source_id=source_id] [--keep="file1 file2"] [--full_replace] # | arg: -d, --dest_dir= - Directory where to setup sources # | arg: -s, --source_id= - Name of the source, defaults to `main` (when the sources resource exists in manifest.toml) or (legacy) `app` otherwise -# | arg: -k, --keep= - Space-separated list of files/folders that will be backup/restored in $dest_dir, such as a config file you don't want to overwrite. For example 'conf.json secrets.json logs/' +# | arg: -k, --keep= - Space-separated list of files/folders that will be backup/restored in $dest_dir, such as a config file you don't want to overwrite. For example 'conf.json secrets.json logs' (no trailing `/` for folders) # | arg: -r, --full_replace= - Remove previous sources before installing new sources # # #### New 'sources' resources From cbb85f8c3b860422382c5ea5353b251127464442 Mon Sep 17 00:00:00 2001 From: axolotle Date: Sun, 24 Sep 2023 17:13:33 +0200 Subject: [PATCH 028/113] dyndns: handle too many requests in availability testing --- locales/en.json | 1 + src/dyndns.py | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/locales/en.json b/locales/en.json index 60f58f639..05194c7f0 100644 --- a/locales/en.json +++ b/locales/en.json @@ -396,6 +396,7 @@ "downloading": "Downloading...", "dpkg_is_broken": "You cannot do this right now because dpkg/APT (the system package managers) seems to be in a broken state... You can try to solve this issue by connecting through SSH and running `sudo apt install --fix-broken` and/or `sudo dpkg --configure -a` and/or `sudo dpkg --audit`.", "dpkg_lock_not_available": "This command can't be run right now because another program seems to be using the lock of dpkg (the system package manager)", + "dyndns_availability_too_many_requests": "YunoHost's free domain service received too many requests from you, wait 1 minute or so before trying again.", "dyndns_could_not_check_available": "Could not check if {domain} is available on {provider}.", "dyndns_domain_not_provided": "DynDNS provider {provider} cannot provide domain {domain}.", "dyndns_ip_update_failed": "Could not update IP address to DynDNS", diff --git a/src/dyndns.py b/src/dyndns.py index a3afd655f..c9bf8afe6 100644 --- a/src/dyndns.py +++ b/src/dyndns.py @@ -63,19 +63,28 @@ def _dyndns_available(domain): Returns: True if the domain is available, False otherwise. """ + import requests # lazy loading this module for performance reasons + logger.debug(f"Checking if domain {domain} is available on {DYNDNS_PROVIDER} ...") try: - r = download_json( - f"https://{DYNDNS_PROVIDER}/test/{domain}", expected_status_code=None - ) + r = requests.get(f"https://{DYNDNS_PROVIDER}/test/{domain}", timeout=30) except MoulinetteError as e: logger.error(str(e)) raise YunohostError( "dyndns_could_not_check_available", domain=domain, provider=DYNDNS_PROVIDER ) - return r == f"Domain {domain} is available" + if r.status_code == 200: + return r == f"Domain {domain} is available" + elif r.status_code == 409: + return False + elif r.status_code == 429: + raise YunohostValidationError("dyndns_availability_too_many_requests") + else: + raise YunohostError( + "dyndns_could_not_check_available", domain=domain, provider=DYNDNS_PROVIDER + ) @is_unit_operation(exclude=["recovery_password"]) From 322fc3b7124d0cf5d274b4d822a511a896670588 Mon Sep 17 00:00:00 2001 From: axolotle Date: Sun, 24 Sep 2023 17:15:56 +0200 Subject: [PATCH 029/113] dyndns: try to unsubscribe with password before subscribing if domain is not available --- src/dyndns.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/dyndns.py b/src/dyndns.py index c9bf8afe6..c634f169d 100644 --- a/src/dyndns.py +++ b/src/dyndns.py @@ -103,14 +103,26 @@ def dyndns_subscribe(operation_logger, domain=None, recovery_password=None): "dyndns_domain_not_provided", domain=domain, provider=DYNDNS_PROVIDER ) - # Verify if domain is available - if not _dyndns_available(domain): - raise YunohostValidationError("dyndns_unavailable", domain=domain) - # Check adding another dyndns domain is still allowed if not is_subscribing_allowed(): raise YunohostValidationError("domain_dyndns_already_subscribed") + # Verify if domain is available + if not _dyndns_available(domain): + # Prompt for a password if running in CLI and no password provided + if not recovery_password and Moulinette.interface.type == "cli": + logger.warning(m18n.n("ask_dyndns_recovery_password_explain_unavailable")) + recovery_password = Moulinette.prompt( + m18n.n("ask_dyndns_recovery_password"), is_password=True, confirm=True + ) + + if recovery_password: + # Try to unsubscribe the domain so it can be subscribed again + # If successful, it will be resubscribed with the same recovery password + dyndns_unsubscribe(domain=domain, recovery_password=recovery_password) + else: + raise YunohostValidationError("dyndns_unavailable", domain=domain) + # Prompt for a password if running in CLI and no password provided if not recovery_password and Moulinette.interface.type == "cli": logger.warning(m18n.n("ask_dyndns_recovery_password_explain")) From 67e28567ff6d4865dc8c3a3c3a2de89885b0b3e5 Mon Sep 17 00:00:00 2001 From: axolotle Date: Sun, 24 Sep 2023 17:19:24 +0200 Subject: [PATCH 030/113] dyndns: switch to ValidationError for some service response --- locales/en.json | 2 ++ src/dyndns.py | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/locales/en.json b/locales/en.json index 05194c7f0..d9f42dede 100644 --- a/locales/en.json +++ b/locales/en.json @@ -91,6 +91,7 @@ "ask_new_path": "New path", "ask_password": "Password", "ask_dyndns_recovery_password_explain": "Please pick a recovery password for your DynDNS domain, in case you need to reset it later.", + "ask_dyndns_recovery_password_explain_unavailable": "This DynDNS domain is not available, please enter the recovery password if this your domain.", "ask_dyndns_recovery_password": "DynDNS recovery password", "ask_dyndns_recovery_password_explain_during_unsubscribe": "Please enter the recovery password for this DynDNS domain.", "ask_user_domain": "Domain to use for the user's email address and XMPP account", @@ -411,6 +412,7 @@ "dyndns_unsubscribed": "DynDNS domain unsubscribed", "dyndns_unsubscribe_denied": "Failed to unsubscribe domain: invalid credentials", "dyndns_unsubscribe_already_unsubscribed": "Domain is already unsubscribed", + "dyndns_unsubscribe_too_many_requests": "YunoHost's free domain service received too many requests from you, wait 1 hour or so before trying again.", "dyndns_set_recovery_password_denied": "Failed to set recovery password: invalid key", "dyndns_set_recovery_password_unknown_domain": "Failed to set recovery password: domain not registered", "dyndns_set_recovery_password_invalid_password": "Failed to set recovery password: password is not strong enough", diff --git a/src/dyndns.py b/src/dyndns.py index c634f169d..8efa5e6df 100644 --- a/src/dyndns.py +++ b/src/dyndns.py @@ -273,9 +273,11 @@ def dyndns_unsubscribe(operation_logger, domain, recovery_password=None): # in /etc/yunohost/dyndns regen_conf(["yunohost"]) elif r.status_code == 403: - raise YunohostError("dyndns_unsubscribe_denied") + raise YunohostValidationError("dyndns_unsubscribe_denied") elif r.status_code == 409: - raise YunohostError("dyndns_unsubscribe_already_unsubscribed") + raise YunohostValidationError("dyndns_unsubscribe_already_unsubscribed") + elif r.status_code == 429: + raise YunohostValidationError("dyndns_unsubscribe_too_many_requests") else: raise YunohostError( "dyndns_unsubscribe_failed", From 65843bda6dd01ec679c809f8c501d12f06e8e6fd Mon Sep 17 00:00:00 2001 From: axolotle Date: Sun, 24 Sep 2023 18:11:28 +0200 Subject: [PATCH 031/113] dyndns: add postinstall recovery password handling --- src/tools.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/tools.py b/src/tools.py index cd48f00ee..2b0b566e2 100644 --- a/src/tools.py +++ b/src/tools.py @@ -157,7 +157,7 @@ def tools_postinstall( overwrite_root_password=True, ): from yunohost.dyndns import _dyndns_available - from yunohost.utils.dns import is_yunohost_dyndns_domain + from yunohost.utils.dns import is_yunohost_dyndns_domain, dyndns_unsubscribe from yunohost.utils.password import ( assert_password_is_strong_enough, assert_password_is_compatible, @@ -218,7 +218,14 @@ def tools_postinstall( ) else: if not available: - raise YunohostValidationError("dyndns_unavailable", domain=domain) + if dyndns_recovery_password: + # Try to unsubscribe the domain so it can be subscribed again + # If successful, it will be resubscribed with the same recovery password + dyndns_unsubscribe( + domain=domain, recovery_password=dyndns_recovery_password + ) + else: + raise YunohostValidationError("dyndns_unavailable", domain=domain) if os.system("iptables -V >/dev/null 2>/dev/null") != 0: raise YunohostValidationError( From 97c2cdc593966b554ad792fd54d33af6be3d84dd Mon Sep 17 00:00:00 2001 From: axolotle Date: Mon, 25 Sep 2023 13:55:01 +0200 Subject: [PATCH 032/113] domain: move domain files removal so dyndns API key still exists while trying to unsubscribe --- src/domain.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/domain.py b/src/domain.py index 8fc9799cd..40e8b50d0 100644 --- a/src/domain.py +++ b/src/domain.py @@ -342,6 +342,7 @@ def domain_remove( dyndns_recovery_password -- Recovery password used at the creation of the DynDNS domain ignore_dyndns -- If we just remove the DynDNS domain, without unsubscribing """ + import glob from yunohost.hook import hook_callback from yunohost.app import app_ssowatconf, app_info, app_remove from yunohost.utils.ldap import _get_ldap_interface @@ -427,15 +428,6 @@ def domain_remove( global domain_list_cache domain_list_cache = [] - stuff_to_delete = [ - f"/etc/yunohost/certs/{domain}", - f"/etc/yunohost/dyndns/K{domain}.+*", - f"{DOMAIN_SETTINGS_DIR}/{domain}.yml", - ] - - for stuff in stuff_to_delete: - rm(stuff, force=True, recursive=True) - # Sometime we have weird issues with the regenconf where some files # appears as manually modified even though they weren't touched ... # There are a few ideas why this happens (like backup/restore nginx @@ -469,6 +461,11 @@ def domain_remove( domain=domain, recovery_password=dyndns_recovery_password ) + rm(f"/etc/yunohost/certs/{domain}", force=True, recursive=True) + for key_file in glob.glob(f"/etc/yunohost/dyndns/K{domain}.+*"): + rm(key_file, force=True) + rm(f"{DOMAIN_SETTINGS_DIR}/{domain}.yml", force=True) + logger.success(m18n.n("domain_deleted")) From fc68f769f9c2e3923838be99fe8701ca239cdd48 Mon Sep 17 00:00:00 2001 From: axolotle Date: Mon, 25 Sep 2023 14:37:18 +0200 Subject: [PATCH 033/113] domain: add recovery passoword in config panel --- src/dns.py | 3 +++ src/domain.py | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/dns.py b/src/dns.py index e25d0f3ec..fbb461463 100644 --- a/src/dns.py +++ b/src/dns.py @@ -545,6 +545,9 @@ def _get_registrar_config_section(domain): "value": "yunohost", } ) + registrar_infos["recovery_password"] = OrderedDict( + {"type": "password", "ask": m18n.n("ask_dyndns_recovery_password"), "default": ""} + ) return OrderedDict(registrar_infos) elif is_special_use_tld(dns_zone): registrar_infos["registrar"] = OrderedDict( diff --git a/src/domain.py b/src/domain.py index 40e8b50d0..b68c7dffc 100644 --- a/src/domain.py +++ b/src/domain.py @@ -317,6 +317,11 @@ def domain_add( pass raise e + if dyndns and dyndns_recovery_password: + domain_config_set( + domain, "dns.registrar.recovery_password", dyndns_recovery_password + ) + hook_callback("post_domain_add", args=[domain]) logger.success(m18n.n("domain_created")) @@ -704,6 +709,14 @@ class DomainConfigPanel(ConfigPanel): domain=self.entity, other_app=app_map(raw=True)[self.entity]["/"]["id"], ) + if ( + "recovery_password" in self.future_values + and self.future_values["recovery_password"] + != self.values["recovery_password"] + ): + domain_dyndns_set_recovery_password( + self.entity, self.future_values["recovery_password"] + ) super()._apply() From e9802ce2dca0f91a175f121ebc31ff6f9a99c1f4 Mon Sep 17 00:00:00 2001 From: axolotle Date: Wed, 27 Sep 2023 19:31:50 +0200 Subject: [PATCH 034/113] domain dyndns: do not save recovery password --- src/domain.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/domain.py b/src/domain.py index b68c7dffc..154da54dc 100644 --- a/src/domain.py +++ b/src/domain.py @@ -317,11 +317,6 @@ def domain_add( pass raise e - if dyndns and dyndns_recovery_password: - domain_config_set( - domain, "dns.registrar.recovery_password", dyndns_recovery_password - ) - hook_callback("post_domain_add", args=[domain]) logger.success(m18n.n("domain_created")) @@ -710,13 +705,14 @@ class DomainConfigPanel(ConfigPanel): other_app=app_map(raw=True)[self.entity]["/"]["id"], ) if ( - "recovery_password" in self.future_values - and self.future_values["recovery_password"] - != self.values["recovery_password"] + "recovery_password" in self.new_values + and self.new_values["recovery_password"] ): domain_dyndns_set_recovery_password( - self.entity, self.future_values["recovery_password"] + self.entity, self.new_values["recovery_password"] ) + # Do not save password in yaml settings + del self.new_values["recovery_password"] super()._apply() From 2e86bae4efbeacff1026af9039f47090c65d504f Mon Sep 17 00:00:00 2001 From: axolotle Date: Wed, 27 Sep 2023 19:58:52 +0200 Subject: [PATCH 035/113] domain: make sure of it --- src/domain.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/domain.py b/src/domain.py index 154da54dc..04d8370e4 100644 --- a/src/domain.py +++ b/src/domain.py @@ -712,7 +712,9 @@ class DomainConfigPanel(ConfigPanel): self.entity, self.new_values["recovery_password"] ) # Do not save password in yaml settings + del self.values["recovery_password"] del self.new_values["recovery_password"] + assert "recovery_password" not in self.future_values super()._apply() From cd079459b98566d4fa2042ad1b30cde6a5a681cf Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 27 Sep 2023 20:47:17 +0200 Subject: [PATCH 036/113] dyndns: fix import typo --- src/tools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools.py b/src/tools.py index 2b0b566e2..088400067 100644 --- a/src/tools.py +++ b/src/tools.py @@ -156,8 +156,8 @@ def tools_postinstall( force_diskspace=False, overwrite_root_password=True, ): - from yunohost.dyndns import _dyndns_available - from yunohost.utils.dns import is_yunohost_dyndns_domain, dyndns_unsubscribe + from yunohost.dyndns import _dyndns_available, dyndns_unsubscribe + from yunohost.utils.dns import is_yunohost_dyndns_domain from yunohost.utils.password import ( assert_password_is_strong_enough, assert_password_is_compatible, From 2e4f2e8e3a7df7f45fb228fefe1ab8b757cc86f3 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 27 Sep 2023 20:57:16 +0200 Subject: [PATCH 037/113] quality: unused import --- src/dyndns.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dyndns.py b/src/dyndns.py index 8efa5e6df..78a6b0a90 100644 --- a/src/dyndns.py +++ b/src/dyndns.py @@ -27,7 +27,6 @@ from moulinette import Moulinette, m18n from moulinette.core import MoulinetteError from moulinette.utils.log import getActionLogger from moulinette.utils.filesystem import write_to_file, rm, chown, chmod -from moulinette.utils.network import download_json from yunohost.utils.error import YunohostError, YunohostValidationError from yunohost.domain import _get_maindomain From 82affd298452cbab360df4d93303c9817f146707 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 28 Sep 2023 14:19:00 +0200 Subject: [PATCH 038/113] dyndns: fix availability check, polish UX --- locales/en.json | 6 +++--- src/domain.py | 11 +++++++---- src/dyndns.py | 4 ++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/locales/en.json b/locales/en.json index d9f42dede..dbf95caa6 100644 --- a/locales/en.json +++ b/locales/en.json @@ -91,7 +91,7 @@ "ask_new_path": "New path", "ask_password": "Password", "ask_dyndns_recovery_password_explain": "Please pick a recovery password for your DynDNS domain, in case you need to reset it later.", - "ask_dyndns_recovery_password_explain_unavailable": "This DynDNS domain is not available, please enter the recovery password if this your domain.", + "ask_dyndns_recovery_password_explain_unavailable": "This DynDNS domain is aleady registered. If you are the person who originally registered this domain, you may enter the recovery password to reclaim this domain.", "ask_dyndns_recovery_password": "DynDNS recovery password", "ask_dyndns_recovery_password_explain_during_unsubscribe": "Please enter the recovery password for this DynDNS domain.", "ask_user_domain": "Domain to use for the user's email address and XMPP account", @@ -397,7 +397,7 @@ "downloading": "Downloading...", "dpkg_is_broken": "You cannot do this right now because dpkg/APT (the system package managers) seems to be in a broken state... You can try to solve this issue by connecting through SSH and running `sudo apt install --fix-broken` and/or `sudo dpkg --configure -a` and/or `sudo dpkg --audit`.", "dpkg_lock_not_available": "This command can't be run right now because another program seems to be using the lock of dpkg (the system package manager)", - "dyndns_availability_too_many_requests": "YunoHost's free domain service received too many requests from you, wait 1 minute or so before trying again.", + "dyndns_availability_too_many_requests": "YunoHost's dyndns service received too many requests from you, wait 1 minute or so before trying again.", "dyndns_could_not_check_available": "Could not check if {domain} is available on {provider}.", "dyndns_domain_not_provided": "DynDNS provider {provider} cannot provide domain {domain}.", "dyndns_ip_update_failed": "Could not update IP address to DynDNS", @@ -412,7 +412,7 @@ "dyndns_unsubscribed": "DynDNS domain unsubscribed", "dyndns_unsubscribe_denied": "Failed to unsubscribe domain: invalid credentials", "dyndns_unsubscribe_already_unsubscribed": "Domain is already unsubscribed", - "dyndns_unsubscribe_too_many_requests": "YunoHost's free domain service received too many requests from you, wait 1 hour or so before trying again.", + "dyndns_unsubscribe_too_many_requests": "YunoHost's dyndns service received too many requests from you, wait 1 hour or so before trying again.", "dyndns_set_recovery_password_denied": "Failed to set recovery password: invalid key", "dyndns_set_recovery_password_unknown_domain": "Failed to set recovery password: domain not registered", "dyndns_set_recovery_password_invalid_password": "Failed to set recovery password: password is not strong enough", diff --git a/src/domain.py b/src/domain.py index 04d8370e4..beedf43e0 100644 --- a/src/domain.py +++ b/src/domain.py @@ -456,10 +456,13 @@ def domain_remove( # If a password is provided, delete the DynDNS record if dyndns: - # Actually unsubscribe - domain_dyndns_unsubscribe( - domain=domain, recovery_password=dyndns_recovery_password - ) + try: + # Actually unsubscribe + domain_dyndns_unsubscribe( + domain=domain, recovery_password=dyndns_recovery_password + ) + except Exception as e: + logger.warning(str(e)) rm(f"/etc/yunohost/certs/{domain}", force=True, recursive=True) for key_file in glob.glob(f"/etc/yunohost/dyndns/K{domain}.+*"): diff --git a/src/dyndns.py b/src/dyndns.py index 78a6b0a90..70f44672d 100644 --- a/src/dyndns.py +++ b/src/dyndns.py @@ -75,7 +75,7 @@ def _dyndns_available(domain): ) if r.status_code == 200: - return r == f"Domain {domain} is available" + return r.text.strip('"') == f"Domain {domain} is available" elif r.status_code == 409: return False elif r.status_code == 429: @@ -112,7 +112,7 @@ def dyndns_subscribe(operation_logger, domain=None, recovery_password=None): if not recovery_password and Moulinette.interface.type == "cli": logger.warning(m18n.n("ask_dyndns_recovery_password_explain_unavailable")) recovery_password = Moulinette.prompt( - m18n.n("ask_dyndns_recovery_password"), is_password=True, confirm=True + m18n.n("ask_dyndns_recovery_password"), is_password=True ) if recovery_password: From 53ffe3c1c07078998d192fb2128fdc5a8fa6868c Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 28 Sep 2023 14:25:36 +0200 Subject: [PATCH 039/113] dyndns: fix tests --- src/domain.py | 6 ++++-- src/tests/test_domains.py | 12 +++--------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/domain.py b/src/domain.py index beedf43e0..a503a129c 100644 --- a/src/domain.py +++ b/src/domain.py @@ -715,8 +715,10 @@ class DomainConfigPanel(ConfigPanel): self.entity, self.new_values["recovery_password"] ) # Do not save password in yaml settings - del self.values["recovery_password"] - del self.new_values["recovery_password"] + if "recovery_password" in self.values: + del self.values["recovery_password"] + if "recovery_password" in self.new_values: + del self.new_values["recovery_password"] assert "recovery_password" not in self.future_values super()._apply() diff --git a/src/tests/test_domains.py b/src/tests/test_domains.py index 1bbbb7890..03141b4fe 100644 --- a/src/tests/test_domains.py +++ b/src/tests/test_domains.py @@ -75,12 +75,13 @@ def test_domain_add(): assert TEST_DOMAINS[2] in domain_list()["domains"] -def test_domain_add_subscribe(): +def test_domain_add_and_remove_dyndns(): time.sleep(35) # Dynette blocks requests that happen too frequently assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] domain_add(TEST_DYNDNS_DOMAIN, dyndns_recovery_password=TEST_DYNDNS_PASSWORD) assert TEST_DYNDNS_DOMAIN in domain_list()["domains"] - + domain_remove(TEST_DYNDNS_DOMAIN, dyndns_recovery_password=TEST_DYNDNS_PASSWORD) + assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] def test_domain_add_existing_domain(): with pytest.raises(MoulinetteError): @@ -94,13 +95,6 @@ def test_domain_remove(): assert TEST_DOMAINS[1] not in domain_list()["domains"] -def test_domain_remove_unsubscribe(): - time.sleep(35) # Dynette blocks requests that happen too frequently - assert TEST_DYNDNS_DOMAIN in domain_list()["domains"] - domain_remove(TEST_DYNDNS_DOMAIN, dyndns_recovery_password=TEST_DYNDNS_PASSWORD) - assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] - - def test_main_domain(): current_main_domain = _get_maindomain() assert domain_main_domain()["current_main_domain"] == current_main_domain From 125af4670f74cf65890d4dc87d44749a9b546b32 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 28 Sep 2023 14:29:18 +0200 Subject: [PATCH 040/113] dyndns: typo --- locales/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/en.json b/locales/en.json index dbf95caa6..dddad3ef9 100644 --- a/locales/en.json +++ b/locales/en.json @@ -91,7 +91,7 @@ "ask_new_path": "New path", "ask_password": "Password", "ask_dyndns_recovery_password_explain": "Please pick a recovery password for your DynDNS domain, in case you need to reset it later.", - "ask_dyndns_recovery_password_explain_unavailable": "This DynDNS domain is aleady registered. If you are the person who originally registered this domain, you may enter the recovery password to reclaim this domain.", + "ask_dyndns_recovery_password_explain_unavailable": "This DynDNS domain is already registered. If you are the person who originally registered this domain, you may enter the recovery password to reclaim this domain.", "ask_dyndns_recovery_password": "DynDNS recovery password", "ask_dyndns_recovery_password_explain_during_unsubscribe": "Please enter the recovery password for this DynDNS domain.", "ask_user_domain": "Domain to use for the user's email address and XMPP account", From 0f109db6cadfa8bf29d45bfd76278197cf4a37e2 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 28 Sep 2023 14:29:53 +0200 Subject: [PATCH 041/113] dyndns/domain_remove: be paranoid and keep the dyndns unsubscribe + cert/dyndns/setting cleanup before the regenconf --- src/domain.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/domain.py b/src/domain.py index a503a129c..79194df2d 100644 --- a/src/domain.py +++ b/src/domain.py @@ -428,6 +428,21 @@ def domain_remove( global domain_list_cache domain_list_cache = [] + # If a password is provided, delete the DynDNS record + if dyndns: + try: + # Actually unsubscribe + domain_dyndns_unsubscribe( + domain=domain, recovery_password=dyndns_recovery_password + ) + except Exception as e: + logger.warning(str(e)) + + rm(f"/etc/yunohost/certs/{domain}", force=True, recursive=True) + for key_file in glob.glob(f"/etc/yunohost/dyndns/K{domain}.+*"): + rm(key_file, force=True) + rm(f"{DOMAIN_SETTINGS_DIR}/{domain}.yml", force=True) + # Sometime we have weird issues with the regenconf where some files # appears as manually modified even though they weren't touched ... # There are a few ideas why this happens (like backup/restore nginx @@ -454,21 +469,6 @@ def domain_remove( hook_callback("post_domain_remove", args=[domain]) - # If a password is provided, delete the DynDNS record - if dyndns: - try: - # Actually unsubscribe - domain_dyndns_unsubscribe( - domain=domain, recovery_password=dyndns_recovery_password - ) - except Exception as e: - logger.warning(str(e)) - - rm(f"/etc/yunohost/certs/{domain}", force=True, recursive=True) - for key_file in glob.glob(f"/etc/yunohost/dyndns/K{domain}.+*"): - rm(key_file, force=True) - rm(f"{DOMAIN_SETTINGS_DIR}/{domain}.yml", force=True) - logger.success(m18n.n("domain_deleted")) From ca1e088f2948d53905d3477fbcccb77fc61ae8e3 Mon Sep 17 00:00:00 2001 From: axolotle Date: Thu, 28 Sep 2023 15:41:57 +0200 Subject: [PATCH 042/113] test:domains: add complex recovery password test --- src/tests/test_domains.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/tests/test_domains.py b/src/tests/test_domains.py index 03141b4fe..b968777d2 100644 --- a/src/tests/test_domains.py +++ b/src/tests/test_domains.py @@ -83,6 +83,32 @@ def test_domain_add_and_remove_dyndns(): domain_remove(TEST_DYNDNS_DOMAIN, dyndns_recovery_password=TEST_DYNDNS_PASSWORD) assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] + +def test_domain_dyndns_recovery(): + # time.sleep(35) + assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] + # add domain without recovery password + domain_add(TEST_DYNDNS_DOMAIN) + assert TEST_DYNDNS_DOMAIN in domain_list()["domains"] + # set the recovery password with config panel + domain_config_set(TEST_DYNDNS_DOMAIN, "dns.registrar.recovery_password", TEST_DYNDNS_PASSWORD) + # remove domain without unsubscribing + domain_remove(TEST_DYNDNS_DOMAIN, ignore_dyndns=True) + assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] + # readding domain with bad password should fail + with pytest.raises(YunohostValidationError): + domain_add( + TEST_DYNDNS_DOMAIN, dyndns_recovery_password="wrong" + TEST_DYNDNS_PASSWORD + ) + assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] + # readding domain with password should work + domain_add(TEST_DYNDNS_DOMAIN, dyndns_recovery_password=TEST_DYNDNS_PASSWORD) + assert TEST_DYNDNS_DOMAIN in domain_list()["domains"] + # remove the dyndns domain + domain_remove(TEST_DYNDNS_DOMAIN, dyndns_recovery_password=TEST_DYNDNS_PASSWORD) + assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] + + def test_domain_add_existing_domain(): with pytest.raises(MoulinetteError): assert TEST_DOMAINS[1] in domain_list()["domains"] From 4a7b2b2cbfdb57f50dc2376272942050a922462e Mon Sep 17 00:00:00 2001 From: axolotle Date: Thu, 28 Sep 2023 15:54:57 +0200 Subject: [PATCH 043/113] domains: unique i18n key for dyndns too many requests --- locales/en.json | 3 +-- src/dyndns.py | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/locales/en.json b/locales/en.json index dddad3ef9..e7deb9e95 100644 --- a/locales/en.json +++ b/locales/en.json @@ -397,7 +397,6 @@ "downloading": "Downloading...", "dpkg_is_broken": "You cannot do this right now because dpkg/APT (the system package managers) seems to be in a broken state... You can try to solve this issue by connecting through SSH and running `sudo apt install --fix-broken` and/or `sudo dpkg --configure -a` and/or `sudo dpkg --audit`.", "dpkg_lock_not_available": "This command can't be run right now because another program seems to be using the lock of dpkg (the system package manager)", - "dyndns_availability_too_many_requests": "YunoHost's dyndns service received too many requests from you, wait 1 minute or so before trying again.", "dyndns_could_not_check_available": "Could not check if {domain} is available on {provider}.", "dyndns_domain_not_provided": "DynDNS provider {provider} cannot provide domain {domain}.", "dyndns_ip_update_failed": "Could not update IP address to DynDNS", @@ -408,11 +407,11 @@ "dyndns_provider_unreachable": "Unable to reach DynDNS provider {provider}: either your YunoHost is not correctly connected to the internet or the dynette server is down.", "dyndns_subscribed": "DynDNS domain subscribed", "dyndns_subscribe_failed": "Could not subscribe DynDNS domain: {error}", + "dyndns_too_many_requests": "YunoHost's dyndns service received too many requests from you, wait 1 hour or so before trying again.", "dyndns_unsubscribe_failed": "Could not unsubscribe DynDNS domain: {error}", "dyndns_unsubscribed": "DynDNS domain unsubscribed", "dyndns_unsubscribe_denied": "Failed to unsubscribe domain: invalid credentials", "dyndns_unsubscribe_already_unsubscribed": "Domain is already unsubscribed", - "dyndns_unsubscribe_too_many_requests": "YunoHost's dyndns service received too many requests from you, wait 1 hour or so before trying again.", "dyndns_set_recovery_password_denied": "Failed to set recovery password: invalid key", "dyndns_set_recovery_password_unknown_domain": "Failed to set recovery password: domain not registered", "dyndns_set_recovery_password_invalid_password": "Failed to set recovery password: password is not strong enough", diff --git a/src/dyndns.py b/src/dyndns.py index 70f44672d..387f33930 100644 --- a/src/dyndns.py +++ b/src/dyndns.py @@ -79,7 +79,7 @@ def _dyndns_available(domain): elif r.status_code == 409: return False elif r.status_code == 429: - raise YunohostValidationError("dyndns_availability_too_many_requests") + raise YunohostValidationError("dyndns_too_many_requests") else: raise YunohostError( "dyndns_could_not_check_available", domain=domain, provider=DYNDNS_PROVIDER @@ -276,7 +276,7 @@ def dyndns_unsubscribe(operation_logger, domain, recovery_password=None): elif r.status_code == 409: raise YunohostValidationError("dyndns_unsubscribe_already_unsubscribed") elif r.status_code == 429: - raise YunohostValidationError("dyndns_unsubscribe_too_many_requests") + raise YunohostValidationError("dyndns_too_many_requests") else: raise YunohostError( "dyndns_unsubscribe_failed", From c019f7f24ab80a9ab63d8f4bb8656dad24186f75 Mon Sep 17 00:00:00 2001 From: axolotle Date: Thu, 28 Sep 2023 16:48:31 +0200 Subject: [PATCH 044/113] test:domains: remove sleep --- src/tests/test_domains.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/test_domains.py b/src/tests/test_domains.py index b968777d2..bc2c31465 100644 --- a/src/tests/test_domains.py +++ b/src/tests/test_domains.py @@ -76,7 +76,7 @@ def test_domain_add(): def test_domain_add_and_remove_dyndns(): - time.sleep(35) # Dynette blocks requests that happen too frequently + # Devs: if you get `too_many_request` errors, ask the team to add your IP to the rate limit excempt assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] domain_add(TEST_DYNDNS_DOMAIN, dyndns_recovery_password=TEST_DYNDNS_PASSWORD) assert TEST_DYNDNS_DOMAIN in domain_list()["domains"] @@ -85,7 +85,7 @@ def test_domain_add_and_remove_dyndns(): def test_domain_dyndns_recovery(): - # time.sleep(35) + # Devs: if you get `too_many_request` errors, ask the team to add your IP to the rate limit excempt assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] # add domain without recovery password domain_add(TEST_DYNDNS_DOMAIN) From 253a042314ea5b4f24556c7019e054fdc59a190d Mon Sep 17 00:00:00 2001 From: axolotle Date: Thu, 28 Sep 2023 17:23:51 +0200 Subject: [PATCH 045/113] test:domains: dyndns_recovery mock as api call to avoid cli prompts --- src/tests/test_domains.py | 45 ++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/tests/test_domains.py b/src/tests/test_domains.py index bc2c31465..cc33a87d5 100644 --- a/src/tests/test_domains.py +++ b/src/tests/test_domains.py @@ -1,8 +1,10 @@ import pytest import os -import time import random +from mock import patch + +from moulinette import Moulinette from moulinette.core import MoulinetteError from yunohost.utils.error import YunohostError, YunohostValidationError @@ -87,25 +89,28 @@ def test_domain_add_and_remove_dyndns(): def test_domain_dyndns_recovery(): # Devs: if you get `too_many_request` errors, ask the team to add your IP to the rate limit excempt assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] - # add domain without recovery password - domain_add(TEST_DYNDNS_DOMAIN) - assert TEST_DYNDNS_DOMAIN in domain_list()["domains"] - # set the recovery password with config panel - domain_config_set(TEST_DYNDNS_DOMAIN, "dns.registrar.recovery_password", TEST_DYNDNS_PASSWORD) - # remove domain without unsubscribing - domain_remove(TEST_DYNDNS_DOMAIN, ignore_dyndns=True) - assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] - # readding domain with bad password should fail - with pytest.raises(YunohostValidationError): - domain_add( - TEST_DYNDNS_DOMAIN, dyndns_recovery_password="wrong" + TEST_DYNDNS_PASSWORD - ) - assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] - # readding domain with password should work - domain_add(TEST_DYNDNS_DOMAIN, dyndns_recovery_password=TEST_DYNDNS_PASSWORD) - assert TEST_DYNDNS_DOMAIN in domain_list()["domains"] - # remove the dyndns domain - domain_remove(TEST_DYNDNS_DOMAIN, dyndns_recovery_password=TEST_DYNDNS_PASSWORD) + # mocked as API call to avoid CLI prompts + with patch.object(Moulinette.interface, "type", "api"): + # add domain without recovery password + domain_add(TEST_DYNDNS_DOMAIN) + assert TEST_DYNDNS_DOMAIN in domain_list()["domains"] + # set the recovery password with config panel + domain_config_set(TEST_DYNDNS_DOMAIN, "dns.registrar.recovery_password", TEST_DYNDNS_PASSWORD) + # remove domain without unsubscribing + domain_remove(TEST_DYNDNS_DOMAIN, ignore_dyndns=True) + assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] + # readding domain with bad password should fail + with pytest.raises(YunohostValidationError): + domain_add( + TEST_DYNDNS_DOMAIN, dyndns_recovery_password="wrong" + TEST_DYNDNS_PASSWORD + ) + assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] + # readding domain with password should work + domain_add(TEST_DYNDNS_DOMAIN, dyndns_recovery_password=TEST_DYNDNS_PASSWORD) + assert TEST_DYNDNS_DOMAIN in domain_list()["domains"] + # remove the dyndns domain + domain_remove(TEST_DYNDNS_DOMAIN, dyndns_recovery_password=TEST_DYNDNS_PASSWORD) + assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] From bb097fedca2db668cbc8cc490887048478c86362 Mon Sep 17 00:00:00 2001 From: tituspijean Date: Fri, 29 Sep 2023 12:05:48 +0200 Subject: [PATCH 046/113] Add home.arpa as special TLD (#1718) * Add home.arpa as special TLD * Update dns.py --- src/utils/dns.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/dns.py b/src/utils/dns.py index b3ca4b564..569dad466 100644 --- a/src/utils/dns.py +++ b/src/utils/dns.py @@ -21,7 +21,7 @@ from typing import List from moulinette.utils.filesystem import read_file -SPECIAL_USE_TLDS = ["local", "localhost", "onion", "test"] +SPECIAL_USE_TLDS = ["home.arpa", "local", "localhost", "onion", "test"] YNH_DYNDNS_DOMAINS = ["nohost.me", "noho.st", "ynh.fr"] From a457f8dbcb754997cdcfb9205634839ee4a90394 Mon Sep 17 00:00:00 2001 From: axolotle Date: Fri, 29 Sep 2023 16:35:24 +0200 Subject: [PATCH 047/113] app: add "support_purge" to app info --- src/app.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app.py b/src/app.py index df5eecae2..78c61dfcd 100644 --- a/src/app.py +++ b/src/app.py @@ -237,6 +237,10 @@ def app_info(app, full=False, upgradable=False): ret["supports_config_panel"] = os.path.exists( os.path.join(setting_path, "config_panel.toml") ) + ret["supports_purge"] = ( + local_manifest["packaging_format"] >= 2 + and local_manifest["resources"].get("data_dir") is not None + ) ret["permissions"] = permissions ret["label"] = permissions.get(app + ".main", {}).get("label") From 58a539bf7d4edd87a9921d4381495a5bf441bf0c Mon Sep 17 00:00:00 2001 From: orhtej2 <2871798+orhtej2@users.noreply.github.com> Date: Mon, 2 Oct 2023 23:19:01 +0200 Subject: [PATCH 048/113] Allow `phpX.Y` as sole dependency that'll trigger usage of `$phpversion=X.Y` --- helpers/apt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpers/apt b/helpers/apt index a2f2d3de8..8ff9a3cd1 100644 --- a/helpers/apt +++ b/helpers/apt @@ -250,7 +250,7 @@ ynh_install_app_dependencies() { # Check for specific php dependencies which requires sury # This grep will for example return "7.4" if dependencies is "foo bar php7.4-pwet php-gni" # The (?<=php) syntax corresponds to lookbehind ;) - local specific_php_version=$(echo $dependencies | grep -oP '(?<=php)[0-9.]+(?=-|\>)' | sort -u) + local specific_php_version=$(echo $dependencies | grep -oP '(?<=php)[0-9.]+(?=-|\>|)' | sort -u) if [[ -n "$specific_php_version" ]] then From a83fbc1bc96a2e9d0763cf916a3d728d5e384c5a Mon Sep 17 00:00:00 2001 From: xabirequejo Date: Sat, 2 Sep 2023 20:37:20 +0000 Subject: [PATCH 049/113] Translated using Weblate (Basque) Currently translated at 95.0% (741 of 780 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/eu/ --- locales/eu.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/locales/eu.json b/locales/eu.json index 0267b3366..85e7c36fc 100644 --- a/locales/eu.json +++ b/locales/eu.json @@ -766,5 +766,13 @@ "group_mailalias_add": "'{mail}' ePosta aliasa jarri zaio '{group}' taldeari", "group_mailalias_remove": "'{mail}' ePosta aliasa kendu zaio '{group}' taldeari", "group_user_remove": "'{user}' erabiltzailea '{group}' taldetik kenduko da", - "group_user_add": "'{user}' erabiltzailea '{group}' taldera gehituko da" + "group_user_add": "'{user}' erabiltzailea '{group}' taldera gehituko da", + "ask_dyndns_recovery_password_explain": "Aukeratu DynDNS domeinua berreskuratzeko pasahitza, etorkizunean berrezarri beharko bazenu.", + "ask_dyndns_recovery_password_explain_during_unsubscribe": "Sartu DynDNS domeinurako berreskuraketa pasahitza.", + "dyndns_no_recovery_password": "Ez da berreskurapen pasahitzik zehaztu! Domeinuaren gaineko kontrola galduz gero, YunoHost taldeko administrariarekin jarri beharko zara harremanetan!", + "ask_dyndns_recovery_password": "DynDNS berreskuratzeko pasahitza", + "dyndns_subscribed": "DynDNS domeinua harpidetu da", + "dyndns_subscribe_failed": "Ezin izan da DynDNS domeinua harpidetu: {error}", + "dyndns_unsubscribe_failed": "Ezin izan da DynDNS domeinuaren harpidetza utzi: {error}", + "dyndns_unsubscribed": "DynDNS domeinuaren harpidetza utzi da" } From 179b60062191d333cf32225f309df9d45123569a Mon Sep 17 00:00:00 2001 From: ppr Date: Sat, 30 Sep 2023 11:07:30 +0000 Subject: [PATCH 050/113] Translated using Weblate (French) Currently translated at 98.3% (769 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/locales/fr.json b/locales/fr.json index 2cc0f612c..a6e41ba8e 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -781,6 +781,8 @@ "dyndns_set_recovery_password_unknown_domain": "Échec de la définition du mot de passe de récupération : le domaine n'est pas enregistré", "dyndns_set_recovery_password_invalid_password": "Échec de la définition du mot de passe de récupération : le mot de passe n'est pas assez fort/solide", "dyndns_set_recovery_password_failed": "Échec de la définition du mot de passe de récupération : {erreur}", - "dyndns_set_recovery_password_success": "Mot de passe de récupération défini/configuré !", - "log_dyndns_unsubscribe": "Se désabonner d'un sous-domaine YunoHost '{}'" + "dyndns_set_recovery_password_success": "Mot de passe de récupération activé/défini/configuré !", + "log_dyndns_unsubscribe": "Se désabonner d'un sous-domaine YunoHost '{}'", + "dyndns_too_many_requests": "Le service dyndns de YunoHost a reçu trop de requêtes/demandes de votre part, attendez environ 1 heure avant de réessayer.", + "ask_dyndns_recovery_password_explain_unavailable": "Ce domaine DynDNS est déjà enregistré. Si vous êtes la personne qui a enregistré ce domaine lors de sa création, vous pouvez entrer le mot de passe de récupération pour récupérer ce domaine." } From 6385b402f7665e4cc3a7308ace34a82cf57dd129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Tue, 3 Oct 2023 15:48:49 +0200 Subject: [PATCH 051/113] Add ynh_exec_stderr_on_error that only prints stderr when command fails --- helpers/logging | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/helpers/logging b/helpers/logging index ab5d564aa..8989140f6 100644 --- a/helpers/logging +++ b/helpers/logging @@ -186,6 +186,26 @@ ynh_exec_fully_quiet() { fi } +# Execute a command and redirect stderr in /dev/null. Print stderr on error. +# +# usage: ynh_exec_stderr_on_error your command and args +# | arg: command - command to execute +# +# Note that you should NOT quote the command but only prefix it with ynh_exec_stderr_on_error +# +# Requires YunoHost version 11.2 or higher. +ynh_exec_stderr_on_error() { + logfile="$(mktemp)" + rc=0 + # Note that "$@" is used and not $@, c.f. https://unix.stackexchange.com/a/129077 + "$@" 2> "$logfile" || rc="$?" + if (( rc != 0 )); then + ynh_exec_warn cat "$logfile" + ynh_secure_remove "$logfile" + return "$rc" + fi +} + # Remove any logs for all the following commands. # # usage: ynh_print_OFF @@ -248,7 +268,7 @@ ynh_script_progression() { # Re-disable xtrace, ynh_handle_getopts_args set it back set +o xtrace # set +x weight=${weight:-1} - + # Always activate time when running inside CI tests if [ ${PACKAGE_CHECK_EXEC:-0} -eq 1 ]; then time=${time:-1} From f4d8ada3688917a5915486a8ce70d14d4cd74c37 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin <4533074+alexAubin@users.noreply.github.com> Date: Mon, 9 Oct 2023 23:12:44 +0200 Subject: [PATCH 052/113] Update locales/fr.json --- locales/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.json b/locales/fr.json index a6e41ba8e..2e4d1602b 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -781,7 +781,7 @@ "dyndns_set_recovery_password_unknown_domain": "Échec de la définition du mot de passe de récupération : le domaine n'est pas enregistré", "dyndns_set_recovery_password_invalid_password": "Échec de la définition du mot de passe de récupération : le mot de passe n'est pas assez fort/solide", "dyndns_set_recovery_password_failed": "Échec de la définition du mot de passe de récupération : {erreur}", - "dyndns_set_recovery_password_success": "Mot de passe de récupération activé/défini/configuré !", + "dyndns_set_recovery_password_success": "Mot de passe de récupération changé !", "log_dyndns_unsubscribe": "Se désabonner d'un sous-domaine YunoHost '{}'", "dyndns_too_many_requests": "Le service dyndns de YunoHost a reçu trop de requêtes/demandes de votre part, attendez environ 1 heure avant de réessayer.", "ask_dyndns_recovery_password_explain_unavailable": "Ce domaine DynDNS est déjà enregistré. Si vous êtes la personne qui a enregistré ce domaine lors de sa création, vous pouvez entrer le mot de passe de récupération pour récupérer ce domaine." From e8700bfe7b621a236dae3d68730cb4189ddda78f Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 9 Oct 2023 23:15:54 +0200 Subject: [PATCH 053/113] debian: fix conflict with openssl that is too harsh, openssl version on bullseye is now 1.1.1w, bookworm has 3.x --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 0258eaac7..2fa1a1220 100644 --- a/debian/control +++ b/debian/control @@ -43,7 +43,7 @@ Conflicts: iptables-persistent , apache2 , bind9 , nginx-extras (>= 1.19) - , openssl (>= 1.1.1o-0) + , openssl (>= 3.0) , slapd (>= 2.4.58) , dovecot-core (>= 1:2.3.14) , redis-server (>= 5:6.1) From 6f1a00922a8fa866823ecd87dc6e6da2ab8e5005 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 10 Oct 2023 01:07:19 +0200 Subject: [PATCH 054/113] Update changelog for 11.2.5 --- debian/changelog | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/debian/changelog b/debian/changelog index 610109fcd..0effd40ba 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,21 @@ +yunohost (11.2.5) stable; urgency=low + + - debian: fix conflict with openssl that is too harsh, openssl version on bullseye is now 1.1.1w, bookworm has 3.x (e8700bfe7) + - dyndns: tweak dyndns subscribe/unsubscribe for dyndns recovery password integration in webadmin ([#1715](https://github.com/yunohost/yunohost/pull/1715)) + - helpers: ynh_setup_source: check and re-download a prefetched file that doesn't match the checksum (3dfab89c1) + - helpers: ynh_setup_source: fix misleading example ([#1714](https://github.com/yunohost/yunohost/pull/1714)) + - helpers: php/apt: allow `phpX.Y` as sole dependency for `$phpversion=X.Y` ([#1722](https://github.com/yunohost/yunohost/pull/1722)) + - apps: fix typo in log statement ([#1709](https://github.com/yunohost/yunohost/pull/1709)) + - apps: allow system users to send mails from IPv6 localhost. ([#1710](https://github.com/yunohost/yunohost/pull/1710)) + - apps: add "support_purge" to app info for webadmin integration ([#1719](https://github.com/yunohost/yunohost/pull/1719)) + - diagnosis: be more flexible regarding accepted values for DMARC DNS records ([#1713](https://github.com/yunohost/yunohost/pull/1713)) + - dns: add home.arpa as special TLD (#1718) (bb097fedc) + - i18n: Translations updated for Basque, French + + Thanks to all contributors <3 ! (axolotle, Florian, Kayou, orhtej2, Pierre de La Morinerie, ppr, stanislas, tituspijean, xabirequejo) + + -- Alexandre Aubin Mon, 09 Oct 2023 23:16:13 +0200 + yunohost (11.2.4) stable; urgency=low - doc: Improve --help for 'yunohost app install' ([#1702](https://github.com/yunohost/yunohost/pull/1702)) From f003565074f2349a1341c0a672c94888992635e0 Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Tue, 10 Oct 2023 02:31:47 +0000 Subject: [PATCH 055/113] [CI] Format code with Black --- src/app.py | 6 ++++-- src/dns.py | 6 +++++- src/tests/test_domains.py | 7 +++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/app.py b/src/app.py index 78c61dfcd..12b3c4233 100644 --- a/src/app.py +++ b/src/app.py @@ -2255,11 +2255,11 @@ def _parse_app_doc_and_notifications(path): def _hydrate_app_template(template, data): - # Apply jinja for stuff like {% if .. %} blocks, # but only if there's indeed an if block (to try to reduce overhead or idk) if "{%" in template: from jinja2 import Template + template = Template(template).render(**data) stuff_to_replace = set(re.findall(r"__[A-Z0-9]+?[A-Z0-9_]*?[A-Z0-9]*?__", template)) @@ -3187,7 +3187,9 @@ def _filter_and_hydrate_notifications(notifications, current_version=None, data= } # Filter out empty notifications (notifications may be empty because of if blocks) - return {name:content for name, content in out.items() if content and content.strip()} + return { + name: content for name, content in out.items() if content and content.strip() + } def _display_notifications(notifications, force=False): diff --git a/src/dns.py b/src/dns.py index fbb461463..1ec88a5c0 100644 --- a/src/dns.py +++ b/src/dns.py @@ -546,7 +546,11 @@ def _get_registrar_config_section(domain): } ) registrar_infos["recovery_password"] = OrderedDict( - {"type": "password", "ask": m18n.n("ask_dyndns_recovery_password"), "default": ""} + { + "type": "password", + "ask": m18n.n("ask_dyndns_recovery_password"), + "default": "", + } ) return OrderedDict(registrar_infos) elif is_special_use_tld(dns_zone): diff --git a/src/tests/test_domains.py b/src/tests/test_domains.py index cc33a87d5..13a9f63b8 100644 --- a/src/tests/test_domains.py +++ b/src/tests/test_domains.py @@ -95,14 +95,17 @@ def test_domain_dyndns_recovery(): domain_add(TEST_DYNDNS_DOMAIN) assert TEST_DYNDNS_DOMAIN in domain_list()["domains"] # set the recovery password with config panel - domain_config_set(TEST_DYNDNS_DOMAIN, "dns.registrar.recovery_password", TEST_DYNDNS_PASSWORD) + domain_config_set( + TEST_DYNDNS_DOMAIN, "dns.registrar.recovery_password", TEST_DYNDNS_PASSWORD + ) # remove domain without unsubscribing domain_remove(TEST_DYNDNS_DOMAIN, ignore_dyndns=True) assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] # readding domain with bad password should fail with pytest.raises(YunohostValidationError): domain_add( - TEST_DYNDNS_DOMAIN, dyndns_recovery_password="wrong" + TEST_DYNDNS_PASSWORD + TEST_DYNDNS_DOMAIN, + dyndns_recovery_password="wrong" + TEST_DYNDNS_PASSWORD, ) assert TEST_DYNDNS_DOMAIN not in domain_list()["domains"] # readding domain with password should work From 6a8693fa44dc4617015421f1364788b2001d6e3b Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Sun, 15 Oct 2023 05:10:23 +0000 Subject: [PATCH 056/113] Upgrade n to v --- helpers/vendor/n/n | 61 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/helpers/vendor/n/n b/helpers/vendor/n/n index 2a877c45b..eb276a2f5 100755 --- a/helpers/vendor/n/n +++ b/helpers/vendor/n/n @@ -61,7 +61,7 @@ function n_grep() { # Setup and state # -VERSION="v9.1.0" +VERSION="v9.2.0" N_PREFIX="${N_PREFIX-/usr/local}" N_PREFIX=${N_PREFIX%/} @@ -135,6 +135,7 @@ g_target_node= DOWNLOAD=false # set to opt-out of activate (install), and opt-in to download (run, exec) ARCH= SHOW_VERBOSE_LOG="true" +OFFLINE=false # ANSI escape codes # https://en.wikipedia.org/wiki/ANSI_escape_code @@ -393,6 +394,7 @@ Options: -q, --quiet Disable curl output. Disable log messages processing "auto" and "engine" labels. -d, --download Download if necessary, and don't make active -a, --arch Override system architecture + --offline Resolve target version against cached downloads instead of internet lookup --all ls-remote displays all matches instead of last 20 --insecure Turn off certificate checking for https requests (may be needed from behind a proxy server) --use-xz/--no-use-xz Override automatic detection of xz support and enable/disable use of xz compressed node downloads. @@ -784,6 +786,9 @@ install() { exit fi fi + if [[ "$OFFLINE" == "true" ]]; then + abort "version unavailable offline" + fi log installing "${g_mirror_folder_name}-v$version" @@ -1103,6 +1108,7 @@ function get_package_engine_version() { verbose_log "target" "${version}" else command -v npx &> /dev/null || abort "an active version of npx is required to use complex 'engine' ranges from package.json" + [[ "$OFFLINE" != "true" ]] || abort "offline: an internet connection is required for looking up complex 'engine' ranges from package.json" verbose_log "resolving" "${range}" local version_per_line="$(n lsr --all)" local versions_one_line=$(echo "${version_per_line}" | tr '\n' ' ') @@ -1199,6 +1205,8 @@ function get_latest_resolved_version() { # Just numbers, already resolved, no need to lookup first. simple_version="${simple_version#v}" g_target_node="${simple_version}" + elif [[ "$OFFLINE" == "true" ]]; then + g_target_node=$(display_local_versions "${version}") else # Complicated recognising exact version, KISS and lookup. g_target_node=$(N_MAX_REMOTE_MATCHES=1 display_remote_versions "$version") @@ -1232,6 +1240,56 @@ function display_match_limit(){ fi } +# +# Synopsis: display_local_versions version +# + +function display_local_versions() { + local version="$1" + local match='.' + verbose_log "offline" "matching cached versions" + + # Transform some labels before processing further. + if is_node_support_version "${version}"; then + version="$(display_latest_node_support_alias "${version}")" + match_count=1 + elif [[ "${version}" = "auto" ]]; then + # suppress stdout logging so lsr layout same as usual for scripting + get_auto_version || return 2 + version="${g_target_node}" + elif [[ "${version}" = "engine" ]]; then + # suppress stdout logging so lsr layout same as usual for scripting + get_engine_version || return 2 + version="${g_target_node}" + fi + + if [[ "${version}" = "latest" || "${version}" = "current" ]]; then + match='^node/.' + elif is_exact_numeric_version "${version}"; then + # Quote any dots in version so they are literal for expression + match="^node/${version//\./\.}" + elif is_numeric_version "${version}"; then + version="${version#v}" + # Quote any dots in version so they are literal for expression + match="${version//\./\.}" + # Avoid 1.2 matching 1.23 + match="^node/${match}[^0-9]" + # elif is_lts_codename "${version}"; then + # see if demand + elif is_download_folder "${version}"; then + match="^${version}/" + # elif is_download_version "${version}"; then + # see if demand + else + abort "invalid version '$1' for offline matching" + fi + + display_versions_paths \ + | n_grep -E "${match}" \ + | tail -n 1 \ + | sed 's|node/||' +} + # # Synopsis: display_remote_versions version # @@ -1577,6 +1635,7 @@ while [[ $# -ne 0 ]]; do -h|--help|help) display_help; exit ;; -q|--quiet) set_quiet ;; -d|--download) DOWNLOAD="true" ;; + --offline) OFFLINE="true" ;; --insecure) set_insecure ;; -p|--preserve) N_PRESERVE_NPM="true" N_PRESERVE_COREPACK="true" ;; --no-preserve) N_PRESERVE_NPM="" N_PRESERVE_COREPACK="" ;; From 075095b4d7d72c6abb8870a1914a5da436401930 Mon Sep 17 00:00:00 2001 From: tituspijean Date: Sun, 15 Oct 2023 14:59:45 +0200 Subject: [PATCH 057/113] Display n version in auto-update PRs --- .github/workflows/n_updater.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/n_updater.yml b/.github/workflows/n_updater.yml index ce3e9c925..a1a835a78 100644 --- a/.github/workflows/n_updater.yml +++ b/.github/workflows/n_updater.yml @@ -20,9 +20,11 @@ jobs: # Setting up Git user git config --global user.name 'yunohost-bot' git config --global user.email 'yunohost-bot@users.noreply.github.com' - # Run the updater script + # Download n wget https://raw.githubusercontent.com/tj/n/master/bin/n --output-document=helpers/vendor/n/n + # Proceed only if there is a change [[ -z "$(git diff helpers/vendor/n/n)" ]] || echo "PROCEED=true" >> $GITHUB_ENV + echo "VERSION=$(sed -n 's/^VERSION=\"\(.*\)\"/\1/p' < n)" >> $GITHUB_ENV - name: Commit changes id: commit if: ${{ env.PROCEED == 'true' }} @@ -34,14 +36,14 @@ jobs: uses: peter-evans/create-pull-request@v3 with: token: ${{ secrets.GITHUB_TOKEN }} - commit-message: Update n to version ${{ env.VERSION }} + commit-message: Update n to ${{ env.VERSION }} committer: 'yunohost-bot ' author: 'yunohost-bot ' signoff: false base: dev branch: ci-auto-update-n-v${{ env.VERSION }} delete-branch: true - title: 'Upgrade n to version ${{ env.VERSION }}' + title: 'Upgrade n to ${{ env.VERSION }}' body: | - Upgrade `n` to v${{ env.VERSION }} + Upgrade `n` to ${{ env.VERSION }} draft: false From 96e99459e6271c49de9b6f07ec8bbf4307aa24e4 Mon Sep 17 00:00:00 2001 From: tituspijean Date: Sun, 15 Oct 2023 16:31:14 +0200 Subject: [PATCH 058/113] Support packages_from_raw_bash in extra packages --- src/utils/resources.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/utils/resources.py b/src/utils/resources.py index 69b260334..f206b9b96 100644 --- a/src/utils/resources.py +++ b/src/utils/resources.py @@ -1086,7 +1086,6 @@ class AptDependenciesAppResource(AppResource): packages: List = [] packages_from_raw_bash: str = "" extras: Dict[str, Dict[str, Union[str, List]]] = {} - def __init__(self, properties: Dict[str, Any], *args, **kwargs): super().__init__(properties, *args, **kwargs) @@ -1106,13 +1105,25 @@ class AptDependenciesAppResource(AppResource): if isinstance(values.get("packages"), str): values["packages"] = [value.strip() for value in values["packages"].split(",")] # type: ignore + if isinstance(values.get("packages_from_raw_bash"), str): + out, err = self.check_output_bash_snippet(values.get("packages_from_raw_bash")) + if err: + logger.error( + "Error while running apt resource packages_from_raw_bash snippet for '" + str(key) + "' extras:" + ) + logger.error(err) + values["packages"] = [value.strip() for value in out.split("\n")] + if ( not isinstance(values.get("repo"), str) or not isinstance(values.get("key"), str) - or not isinstance(values.get("packages"), list) + or ( + not isinstance(values.get("packages"), list) + and not isinstance(values.get("packages_from_raw_bash"), str) + ) ): raise YunohostError( - "In apt resource in the manifest: 'extras' repo should have the keys 'repo', 'key' defined as strings and 'packages' defined as list", + "In apt resource in the manifest: 'extras' repo should have the keys 'repo', 'key' defined as strings, 'packages' defined as list or 'packages_from_raw_bash' defined as string", raw_msg=True, ) From a69b80972eaec9673dc848b7ef09a043e0730272 Mon Sep 17 00:00:00 2001 From: tituspijean Date: Sun, 15 Oct 2023 16:46:24 +0200 Subject: [PATCH 059/113] Improve support for packages_from_raw_bash Co-authored-by: Alexandre Aubin <4533074+alexAubin@users.noreply.github.com> --- src/utils/resources.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/utils/resources.py b/src/utils/resources.py index f206b9b96..18b1bdb4c 100644 --- a/src/utils/resources.py +++ b/src/utils/resources.py @@ -1109,10 +1109,10 @@ class AptDependenciesAppResource(AppResource): out, err = self.check_output_bash_snippet(values.get("packages_from_raw_bash")) if err: logger.error( - "Error while running apt resource packages_from_raw_bash snippet for '" + str(key) + "' extras:" + f"Error while running apt resource packages_from_raw_bash snippet for '{key}' extras:" ) logger.error(err) - values["packages"] = [value.strip() for value in out.split("\n")] + values["packages"] = values.get("packages", []) + [value.strip() for value in out.split("\n")] if ( not isinstance(values.get("repo"), str) @@ -1126,6 +1126,9 @@ class AptDependenciesAppResource(AppResource): "In apt resource in the manifest: 'extras' repo should have the keys 'repo', 'key' defined as strings, 'packages' defined as list or 'packages_from_raw_bash' defined as string", raw_msg=True, ) + + # Drop 'extras' entries associated to no packages + self.extras = {key: value for key, values in self.extras.items() if values["packages"]} def provision_or_update(self, context: Dict = {}): script = " ".join(["ynh_install_app_dependencies", *self.packages]) From dc362dd636eaf912c788b2d468c015eb7bf035d1 Mon Sep 17 00:00:00 2001 From: tituspijean Date: Sun, 15 Oct 2023 16:48:59 +0200 Subject: [PATCH 060/113] Revert packages_from_raw_bash test Co-authored-by: Alexandre Aubin --- src/utils/resources.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/utils/resources.py b/src/utils/resources.py index 18b1bdb4c..ba1a915e4 100644 --- a/src/utils/resources.py +++ b/src/utils/resources.py @@ -1117,10 +1117,7 @@ class AptDependenciesAppResource(AppResource): if ( not isinstance(values.get("repo"), str) or not isinstance(values.get("key"), str) - or ( - not isinstance(values.get("packages"), list) - and not isinstance(values.get("packages_from_raw_bash"), str) - ) + or not isinstance(values.get("packages"), list) ): raise YunohostError( "In apt resource in the manifest: 'extras' repo should have the keys 'repo', 'key' defined as strings, 'packages' defined as list or 'packages_from_raw_bash' defined as string", From 23cdf91b0198ce8d4a034aea04f95406795b7c5f Mon Sep 17 00:00:00 2001 From: tituspijean Date: Sun, 15 Oct 2023 16:49:55 +0200 Subject: [PATCH 061/113] Restore deleted line --- src/utils/resources.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/resources.py b/src/utils/resources.py index ba1a915e4..87f6ae368 100644 --- a/src/utils/resources.py +++ b/src/utils/resources.py @@ -1086,6 +1086,7 @@ class AptDependenciesAppResource(AppResource): packages: List = [] packages_from_raw_bash: str = "" extras: Dict[str, Dict[str, Union[str, List]]] = {} + def __init__(self, properties: Dict[str, Any], *args, **kwargs): super().__init__(properties, *args, **kwargs) From 662998a1ab229f1c3cd2cdb736149fb3589aa23d Mon Sep 17 00:00:00 2001 From: Alexandre Aubin <4533074+alexAubin@users.noreply.github.com> Date: Mon, 16 Oct 2023 15:49:12 +0200 Subject: [PATCH 062/113] Update src/utils/resources.py --- src/utils/resources.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils/resources.py b/src/utils/resources.py index 87f6ae368..ba1a915e4 100644 --- a/src/utils/resources.py +++ b/src/utils/resources.py @@ -1086,7 +1086,6 @@ class AptDependenciesAppResource(AppResource): packages: List = [] packages_from_raw_bash: str = "" extras: Dict[str, Dict[str, Union[str, List]]] = {} - def __init__(self, properties: Dict[str, Any], *args, **kwargs): super().__init__(properties, *args, **kwargs) From a2faa8add90d512e56c4dae999a813b53d513a5b Mon Sep 17 00:00:00 2001 From: Chris Vogel Date: Tue, 17 Oct 2023 14:49:32 +0200 Subject: [PATCH 063/113] add redis database configuration https://github.com/YunoHost/issues/issues/2266 without this rspamd does not use the redis database --- conf/rspamd/redis.conf | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 conf/rspamd/redis.conf diff --git a/conf/rspamd/redis.conf b/conf/rspamd/redis.conf new file mode 100644 index 000000000..03152581e --- /dev/null +++ b/conf/rspamd/redis.conf @@ -0,0 +1,2 @@ +# set redis server +servers = "127.0.0.1"; From 379b6922ad16cb744c9c3fba2138613fbf2e68d5 Mon Sep 17 00:00:00 2001 From: Chris Vogel Date: Tue, 17 Oct 2023 21:13:09 +0200 Subject: [PATCH 064/113] install file to redis configuration ouch... Thanks @Tagadda! --- hooks/conf_regen/31-rspamd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hooks/conf_regen/31-rspamd b/hooks/conf_regen/31-rspamd index 6807ce0cd..6333a755f 100755 --- a/hooks/conf_regen/31-rspamd +++ b/hooks/conf_regen/31-rspamd @@ -13,6 +13,8 @@ do_pre_regen() { "${pending_dir}/etc/rspamd/local.d/dkim_signing.conf" install -D -m 644 rspamd.sieve \ "${pending_dir}/etc/dovecot/global_script/rspamd.sieve" + install -D -m 644 redis.conf \ + "${pending_dir}/etc/rspamd/local.d/redis.conf" } do_post_regen() { From e6e58ec2695fff37b617f67361ef218fb8d70c94 Mon Sep 17 00:00:00 2001 From: Chris Vogel Date: Wed, 18 Oct 2023 23:04:24 +0200 Subject: [PATCH 065/113] improve dovecots rspamd integration For rspamd being able to learn ham or spam from messages being moved into spam/junk folders or out of them dovecot needs to know how spam/junk folders and trash folders are named. The former rules narrowed the folders being recognized as spam/trash down to just 'Junk, SPAM, Trash' (case-senistive). Since users and admins can change the foldernames and write their own seive filters to use those folders I think it is a big improvement if more folders will be recognized. The change is supposed to accept some more commonly used folder names for spam and trash in a case-insensitive manner. --- conf/dovecot/dovecot.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/dovecot/dovecot.conf b/conf/dovecot/dovecot.conf index 152f4c01c..4f491d1df 100644 --- a/conf/dovecot/dovecot.conf +++ b/conf/dovecot/dovecot.conf @@ -119,8 +119,8 @@ plugin { antispam_debug_target = syslog antispam_verbose_debug = 0 antispam_backend = pipe - antispam_spam = Junk;SPAM - antispam_trash = Trash + antispam_spam_pattern_ignorecase = junk;spam + antispam_trash_pattern_ignorecase = trash;papierkorb;deleted messages antispam_pipe_program = /usr/bin/rspamc antispam_pipe_program_args = -h;localhost:11334;-P;q1 antispam_pipe_program_spam_arg = learn_spam From 74fd75ea33e8ddf246a8c83e3035d6f11b733089 Mon Sep 17 00:00:00 2001 From: Sebastian Gumprich Date: Sun, 22 Oct 2023 18:43:26 +0200 Subject: [PATCH 066/113] fix typos --- src/utils/resources.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/utils/resources.py b/src/utils/resources.py index 69b260334..1720b4890 100644 --- a/src/utils/resources.py +++ b/src/utils/resources.py @@ -61,10 +61,10 @@ class AppResourceManager: try: if todo == "deprovision": # FIXME : i18n, better info strings - logger.info(f"Deprovisionning {name}...") + logger.info(f"Deprovisioning {name}...") old.deprovision(context=context) elif todo == "provision": - logger.info(f"Provisionning {name}...") + logger.info(f"Provisioning {name}...") new.provision_or_update(context=context) elif todo == "update": logger.info(f"Updating {name}...") @@ -90,14 +90,14 @@ class AppResourceManager: # (NB. here we want to undo the todo) if todo == "deprovision": # FIXME : i18n, better info strings - logger.info(f"Reprovisionning {name}...") + logger.info(f"Reprovisioning {name}...") old.provision_or_update(context=context) elif todo == "provision": - logger.info(f"Deprovisionning {name}...") + logger.info(f"Deprovisioning {name}...") new.deprovision(context=context) elif todo == "update": logger.info(f"Reverting {name}...") - old.provision_or_update(context=context) + old.sion_or_update(context=context) except (KeyboardInterrupt, Exception) as e: if isinstance(e, KeyboardInterrupt): logger.error(m18n.n("operation_interrupted")) From 54bc79ed587fc55c467e03e349d9097f56e1118d Mon Sep 17 00:00:00 2001 From: Alexandre Aubin <4533074+alexAubin@users.noreply.github.com> Date: Sun, 22 Oct 2023 18:53:57 +0200 Subject: [PATCH 067/113] Apply suggestions from code review --- src/utils/resources.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/resources.py b/src/utils/resources.py index 1720b4890..3f9719c39 100644 --- a/src/utils/resources.py +++ b/src/utils/resources.py @@ -97,7 +97,7 @@ class AppResourceManager: new.deprovision(context=context) elif todo == "update": logger.info(f"Reverting {name}...") - old.sion_or_update(context=context) + old.provision_or_update(context=context) except (KeyboardInterrupt, Exception) as e: if isinstance(e, KeyboardInterrupt): logger.error(m18n.n("operation_interrupted")) From 16146913b0207853880a5972256dc4c107f25074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20M?= Date: Tue, 10 Oct 2023 04:26:14 +0000 Subject: [PATCH 068/113] Translated using Weblate (Galician) Currently translated at 100.0% (782 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/gl/ --- locales/gl.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/gl.json b/locales/gl.json index 93f73b528..acbb50fe4 100644 --- a/locales/gl.json +++ b/locales/gl.json @@ -782,5 +782,7 @@ "dyndns_set_recovery_password_invalid_password": "Fallo ao establecer contrasinal de recuperación: o contrasinal non é suficientemente forte", "dyndns_set_recovery_password_failed": "Fallo ao establecer o contrasinal de recuperación: {error}", "dyndns_set_recovery_password_success": "Estableceuse o contrasinal de recuperación!", - "log_dyndns_unsubscribe": "Retirar subscrición para o subdominio YunoHost '{}'" + "log_dyndns_unsubscribe": "Retirar subscrición para o subdominio YunoHost '{}'", + "ask_dyndns_recovery_password_explain_unavailable": "Este dominio DynDNS xa está rexistrado. Se es a persoa que o rexistrou orixinalmente, podes escribir o código de recuperación para reclamar o dominio.", + "dyndns_too_many_requests": "O servicio dyndns de YunoHost recibeu demasiadas peticións do teu sistema, agarda 1 hora e volve intentalo." } From 5d77843cd9d9807321b21d112be48ccac8d638e5 Mon Sep 17 00:00:00 2001 From: Jose Riha Date: Wed, 11 Oct 2023 18:00:04 +0000 Subject: [PATCH 069/113] Translated using Weblate (Slovak) Currently translated at 32.0% (251 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/sk/ --- locales/sk.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/locales/sk.json b/locales/sk.json index bead46713..a6a4f3bb1 100644 --- a/locales/sk.json +++ b/locales/sk.json @@ -218,8 +218,8 @@ "diagnosis_ip_no_ipv6_tip": "Váš server bude fungovať aj bez IPv6, no pre celkové zdravie internetu je lepšie ho nastaviť. V prípade, že je IPv6 dostupné, systém alebo váš poskytovateľ by ho mal automaticky nakonfigurovať. V opačnom prípade budete možno musieť nastaviť zopár vecí ručne tak, ako je vysvetlené v dokumentácii na https://yunohost.org/#/ipv6. Ak nemôžete povoliť IPv6 alebo je to na vás príliš technicky náročné, môžete pokojne toto upozornenie ignorovať.", "diagnosis_ip_broken_dnsresolution": "Zdá sa, že z nejakého dôvodu nefunguje prekladanie názvov domén… Blokuje vaša brána firewall DNS požiadavky?", "diagnosis_ip_broken_resolvconf": "Zdá sa, že na vašom serveri nefunguje prekladanie názvov domén, čo môže súvisieť s tým, že /etc/resolv.conf neukazuje na 127.0.0.1.", - "diagnosis_ip_connected_ipv4": "Server nie je pripojený k internetu prostredníctvom IPv4!", - "diagnosis_ip_connected_ipv6": "Server nie je pripojený k internetu prostredníctvom IPv6!", + "diagnosis_ip_connected_ipv4": "Server je pripojený k internetu prostredníctvom IPv4!", + "diagnosis_ip_connected_ipv6": "Server je pripojený k internetu prostredníctvom IPv6!", "diagnosis_ip_dnsresolution_working": "Preklad názvov domén nefunguje!", "diagnosis_ip_global": "Globálna IP adresa: {global}", "diagnosis_ip_local": "Miestna IP adresa: {local}", @@ -259,5 +259,7 @@ "app_change_url_script_failed": "Vo skripte na zmenu URL adresy sa vyskytla chyba", "app_not_enough_disk": "Táto aplikácia vyžaduje {required} voľného miesta.", "app_not_enough_ram": "Táto aplikácia vyžaduje {required} pamäte na inštaláciu/aktualizáciu, ale k dispozícii je momentálne iba {current}.", - "apps_failed_to_upgrade": "Nasledovné aplikácie nebolo možné aktualizovať: {apps}" + "apps_failed_to_upgrade": "Nasledovné aplikácie nebolo možné aktualizovať: {apps}", + "global_settings_setting_security_experimental_enabled": "Experimentálne bezpečnostné funkcie", + "global_settings_setting_security_experimental_enabled_help": "Povoliť experimentálne bezpečnostné funkcie (nezapínajte túto možnosť, ak neviete, čo môže spôsobiť!)" } From ae70eebc1317cadb4d84231e0a0d878cc8402d34 Mon Sep 17 00:00:00 2001 From: Jose Riha Date: Wed, 11 Oct 2023 18:34:57 +0000 Subject: [PATCH 070/113] Translated using Weblate (Slovak) Currently translated at 32.4% (254 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/sk/ --- locales/sk.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/locales/sk.json b/locales/sk.json index a6a4f3bb1..5e057bf55 100644 --- a/locales/sk.json +++ b/locales/sk.json @@ -114,7 +114,7 @@ "certmanager_attempt_to_replace_valid_cert": "Chystáte sa prepísať správny a platný certifikát pre doménu {domain}! (Použite --force na vynútenie)", "certmanager_cannot_read_cert": "Počas otvárania aktuálneho certifikátu pre doménu {domain} došlo k neznámej chybe (súbor: {file}), príčina: {reason}", "certmanager_cert_install_success": "Pre doménu '{domain}' bol práve nainštalovaný certifikát od Let's Encrypt", - "certmanager_cert_install_success_selfsigned": "Pre doménu '{domain}' bol práve nainštalovaný vlastnoručne podpísany (self-signed) certifikát", + "certmanager_cert_install_success_selfsigned": "Pre doménu '{domain}' bol práve nainštalovaný vlastnoručne podpísaný (self-signed) certifikát", "certmanager_cert_renew_success": "Certifikát od Let's Encrypt pre doménu '{domain}' bol úspešne obnovený", "certmanager_cert_signing_failed": "Nepodarilo sa podpísať nový certifikát", "certmanager_domain_cert_not_selfsigned": "Certifikát pre doménu {domain} nie je vlastnoručne podpísaný (self-signed). Naozaj ho chcete nahradiť? (Použite '--force', ak to chcete urobiť.)", @@ -261,5 +261,8 @@ "app_not_enough_ram": "Táto aplikácia vyžaduje {required} pamäte na inštaláciu/aktualizáciu, ale k dispozícii je momentálne iba {current}.", "apps_failed_to_upgrade": "Nasledovné aplikácie nebolo možné aktualizovať: {apps}", "global_settings_setting_security_experimental_enabled": "Experimentálne bezpečnostné funkcie", - "global_settings_setting_security_experimental_enabled_help": "Povoliť experimentálne bezpečnostné funkcie (nezapínajte túto možnosť, ak neviete, čo môže spôsobiť!)" + "global_settings_setting_security_experimental_enabled_help": "Povoliť experimentálne bezpečnostné funkcie (nezapínajte túto možnosť, ak neviete, čo môže spôsobiť!)", + "service_description_rspamd": "Filtruje spam a iné funkcie týkajúce sa e-mailu", + "log_letsencrypt_cert_renew": "Obnoviť '{}' certifikát Let's Encrypt", + "domain_config_cert_summary_selfsigned": "UPOZORNENIE: Aktuálny certifikát je vlastnoručne podpísaný. Prehliadače budú návštevníkom zobrazovať strašidelné varovanie!" } From 00d7f1a20850cacc1cf088e135d943029579a43b Mon Sep 17 00:00:00 2001 From: "Jorge-vitrubio.net" Date: Fri, 13 Oct 2023 11:49:22 +0000 Subject: [PATCH 071/113] Translated using Weblate (Catalan) Currently translated at 62.9% (492 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/ca/ --- locales/ca.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/ca.json b/locales/ca.json index 821e5c3eb..ea9b74015 100644 --- a/locales/ca.json +++ b/locales/ca.json @@ -546,7 +546,7 @@ "global_settings_setting_admin_strength": "Robustesa de la contrasenya d'administrador", "global_settings_setting_user_strength": "Robustesa de la contrasenya de l'usuari", "global_settings_setting_postfix_compatibility_help": "Solució de compromís entre compatibilitat i seguretat pel servidor Postfix. Afecta els criptògrafs (i altres aspectes relacionats amb la seguretat)", - "global_settings_setting_ssh_compatibility_help": "Solució de compromís entre compatibilitat i seguretat pel servidor SSH. Afecta els criptògrafs (i altres aspectes relacionats amb la seguretat)", + "global_settings_setting_ssh_compatibility_help": "Solució de compromís entre compatibilitat i seguretat pel servidor SSH. Afecta els criptògrafs (i altres aspectes relacionats amb la seguretat). Visita https://infosec.mozilla.org/guidelines/openssh (anglés) per mes informació.", "global_settings_setting_smtp_allow_ipv6_help": "Permet l'ús de IPv6 per rebre i enviar correus electrònics", "global_settings_setting_smtp_relay_enabled_help": "L'amfitrió de tramesa SMTP que s'ha d'utilitzar per enviar correus electrònics en lloc d'aquesta instància de YunoHost. És útil si esteu en una de les següents situacions: el port 25 està bloquejat per el vostre proveïdor d'accés a internet o proveïdor de servidor privat virtual, si teniu una IP residencial llistada a DUHL, si no podeu configurar el DNS invers o si el servidor no està directament exposat a internet i voleu utilitzar-ne un altre per enviar correus electrònics." -} \ No newline at end of file +} From 9c33d9e74f4de80a84becfa9574e64c075353b47 Mon Sep 17 00:00:00 2001 From: cristian amoyao Date: Fri, 13 Oct 2023 11:59:23 +0000 Subject: [PATCH 072/113] Translated using Weblate (Spanish) Currently translated at 100.0% (782 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/es/ --- locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/es.json b/locales/es.json index 5003c305c..e889ba385 100644 --- a/locales/es.json +++ b/locales/es.json @@ -737,7 +737,7 @@ "migration_0024_rebuild_python_venv_disclaimer_base": "Tras la actualización a Debian Bullseye, algunas aplicaciones Python necesitan ser parcialmente reconstruidas para ser convertidas a la nueva versión de Python distribuida en Debian (en términos técnicos: lo que se llama el 'virtualenv' necesita ser recreado). Mientras tanto, esas aplicaciones Python pueden no funcionar. YunoHost puede intentar reconstruir el virtualenv para algunas de ellas, como se detalla a continuación. Para otras aplicaciones, o si el intento de reconstrucción falla, necesitarás forzar manualmente una actualización para esas aplicaciones.", "migration_description_0024_rebuild_python_venv": "Reparar la aplicación Python tras la migración a bullseye", "global_settings_setting_smtp_relay_enabled": "Activar el relé SMTP", - "domain_config_acme_eligible": "Elegibilidad ACME", + "domain_config_acme_eligible": "Requisitos ACME", "global_settings_setting_ssh_password_authentication": "Autenticación por contraseña", "domain_config_cert_issuer": "Autoridad de certificación", "invalid_shell": "Shell inválido: {shell}", From 75e6afaf5c6ba317180d037db9301bfc547dae88 Mon Sep 17 00:00:00 2001 From: "Jorge-vitrubio.net" Date: Fri, 13 Oct 2023 11:38:21 +0000 Subject: [PATCH 073/113] Translated using Weblate (Spanish) Currently translated at 100.0% (782 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/es/ --- locales/es.json | 60 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/locales/es.json b/locales/es.json index e889ba385..a1a89ca8c 100644 --- a/locales/es.json +++ b/locales/es.json @@ -27,10 +27,10 @@ "backup_archive_name_unknown": "Copia de seguridad local desconocida '{name}'", "backup_archive_open_failed": "No se pudo abrir el archivo de respaldo", "backup_cleaning_failed": "No se pudo limpiar la carpeta de respaldo temporal", - "backup_created": "Se ha creado la copia de seguridad", + "backup_created": "Copia de seguridad creada: {name}", "backup_creation_failed": "No se pudo crear el archivo de respaldo", "backup_delete_error": "No se pudo eliminar «{path}»", - "backup_deleted": "Eliminada la copia de seguridad", + "backup_deleted": "Copia de seguridad eliminada: {name}", "backup_hook_unknown": "El gancho «{hook}» de la copia de seguridad es desconocido", "backup_nothings_done": "Nada que guardar", "backup_output_directory_forbidden": "Elija un directorio de salida diferente. Las copias de seguridad no se pueden crear en /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var o /home/yunohost.backup/archives subcarpetas", @@ -75,7 +75,7 @@ "main_domain_change_failed": "No se pudo cambiar el dominio principal", "main_domain_changed": "El dominio principal ha cambiado", "not_enough_disk_space": "No hay espacio libre suficiente en «{path}»", - "pattern_backup_archive_name": "Debe ser un nombre de archivo válido con un máximo de 30 caracteres, solo se admiten caracteres alfanuméricos y los caracteres -_. (guiones y punto)", + "pattern_backup_archive_name": "Debe ser un nombre de archivo válido con un máximo de 30 caracteres, solo se admiten caracteres alfanuméricos y los caracteres -_. (guiones y punto)", "pattern_domain": "El nombre de dominio debe ser válido (por ejemplo mi-dominio.org)", "pattern_email": "Debe ser una dirección de correo electrónico válida, sin el símbolo '+' (ej. alguien@ejemplo.com)", "pattern_firstname": "Debe ser un nombre válido (al menos 3 caracteres)", @@ -310,7 +310,7 @@ "group_deleted": "Eliminado el grupo «{group}»", "group_creation_failed": "No se pudo crear el grupo «{group}»: {error}", "group_created": "Creado el grupo «{group}»", - "good_practices_about_admin_password": "Ahora está a punto de definir una nueva contraseña de usuario. La contraseña debe tener al menos 8 caracteres, aunque es una buena práctica usar una contraseña más larga (es decir, una frase de contraseña) y / o una variación de caracteres (mayúsculas, minúsculas, dígitos y caracteres especiales).", + "good_practices_about_admin_password": "Ahora está a punto de definir una nueva contraseña de usuario. La contraseña debe tener al menos 8 caracteres, aunque es una buena práctica usar una contraseña más larga (es decir, una frase como contraseña) y/o una variación de caracteres (mayúsculas, minúsculas, dígitos y caracteres especiales).", "file_does_not_exist": "El archivo {path} no existe.", "dyndns_could_not_check_available": "No se pudo comprobar si {domain} está disponible en {provider}.", "domain_dns_conf_is_just_a_recommendation": "Este comando muestra la configuración *recomendada*. No configura las entradas DNS por ti. Es tu responsabilidad configurar la zona DNS en su registrador según esta recomendación.", @@ -342,7 +342,7 @@ "app_action_broke_system": "Esta acción parece que ha roto estos servicios importantes: {services}", "operation_interrupted": "¿La operación fue interrumpida manualmente?", "apps_already_up_to_date": "Todas las aplicaciones están ya actualizadas", - "dyndns_provider_unreachable": "No se puede conectar con el proveedor de Dyndns {provider}: o su YunoHost no está correctamente conectado a Internet o el servidor dynette está caído.", + "dyndns_provider_unreachable": "No se puede conectar con el proveedor de Dyndns {provider}: o su YunoHost no está correctamente conectado a Internet o el servidor dynette está caído.", "group_already_exist": "El grupo {group} ya existe", "group_already_exist_on_system": "El grupo {group} ya existe en los grupos del sistema", "group_cannot_be_deleted": "El grupo {group} no se puede eliminar manualmente.", @@ -569,7 +569,7 @@ "domain_config_auth_consumer_key": "Llave de consumidor", "domain_config_default_app": "App predeterminada", "domain_dns_push_success": "¡Registros DNS actualizados!", - "domain_dns_push_failed_to_authenticate": "No se pudo autenticar en la API del registrador para el dominio '{domain}'. ¿Lo más probable es que las credenciales sean incorrectas? (Error: {error})", + "domain_dns_push_failed_to_authenticate": "No se pudo autenticar en la API del registrador para el dominio '{domain}'. ¿Es probable que las credenciales sean incorrectas? (Error: {error})", "domain_dns_registrar_experimental": "Hasta ahora, la comunidad de YunoHost no ha probado ni revisado correctamente la interfaz con la API de **{registrar}**. El soporte es **muy experimental**. ¡Ten cuidado!", "domain_dns_push_record_failed": "No se pudo {action} registrar {type}/{name}: {error}", "domain_config_mail_in": "Correos entrantes", @@ -654,7 +654,7 @@ "global_settings_setting_admin_strength": "Seguridad de la contraseña del administrador", "global_settings_setting_user_strength": "Seguridad de la contraseña de usuario", "global_settings_setting_postfix_compatibility_help": "Compromiso entre compatibilidad y seguridad para el servidor Postfix. Afecta al cifrado (y otros aspectos relacionados con la seguridad)", - "global_settings_setting_ssh_compatibility_help": "Compromiso entre compatibilidad y seguridad para el servidor SSH. Afecta al cifrado (y otros aspectos relacionados con la seguridad)", + "global_settings_setting_ssh_compatibility_help": "Compromiso entre compatibilidad y seguridad para el servidor SSH. Afecta al cifrado (y otros aspectos relacionados con la seguridad). Visite https://infosec.mozilla.org/guidelines/openssh (inglés) para más información.", "global_settings_setting_ssh_password_authentication_help": "Permitir autenticación de contraseña para SSH", "global_settings_setting_ssh_port": "Puerto SSH", "global_settings_setting_webadmin_allowlist_help": "Direcciones IP permitidas para acceder al webadmin. Separado por comas.", @@ -681,15 +681,15 @@ "domain_cannot_add_muc_upload": "No puedes añadir dominios que empiecen por 'muc.'. Este tipo de nombre está reservado para la función de chat XMPP multi-usuarios integrada en YunoHost.", "domain_config_cert_renew_help": "El certificado se renovará automáticamente durante los últimos 15 días de validez. Si lo desea, puede renovarlo manualmente. (No recomendado).", "domain_config_cert_summary_expired": "CRÍTICO: ¡El certificado actual no es válido! ¡HTTPS no funcionará en absoluto!", - "domain_config_cert_summary_letsencrypt": "¡Muy bien! Estás utilizando un certificado Let's Encrypt válido.", + "domain_config_cert_summary_letsencrypt": "¡Muy bien! ¡Estás utilizando un certificado Let's Encrypt válido!", "global_settings_setting_postfix_compatibility": "Compatibilidad con Postfix", "global_settings_setting_root_password_confirm": "Nueva contraseña de root (confirmar)", "global_settings_setting_webadmin_allowlist_enabled": "Activar la lista de IPs permitidas para Webadmin", "migration_0024_rebuild_python_venv_broken_app": "Omitiendo {app} porque virtualenv no puede ser reconstruido fácilmente para esta app. En su lugar, deberías arreglar la situación forzando la actualización de esta app usando `yunohost app upgrade --force {app}`.", "migration_0024_rebuild_python_venv_in_progress": "Ahora intentando reconstruir el virtualenv de Python para `{app}`", - "confirm_app_insufficient_ram": "¡PELIGRO! Esta aplicación requiere {required} de RAM para ser instalada/actualizada, pero solo hay {current} disponible actualmente. Incluso si esta aplicación pudiera ejecutarse, su proceso de instalación/actualización requiere una gran cantidad de RAM, por lo que tu servidor puede congelarse y fallar miserablemente. Si estás dispuesto a asumir ese riesgo de todos modos, escribe '{answers}'", + "confirm_app_insufficient_ram": "¡PELIGRO! Esta aplicación requiere {required} de RAM para ser instalada/actualizada, pero solo hay {current} disponible actualmente. Incluso si esta aplicación pudiera ejecutarse, su proceso de instalación/actualización requiere una gran cantidad de RAM, por lo que tu servidor puede congelarse y fallar miserablemente. Si estás dispuesto a asumir ese riesgo de todos modos, teclea '{answers}'", "confirm_notifications_read": "ADVERTENCIA: Deberías revisar las notificaciones de la aplicación antes de continuar, puede haber información importante que debes conocer. [{answers}]", - "domain_config_cert_summary_selfsigned": "ADVERTENCIA: El certificado actual es autofirmado. ¡Los navegadores mostrarán una espeluznante advertencia a los nuevos visitantes!.", + "domain_config_cert_summary_selfsigned": "ADVERTENCIA: El certificado actual es autofirmado. ¡Los navegadores mostrarán una espeluznante advertencia a los nuevos visitantes!", "global_settings_setting_backup_compress_tar_archives": "Comprimir las copias de seguridad", "global_settings_setting_root_access_explain": "En sistemas Linux, 'root' es el administrador absoluto. En el contexto de YunoHost, el acceso directo 'root' SSH está deshabilitado por defecto - excepto desde la red local del servidor. Los miembros del grupo 'admins' pueden usar el comando sudo para actuar como root desde la linea de comandos. Sin embargo, puede ser útil tener una contraseña de root (robusta) para depurar el sistema si por alguna razón los administradores regulares ya no pueden iniciar sesión.", "migration_0021_not_buster2": "¡La distribución Debian actual no es Buster! Si ya ha ejecutado la migración Buster->Bullseye, entonces este error es sintomático del hecho de que el procedimiento de migración no fue 100% exitoso (de lo contrario YunoHost lo habría marcado como completado). Se recomienda investigar lo sucedido con el equipo de soporte, que necesitará el registro **completo** de la `migración, que se puede encontrar en Herramientas > Registros en el webadmin.", @@ -703,7 +703,7 @@ "global_settings_setting_security_experimental_enabled": "Funciones de seguridad experimentales", "migration_0024_rebuild_python_venv_disclaimer_ignored": "Virtualenvs no puede reconstruirse automáticamente para esas aplicaciones. Necesitas forzar una actualización para ellas, lo que puede hacerse desde la línea de comandos con: `yunohost app upgrade --force APP`: {ignored_apps}", "migration_0024_rebuild_python_venv_failed": "Error al reconstruir el virtualenv de Python para {app}. La aplicación puede no funcionar mientras esto no se resuelva. Deberías arreglar la situación forzando la actualización de esta app usando `yunohost app upgrade --force {app}`.", - "app_arch_not_supported": "Esta aplicación sólo puede instalarse en arquitecturas {required} pero la arquitectura de su servidor es {current}", + "app_arch_not_supported": "Esta aplicación solo se puede instalar en arquitecturas {', '.join(required)} pero la arquitectura de tu servidor es {current}", "app_resource_failed": "Falló la asignación, desasignación o actualización de recursos para {app}: {error}", "app_not_enough_disk": "Esta aplicación requiere {required} espacio libre.", "app_not_enough_ram": "Esta aplicación requiere {required} de RAM para ser instalada/actualizada, pero solo hay {current} disponible actualmente.", @@ -724,9 +724,9 @@ "pattern_fullname": "Debe ser un nombre completo válido (al menos 3 caracteres)", "password_confirmation_not_the_same": "La contraseña y su confirmación no coinciden", "password_too_long": "Elija una contraseña de menos de 127 caracteres", - "diagnosis_using_yunohost_testing": "apt (el gestor de paquetes del sistema) está actualmente configurado para instalar cualquier actualización de 'testing' para el núcleo de YunoHost.", + "diagnosis_using_yunohost_testing": "apt (el gestor de paquetes del sistema) está configurado actualmente para instalar cualquier actualización 'testing' para el núcleo de YunoHost.", "diagnosis_using_yunohost_testing_details": "Esto probablemente esté bien si sabes lo que estás haciendo, ¡pero presta atención a las notas de la versión antes de instalar actualizaciones de YunoHost! Si quieres deshabilitar las actualizaciones de prueba, debes eliminar la palabra clave testing de /etc/apt/sources.list.d/yunohost.list.", - "global_settings_setting_passwordless_sudo": "Permitir a los administradores utilizar 'sudo' sin tener que volver a escribir sus contraseñas.", + "global_settings_setting_passwordless_sudo": "Permitir a los administradores utilizar 'sudo' sin tener que volver a escribir sus contraseñas", "group_update_aliases": "Actualizando alias para el grupo '{group}'", "group_no_change": "Nada que cambiar para el grupo '{group}'", "global_settings_setting_portal_theme": "Tema del portal", @@ -752,5 +752,37 @@ "app_corrupt_source": "YunoHost ha podido descargar el recurso '{source_id}' ({url}) para {app}, pero no coincide con la suma de comprobación esperada. Esto puede significar que ocurrió un fallo de red en tu servidor, o que el recurso ha sido modificado por el responsable de la aplicación (¿o un actor malicioso?) y los responsables de empaquetar esta aplicación para YunoHost necesitan investigar y actualizar el manifesto de la aplicación para reflejar estos cambios. \n Suma de control sha256 esperada: {expected_sha256}\n Suma de control sha256 descargada: {computed_sha256}\n Tamaño del archivo descargado: {size}", "app_change_url_failed": "No es possible cambiar la URL para {app}: {error}", "app_change_url_require_full_domain": "{app} no se puede mover a esta nueva URL porque requiere un dominio completo (es decir, con una ruta = /)", - "app_change_url_script_failed": "Se ha producido un error en el script de modificación de la url" + "app_change_url_script_failed": "Se ha producido un error en el script de modificación de la url", + "group_mailalias_add": "El alias de '{mail}' será añadido al del grupo '{ group} '", + "group_user_add": "La persona usuaria '{ user} ' será añadida al grupo '{ group} '", + "dyndns_no_recovery_password": "¡No especificó la password de recuperación! ¡En caso de perder control de este dominio, necesitará contactar con una persona administradora del equipo de YunoHost!", + "dyndns_too_many_requests": "El servicio DynDNS de YunoHost recibió demasiadas peticiones de su parte, por favor espere 1 hora antes de intentarlo de nuevo.", + "dyndns_set_recovery_password_unknown_domain": "Falló al establecer la password de recuperación: dominio no registrado", + "global_settings_setting_dns_exposure": "Versión IP del DNS establecida en la configuración y diagnósticos", + "group_mailalias_remove": "El alias de '{mail}' será eliminado del grupo '{ group} '", + "group_user_remove": "La persona usuaria '{ user} ' será eliminada al grupo '{ group} '", + "app_failed_to_upgrade_but_continue": "La aplicación {failed_app} no pudo actualizarse, continúe con las siguientes actualizaciones como solicitado. Ejecuta 'yunohost log show {operation_logger_name}' para visualizar el log de fallos", + "app_not_upgraded_broken_system": "La aplicacion '{failed_app}' falló en la actualización he hizo que el sistema pasase a un estado de fallo, como consecuencia las siguientes actualizaciones de aplicaciones han sido canceladas: {apps}", + "app_not_upgraded_broken_system_continue": "La aplicacion '{failed_app}' falló en la actualización he hizo que el sistema pasase a un estado de fallo (así que --continue-on-failure se ignoró), como consecuencia las siguientes actualizaciones de aplicaciones han sido canceladas: {apps}", + "apps_failed_to_upgrade": "Estas actualizaciones de aplicaciones fallaron: {apps}", + "apps_failed_to_upgrade_line": "\n * {app_id} (para ver el correspondiente log utilice 'yunohost log show {operation_logger_name}')", + "diagnosis_ip_no_ipv6_tip_important": "La IPv6 normalmente debería ser automáticamente configurada por su proveedor de sistemas si estuviese disponible. Si no fuese saí, quizás deba configurar algunos parámetros manualmente tal y como lo explica la documentación: https://yunohost.org/#/ipv6.", + "ask_dyndns_recovery_password_explain": "Porfavor obtenga una password de recuperación para su dominio DynDNS, por si la necesita más adelante.", + "ask_dyndns_recovery_password": "Password de recuperación de DynDNS", + "ask_dyndns_recovery_password_explain_during_unsubscribe": "Por favor introduzca la password de recuperación de este dominio DynDNS.", + "log_dyndns_unsubscribe": "Desuscribir del subdominio YunoHost '{}'", + "ask_dyndns_recovery_password_explain_unavailable": "Este domino DynDNS ya está registrado. Si usted es la persona que originalmente registro este dominio, puede introducir la password de recuperación de este dominio.", + "domain_config_default_app_help": "Las personas será automáticamente redirigidas a esta aplicación cuando visiten este dominio. Si no especifica una aplicación, estas serán redirigidas al formulario del portal de usuarias.", + "domain_config_xmpp_help": "NB: algunas opciones de XMPP necesitarán que actualice sus registros DNS y que regenere sus certificados Let's Encrypt para que sean habilitadas", + "dyndns_subscribed": "Dominio DynDNS suscrito", + "dyndns_subscribe_failed": "No pudo suscribirse al dominio DynDNS: {error}", + "dyndns_unsubscribe_failed": "No pudo desuscribirse del dominio DynDNS: {error}", + "dyndns_unsubscribed": "Dominio DynDNS desuscrito", + "dyndns_unsubscribe_denied": "Falló la desuscripción del dominio: credenciales incorrectas", + "dyndns_unsubscribe_already_unsubscribed": "El dominio está ya desuscrito", + "dyndns_set_recovery_password_denied": "Falló al establecer la password de recuperación: llave invalida", + "dyndns_set_recovery_password_invalid_password": "Falló al establecer la password de recuperación: la password no es suficientemente fuerte", + "dyndns_set_recovery_password_failed": "Falló al establecer la password de recuperación: {error}", + "dyndns_set_recovery_password_success": "¡Password de recuperación establecida!", + "global_settings_setting_dns_exposure_help": "NB: Esto afecta únicamente a la configuración recomentada de DNS y en las pruebas de diagnóstico. No afecta a la configuración del sistema." } From 4f4dfdb7f7ef5d248138326b7b78e6c636a86f7e Mon Sep 17 00:00:00 2001 From: "Jorge-vitrubio.net" Date: Fri, 13 Oct 2023 11:43:53 +0000 Subject: [PATCH 074/113] Translated using Weblate (Italian) Currently translated at 74.5% (583 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/it/ --- locales/it.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/it.json b/locales/it.json index 21fb52367..4ef8ab5f2 100644 --- a/locales/it.json +++ b/locales/it.json @@ -561,7 +561,7 @@ "domain_dns_push_not_applicable": "La configurazione automatica del DNS non è applicabile al dominio {domain}. Dovresti configurare i tuoi record DNS manualmente, seguendo la documentazione su https://yunohost.org/dns_config.", "domain_dns_registrar_not_supported": "YunoHost non è riuscito a riconoscere quale registrar sta gestendo questo dominio. Dovresti configurare i tuoi record DNS manualmente, seguendo la documentazione.", "domain_dns_registrar_experimental": "Per ora, il collegamento con le API di **{registrar}** non è stata opportunamente testata e revisionata dalla comunità di YunoHost. Questa funzionalità è **altamente sperimentale**, fai attenzione!", - "domain_dns_push_failed_to_authenticate": "L’autenticazione sulle API del registrar per il dominio '{domain}' è fallita. Probabilmente le credenziali non sono corrette. (Error: {error})", + "domain_dns_push_failed_to_authenticate": "L’autenticazione sulle API del registrar per il dominio '{domain}' è fallita. Probabilmente le credenziali non sono giuste. (Error: {error})", "domain_dns_push_failed_to_list": "Il reperimento dei record attuali usando le API del registrar è fallito: {error}", "domain_dns_push_already_up_to_date": "I record sono aggiornati, nulla da fare.", "domain_dns_pushing": "Sincronizzando i record DNS…", @@ -631,7 +631,7 @@ "global_settings_setting_admin_strength": "Complessità della password di amministratore", "global_settings_setting_user_strength": "Complessità della password utente", "global_settings_setting_postfix_compatibility_help": "Bilanciamento tra compatibilità e sicurezza per il server Postfix. Riguarda gli algoritmi di cifratura (e altri aspetti legati alla sicurezza)", - "global_settings_setting_ssh_compatibility_help": "Bilanciamento tra compatibilità e sicurezza per il server SSH. Riguarda gli algoritmi di cifratura (e altri aspetti legati alla sicurezza)", + "global_settings_setting_ssh_compatibility_help": "Bilanciamento tra compatibilità e sicurezza per il server SSH. Riguarda gli algoritmi di cifratura (e altri aspetti legati alla sicurezza). Segue https://infosec.mozilla.org/guidelines/openssh (inglesse) per averne piú informazione.", "global_settings_setting_ssh_port": "Porta SSH", "global_settings_setting_webadmin_allowlist_help": "Indirizzi IP con il permesso di accedere al webadmin, separati da virgola.", "global_settings_setting_webadmin_allowlist_enabled_help": "Permetti solo ad alcuni IP di accedere al webadmin.", @@ -639,4 +639,4 @@ "global_settings_setting_smtp_relay_enabled_help": "Utilizza SMTP relay per inviare mail al posto di questa instanza yunohost. Utile se sei in una di queste situazioni: la tua porta 25 è bloccata dal tuo provider ISP o VPS; hai un IP residenziale listato su DUHL; non sei puoi configurare il DNS inverso; oppure questo server non è direttamente esposto a Internet e vuoi usarne un'altro per spedire email.", "domain_config_default_app": "Applicazione di default", "app_change_url_failed": "Non è possibile cambiare l'URL per {app}:{error}" -} \ No newline at end of file +} From b719563c7ee08efcc9b6c09fdc483d5fe291900b Mon Sep 17 00:00:00 2001 From: cristian amoyao Date: Fri, 13 Oct 2023 12:01:41 +0000 Subject: [PATCH 075/113] Translated using Weblate (Spanish) Currently translated at 100.0% (782 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/es/ --- locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/es.json b/locales/es.json index a1a89ca8c..892658fc9 100644 --- a/locales/es.json +++ b/locales/es.json @@ -738,7 +738,7 @@ "migration_description_0024_rebuild_python_venv": "Reparar la aplicación Python tras la migración a bullseye", "global_settings_setting_smtp_relay_enabled": "Activar el relé SMTP", "domain_config_acme_eligible": "Requisitos ACME", - "global_settings_setting_ssh_password_authentication": "Autenticación por contraseña", + "global_settings_setting_ssh_password_authentication": "Autenticación de contraseña", "domain_config_cert_issuer": "Autoridad de certificación", "invalid_shell": "Shell inválido: {shell}", "log_settings_reset": "Restablecer ajuste", From 1d1cbedf3a6de8c9abadc0bff5e14f763eec7f1f Mon Sep 17 00:00:00 2001 From: "Jorge-vitrubio.net" Date: Fri, 13 Oct 2023 12:04:40 +0000 Subject: [PATCH 076/113] Translated using Weblate (Italian) Currently translated at 74.6% (584 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/it/ --- locales/it.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/it.json b/locales/it.json index 4ef8ab5f2..98512df40 100644 --- a/locales/it.json +++ b/locales/it.json @@ -182,7 +182,7 @@ "certmanager_cannot_read_cert": "Qualcosa è andato storto nel tentativo di aprire il certificato attuale per il dominio {domain} (file: {file}), motivo: {reason}", "certmanager_cert_install_success": "Certificato Let's Encrypt per il dominio {domain} installato", "aborting": "Annullamento.", - "app_not_upgraded": "Impossibile aggiornare le applicazioni '{failed_app}' e di conseguenza l'aggiornamento delle seguenti applicazione è stato cancellato: {apps}", + "app_not_upgraded": "Impossibile aggiornare le applicazioni '{failed_app}' e di conseguenza l'aggiornamento delle seguenti applicazione è stato cancellato: {apps}", "app_start_install": "Installando '{app}'...", "app_start_remove": "Rimozione di {app}...", "app_start_backup": "Raccogliendo file da salvare nel backup per '{app}'...", @@ -361,7 +361,7 @@ "diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "DNS invero corrente: {rdns_domain}
Valore atteso: {ehlo_domain}", "diagnosis_mail_fcrdns_different_from_ehlo_domain": "Il DNS inverso non è correttamente configurato su IPv{ipversion}. Alcune email potrebbero non essere spedite o segnalate come SPAM.", "diagnosis_mail_fcrdns_nok_alternatives_6": "Alcuni provider non permettono di configurare un DNS inverso (o non è configurato bene...). Se il tuo DNS inverso è correttamente configurato per IPv4, puoi provare a disabilitare l'utilizzo di IPv6 durante l'invio mail eseguendo yunohost settings set smtp.allow_ipv6 -v off. NB: se esegui il comando non sarà più possibile inviare o ricevere email da i pochi IPv6-only server mail esistenti.", - "yunohost_postinstall_end_tip": "La post-installazione è completata! Per rifinire il tuo setup, considera di:\n\t- aggiungere il primo utente nella sezione 'Utenti' del webadmin (o eseguendo da terminale 'yunohost user create ');\n\t- eseguire una diagnosi alla ricerca di problemi nella sezione 'Diagnosi' del webadmin (o eseguendo da terminale 'yunohost diagnosis run');\n\t- leggere 'Finalizing your setup' e 'Getting to know YunoHost' nella documentazione admin: https://yunohost.org/admindoc.", + "yunohost_postinstall_end_tip": "La post-installazione è completata! Per rifinire il tuo setup, considera di:\n\t- eseguire una diagnosi per la ricerca di problemi nella sezione 'Diagnosi' del webadmin (o eseguendo da terminale 'yunohost diagnosis run');\n\t- leggere 'Finalizing your setup' e 'Getting to know YunoHost' nella documentazione admin: https://yunohost.org/admindoc.", "user_already_exists": "L'utente '{user}' esiste già", "update_apt_cache_warning": "Qualcosa è andato storto mentre eseguivo l'aggiornamento della cache APT (package manager di Debian). Ecco il dump di sources.list, che potrebbe aiutare ad identificare le linee problematiche:\n{sourceslist}", "update_apt_cache_failed": "Impossibile aggiornare la cache di APT (package manager di Debian). Ecco il dump di sources.list, che potrebbe aiutare ad identificare le linee problematiche:\n{sourceslist}", From 9c6be3ffd631cbe048eb9469baf24ad880fa3932 Mon Sep 17 00:00:00 2001 From: xabirequejo Date: Sat, 21 Oct 2023 16:06:42 +0000 Subject: [PATCH 077/113] Translated using Weblate (Basque) Currently translated at 99.1% (775 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/eu/ --- locales/eu.json | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/locales/eu.json b/locales/eu.json index 85e7c36fc..c2a461445 100644 --- a/locales/eu.json +++ b/locales/eu.json @@ -11,7 +11,7 @@ "backup_deleted": "Babeskopia ezabatu da: {name}", "app_argument_required": "'{name}' argumentua ezinbestekoa da", "certmanager_acme_not_configured_for_domain": "Une honetan ezinezkoa da ACME azterketa {domain} domeinurako burutzea nginx ezarpenek ez dutelako beharrezko kodea… Egiaztatu nginx ezarpenak egunean daudela 'yunohost tools regen-conf nginx --dry-run --with-diff' komandoa exekutatuz.", - "certmanager_domain_dns_ip_differs_from_public_ip": "'{domain}' domeinurako DNS balioak ez datoz bat zerbitzariaren IParekin. Egiaztatu 'DNS balioak' (oinarrizkoa) kategoria diagnostikoen atalean. 'A' balioak duela gutxi aldatu badituzu, itxaron hedatu daitezen (badaude DNSen hedapena ikusteko erramintak interneten). (Zertan ari zeren baldin badakizu, erabili '--no-checks' egiaztapen horiek desgaitzeko.)", + "certmanager_domain_dns_ip_differs_from_public_ip": "'{domain}' domeinurako DNS balioak ez datoz bat zerbitzariaren IParekin. Egiaztatu 'DNS balioak' (oinarrizkoa) atala diagnostikoen gunean. 'A' balioak duela gutxi aldatu badituzu, itxaron hedatu daitezen (badaude DNSen hedapena ikusteko erramintak interneten). (Zertan ari zeren baldin badakizu, erabili '--no-checks' egiaztapen horiek desgaitzeko.)", "confirm_app_install_thirdparty": "KONTUZ! Aplikazio hau ez da YunoHosten aplikazioen katalogokoa. Kanpoko aplikazioek sistemaren integritate eta segurtasuna arriskuan jar dezakete. Ziur asko EZ zenuke instalatu beharko zertan ari zaren ez badakizu. Aplikazio hau ez badabil edo sistema kaltetzen badu EZ DA LAGUNTZARIK EMANGO… aurrera jarraitu nahi duzu hala ere? Hautatu '{answers}'", "app_start_remove": "{app} ezabatzen…", "diagnosis_http_hairpinning_issue_details": "Litekeena da erantzulea zure kable-modem / routerra izatea. Honen eraginez, saretik kanpo daudenek zerbitzaria arazorik gabe erabili ahal izango dute, baina sare lokalean bertan daudenek (ziur asko zure kasua) ezingo dute kanpoko IPa edo domeinu izena erabili zerbitzarira konektatzeko. Egoera hobetu edo guztiz konpontzeko, irakurri dokumentazioa", @@ -83,7 +83,7 @@ "config_forbidden_keyword": "'{keyword}' etiketa sistemak bakarrik erabil dezake; ezin da ID hau daukan baliorik sortu edo erabili.", "config_unknown_filter_key": "'{filter_key}' filtroaren kakoa ez da zuzena.", "config_validate_color": "RGB hamaseitar kolore bat izan behar da", - "diagnosis_cant_run_because_of_dep": "Ezinezkoa da diagnosia abiaraztea {category} atalerako {dep}(r)i lotutako arazo garrantzitsuak / garrantzitsuek dirau(t)en artean.", + "diagnosis_cant_run_because_of_dep": "Ezinezkoa da diagnostikoa abiaraztea {category} atalerako {dep}(r)i lotutako arazo garrantzitsuak / garrantzitsuek dirau(t)en artean.", "diagnosis_dns_missing_record": "Proposatutako DNS konfigurazioaren arabera, ondorengo informazioa gehitu beharko zenuke DNS erregistroan:
Mota: {type}
Izena: {name}
Balioa: {value}", "diagnosis_http_nginx_conf_not_up_to_date": "Domeinu honen nginx ezarpenak eskuz moldatu direla dirudi eta YunoHostek ezin du egiaztatu HTTP bidez eskuragarri dagoenik.", "ask_new_admin_password": "Administrazio-pasahitz berria", @@ -116,7 +116,7 @@ "app_remove_after_failed_install": "Aplikazioa ezabatzen instalatzerakoan errorea dela-eta…", "diagnosis_basesystem_ynh_single_version": "{package} bertsioa: {version} ({repo})", "diagnosis_failed_for_category": "'{category}' ataleko diagnostikoak kale egin du: {error}", - "diagnosis_cache_still_valid": "(Katxea oraindik baliogarria da {category} ataleko diagnosirako. Ez da berrabiaraziko!)", + "diagnosis_cache_still_valid": "(Katxea oraindik baliogarria da {category} ataleko diagnostikorako. Ez da berrabiaraziko!)", "diagnosis_found_errors": "{category} atalari dago(z)kion {errors} arazo aurkitu d(ir)a!", "diagnosis_found_warnings": "{category} atalari dagokion eta hobetu daite(z)keen {warnings} abisu aurkitu d(ir)a.", "diagnosis_ip_connected_ipv6": "Zerbitzaria IPv6 bidez dago internetera konektatuta!", @@ -138,7 +138,7 @@ "diagnosis_description_mail": "Posta elektronikoa", "diagnosis_http_connection_error": "Arazoa konexioan: ezin izan da domeinu horretara konektatu, litekeena da eskuragarri ez egotea.", "diagnosis_description_web": "Weba", - "diagnosis_display_tip": "Aurkitu diren arazoak ikusteko joan administrazio-atariko Diagnostikoak atalera, edo exekutatu 'yunohost diagnosis show --issues --human-readable' komandoak nahiago badituzu.", + "diagnosis_display_tip": "Aurkitu diren arazoak ikusteko joan administrazio-atariko Diagnostikoak gunera, edo exekutatu 'yunohost diagnosis show --issues --human-readable' komandoak nahiago badituzu.", "diagnosis_dns_point_to_doc": "Irakurri dokumentazioa DNS erregistroekin laguntza behar baduzu.", "diagnosis_mail_ehlo_unreachable": "SMTP posta zerbitzaria ez dago eskuragarri IPv{ipversion}ko sare lokaletik kanpo eta, beraz, ez da posta elektronikoa jasotzeko gai.", "diagnosis_mail_ehlo_bad_answer_details": "Litekeena da zure zerbitzaria ez den beste gailu batek erantzun izana.", @@ -216,7 +216,7 @@ "certmanager_cert_install_success_selfsigned": "Norberak sinatutako ziurtagiria instalatu da '{domain}' domeinurako", "certmanager_domain_cert_not_selfsigned": "{domain} domeinurako ziurtagiria ez da norberak sinatutakoa. Ziur al zaude ordezkatu nahi duzula? (Erabili '--force' hori egiteko.)", "certmanager_certificate_fetching_or_enabling_failed": "{domain} domeinurako ziurtagiri berriak kale egin du…", - "certmanager_domain_http_not_working": "Ez dirudi {domain} domeinua HTTP bidez ikusgai dagoenik. Egiaztatu 'Weba' atala diagnosien gunean informazio gehiagorako. (Zertan ari zaren baldin badakizu, erabili '--no-checks' egiaztapen horiek desgaitzeko.)", + "certmanager_domain_http_not_working": "Ez dirudi {domain} domeinua HTTP bidez ikusgai dagoenik. Egiaztatu 'Weba' atala diagnostikoen gunean informazio gehiagorako. (Zertan ari zaren baldin badakizu, erabili '--no-checks' egiaztapen horiek desgaitzeko.)", "certmanager_hit_rate_limit": "{domain} domeinu-multzorako ziurtagiri gehiegi jaulki dira dagoeneko. Saia saitez geroago. Ikus https://letsencrypt.org/docs/rate-limits/ xehetasun gehiagorako", "certmanager_no_cert_file": "Ezinezkoa izan da {domain} domeinurako ziurtagiri fitxategia irakurrtzea (fitxategia: {file})", "certmanager_self_ca_conf_file_not_found": "Ezinezkoa izan da konfigurazio-fitxategia aurkitzea norberak sinatutako ziurtagirirako (fitxategia: {file})", @@ -333,7 +333,7 @@ "log_tools_migrations_migrate_forward": "Exekutatu migrazioak", "log_tools_postinstall": "Abiarazi YunoHost zerbitzariaren instalazio ondorengo prozesua", "diagnosis_mail_fcrdns_nok_alternatives_4": "Operadore batzuek ez dute alderantzizko DNSa konfiguratzen uzten (edo funtzioa ez dabil…). Hau dela-eta arazoak badituzu, irtenbide batzuk eduki ditzakezu:
- Operadore batzuek relay posta zerbitzari bat eskaini dezakete, baina kasu horretan zure posta elektronikoa zelatatu dezakete.
- Pribatutasuna bermatzeko *IP publikoa* duen VPN bat erabiltzea izan daiteke irtenbidea. Ikus https://yunohost.org/#/vpn_advantage
- Edo operadore desberdin batera aldatu", - "domain_dns_registrar_supported": "YunoHostek automatikoki antzeman du domeinu hau **{registrar}** erregistro-enpresak kudeatzen duela. Nahi baduzu YunoHostek automatikoki konfiguratu ditzake DNS ezarpenak, API egiaztagiri zuzenak zehazten badituzu. API egiaztagiriak non lortzeko dokumentazioa orri honetan duzu: https://yunohost.org/registar_api_{registrar}. (Baduzu DNS erregistroak eskuz konfiguratzeko aukera ere, gidalerro hauetan ageri den bezala: https://yunohost.org/dns)", + "domain_dns_registrar_supported": "YunoHostek automatikoki antzeman du domeinu hau **{registrar}** erregistro-enpresak kudeatzen duela. Nahi baduzu YunoHostek automatikoki konfiguratu ditzake DNS ezarpenak, API egiaztagiri zuzenak zehazten badituzu. API egiaztagiriak non lortzeko dokumentazioa orri honetan daukazu: https://yunohost.org/registar_api_{registrar}. (Baduzu DNS erregistroak eskuz konfiguratzeko aukera ere, gidalerro hauetan ageri den bezala: https://yunohost.org/dns)", "domain_dns_push_failed_to_list": "Ezinezkoa izan da APIa erabiliz oraingo erregistroak antzematea: {error}", "domain_dns_push_already_up_to_date": "Ezarpenak egunean daude, ez dago zereginik.", "domain_config_mail_out": "Bidalitako mezuak", @@ -583,7 +583,7 @@ "port_already_opened": "{port}. ataka dagoeneko irekita dago {ip_version} konexioetarako", "user_home_creation_failed": "Ezin izan da erabiltzailearentzat '{home}' direktorioa sortu", "user_unknown": "Erabiltzaile ezezaguna: {user}", - "yunohost_postinstall_end_tip": "Instalazio ondorengo prozesua amaitu da! Sistemaren konfigurazioa bukatzeko:\n- erabili 'Diagnostikoak' atala ohiko arazoei aurre hartzeko. Administrazio-atarian abiarazi edo 'yunohost diagnosis run' exekutatu;\n- irakurri 'Finalizing your setup' eta 'Getting to know YunoHost' atalak. Dokumentazioan aurki ditzakezu: https://yunohost.org/admindoc.", + "yunohost_postinstall_end_tip": "Instalazio ondorengo prozesua amaitu da! Sistemaren konfigurazioa bukatzeko:\n- erabili 'Diagnostikoak' gunea ohiko arazoei aurre hartzeko. Administrazio-atarian abiarazi edo 'yunohost diagnosis run' exekutatu;\n- irakurri 'Finalizing your setup' eta 'Getting to know YunoHost' atalak. Dokumentazioan aurki ditzakezu: https://yunohost.org/admindoc.", "yunohost_not_installed": "YunoHost ez da zuzen instalatu. Exekutatu 'yunohost tools postinstall'", "unlimit": "Mugarik ez", "restore_already_installed_apps": "Ondorengo aplikazioak ezin dira lehengoratu dagoeneko instalatuta daudelako: {apps}", @@ -693,16 +693,16 @@ "global_settings_setting_security_experimental_enabled": "Segurtasun ezaugarri esperimentalak", "registrar_infos": "Erregistro-enpresaren informazioa", "global_settings_setting_pop3_enabled": "Gaitu POP3", - "global_settings_reset_success": "Berrezarri ezarpen globalak", + "global_settings_reset_success": "Berrezarri ezarpen orokorrak", "global_settings_setting_backup_compress_tar_archives": "Konprimatu babeskopiak", "config_forbidden_readonly_type": "'{type}' mota ezin da ezarri readonly bezala; beste mota bat erabili balio hau emateko (argudioaren ida: '{id}').", "diagnosis_using_stable_codename": "apt (sistemaren pakete kudeatzailea) 'stable' (egonkorra) izen kodea duten paketeak instalatzeko ezarrita dago une honetan, eta ez uneko Debianen bertsioaren (bullseye) izen kodea.", "diagnosis_using_yunohost_testing": "apt (sistemaren pakete kudeatzailea) YunoHosten muinerako 'testing' (proba) izen kodea duten paketeak instalatzeko ezarrita dago une honetan.", "diagnosis_using_yunohost_testing_details": "Ez dago arazorik zertan ari zaren baldin badakizu, baina arretaz irakurri oharrak YunoHosten eguneraketak instalatu baino lehen! 'testing' (proba) bertsioak ezgaitu nahi badituzu, kendu testing gakoa /etc/apt/sources.list.d/yunohost.list fitxategitik.", "global_settings_setting_smtp_allow_ipv6": "Baimendu IPv6", - "global_settings_setting_smtp_relay_host": "SMTP relay ostatatzailea", + "global_settings_setting_smtp_relay_host": "SMTP errele-ostatatzailea", "domain_config_acme_eligible": "ACME egokitasuna", - "domain_config_acme_eligible_explain": "Ez dirudi domeinu hau Let's Encrypt ziurtagirirako prest dagoenik. Egiaztatu DNS ezarpenak eta zerbitzariaren HTTP irisgarritasuna. Diagnostikoen orrialdeko 'DNS erregistroak' eta 'Web' atalek zer dagoen gaizki ulertzen lagun zaitzakete.", + "domain_config_acme_eligible_explain": "Ez dirudi domeinu hau Let's Encrypt ziurtagirirako prest dagoenik. Egiaztatu DNS ezarpenak eta zerbitzariaren HTTP irisgarritasuna. Diagnostikoen guneko 'DNS erregistroak' eta 'Web' atalek zer dagoen gaizki ulertzen lagun zaitzakete.", "domain_config_cert_install": "Instalatu Let's Encrypt ziurtagiria", "domain_config_cert_issuer": "Ziurtagiriaren jaulkitzailea", "domain_config_cert_no_checks": "Muzin egin diagnostikoaren egiaztapenei", @@ -719,7 +719,7 @@ "global_settings_setting_pop3_enabled_help": "Gaitu POP3 protokoloa eposta zerbitzarirako", "global_settings_setting_root_password": "root pasahitz berria", "global_settings_setting_root_password_confirm": "root pasahitz berria (egiaztatu)", - "global_settings_setting_smtp_relay_enabled": "Gaitu SMTP relay", + "global_settings_setting_smtp_relay_enabled": "Gaitu SMTP errelea", "global_settings_setting_ssh_compatibility": "SSH bateragarritasuna", "global_settings_setting_ssh_password_authentication": "Pasahitz bidezko autentifikazioa", "global_settings_setting_user_strength_help": "Betekizun hauek lehenbizikoz sortzerakoan edo pasahitza aldatzerakoan bete behar dira soilik", @@ -738,7 +738,7 @@ "app_not_enough_ram": "Aplikazio honek {required} RAM behar ditu instalatu edo bertsio-berritzeko, baina {current} bakarrik daude erabilgarri une honetan.", "domain_cannot_add_muc_upload": "Ezin duzu 'muc.'-ekin hasten den domeinurik gehitu. Mota honetako izenak YunoHosten integratuta dagoen XMPP taldeko txatek erabil ditzaten gordeta daude.", "confirm_app_insufficient_ram": "KONTUZ! Aplikazio honek {required} RAM behar ditu instalatu edo bertsio-berritzeko baina unean soilik {current} daude erabilgarri. Aplikazioa ibiliko balitz ere, instalazioak edo bertsio-berritzeak RAM kopuru handia behar du eta zure zerbitzariak erantzuteari utzi eta huts egin lezake. Hala ere arriskatu nahi baduzu idatzi '{answers}'", - "confirm_notifications_read": "ADI: ikuskatu aplikazioaren jakinarazpenak jarraitu baino lehen, baliteke jakin beharreko zerbait esatea. [{answers}]", + "confirm_notifications_read": "ADI: Aztertu aplikazioaren jakinarazpenak jarraitu baino lehen, baliteke jakin beharreko zerbait esatea. [{answers}]", "app_arch_not_supported": "Aplikazio hau {required} arkitekturan instala daiteke bakarrik, baina zure zerbitzariaren arkitektura {current} da", "app_resource_failed": "Huts egin du {app} aplikaziorako baliabideen eguneraketak / prestaketak / askapenak: {error}", "app_not_enough_disk": "Aplikazio honek {required} espazio libre behar ditu.", @@ -754,10 +754,10 @@ "diagnosis_ip_no_ipv6_tip_important": "IPv6 automatikoki ezarri ohi du sistemak edo hornitzaileak erabilgarri baldin badago. Bestela eskuz ezarri beharko dituzu aukera batzuk ondorengo dokumentazioan azaldu bezala: https://yunohost.org/#/ipv6.", "pattern_fullname": "Baliozko izen oso bat izan behar da (gutxienez hiru karaktere)", "app_change_url_failed": "Ezin izan da {app} aplikazioaren URLa aldatu: {error}", - "app_change_url_require_full_domain": "Ezin da {app} aplikazioa URL berri honetara aldatu domeinu oso bat behar duelako (i.e. with path = /)", + "app_change_url_require_full_domain": "Ezin da {app} aplikazioa URL berri honetara aldatu domeinu oso bat behar duelako (hots, / bide-izena duena)", "app_change_url_script_failed": "Errorea gertatu da URLa aldatzeko aginduaren barnean", "app_corrupt_source": "YunoHostek deskargatu du {app} aplikaziorako '{source_id}' ({url}) baliabidea baina ez dator bat espero zen 'checksum'arekin. Agian zerbitzariak interneteko konexioa galdu du tarte batez, EDO baliabidea nolabait moldatua izan da arduradunaren aldetik (edo partehartzaile maltzur batetik?) eta YunoHosten arduradunek egoera aztertu eta aplikazioaren manifestua eguneratu behar dute aldaketa hau kontuan hartzeko.\n Espero zen sha256 checksuma: {expected_sha256}\n Deskargatutakoaren sha256 checksuma: {computed_sha256}\n Deskargatutako fitxategiaren tamaina: {size}", - "app_failed_to_upgrade_but_continue": "{failed_app} aplikazioaren bertsio-berritzeak huts egin du, jarraitu hurrengo bertsio-berritzeetara eskatu bezala. Exekutatu 'yunohost log show {operation_logger_name}' errorearen erregistroa ikusteko", + "app_failed_to_upgrade_but_continue": "{failed_app} aplikazioaren bertsio-berritzeak huts egin du, jarraitu hurrengo bertsio-berritzeekin, eskatu bezala. Exekutatu 'yunohost log show {operation_logger_name}' errorearen erregistroa ikusteko", "app_not_upgraded_broken_system": "{failed_app} aplikazioaren bertsio-berritzeak huts egin du eta sistema hondatu du, beraz, ondorengo aplikazioen bertsio-berritzeak ezeztatu dira: {apps}", "app_not_upgraded_broken_system_continue": "{failed_app} aplikazioaren bertsio-berritzeak huts egin du eta sistema hondatu du (beraz, --continue-on-failure aukerari muzin egin zaio) eta ondorengo aplikazioen bertsio-berritzeak ezeztatu dira: {apps}", "app_failed_to_download_asset": "{app} aplikaziorako '{source_id}' ({url}) baliabidea deskargatzeak huts egin du: {out}", @@ -767,12 +767,22 @@ "group_mailalias_remove": "'{mail}' ePosta aliasa kendu zaio '{group}' taldeari", "group_user_remove": "'{user}' erabiltzailea '{group}' taldetik kenduko da", "group_user_add": "'{user}' erabiltzailea '{group}' taldera gehituko da", - "ask_dyndns_recovery_password_explain": "Aukeratu DynDNS domeinua berreskuratzeko pasahitza, etorkizunean berrezarri beharko bazenu.", - "ask_dyndns_recovery_password_explain_during_unsubscribe": "Sartu DynDNS domeinurako berreskuraketa pasahitza.", - "dyndns_no_recovery_password": "Ez da berreskurapen pasahitzik zehaztu! Domeinuaren gaineko kontrola galduz gero, YunoHost taldeko administrariarekin jarri beharko zara harremanetan!", - "ask_dyndns_recovery_password": "DynDNS berreskuratzeko pasahitza", + "ask_dyndns_recovery_password_explain": "Aukeratu DynDNS domeinurako berreskuratze-pasahitza, etorkizunean berrezarri beharko bazenu.", + "ask_dyndns_recovery_password_explain_during_unsubscribe": "Sartu DynDNS domeinuaren berreskuratze-pasahitza.", + "dyndns_no_recovery_password": "Ez da berreskuratze-pasahitzik zehaztu! Domeinuaren gaineko kontrola galduz gero, YunoHost taldeko administrariarekin jarri beharko zara harremanetan!", + "ask_dyndns_recovery_password": "DynDNS berreskuratze-pasahitza", "dyndns_subscribed": "DynDNS domeinua harpidetu da", "dyndns_subscribe_failed": "Ezin izan da DynDNS domeinua harpidetu: {error}", "dyndns_unsubscribe_failed": "Ezin izan da DynDNS domeinuaren harpidetza utzi: {error}", - "dyndns_unsubscribed": "DynDNS domeinuaren harpidetza utzi da" + "dyndns_unsubscribed": "DynDNS domeinuaren harpidetza utzi da", + "log_dyndns_unsubscribe": "Utzi '{}' YunoHost azpidomeinuaren harpidetza", + "ask_dyndns_recovery_password_explain_unavailable": "DynDNS domeinu hau erregistratuta dago lehendik ere. Domeinua zeuk erregistratu bazenuen, sartu berreskuratze-pasahitza domeinua berreskuratzeko.", + "dyndns_too_many_requests": "YunoHosten dyndns zerbitzuak zuk egindako eskaera gehiegi jaso ditu, itxaron ordubete inguru berriro saiatu baino lehen.", + "dyndns_unsubscribe_denied": "Ezin izan da domeinuaren harpidetza utzi: datu okerrak", + "dyndns_unsubscribe_already_unsubscribed": "Domeinuaren harpidetza utzita dago lehendik ere", + "dyndns_set_recovery_password_denied": "Berreskuratze-pasahitza ezartzeak huts egin du: gako okerra", + "dyndns_set_recovery_password_unknown_domain": "Berreskuratze-pasahitza ezartzeak huts egin du: domeinua ez dago erregistratuta", + "dyndns_set_recovery_password_invalid_password": "Berreskuratze-pasahitza ezartzeak huts egin du: pasahitza ez da nahikoa sendoa", + "dyndns_set_recovery_password_failed": "Berreskuratze-pasahitza ezartzeak huts egin du: {error}", + "dyndns_set_recovery_password_success": "Berreskuratze-pasahitza ezarri da!" } From 238c1ac4d30b1e37ed53c7515252582c5dcf1ad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Gaspar?= Date: Sun, 22 Oct 2023 12:49:29 +0000 Subject: [PATCH 078/113] Translated using Weblate (French) Currently translated at 98.4% (770 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.json b/locales/fr.json index 2e4d1602b..d439516de 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -718,7 +718,7 @@ "domain_config_cert_summary_expired": "ATTENTION : Le certificat actuel n'est pas valide ! HTTPS ne fonctionnera pas du tout !", "domain_config_cert_summary_letsencrypt": "Bravo ! Vous utilisez un certificat Let's Encrypt valide !", "domain_config_cert_summary_ok": "Bien, le certificat actuel semble bon !", - "domain_config_cert_summary_selfsigned": "AVERTISSEMENT : Le certificat actuel est auto-signé. Les navigateurs afficheront un avertissement effrayant aux nouveaux visiteurs !", + "domain_config_cert_summary_selfsigned": "AVERTISSEMENT : Le certificat actuel est auto-signé. Les navigateurs afficheront un avertissement alarmiste aux nouveaux visiteurs !", "domain_config_cert_validity": "Validité", "global_settings_setting_admin_strength_help": "Ces paramètres ne seront appliqués que lors de l'initialisation ou de la modification du mot de passe", "global_settings_setting_nginx_compatibility": "Compatibilité NGINX", From 022fed7787f7103f13d54fb878b650546d173381 Mon Sep 17 00:00:00 2001 From: Jose Riha Date: Sun, 22 Oct 2023 14:21:04 +0000 Subject: [PATCH 079/113] Translated using Weblate (Slovak) Currently translated at 32.4% (254 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/sk/ --- locales/sk.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/sk.json b/locales/sk.json index 5e057bf55..34332c981 100644 --- a/locales/sk.json +++ b/locales/sk.json @@ -30,7 +30,7 @@ "app_manifest_install_ask_domain": "Vyberte doménu, kam bude táto aplikácia nainštalovaná", "app_manifest_install_ask_is_public": "Má byť táto aplikácia viditeľná pre anonymných návštevníkov?", "app_manifest_install_ask_password": "Vyberte heslo pre správu tejto aplikácie", - "app_manifest_install_ask_path": "Vyberte cestu adresy URL (po názve domény), kde bude táto aplikácia nainštalovaná", + "app_manifest_install_ask_path": "Vyberte cestu adresy URL (po názve domény), kam bude táto aplikácia nainštalovaná", "app_not_correctly_installed": "Zdá sa, že {app} nie je správne nainštalovaná", "app_not_properly_removed": "{app} nebola správne odstránená", "app_packaging_format_not_supported": "Túto aplikáciu nie je možné nainštalovať, pretože formát balíčkov, ktorý používa, nie je podporovaný Vašou verziou YunoHost. Mali by ste zvážiť aktualizovanie Vášho systému.", From 6fdfd81cbb4cdd4de69b97f30b81583d7246ce68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20M?= Date: Thu, 26 Oct 2023 03:16:08 +0000 Subject: [PATCH 080/113] Translated using Weblate (Galician) Currently translated at 100.0% (782 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/gl/ --- locales/gl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/gl.json b/locales/gl.json index acbb50fe4..5d28e06e4 100644 --- a/locales/gl.json +++ b/locales/gl.json @@ -714,7 +714,7 @@ "visitors": "Visitantes", "global_settings_setting_security_experimental_enabled": "Ferramentas experimentais de seguridade", "diagnosis_using_stable_codename": "apt (o xestor de paquetes do sistema) está configurado para instalar paquetes co nome de código 'stable', no lugar do nome de código da versión actual de Debian (bullseye).", - "diagnosis_using_stable_codename_details": "Normalmente esto é debido a unha configuración incorrecta do teu provedor de hospedaxe. Esto é perigoso, porque tan pronto como a nova versión de Debian se convirta en 'stable', apt vai querer actualizar tódolos paquetes do sistema se realizar o procedemento de migración requerido. É recomendable arranxar isto editando a fonte de apt ao repositorio base de Debian, e substituir a palabra stable por bullseye. O ficheiro de configuración correspondente debería ser /etc/sources.list, ou ficheiro dentro de /etc/apt/sources.list.d/.", + "diagnosis_using_stable_codename_details": "Normalmente isto débese a unha configuración incorrecta do teu provedor de hospedaxe. Isoto é perigoso, porque tan pronto como a nova versión de Debian se convirta en 'stable', apt vai querer actualizar todos os paquetes do sistema sen realizar o procedemento de migración axeitado. É recomendable arranxar isto editando a fonte de apt ao repositorio base de Debian, e substituir a palabra stable por bullseye. O ficheiro de configuración correspondente debería ser /etc/sources.list, ou ficheiro dentro de /etc/apt/sources.list.d/.", "diagnosis_using_yunohost_testing": "apt (o xestor de paquetes do sistema) está configurado actualmente para instalar calquera actualización 'testing' para o núcleo YunoHost.", "diagnosis_using_yunohost_testing_details": "Isto probablemente sexa correcto se sabes o que estás a facer, pero pon coidado e le as notas de publicación antes de realizar actualizacións de YunoHost! Se queres desactivar as actualizacións 'testing', deberías eliminar a palabra testing de /etc/apt/sources.list.d/yunohost.list.", "global_settings_setting_backup_compress_tar_archives": "Comprimir copias de apoio", From 5547208be495d34091551545af8187005cedfbf1 Mon Sep 17 00:00:00 2001 From: Thomas <51749973+Thovi98@users.noreply.github.com> Date: Fri, 27 Oct 2023 14:15:09 +0200 Subject: [PATCH 081/113] Update docker-image-extract --- helpers/vendor/docker-image-extract/LICENSE | 26 +++++---- helpers/vendor/docker-image-extract/README.md | 2 +- .../docker-image-extract/docker-image-extract | 54 ++++++++++++++----- 3 files changed, 53 insertions(+), 29 deletions(-) diff --git a/helpers/vendor/docker-image-extract/LICENSE b/helpers/vendor/docker-image-extract/LICENSE index 82579b059..986360f1a 100644 --- a/helpers/vendor/docker-image-extract/LICENSE +++ b/helpers/vendor/docker-image-extract/LICENSE @@ -1,21 +1,19 @@ -MIT License +Copyright (c) 2020-2023, Jeremy Lin -Copyright (c) 2021 Emmanuel Frecon +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/helpers/vendor/docker-image-extract/README.md b/helpers/vendor/docker-image-extract/README.md index 6f6cb5074..4c4fa301f 100644 --- a/helpers/vendor/docker-image-extract/README.md +++ b/helpers/vendor/docker-image-extract/README.md @@ -1 +1 @@ -This is taken from https://github.com/efrecon/docker-image-extract +This is taken from https://github.com/jjlin/docker-image-extract, under MIT license. \ No newline at end of file diff --git a/helpers/vendor/docker-image-extract/docker-image-extract b/helpers/vendor/docker-image-extract/docker-image-extract index 4842a8e04..b5dfdb7a7 100755 --- a/helpers/vendor/docker-image-extract/docker-image-extract +++ b/helpers/vendor/docker-image-extract/docker-image-extract @@ -2,7 +2,7 @@ # # This script pulls and extracts all files from an image in Docker Hub. # -# Copyright (c) 2020-2022, Jeremy Lin +# Copyright (c) 2020-2023, Jeremy Lin # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), @@ -103,6 +103,17 @@ if [ $# -eq 0 ]; then exit 1 fi +if [ -e "${OUT_DIR}" ]; then + if [ -d "${OUT_DIR}" ]; then + echo "WARNING: Output dir already exists. If it contains a previous extracted image," + echo "there may be errors when trying to overwrite files with read-only permissions." + echo + else + echo "ERROR: Output dir already exists, but is not a directory." + exit 1 + fi +fi + have_curl() { command -v curl >/dev/null } @@ -173,16 +184,20 @@ fetch() { # https://docs.docker.com/docker-hub/api/latest/#tag/repositories manifest_list_url="https://hub.docker.com/v2/repositories/${image}/tags/${ref}" -# If we're pulling the image for the default platform, or the ref is already -# a SHA-256 image digest, then we don't need to look up anything. -if [ "${PLATFORM}" = "${PLATFORM_DEFAULT}" ] || [ -z "${ref##sha256:*}" ]; then +# If the ref is already a SHA-256 image digest, then we don't need to look up anything. +if [ -z "${ref##sha256:*}" ]; then digest="${ref}" else echo "Getting multi-arch manifest list..." + NL=' +' digest=$(fetch "${manifest_list_url}" | # Break up the single-line JSON output into separate lines by adding # newlines before and after the chars '[', ']', '{', and '}'. - sed -e 's/\([][{}]\)/\n\1\n/g' | + # This uses the \${NL} syntax because some BSD variants of sed don't + # support \n syntax in the replacement string, but instead require + # a literal newline preceded by a backslash. + sed -e 's/\([][{}]\)/\'"${NL}"'\1\'"${NL}"'/g' | # Extract the "images":[...] list. sed -n '/"images":/,/]/ p' | # Each image's details are now on a separate line, e.g. @@ -205,13 +220,13 @@ else break fi done) -fi -if [ -n "${digest}" ]; then - echo "Platform ${PLATFORM} resolved to '${digest}'..." -else - echo "No image digest found. Verify that the image, ref, and platform are valid." - exit 1 + if [ -n "${digest}" ]; then + echo "Platform ${PLATFORM} resolved to '${digest}'..." + else + echo "No image digest found. Verify that the image, ref, and platform are valid." + exit 1 + fi fi # https://docs.docker.com/registry/spec/auth/token/#how-to-authenticate @@ -226,10 +241,21 @@ blobs_base_url="https://registry-1.docker.io/v2/${image}/blobs" echo "Getting API token..." token=$(fetch "${api_token_url}" | extract 'token') auth_header="Authorization: Bearer $token" -v2_header="Accept: application/vnd.docker.distribution.manifest.v2+json" + +# https://github.com/distribution/distribution/blob/main/docs/spec/manifest-v2-2.md +docker_manifest_v2="application/vnd.docker.distribution.manifest.v2+json" + +# https://github.com/opencontainers/image-spec/blob/main/manifest.md +oci_manifest_v1="application/vnd.oci.image.manifest.v1+json" + +# Docker Hub can return either type of manifest format. Most images seem to +# use the Docker format for now, but the OCI format will likely become more +# common as features that require that format become enabled by default +# (e.g., https://github.com/docker/build-push-action/releases/tag/v3.3.0). +accept_header="Accept: ${docker_manifest_v2},${oci_manifest_v1}" echo "Getting image manifest for $image:$ref..." -layers=$(fetch "${manifest_url}" "${auth_header}" "${v2_header}" | +layers=$(fetch "${manifest_url}" "${auth_header}" "${accept_header}" | # Extract `digest` values only after the `layers` section appears. sed -n '/"layers":/,$ p' | extract 'digest') @@ -259,4 +285,4 @@ for layer in $layers; do IFS="${OLD_IFS}" done -echo "Image contents extracted into ${OUT_DIR}." +echo "Image contents extracted into ${OUT_DIR}." \ No newline at end of file From bfb7dda42e11b294552ca09564ef48910518285d Mon Sep 17 00:00:00 2001 From: Alexandre Aubin <4533074+alexAubin@users.noreply.github.com> Date: Mon, 30 Oct 2023 14:03:26 +0100 Subject: [PATCH 082/113] Rename helper into "ynh_exec_and_print_stderr_only_if_error" --- helpers/logging | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/helpers/logging b/helpers/logging index 8989140f6..accb8f9b0 100644 --- a/helpers/logging +++ b/helpers/logging @@ -188,13 +188,13 @@ ynh_exec_fully_quiet() { # Execute a command and redirect stderr in /dev/null. Print stderr on error. # -# usage: ynh_exec_stderr_on_error your command and args +# usage: ynh_exec_and_print_stderr_only_if_error your command and args # | arg: command - command to execute # -# Note that you should NOT quote the command but only prefix it with ynh_exec_stderr_on_error +# Note that you should NOT quote the command but only prefix it with ynh_exec_and_print_stderr_only_if_error # # Requires YunoHost version 11.2 or higher. -ynh_exec_stderr_on_error() { +ynh_exec_and_print_stderr_only_if_error() { logfile="$(mktemp)" rc=0 # Note that "$@" is used and not $@, c.f. https://unix.stackexchange.com/a/129077 From 1131e76f4ce1ca87f717b5437045ae4b13d306a1 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 30 Oct 2023 19:19:02 +0100 Subject: [PATCH 083/113] quality: fix typo, handle mypy error --- src/utils/resources.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/utils/resources.py b/src/utils/resources.py index 3f46aacfb..d8dba9147 100644 --- a/src/utils/resources.py +++ b/src/utils/resources.py @@ -1112,7 +1112,7 @@ class AptDependenciesAppResource(AppResource): f"Error while running apt resource packages_from_raw_bash snippet for '{key}' extras:" ) logger.error(err) - values["packages"] = values.get("packages", []) + [value.strip() for value in out.split("\n")] + values["packages"] = values.get("packages", []) + [value.strip() for value in out.split("\n")] # type: ignore if ( not isinstance(values.get("repo"), str) @@ -1123,9 +1123,9 @@ class AptDependenciesAppResource(AppResource): "In apt resource in the manifest: 'extras' repo should have the keys 'repo', 'key' defined as strings, 'packages' defined as list or 'packages_from_raw_bash' defined as string", raw_msg=True, ) - - # Drop 'extras' entries associated to no packages - self.extras = {key: value for key, values in self.extras.items() if values["packages"]} + + # Drop 'extras' entries associated to no packages + self.extras = {key: values for key, values in self.extras.items() if values["packages"]} def provision_or_update(self, context: Dict = {}): script = " ".join(["ynh_install_app_dependencies", *self.packages]) From 917b2961d280e90a45bb8b8d0a9f5b7ffe85a810 Mon Sep 17 00:00:00 2001 From: Tharyrok Date: Mon, 30 Oct 2023 21:55:59 +0100 Subject: [PATCH 084/113] Disable resolve ip --- src/firewall.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/firewall.py b/src/firewall.py index 392678fe1..2ba083312 100644 --- a/src/firewall.py +++ b/src/firewall.py @@ -256,7 +256,7 @@ def firewall_reload(skip_upnp=False): # IPv4 try: - process.check_output("iptables -w -L") + process.check_output("iptables -n -w -L") except process.CalledProcessError as e: logger.debug( "iptables seems to be not available, it outputs:\n%s", @@ -289,7 +289,7 @@ def firewall_reload(skip_upnp=False): # IPv6 try: - process.check_output("ip6tables -L") + process.check_output("ip6tables -n -L") except process.CalledProcessError as e: logger.debug( "ip6tables seems to be not available, it outputs:\n%s", From 8cb6a5649b93b6388955e794e80c402460916d7f Mon Sep 17 00:00:00 2001 From: chri2 Date: Tue, 31 Oct 2023 14:07:36 +0100 Subject: [PATCH 085/113] let dovecot create folders on first login tells dovecot to create standard folders on first login if they do not exist and which folder names are used for special purposes like archive, spam/junk, sent, etc. --- conf/dovecot/dovecot.conf | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/conf/dovecot/dovecot.conf b/conf/dovecot/dovecot.conf index 4f491d1df..1bd5ad5e3 100644 --- a/conf/dovecot/dovecot.conf +++ b/conf/dovecot/dovecot.conf @@ -65,13 +65,40 @@ protocol imap { mail_plugins = $mail_plugins imap_quota antispam } - protocol lda { auth_socket_path = /var/run/dovecot/auth-master mail_plugins = quota sieve postmaster_address = postmaster@{{ main_domain }} } +namespace inbox { + inbox = yes + + mailbox Drafts { + special_use = \Drafts + auto = subscribe + } + mailbox Junk { + special_use = \Junk + auto = subscribe + } + mailbox Trash { + special_use = \Trash + auto = subscribe + } + mailbox Sent { + special_use = \Sent + auto = subscribe + } + mailbox "Sent Messages" { + special_use = \Sent + } + mailbox "Archive" { + special_use = \Archive + auto = subscribe + } +} + protocol sieve { } From 8ee5aade72d0845fcf98b2de42f3b7b1ccceca12 Mon Sep 17 00:00:00 2001 From: selfhoster1312 Date: Sat, 4 Nov 2023 14:36:32 +0100 Subject: [PATCH 086/113] Don't make so many queries for user info when building UserOption form --- src/utils/form.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/utils/form.py b/src/utils/form.py index 1ca03373e..d164fedf0 100644 --- a/src/utils/form.py +++ b/src/utils/form.py @@ -941,9 +941,11 @@ class UserOption(BaseChoicesOption): super().__init__(question) + users = user_list(fields = ["username", "fullname", "mail", "mail-alias"])["users"] + self.choices = { username: f"{infos['fullname']} ({infos['mail']})" - for username, infos in user_list()["users"].items() + for username, infos in users.items() } if not self.choices: @@ -958,7 +960,7 @@ class UserOption(BaseChoicesOption): # Should be replaced by something like "any first user we find in the admin group" root_mail = "root@%s" % _get_maindomain() for user in self.choices.keys(): - if root_mail in user_info(user).get("mail-aliases", []): + if root_mail in users[user].get("mail-aliases", []): self.default = user break From 02e6346bc598415f6f6531f23a3690a142dae5e7 Mon Sep 17 00:00:00 2001 From: tituspijean Date: Wed, 8 Nov 2023 12:56:42 +0100 Subject: [PATCH 087/113] Fix certificates validity in actionsmap.yml --- share/actionsmap.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/actionsmap.yml b/share/actionsmap.yml index e44a72125..464a4e024 100644 --- a/share/actionsmap.yml +++ b/share/actionsmap.yml @@ -617,7 +617,7 @@ domain: help: Domains for which to renew the certificates nargs: "*" --force: - help: Ignore the validity threshold (30 days) + help: Ignore the validity threshold (15 days) action: store_true --email: help: Send an email to root with logs if some renewing fails From 61defdb4c1b19ac60319c627c07fc907c77bb27b Mon Sep 17 00:00:00 2001 From: mh4ckt3mh4ckt1c4s Date: Fri, 10 Nov 2023 20:58:37 +0100 Subject: [PATCH 088/113] Fix backup error message if archive already exists --- locales/en.json | 2 +- locales/fr.json | 2 +- src/backup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/en.json b/locales/en.json index e7deb9e95..7755147cc 100644 --- a/locales/en.json +++ b/locales/en.json @@ -105,7 +105,7 @@ "backup_archive_broken_link": "Could not access the backup archive (broken link to {path})", "backup_archive_cant_retrieve_info_json": "Could not load info for archive '{archive}'... The info.json file cannot be retrieved (or is not a valid json).", "backup_archive_corrupted": "It looks like the backup archive '{archive}' is corrupted : {error}", - "backup_archive_name_exists": "A backup archive with this name already exists.", + "backup_archive_name_exists": "A backup archive with the name '{name}' already exists.", "backup_archive_name_unknown": "Unknown local backup archive named '{name}'", "backup_archive_open_failed": "Could not open the backup archive", "backup_archive_system_part_not_available": "System part '{part}' unavailable in this backup", diff --git a/locales/fr.json b/locales/fr.json index d439516de..190788ff1 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -23,7 +23,7 @@ "ask_password": "Mot de passe", "backup_app_failed": "Impossible de sauvegarder {app}", "backup_archive_app_not_found": "{app} n'a pas été trouvée dans l'archive de la sauvegarde", - "backup_archive_name_exists": "Une archive de sauvegarde avec ce nom existe déjà.", + "backup_archive_name_exists": "Une archive de sauvegarde avec le nom '{name}' existe déjà.", "backup_archive_name_unknown": "L'archive locale de sauvegarde nommée '{name}' est inconnue", "backup_archive_open_failed": "Impossible d'ouvrir l'archive de la sauvegarde", "backup_cleaning_failed": "Impossible de nettoyer le dossier temporaire de sauvegarde", diff --git a/src/backup.py b/src/backup.py index 7dffce321..3b66cec97 100644 --- a/src/backup.py +++ b/src/backup.py @@ -2208,7 +2208,7 @@ def backup_create( # Validate there is no archive with the same name if name and name in backup_list()["archives"]: - raise YunohostValidationError("backup_archive_name_exists") + raise YunohostValidationError("backup_archive_name_exists", name=name) # By default we backup using the tar method if not methods: From 300c999a5a6cf3c819c23ee92ec3a6161cfbcebe Mon Sep 17 00:00:00 2001 From: OniriCorpe Date: Mon, 20 Nov 2023 19:01:33 +0100 Subject: [PATCH 089/113] logrotate: fix generated config file perms (#1736) * fix generated logrotate config file perms * apply perms to the right file (I'm so tired lmao) * fix indent * update docs * revert: wrong branch :sob: --------- Co-authored-by: OniriCorpe --- helpers/logrotate | 1 + 1 file changed, 1 insertion(+) diff --git a/helpers/logrotate b/helpers/logrotate index 45f66d443..de9f8d3c1 100644 --- a/helpers/logrotate +++ b/helpers/logrotate @@ -99,6 +99,7 @@ $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) + chmod 644 "/etc/logrotate.d/$app" # Make sure permissions are correct (otherwise the config file could be ignored and the corresponding logs never rotated) } # Remove the app's logrotate config. From 9a7731aa4ed8cc018720bfe2ddcad1041d4c5dd8 Mon Sep 17 00:00:00 2001 From: OniriCorpe Date: Tue, 21 Nov 2023 03:26:27 +0100 Subject: [PATCH 090/113] fail2ban: make sure the logfile exists (#1737) * make sure the logfile exists before reloading fail2ban * update docs * enhancement: fix file perms and make sure the folder exists * fix folder path --------- Co-authored-by: OniriCorpe --- helpers/fail2ban | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/helpers/fail2ban b/helpers/fail2ban index 31f55b312..28edeb604 100644 --- a/helpers/fail2ban +++ b/helpers/fail2ban @@ -53,8 +53,6 @@ # You can find some more explainations about how to make a regex here : # https://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Filters # -# Note that the logfile need to exist before to call this helper !! -# # To validate your regex you can test with this command: # ``` # fail2ban-regex /var/log/YOUR_LOG_FILE_PATH /etc/fail2ban/filter.d/YOUR_APP.conf @@ -102,6 +100,15 @@ ignoreregex = ynh_add_config --template="f2b_jail.conf" --destination="/etc/fail2ban/jail.d/$app.conf" ynh_add_config --template="f2b_filter.conf" --destination="/etc/fail2ban/filter.d/$app.conf" + # Create the folder and logfile if they doesn't exist, + # as fail2ban require an existing logfile before configuration + mkdir -p "/var/log/$app" + if [ ! -f "$logpath" ]; then + touch "$logpath" + chown -R "$app:$app" "/var/log/$app" + chmod -R u=rwX,g=rX,o= "/var/log/$app" + fi + ynh_systemd_action --service_name=fail2ban --action=reload --line_match="(Started|Reloaded) Fail2Ban Service" --log_path=systemd local fail2ban_error="$(journalctl --no-hostname --unit=fail2ban | tail --lines=50 | grep "WARNING.*$app.*")" From da20964044f509084a456c0f21f145d7cf5ba936 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin <4533074+alexAubin@users.noreply.github.com> Date: Fri, 24 Nov 2023 21:00:10 +0100 Subject: [PATCH 091/113] quality: unused import --- src/utils/form.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/form.py b/src/utils/form.py index d164fedf0..4fc2cd078 100644 --- a/src/utils/form.py +++ b/src/utils/form.py @@ -936,7 +936,7 @@ class UserOption(BaseChoicesOption): type: Literal[OptionType.user] = OptionType.user def __init__(self, question): - from yunohost.user import user_list, user_info + from yunohost.user import user_list from yunohost.domain import _get_maindomain super().__init__(question) From 5746b94dff4db4fc7acb12586f1a8e4fab685a18 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 24 Nov 2023 22:17:47 +0100 Subject: [PATCH 092/113] Update changelog for 11.2.6 --- debian/changelog | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/debian/changelog b/debian/changelog index 0effd40ba..f7cf7a349 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,24 @@ +yunohost (11.2.6) stable; urgency=low + + - mail: Improve dovecots rspamd integration wrt junk/spam folder naming ([#1731](https://github.com/yunohost/yunohost/pull/1731)) + - mail: add redis database configuration in rspamd ([#1730](https://github.com/yunohost/yunohost/pull/1730)) + - mail: let dovecot create folders on first login ([#1735](https://github.com/yunohost/yunohost/pull/1735)) + - apps: Support packages_from_raw_bash in extra packages ([#1729](https://github.com/yunohost/yunohost/pull/1729)) + - apps/configpanel: support bind 'heritage', avoid repeating the same bind statement for multiple options ([#1706](https://github.com/yunohost/yunohost/pull/1706)) + - helpers: Upgrade n to version 9.2.0 ([#1727](https://github.com/yunohost/yunohost/pull/1727)) + - helpers: Update docker-image-extract to support more recent docker images ([#1733](https://github.com/yunohost/yunohost/pull/1733)) + - helpers: Add ynh_exec_and_print_stderr_only_if_error that only prints stderr when command fails ([#1723](https://github.com/yunohost/yunohost/pull/1723)) + - helpers: fix logrotate config file permission ([#1736](https://github.com/yunohost/yunohost/pull/1736)) + - helpers: make sure logfile exist when calling fail2ban helper ([#1737](https://github.com/yunohost/yunohost/pull/1737)) + - backup: Add post_app_restore hook ([#1708](https://github.com/yunohost/yunohost/pull/1708)) + - perf: speedup firewall reload ([#1734](https://github.com/yunohost/yunohost/pull/1734)) + - perf: prevent unecessary queries when building UserOption form ([#1738](https://github.com/yunohost/yunohost/pull/1738)) + - i18n: Translations updated for Basque, Catalan, French, Galician, Italian, Slovak, Spanish + + Thanks to all contributors <3 ! (chri2, Chris Vogel, cristian amoyao, Éric Gaspar, Félix Piédallu, Jorge-vitrubio.net, José M, Jose Riha, ljf, mh4ckt3mh4ckt1c4s, OniriCorpe, Sebastian Gumprich, selfhoster1312, Tharyrok, Thomas, tituspijean, xabirequejo) + + -- Alexandre Aubin Fri, 24 Nov 2023 22:01:50 +0100 + yunohost (11.2.5) stable; urgency=low - debian: fix conflict with openssl that is too harsh, openssl version on bullseye is now 1.1.1w, bookworm has 3.x (e8700bfe7) From ce0cbc5fedfa1ea6778ac1b2f2e1c644625f76b6 Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Fri, 24 Nov 2023 21:53:33 +0000 Subject: [PATCH 093/113] [CI] Format code with Black --- src/backup.py | 4 +--- src/utils/configpanel.py | 9 ++++++++- src/utils/form.py | 4 +++- src/utils/resources.py | 9 +++++++-- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/backup.py b/src/backup.py index 3b66cec97..cdd9eb415 100644 --- a/src/backup.py +++ b/src/backup.py @@ -1556,9 +1556,7 @@ class RestoreManager: operation_logger.success() # Call post_app_restore hook - env_dict = _make_environment_for_app_script( - app_instance_name - ) + env_dict = _make_environment_for_app_script(app_instance_name) hook_callback("post_app_restore", env=env_dict) else: self.targets.set_result("apps", app_instance_name, "Error") diff --git a/src/utils/configpanel.py b/src/utils/configpanel.py index cc93f888f..aa3a02411 100644 --- a/src/utils/configpanel.py +++ b/src/utils/configpanel.py @@ -352,7 +352,14 @@ class ConfigPanel: }, }, "sections": { - "properties": ["name", "services", "optional", "help", "visible", "bind"], + "properties": [ + "name", + "services", + "optional", + "help", + "visible", + "bind", + ], "defaults": { "name": "", "services": [], diff --git a/src/utils/form.py b/src/utils/form.py index 4fc2cd078..638b8fac1 100644 --- a/src/utils/form.py +++ b/src/utils/form.py @@ -941,7 +941,9 @@ class UserOption(BaseChoicesOption): super().__init__(question) - users = user_list(fields = ["username", "fullname", "mail", "mail-alias"])["users"] + users = user_list(fields=["username", "fullname", "mail", "mail-alias"])[ + "users" + ] self.choices = { username: f"{infos['fullname']} ({infos['mail']})" diff --git a/src/utils/resources.py b/src/utils/resources.py index d8dba9147..324a0762c 100644 --- a/src/utils/resources.py +++ b/src/utils/resources.py @@ -1086,6 +1086,7 @@ class AptDependenciesAppResource(AppResource): packages: List = [] packages_from_raw_bash: str = "" extras: Dict[str, Dict[str, Union[str, List]]] = {} + def __init__(self, properties: Dict[str, Any], *args, **kwargs): super().__init__(properties, *args, **kwargs) @@ -1106,7 +1107,9 @@ class AptDependenciesAppResource(AppResource): values["packages"] = [value.strip() for value in values["packages"].split(",")] # type: ignore if isinstance(values.get("packages_from_raw_bash"), str): - out, err = self.check_output_bash_snippet(values.get("packages_from_raw_bash")) + out, err = self.check_output_bash_snippet( + values.get("packages_from_raw_bash") + ) if err: logger.error( f"Error while running apt resource packages_from_raw_bash snippet for '{key}' extras:" @@ -1125,7 +1128,9 @@ class AptDependenciesAppResource(AppResource): ) # Drop 'extras' entries associated to no packages - self.extras = {key: values for key, values in self.extras.items() if values["packages"]} + self.extras = { + key: values for key, values in self.extras.items() if values["packages"] + } def provision_or_update(self, context: Dict = {}): script = " ".join(["ynh_install_app_dependencies", *self.packages]) From 4bfe2c96f576f49a811099bce814237821dc801f Mon Sep 17 00:00:00 2001 From: OniriCorpe Date: Mon, 27 Nov 2023 14:07:39 +0100 Subject: [PATCH 094/113] fix the fail2ban helper when using using --use_template arg (#1743) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix the helper when using using --use_template arg * fix app name replacment 😞 * replace any '__VAR__' by their real variable using ynh_replace_vars * fix some SC2086 * extract logpath from /etc/fail2ban/jail.d/$app.conf Co-authored-by: Alexandre Aubin <4533074+alexAubin@users.noreply.github.com> * fix comment * Update helpers/fail2ban --------- Co-authored-by: Alexandre Aubin <4533074+alexAubin@users.noreply.github.com> --- helpers/fail2ban | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/helpers/fail2ban b/helpers/fail2ban index 28edeb604..ee6540d05 100644 --- a/helpers/fail2ban +++ b/helpers/fail2ban @@ -74,7 +74,7 @@ ynh_add_fail2ban_config() { ports=${ports:-http,https} use_template="${use_template:-0}" - if [ $use_template -ne 1 ]; then + if [ "$use_template" -ne 1 ]; then # Usage 1, no template. Build a config file from scratch. test -n "$logpath" || ynh_die --message="ynh_add_fail2ban_config expects a logfile path as first argument and received nothing." test -n "$failregex" || ynh_die --message="ynh_add_fail2ban_config expects a failure regex as second argument and received nothing." @@ -86,7 +86,7 @@ port = __PORTS__ filter = __APP__ logpath = __LOGPATH__ maxretry = __MAX_RETRY__ -" >$YNH_APP_BASEDIR/conf/f2b_jail.conf +" >"$YNH_APP_BASEDIR/conf/f2b_jail.conf" echo " [INCLUDES] @@ -94,20 +94,28 @@ before = common.conf [Definition] failregex = __FAILREGEX__ ignoreregex = -" >$YNH_APP_BASEDIR/conf/f2b_filter.conf +" >"$YNH_APP_BASEDIR/conf/f2b_filter.conf" fi ynh_add_config --template="f2b_jail.conf" --destination="/etc/fail2ban/jail.d/$app.conf" ynh_add_config --template="f2b_filter.conf" --destination="/etc/fail2ban/filter.d/$app.conf" + # if "$logpath" doesn't exist (as if using --use_template argument), assign + # "$logpath" using the one in the previously generated fail2ban conf file + if [ -z "${logpath:-}" ]; then + # the first sed deletes possibles spaces and the second one extract the path + logpath=$(grep logpath "/etc/fail2ban/jail.d/$app.conf" | sed "s/ //g" | sed "s/logpath=//g") + fi + # Create the folder and logfile if they doesn't exist, # as fail2ban require an existing logfile before configuration mkdir -p "/var/log/$app" if [ ! -f "$logpath" ]; then touch "$logpath" - chown -R "$app:$app" "/var/log/$app" - chmod -R u=rwX,g=rX,o= "/var/log/$app" fi + # Make sure log folder's permissions are correct + chown -R "$app:$app" "/var/log/$app" + chmod -R u=rwX,g=rX,o= "/var/log/$app" ynh_systemd_action --service_name=fail2ban --action=reload --line_match="(Started|Reloaded) Fail2Ban Service" --log_path=systemd From 207c0ff1abce81fdd7c073e5154de404bf7c62b1 Mon Sep 17 00:00:00 2001 From: xabirequejo Date: Mon, 6 Nov 2023 17:10:41 +0000 Subject: [PATCH 095/113] Translated using Weblate (Basque) Currently translated at 99.1% (775 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/eu/ --- locales/eu.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/eu.json b/locales/eu.json index c2a461445..349b25f9c 100644 --- a/locales/eu.json +++ b/locales/eu.json @@ -389,7 +389,7 @@ "group_already_exist_on_system_but_removing_it": "{group} taldea existitzen da sistemaren taldeetan, baina YunoHostek ezabatuko du…", "diagnosis_mail_fcrdns_nok_details": "Lehenik eta behin zure routerraren konfigurazio gunean edo hostingaren enpresaren aukeretan alderantzizko DNSa konfiguratzen saiatu beharko zinateke {ehlo_domain} erabiliz. (Hosting enpresaren arabera, ezinbestekoa da beraiekin harremanetan jartzea).", "diagnosis_mail_outgoing_port_25_ok": "SMTP posta zerbitzaria posta elektronikoa bidaltzeko gai da (25. atakaren irteera ez dago blokeatuta).", - "diagnosis_ports_partially_unreachable": "{port}. ataka ez dago eskuragarri kanpotik Pv{failed} erabiliz.", + "diagnosis_ports_partially_unreachable": "{port}. ataka ez dago eskuragarri kanpotik IPv{failed} erabiliz.", "diagnosis_ports_forwarding_tip": "Arazoa konpontzeko, litekeena da operadorearen routerrean ataken birbideraketa konfiguratu behar izatea, https://yunohost.org/isp_box_config-n agertzen den bezala", "domain_creation_failed": "Ezinezkoa izan da {domain} domeinua sortzea: {error}", "domains_available": "Erabilgarri dauden domeinuak:", From ff4c1433d2fb11cb43b6673adc2b4d964d8d3af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20M?= Date: Tue, 21 Nov 2023 06:36:58 +0000 Subject: [PATCH 096/113] Translated using Weblate (Galician) Currently translated at 100.0% (782 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/gl/ --- locales/gl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/gl.json b/locales/gl.json index 5d28e06e4..74199cceb 100644 --- a/locales/gl.json +++ b/locales/gl.json @@ -21,7 +21,7 @@ "backup_archive_cant_retrieve_info_json": "Non se puido cargar a info do arquivo '{archive}'... Non se obtivo o ficheiro info.json (ou é un json non válido).", "backup_archive_open_failed": "Non se puido abrir o arquivo de copia de apoio", "backup_archive_name_unknown": "Arquivo local de copia de apoio descoñecido con nome '{name}'", - "backup_archive_name_exists": "Xa existe un arquivo de copia con este nome.", + "backup_archive_name_exists": "Xa existe un ficheiro de copia con nome '{name}'.", "backup_archive_broken_link": "Non se puido acceder ao arquivo da copia (ligazón rota a {path})", "backup_archive_app_not_found": "Non se atopa {app} no arquivo da copia", "backup_applying_method_tar": "Creando o arquivo TAR da copia...", From fff8b2d95a17ee54a74d14a904f8d74572482482 Mon Sep 17 00:00:00 2001 From: ppr Date: Sat, 25 Nov 2023 10:38:06 +0000 Subject: [PATCH 097/113] Translated using Weblate (French) Currently translated at 99.8% (781 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/fr/ --- locales/fr.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/fr.json b/locales/fr.json index 190788ff1..7953e851b 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -776,11 +776,11 @@ "dyndns_unsubscribe_failed": "Impossible de se désinscrire du domaine DynDNS : {erreur}", "dyndns_unsubscribed": "Désinscription du domaine DynDNS", "dyndns_unsubscribe_denied": "Échec de la désinscription du domaine : informations d'identification non valides", - "dyndns_unsubscribe_already_unsubscribed": "Le domaine est déjà désabonné/retiré", - "dyndns_set_recovery_password_denied": "Échec de la définition du mot de passe de récupération : mot de passe non valide", + "dyndns_unsubscribe_already_unsubscribed": "Le domaine est déjà retiré", + "dyndns_set_recovery_password_denied": "Échec de la mise en place du mot de passe de récupération : mot de passe non valide", "dyndns_set_recovery_password_unknown_domain": "Échec de la définition du mot de passe de récupération : le domaine n'est pas enregistré", - "dyndns_set_recovery_password_invalid_password": "Échec de la définition du mot de passe de récupération : le mot de passe n'est pas assez fort/solide", - "dyndns_set_recovery_password_failed": "Échec de la définition du mot de passe de récupération : {erreur}", + "dyndns_set_recovery_password_invalid_password": "Échec de la mise en place du mot de passe de récupération : le mot de passe n'est pas assez fort/solide", + "dyndns_set_recovery_password_failed": "Échec de la mise en place du mot de passe de récupération : {erreur}", "dyndns_set_recovery_password_success": "Mot de passe de récupération changé !", "log_dyndns_unsubscribe": "Se désabonner d'un sous-domaine YunoHost '{}'", "dyndns_too_many_requests": "Le service dyndns de YunoHost a reçu trop de requêtes/demandes de votre part, attendez environ 1 heure avant de réessayer.", From 04f326528f6ff68eb24cbcce4195043fcb6069a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20M?= Date: Mon, 27 Nov 2023 08:26:14 +0000 Subject: [PATCH 098/113] Translated using Weblate (Galician) Currently translated at 100.0% (782 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/gl/ --- locales/gl.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/locales/gl.json b/locales/gl.json index 74199cceb..bf7d9212b 100644 --- a/locales/gl.json +++ b/locales/gl.json @@ -26,7 +26,7 @@ "backup_archive_app_not_found": "Non se atopa {app} no arquivo da copia", "backup_applying_method_tar": "Creando o arquivo TAR da copia...", "backup_applying_method_custom": "Chamando polo método de copia de apoio personalizado '{method}'...", - "backup_applying_method_copy": "Copiando tódolos ficheiros necesarios...", + "backup_applying_method_copy": "Copiando os ficheiros na copia...", "backup_app_failed": "Non se fixo copia de {app}", "backup_actually_backuping": "Creando o arquivo de copia cos ficheiros recollidos...", "backup_abstract_method": "Este método de copia de apoio aínda non foi implementado", @@ -215,7 +215,7 @@ "diagnosis_mail_ehlo_wrong_details": "O EHLO recibido polo diagnosticador remoto en IPv{ipversion} é diferente ao dominio do teu servidor.
EHLO recibido: {wrong_ehlo}
Agardado: {right_ehlo}
A razón máis habitual para este problema é que o porto 25 non está correctamente redirixido ao teu servidor. Alternativamente, asegúrate de non ter un cortalumes ou reverse-proxy interferindo.", "diagnosis_regenconf_manually_modified_details": "Probablemente todo sexa correcto se sabes o que estás a facer! YunoHost non vai actualizar este ficheiro automáticamente... Pero ten en conta que as actualizacións de YunoHost poderían incluír cambios importantes recomendados. Se queres podes ver as diferenzas con yunohost tools regen-conf {category} --dry-run --with-diff e forzar o restablecemento da configuración recomendada con yunohost tools regen-conf {category} --force", "diagnosis_regenconf_manually_modified": "O ficheiro de configuración {file} semella que foi modificado manualmente.", - "diagnosis_regenconf_allgood": "Tódolos ficheiros de configuración seguen a configuración recomendada!", + "diagnosis_regenconf_allgood": "Todos os ficheiros de configuración seguen a configuración recomendada!", "diagnosis_mail_queue_too_big": "Hai demasiados emails pendentes na cola de correo ({nb_pending} emails)", "diagnosis_mail_queue_unavailable_details": "Erro: {error}", "diagnosis_mail_queue_unavailable": "Non se pode consultar o número de emails pendentes na cola", @@ -358,7 +358,7 @@ "log_app_install": "Instalar a app '{}'", "log_app_change_url": "Cambiar o URL da app '{}'", "log_operation_unit_unclosed_properly": "Non se pechou correctamente a unidade da operación", - "log_does_exists": "Non hai rexistro de operación co nome '{log}', usa 'yunohost log list' para ver tódolos rexistros de operacións dispoñibles", + "log_does_exists": "Non hai rexistro de operación co nome '{log}', usa 'yunohost log list' para ver todos os rexistros de operacións dispoñibles", "log_help_to_get_failed_log": "A operación '{desc}' non se completou. Comparte o rexistro completo da operación utilizando o comando 'yunohost log share {name}' para obter axuda", "log_link_to_failed_log": "Non se completou a operación '{desc}'. Por favor envía o rexistro completo desta operación premendo aquí para obter axuda", "migration_ldap_rollback_success": "Sistema restablecido.", @@ -484,7 +484,7 @@ "service_description_rspamd": "Filtra spam e outras características relacionadas co email", "service_description_redis-server": "Unha base de datos especial utilizada para o acceso rápido a datos, cola de tarefas e comunicación entre programas", "service_description_postfix": "Utilizado para enviar e recibir emails", - "service_description_nginx": "Serve ou proporciona acceso a tódolos sitios web hospedados no teu servidor", + "service_description_nginx": "Serve ou proporciona acceso a todos os sitios web hospedados no teu servidor", "service_description_mysql": "Almacena datos da app (base de datos SQL)", "service_description_metronome": "Xestiona as contas de mensaxería instantánea XMPP", "service_description_fail2ban": "Protexe contra ataques de forza bruta e outro tipo de ataques desde internet", @@ -693,7 +693,7 @@ "global_settings_setting_webadmin_allowlist_enabled": "Activar a lista de IP autorizados", "invalid_credentials": "Credenciais non válidas", "log_settings_reset": "Restablecer axuste", - "log_settings_reset_all": "Restablecer tódolos axustes", + "log_settings_reset_all": "Restablecer todos os axustes", "log_settings_set": "Aplicar axustes", "admins": "Admins", "all_users": "Tódalas usuarias de YunoHost", From 4897f72974fff30b168a40bf55bf917395cca4cc Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Mon, 27 Nov 2023 14:15:19 +0100 Subject: [PATCH 099/113] Update changelog for 11.2.7 --- debian/changelog | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/debian/changelog b/debian/changelog index f7cf7a349..73cbe440b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +yunohost (11.2.7) stable; urgency=low + + - helpers: fix fail2ban helper when using using --use_template arg ([#1743](https://github.com/yunohost/yunohost/pull/1743)) + - i18n: Translations updated for Basque, French, Galician + + Thanks to all contributors <3 ! (José M, OniriCorpe, ppr, xabirequejo) + + -- Alexandre Aubin Mon, 27 Nov 2023 14:13:54 +0100 + yunohost (11.2.6) stable; urgency=low - mail: Improve dovecots rspamd integration wrt junk/spam folder naming ([#1731](https://github.com/yunohost/yunohost/pull/1731)) From 267968074b471cd2ee2081c560127e13dadcca1d Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 28 Nov 2023 13:14:29 +0100 Subject: [PATCH 100/113] helpers/fail2ban: grep logpath is likely to match comments in the file that contain the word logpath... --- helpers/fail2ban | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpers/fail2ban b/helpers/fail2ban index ee6540d05..648a90359 100644 --- a/helpers/fail2ban +++ b/helpers/fail2ban @@ -104,7 +104,7 @@ ignoreregex = # "$logpath" using the one in the previously generated fail2ban conf file if [ -z "${logpath:-}" ]; then # the first sed deletes possibles spaces and the second one extract the path - logpath=$(grep logpath "/etc/fail2ban/jail.d/$app.conf" | sed "s/ //g" | sed "s/logpath=//g") + logpath=$(grep "^logpath" "/etc/fail2ban/jail.d/$app.conf" | sed "s/ //g" | sed "s/logpath=//g") fi # Create the folder and logfile if they doesn't exist, From 59875cae23084e6d9f35ab70031e5cc2e2e4491f Mon Sep 17 00:00:00 2001 From: Alexandre Aubin <4533074+alexAubin@users.noreply.github.com> Date: Tue, 28 Nov 2023 16:30:45 +0100 Subject: [PATCH 101/113] domains: also regen dovecot configuration when adding a domain --- src/domain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/domain.py b/src/domain.py index 79194df2d..0fb9f577c 100644 --- a/src/domain.py +++ b/src/domain.py @@ -305,7 +305,7 @@ def domain_add( # should identify the root of this bug... _force_clear_hashes([f"/etc/nginx/conf.d/{domain}.conf"]) regen_conf( - names=["nginx", "metronome", "dnsmasq", "postfix", "rspamd", "mdns"] + names=["nginx", "metronome", "dnsmasq", "postfix", "rspamd", "mdns", "dovecot"] ) app_ssowatconf() From 570184ac1e3f0ddbef1f50f4de2a7ac9ddfec728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josu=C3=A9=20Tille?= Date: Wed, 1 Nov 2023 17:02:55 +0100 Subject: [PATCH 102/113] Fix change url --- helpers/nginx | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/helpers/nginx b/helpers/nginx index bb0fe0577..cf58c3f1a 100644 --- a/helpers/nginx +++ b/helpers/nginx @@ -53,19 +53,6 @@ ynh_change_url_nginx_config() { local old_nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf local new_nginx_conf_path=/etc/nginx/conf.d/$new_domain.d/$app.conf - # Change the path in the NGINX config file - if [ $change_path -eq 1 ] - then - # Make a backup of the original NGINX config file if modified - ynh_backup_if_checksum_is_different --file="$old_nginx_conf_path" - # Set global variables for NGINX helper - domain="$old_domain" - path="$new_path" - path_url="$new_path" - # Create a dedicated NGINX config - ynh_add_nginx_config - fi - # Change the domain for NGINX if [ $change_domain -eq 1 ] then @@ -73,6 +60,17 @@ ynh_change_url_nginx_config() { mv "$old_nginx_conf_path" "$new_nginx_conf_path" ynh_store_file_checksum --file="$new_nginx_conf_path" fi + + # Change the path in the NGINX config file + if [ $change_path -eq 1 ] + then + # Make a backup of the original NGINX config file if modified + ynh_backup_if_checksum_is_different --file="$old_nginx_conf_path" + # Set global variables for NGINX helper + path="$new_path" + path_url="$new_path" + # Create a dedicated NGINX config + ynh_add_nginx_config + fi ynh_systemd_action --service_name=nginx --action=reload } - From fe3416aa02139eb8215a4d9a7aae61c963893e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josu=C3=A9=20Tille?= Date: Wed, 29 Nov 2023 15:02:47 +0100 Subject: [PATCH 103/113] Set domain with new_domain and path with new_path --- src/app.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app.py b/src/app.py index 12b3c4233..df6cb606b 100644 --- a/src/app.py +++ b/src/app.py @@ -478,6 +478,8 @@ def app_change_url(operation_logger, app, domain, path): env_dict["old_path"] = old_path env_dict["new_domain"] = domain env_dict["new_path"] = path + env_dict["domain"] = domain + env_dict["path"] = path env_dict["change_path"] = "1" if old_path != path else "0" env_dict["change_domain"] = "1" if old_domain != domain else "0" From 8c475d0a7b3acc7871e65256dd712d3aa953d517 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin <4533074+alexAubin@users.noreply.github.com> Date: Tue, 5 Dec 2023 19:01:17 +0100 Subject: [PATCH 104/113] Further simplify ynh_change_url_nginx_config --- helpers/nginx | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/helpers/nginx b/helpers/nginx index cf58c3f1a..600c70a49 100644 --- a/helpers/nginx +++ b/helpers/nginx @@ -44,33 +44,22 @@ ynh_remove_nginx_config() { } -# Move / regen the nginx config in a change url context +# Regen the nginx config in a change url context # # usage: ynh_change_url_nginx_config # # Requires YunoHost version 11.1.9 or higher. ynh_change_url_nginx_config() { + + # Make a backup of the original NGINX config file if manually modified + # (nb: this is possibly different from the same instruction called by + # ynh_add_config inside ynh_add_nginx_config because the path may have + # changed if we're changing the domain too...) local old_nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf - local new_nginx_conf_path=/etc/nginx/conf.d/$new_domain.d/$app.conf + ynh_backup_if_checksum_is_different --file="$old_nginx_conf_path" + ynh_delete_file_checksum --file="$old_nginx_conf_path" + ynh_secure_remove --file="$old_nginx_conf_path" - # Change the domain for NGINX - if [ $change_domain -eq 1 ] - then - ynh_delete_file_checksum --file="$old_nginx_conf_path" - mv "$old_nginx_conf_path" "$new_nginx_conf_path" - ynh_store_file_checksum --file="$new_nginx_conf_path" - fi - - # Change the path in the NGINX config file - if [ $change_path -eq 1 ] - then - # Make a backup of the original NGINX config file if modified - ynh_backup_if_checksum_is_different --file="$old_nginx_conf_path" - # Set global variables for NGINX helper - path="$new_path" - path_url="$new_path" - # Create a dedicated NGINX config - ynh_add_nginx_config - fi - ynh_systemd_action --service_name=nginx --action=reload + # Regen the nginx conf + ynh_add_nginx_config } From 38db30cd70026e9a2d5763c192948fdce94b1bd2 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 5 Dec 2023 19:22:34 +0100 Subject: [PATCH 105/113] Update changelog for 11.2.8 --- debian/changelog | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/debian/changelog b/debian/changelog index 73cbe440b..d94dc5f70 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +yunohost (11.2.8) stable; urgency=low + + - domains: also regen dovecot configuration when adding a domain (59875cae) + - helpers/fail2ban: grep logpath is likely to match comments in the file that contain the word logpath... (26796807) + - helpers: Further simplify the change url helper ([#1746](https://github.com/yunohost/yunohost/pull/1746)) + + Thanks to all contributors <3 ! (Josué Tille) + + -- Alexandre Aubin Tue, 05 Dec 2023 19:21:38 +0100 + yunohost (11.2.7) stable; urgency=low - helpers: fix fail2ban helper when using using --use_template arg ([#1743](https://github.com/yunohost/yunohost/pull/1743)) From f436057d27aca1e632a5243c7d42975c6fc983a1 Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Tue, 5 Dec 2023 19:51:58 +0000 Subject: [PATCH 106/113] [CI] Format code with Black --- src/domain.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/domain.py b/src/domain.py index 0fb9f577c..1914cabc5 100644 --- a/src/domain.py +++ b/src/domain.py @@ -305,7 +305,15 @@ def domain_add( # should identify the root of this bug... _force_clear_hashes([f"/etc/nginx/conf.d/{domain}.conf"]) regen_conf( - names=["nginx", "metronome", "dnsmasq", "postfix", "rspamd", "mdns", "dovecot"] + names=[ + "nginx", + "metronome", + "dnsmasq", + "postfix", + "rspamd", + "mdns", + "dovecot", + ] ) app_ssowatconf() From 169c921444dde57bd1e79bb352d0f359993873ca Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 9 Dec 2023 15:54:04 +0100 Subject: [PATCH 107/113] Fix change_url again, otherwise the lack of path_url default to the old path and fucks up the nginx regen --- src/app.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/app.py b/src/app.py index df6cb606b..59a68af57 100644 --- a/src/app.py +++ b/src/app.py @@ -480,6 +480,7 @@ def app_change_url(operation_logger, app, domain, path): env_dict["new_path"] = path env_dict["domain"] = domain env_dict["path"] = path + env_dict["path_url"] = path env_dict["change_path"] = "1" if old_path != path else "0" env_dict["change_domain"] = "1" if old_domain != domain else "0" @@ -500,6 +501,8 @@ def app_change_url(operation_logger, app, domain, path): change_url_script = os.path.join(tmp_workdir_for_app, "scripts/change_url") + import pdb; pdb.set_trace() + # Execute App change_url script change_url_failed = True try: From 2828b7636410fd7acb1394c5065b22534e33b201 Mon Sep 17 00:00:00 2001 From: Christian Wehrli Date: Wed, 6 Dec 2023 18:19:31 +0000 Subject: [PATCH 108/113] Translated using Weblate (German) Currently translated at 100.0% (782 of 782 strings) Translation: YunoHost/core Translate-URL: https://translate.yunohost.org/projects/yunohost/core/de/ --- locales/de.json | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/locales/de.json b/locales/de.json index 634107b1f..34d9c4819 100644 --- a/locales/de.json +++ b/locales/de.json @@ -19,7 +19,7 @@ "ask_password": "Passwort", "backup_app_failed": "Konnte keine Sicherung für {app} erstellen", "backup_archive_app_not_found": "{app} konnte in keiner Datensicherung gefunden werden", - "backup_archive_name_exists": "Datensicherung mit dem selben Namen existiert bereits.", + "backup_archive_name_exists": "Eine Datensicherung mit dem Namen '{name}' existiert bereits.", "backup_archive_name_unknown": "Unbekanntes lokale Datensicherung mit Namen '{name}' gefunden", "backup_archive_open_failed": "Kann Sicherungsarchiv nicht öfnen", "backup_cleaning_failed": "Temporäres Sicherungsverzeichnis konnte nicht geleert werden", @@ -394,8 +394,8 @@ "group_cannot_edit_primary_group": "Die Gruppe '{group}' kann nicht manuell bearbeitet werden. Es ist die primäre Gruppe, welche dazu gedacht ist, nur ein spezifisches Konto zu enthalten.", "diagnosis_processes_killed_by_oom_reaper": "Das System hat ein paar Prozesse abgewürgt, da ihm der Speicher ausgegangen ist. Dies ist typischerweise sympomatisch eines ungenügenden Vorhandenseins des Arbeitsspeichers oder eines einzelnen Prozesses, der zu viel Speicher verbraucht. Zusammenfassung der abgewürgtenProzesse: \n{kills_summary}", "diagnosis_description_ports": "Geöffnete Ports", - "additional_urls_already_added": "Zusätzliche URL '{url}' bereits hinzugefügt in der zusätzlichen URL für Berechtigung '{permission}'", - "additional_urls_already_removed": "Zusätzliche URL '{url}' bereits entfernt in der zusätzlichen URL für Berechtigung '{permission}'", + "additional_urls_already_added": "Die zusätzliche URL '{url}' wurde bereits hinzugefügt für die Berechtigung '{permission}'", + "additional_urls_already_removed": "Die zusätzliche URL '{url}' wurde bereits entfernt für die Berechtigung '{permission}'", "app_label_deprecated": "Dieser Befehl ist veraltet! Bitte nutze den neuen Befehl 'yunohost user permission update' um das Applabel zu verwalten.", "diagnosis_http_hairpinning_issue_details": "Das liegt wahrscheinlich an Ihrem Router. Dadurch können Personen von ausserhalb deines Netzwerkes, aber nicht von innerhalb deines lokalen Netzwerkes (wie wahrscheinlich Sie selbst), auf Ihren Server zugreifen, wenn dazu die Domäne oder öffentliche IP verwendet wird. Sie können das Problem eventuell beheben, indem Sie einen Blick auf https://yunohost.org/dns_local_network werfen", "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.", @@ -766,5 +766,23 @@ "pattern_fullname": "Muss ein gültiger voller Name sein (mindestens 3 Zeichen)", "migration_0021_not_buster2": "Die aktuelle Debian-Distribution ist nicht Buster! Wenn Sie bereits eine Buster->Bullseye-Migration durchgeführt haben, dann ist dieser Fehler symptomatisch für den Umstand, dass das Migrationsprozedere nicht zu 100% erfolgreich war (andernfalls hätte Yunohost es als vollständig gekennzeichnet). Es ist empfehlenswert, sich der Geschehnisse zusammen mit dem Support-Team anzunehmen, das einen Bedarf an einem **vollständigen** Log der Migration haben wird, das in Werkzeuge > Logs im Adminpanel auffindbar ist.", "migration_0024_rebuild_python_venv_disclaimer_base": "Der Aktualisierung zu Debian Bullseye folgend ist es nötig, dass ein paar Python-Applikationen partiell neu gebaut und in die neue, mit Debian mitgelieferte Python-Version konvertiert werden. (in technischen Begrifflichkeiten: das, was wir die 'virtualenv' nennen, muss erneuert werden). In der Zwischenzeit kann es sein, dass diese Python-Applikationen nicht funktionieren. YunoHost kann versuchen die virtualenv für ein paar davon zu erneuern, wie untenstehend detailliert beschrieben wird. Für die anderen Applikationen, oder für den Fall, dass die Erneuerung fehlschlägt, werden eine erzwungene Aktualisierung für diese Applikationen durchführen müssen.", - "migration_0024_rebuild_python_venv_disclaimer_ignored": "Virtualenvs können für diese Applikationen nicht automatisch erneuert werden. Für diejenigen werden Sie eine erzwungene Aktualisierung durchführen müssen, was in der Kommandozeile bewerkstelligt werden kann mit: `yunohost app upgrade --force APP`: {ignored_apps}" + "migration_0024_rebuild_python_venv_disclaimer_ignored": "Virtualenvs können für diese Applikationen nicht automatisch erneuert werden. Für diejenigen werden Sie eine erzwungene Aktualisierung durchführen müssen, was in der Kommandozeile bewerkstelligt werden kann mit: `yunohost app upgrade --force APP`: {ignored_apps}", + "ask_dyndns_recovery_password_explain_unavailable": "Diese DynDNS-Domäne ist bereits registriert. Wenn Sie die Person sind, die diese Domäne ursprünglich registriert hat, können Sie das Wiederherstellungspasswort eingeben, um diese Domäne wiederherzustellen.", + "ask_dyndns_recovery_password": "DynDNS Wiederherstellungspasswort", + "ask_dyndns_recovery_password_explain_during_unsubscribe": "Bitte geben Sie das Wiederherstellungspasswort für Ihre DynDNS-Domäne ein.", + "dyndns_no_recovery_password": "Es wurde kein Wiederherstellungspasswort spezifiziert! Wenn Sie die Kontrolle über diese Domäne verlieren, werden Sie einen Administrator des YunoHost-Teams kontaktieren müssen!", + "dyndns_too_many_requests": "Der DynDNS-Service von YunoHost hat zu viele Anfragen von Ihnen erhalten, warten Sie ungefähr 1 Stunde bevor Sie erneut versuchen.", + "dyndns_set_recovery_password_invalid_password": "Konnte Wiederherstellungspasswort nicht einstellen: Passwort ist nicht stark genug", + "log_dyndns_unsubscribe": "Von einer YunoHost-Subdomain abmelden '{}'", + "ask_dyndns_recovery_password_explain": "Bitte wählen Sie ein Passwort zur Wiederherstellung ihrer DynDNS, für den Fall, dass Sie sie später zurücksetzen müssen.", + "dyndns_subscribed": "DynDNS-Domäne registriert", + "dyndns_subscribe_failed": "Konnte DynDNS-Domäne nicht registrieren: {error}", + "dyndns_unsubscribe_failed": "Konnte die DynDNS-Domäne nicht abmelden: {error}", + "dyndns_unsubscribed": "DynDNS-Domäne abgemeldet", + "dyndns_unsubscribe_denied": "Konnte Domäne nicht abmelden: ungültige Anmeldedaten", + "dyndns_unsubscribe_already_unsubscribed": "Domäne ist bereits abgemeldet", + "dyndns_set_recovery_password_denied": "Konnte Wiederherstellungspasswort nicht einstellen: ungültiges Passwort", + "dyndns_set_recovery_password_unknown_domain": "Konnte Wiederherstellungspasswort nicht einstellen: Domäne nicht registriert", + "dyndns_set_recovery_password_failed": "Konnte Wiederherstellungspasswort nicht einstellen: {error}", + "dyndns_set_recovery_password_success": "Wiederherstellungspasswort eingestellt!" } From 457289d6cac0072941f28ebd99fcefe9469a965a Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 9 Dec 2023 15:57:03 +0100 Subject: [PATCH 109/113] Update changelog for 11.2.8.1 --- debian/changelog | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/debian/changelog b/debian/changelog index d94dc5f70..89e2231ea 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +yunohost (11.2.8.1) stable; urgency=low + + - apps: fix change_url again, otherwise the lack of path_url default to the old path and fucks up the nginx regen (169c9214) + - i18n: Translations updated for German + + Thanks to all contributors <3 ! (Christian Wehrli) + + -- Alexandre Aubin Sat, 09 Dec 2023 15:56:20 +0100 + yunohost (11.2.8) stable; urgency=low - domains: also regen dovecot configuration when adding a domain (59875cae) From 0a7b5fb0ba956d4f19673036352b7382969ee2f5 Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Sat, 9 Dec 2023 15:12:51 +0000 Subject: [PATCH 110/113] [CI] Format code with Black --- src/app.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app.py b/src/app.py index 59a68af57..4dd76532c 100644 --- a/src/app.py +++ b/src/app.py @@ -501,7 +501,9 @@ def app_change_url(operation_logger, app, domain, path): change_url_script = os.path.join(tmp_workdir_for_app, "scripts/change_url") - import pdb; pdb.set_trace() + import pdb + + pdb.set_trace() # Execute App change_url script change_url_failed = True From 54a6a1b3d246c68e99271c17ba7893aab95859b1 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 9 Dec 2023 18:26:02 +0100 Subject: [PATCH 111/113] Aleks forgot to remove pdb.set_trace ... --- src/app.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/app.py b/src/app.py index 4dd76532c..ad20b3552 100644 --- a/src/app.py +++ b/src/app.py @@ -501,10 +501,6 @@ def app_change_url(operation_logger, app, domain, path): change_url_script = os.path.join(tmp_workdir_for_app, "scripts/change_url") - import pdb - - pdb.set_trace() - # Execute App change_url script change_url_failed = True try: From 9489d200b2c663d1fbe5d437565f2ae4311e01b5 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 9 Dec 2023 18:26:43 +0100 Subject: [PATCH 112/113] Update changelog for 11.2.8.2 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index 89e2231ea..97812a78f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +yunohost (11.2.8.2) stable; urgency=low + + - Aleks forgot to remove pdb.set_trace ... (54a6a1b3) + + -- Alexandre Aubin Sat, 09 Dec 2023 18:26:10 +0100 + yunohost (11.2.8.1) stable; urgency=low - apps: fix change_url again, otherwise the lack of path_url default to the old path and fucks up the nginx regen (169c9214) From 8e3e78884282e211a4ea55002e30115baee2fb93 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 10 Dec 2023 12:07:39 +0100 Subject: [PATCH 113/113] ynh_setup_source: properly handle --keep for directories when the dir already exists in the new setup --- helpers/utils | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/helpers/utils b/helpers/utils index 8b28000d6..edbdbdc3a 100644 --- a/helpers/utils +++ b/helpers/utils @@ -374,7 +374,13 @@ ynh_setup_source() { for stuff_to_keep in $keep; do if [ -e "$keep_dir/$stuff_to_keep" ]; then mkdir --parents "$(dirname "$dest_dir/$stuff_to_keep")" - cp --archive "$keep_dir/$stuff_to_keep" "$dest_dir/$stuff_to_keep" + + # We add "--no-target-directory" (short option is -T) to handle the special case + # when we "keep" a folder, but then the new setup already contains the same dir (but possibly empty) + # in which case a regular "cp" will create a copy of the directory inside the directory ... + # resulting in something like /var/www/$app/data/data instead of /var/www/$app/data + # cf https://unix.stackexchange.com/q/94831 for a more elaborate explanation on the option + cp --archive --no-target-directory "$keep_dir/$stuff_to_keep" "$dest_dir/$stuff_to_keep" fi done fi