mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge branch 'dev' into bullseye
This commit is contained in:
commit
fc0cf79123
49 changed files with 645 additions and 341 deletions
4
.lgtm.yml
Normal file
4
.lgtm.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
extraction:
|
||||
python:
|
||||
python_setup:
|
||||
version: "3"
|
|
@ -9,6 +9,7 @@
|
|||

|
||||
[](https://gitlab.com/yunohost/yunohost/-/pipelines)
|
||||

|
||||
[](https://lgtm.com/projects/g/YunoHost/yunohost/context:python)
|
||||
[](https://github.com/YunoHost/yunohost/blob/dev/LICENSE)
|
||||
[](https://mastodon.social/@yunohost)
|
||||
|
||||
|
|
16
debian/changelog
vendored
16
debian/changelog
vendored
|
@ -25,6 +25,22 @@ yunohost (11.0.1~alpha) unstable; urgency=low
|
|||
|
||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Fri, 05 Feb 2021 00:02:38 +0100
|
||||
|
||||
yunohost (4.3.5) stable; urgency=low
|
||||
|
||||
- [fix] backup: bug in backup_delete when compress_tar_archives is True ([#1381](https://github.com/YunoHost/yunohost/pull/1381))
|
||||
- [fix] helpers logrorate: remove permission tweak .. code was not working as expected. To be re-addressed some day ... (0fc209ac)
|
||||
- [fix] i18n: consistency for deprecation for --apps in 'yunohost tools update/upgrade' ([#1392](https://github.com/YunoHost/yunohost/pull/1392))
|
||||
- [fix] apps: typo when deleting superfluous question keys ([#1393](https://github.com/YunoHost/yunohost/pull/1393))
|
||||
- [fix] diagnosis: typo in dns record diagnoser (a615528c)
|
||||
- [fix] diagnosis: tweak treshold for suspiciously high number of auth failure because too many people getting report about it idk (76abbf03)
|
||||
- [enh] quality: apply pyupgrade ([#1395](https://github.com/YunoHost/yunohost/pull/1395))
|
||||
- [enh] quality: add lgtm/code quality badge ([#1396](https://github.com/YunoHost/yunohost/pull/1396))
|
||||
- [i18n] Translations updated for Dutch, French, Galician, German, Indonesian, Russian, Spanish, Ukrainian
|
||||
|
||||
Thanks to all contributors <3 ! (Boudewijn, Bram, Christian Wehrli, Colin Wawrik, Éric Gaspar, Ilya, José M, Juan Alberto González, Kay0u, liimee, Moutonjr Geoff, tituspijean, Tymofii Lytvynenko, Valentin von Guttenberg)
|
||||
|
||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Wed, 29 Dec 2021 01:01:33 +0100
|
||||
|
||||
yunohost (4.3.4.2) stable; urgency=low
|
||||
|
||||
- [fix] yunomdns: Ignore ipv4 link-local addresses (6854f23c)
|
||||
|
|
|
@ -107,7 +107,7 @@ class Parser:
|
|||
else:
|
||||
# We're getting out of a comment bloc, we should find
|
||||
# the name of the function
|
||||
assert len(line.split()) >= 1, "Malformed line %s in %s" % (
|
||||
assert len(line.split()) >= 1, "Malformed line {} in {}".format(
|
||||
i,
|
||||
self.filename,
|
||||
)
|
||||
|
|
|
@ -90,11 +90,6 @@ $logfile {
|
|||
EOF
|
||||
mkdir --parents $(dirname "$logfile") # Create the log directory, if not exist
|
||||
cat ${app}-logrotate | $customtee /etc/logrotate.d/$app >/dev/null # Append this config to the existing config file, or replace the whole config file (depending on $customtee)
|
||||
|
||||
if ynh_user_exists --username="$app"; then
|
||||
chown $app:$app "$logfile"
|
||||
chmod o-rwx "$logfile"
|
||||
fi
|
||||
}
|
||||
|
||||
# Remove the app's logrotate config.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"admin_password_change_failed": "Ändern des Passworts nicht möglich",
|
||||
"admin_password_changed": "Das Administrator-Kennwort wurde geändert",
|
||||
"app_already_installed": "{app} ist schon installiert",
|
||||
"app_argument_choice_invalid": "Wähle einen der folgenden Werte '{choices}' für das Argument '{name}'",
|
||||
"app_argument_choice_invalid": "Wähle einen gültigen Wert für das Argument '{name}': '{value}' ist nicht unter den verfügbaren Auswahlmöglichkeiten ({choices})",
|
||||
"app_argument_invalid": "Wähle einen gültigen Wert für das Argument '{name}': {error}",
|
||||
"app_argument_required": "Argument '{name}' wird benötigt",
|
||||
"app_extraction_failed": "Installationsdateien konnten nicht entpackt werden",
|
||||
|
@ -127,7 +127,7 @@
|
|||
"user_creation_failed": "Benutzer:in konnte nicht erstellt werden {user}: {error}",
|
||||
"user_deleted": "Benutzer:in gelöscht",
|
||||
"user_deletion_failed": "Benutzer:in konnte nicht gelöscht werden {user}: {error}",
|
||||
"user_home_creation_failed": "Persönlicher Ordner des Benutzers konnte nicht erstellt werden",
|
||||
"user_home_creation_failed": "Persönlicher Ordner '{home}' des/der Benutzers:in konnte nicht erstellt werden",
|
||||
"user_unknown": "Unbekannte:r Benutzer:in : {user}",
|
||||
"user_update_failed": "Benutzer:in konnte nicht aktualisiert werden {user}: {error}",
|
||||
"user_updated": "Benutzerinformationen wurden aktualisiert",
|
||||
|
@ -279,7 +279,7 @@
|
|||
"apps_catalog_obsolete_cache": "Der Cache des App-Katalogs ist leer oder veraltet.",
|
||||
"apps_catalog_update_success": "Der Apps-Katalog wurde aktualisiert!",
|
||||
"password_too_simple_1": "Das Passwort muss mindestens 8 Zeichen lang sein",
|
||||
"diagnosis_everything_ok": "Alles schaut gut aus für {category}!",
|
||||
"diagnosis_everything_ok": "Alles sieht OK aus für {category}!",
|
||||
"diagnosis_failed": "Kann Diagnose-Ergebnis für die Kategorie '{category}' nicht abrufen: {error}",
|
||||
"diagnosis_ip_connected_ipv4": "Der Server ist mit dem Internet über IPv4 verbunden!",
|
||||
"diagnosis_no_cache": "Kein Diagnose Cache aktuell für die Kategorie '{category}'",
|
||||
|
@ -288,7 +288,7 @@
|
|||
"diagnosis_ip_no_ipv6": "Der Server hat kein funktionierendes IPv6.",
|
||||
"diagnosis_ip_not_connected_at_all": "Der Server scheint überhaupt nicht mit dem Internet verbunden zu sein!?",
|
||||
"diagnosis_failed_for_category": "Diagnose fehlgeschlagen für die Kategorie '{category}': {error}",
|
||||
"diagnosis_cache_still_valid": "(Der Cache für die Diagnose {category} ist immer noch gültig. Es wird momentan keine neue Diagnose durchgeführt!)",
|
||||
"diagnosis_cache_still_valid": "(Cache noch gültig für {category} Diagnose. Es wird keine neue Diagnose durchgeführt!)",
|
||||
"diagnosis_cant_run_because_of_dep": "Kann Diagnose für {category} nicht ausführen während wichtige Probleme zu {dep} noch nicht behoben sind.",
|
||||
"diagnosis_found_errors_and_warnings": "Habe {errors} erhebliche(s) Problem(e) (und {warnings} Warnung(en)) in Verbindung mit {category} gefunden!",
|
||||
"diagnosis_ip_broken_dnsresolution": "Domänen-Namens-Auflösung scheint aus einem bestimmten Grund nicht zu funktionieren... Blockiert eine Firewall die DNS Anfragen?",
|
||||
|
@ -314,7 +314,7 @@
|
|||
"diagnosis_domain_expiration_success": "Ihre Domänen sind registriert und werden in nächster Zeit nicht ablaufen.",
|
||||
"diagnosis_domain_not_found_details": "Die Domäne {domain} existiert nicht in der WHOIS-Datenbank oder sie ist abgelaufen!",
|
||||
"diagnosis_domain_expiration_not_found": "Das Ablaufdatum einiger Domains kann nicht überprüft werden",
|
||||
"diagnosis_dns_try_dyndns_update_force": "Die DNS Konfiguration der Domäne sollte von Yunohost kontrolliert werden. Andernfalls, kannst du mit <cmd>yunohost dyndns update --force</cmd> ein Update erzwingen.",
|
||||
"diagnosis_dns_try_dyndns_update_force": "Die DNS-Konfiguration dieser Domäne sollte automatisch von YunoHost verwaltet werden. Andernfalls könntest Du mittels <cmd>yunohost dyndns update --force</cmd> ein Update erzwingen.",
|
||||
"diagnosis_dns_point_to_doc": "Bitte schaue in die Dokumentation unter <a href='https://yunohost.org/dns_config'>https://yunohost.org/dns_config</a> wenn du hilfe bei der Konfiguration der DNS Einträge brauchst.",
|
||||
"diagnosis_dns_discrepancy": "Der folgende DNS Eintrag scheint nicht den empfohlenen Einstellungen zu entsprechen:<br>Typ: <code>{type}</code><br>Name: <code>{name}</code><br>Aktueller Wert: <code>{current}</code><br>Erwarteter Wert: <code>{value}</code>",
|
||||
"diagnosis_dns_missing_record": "Gemäß der empfohlenen DNS-Konfiguration sollten Sie einen DNS-Eintrag mit den folgenden Informationen hinzufügen.<br>Typ: <code>{type}</code><br>Name: <code>{name}</code><br>Wert: <code>{value}</code>",
|
||||
|
@ -345,7 +345,7 @@
|
|||
"diagnosis_diskusage_low": "Der Speicher <code>{mountpoint}</code> (auf Gerät <code>{device}</code>) hat nur noch {free} ({free_percent}%) freien Speicherplatz (von insgesamt {total}). Seien Sie vorsichtig.",
|
||||
"diagnosis_ram_low": "Das System hat nur {available} ({available_percent}%) RAM zur Verfügung! (von insgesamt {total}). Seien Sie vorsichtig.",
|
||||
"service_reload_or_restart_failed": "Der Dienst '{service}' konnte nicht erneut geladen oder gestartet werden.\n\nKürzlich erstellte Logs des Dienstes: {logs}",
|
||||
"diagnosis_domain_expiration_not_found_details": "Die WHOIS Informationen für die Domäne {domain} scheinen keine Informationen über das Ablaufdatum zu enthalten.",
|
||||
"diagnosis_domain_expiration_not_found_details": "Die WHOIS-Informationen für die Domäne {domain} scheinen keine Informationen über das Ablaufdatum zu enthalten. Stimmt das?",
|
||||
"diagnosis_domain_expiration_warning": "Einige Domänen werden bald ablaufen.",
|
||||
"diagnosis_diskusage_ok": "Der Speicher <code>{mountpoint}</code> (auf Gerät <code>{device}</code>) hat immer noch {free} ({free_percent}%) freien Speicherplatz übrig(von insgesamt {total})!",
|
||||
"diagnosis_ram_ok": "Das System hat immer noch {available} ({available_percent}%) RAM zu Verfügung von {total}.",
|
||||
|
@ -370,7 +370,7 @@
|
|||
"ask_user_domain": "Domäne, welche für die E-Mail-Adresse und den XMPP-Account des Benutzers verwendet werden soll",
|
||||
"app_manifest_install_ask_is_public": "Soll diese Applikation für anonyme Benutzer:innen sichtbar sein?",
|
||||
"app_manifest_install_ask_admin": "Wählen Sie einen Administrator für diese Applikation",
|
||||
"app_manifest_install_ask_path": "Wählen Sie den Pfad, in welchem die Applikation installiert werden soll",
|
||||
"app_manifest_install_ask_path": "Wählen Sie den URL-Pfad (nach der Domäne), unter dem die Applikation installiert werden soll",
|
||||
"diagnosis_mail_blacklist_listed_by": "Ihre IP-Adresse oder Domäne <code>{item}</code> ist auf der Blacklist auf {blacklist_name}",
|
||||
"diagnosis_mail_blacklist_ok": "Die IP-Adressen und die Domänen, welche von diesem Server verwendet werden, scheinen nicht auf einer Blacklist zu sein",
|
||||
"diagnosis_mail_fcrdns_different_from_ehlo_domain_details": "Aktueller Reverse-DNS-Eintrag: <code>{rdns_domain}</code><br>Erwarteter Wert: <code>{ehlo_domain}</code>",
|
||||
|
@ -422,8 +422,8 @@
|
|||
"additional_urls_already_removed": "Zusätzliche URL '{url}' bereits entfernt in der zusätzlichen URL für Berechtigung '{permission}'",
|
||||
"app_label_deprecated": "Dieser Befehl ist veraltet! Bitte nutzen Sie den neuen Befehl 'yunohost user permission update' um das Applabel zu verwalten.",
|
||||
"diagnosis_http_hairpinning_issue_details": "Das ist wahrscheinlich aufgrund Ihrer ISP Box / Router. Als Konsequenz können Personen von ausserhalb Ihres Netzwerkes aber nicht von innerhalb Ihres lokalen Netzwerkes (wie wahrscheinlich Sie selber?) wie gewohnt auf Ihren Server zugreifen, wenn Sie ihre Domäne oder Ihre öffentliche IP verwenden. Sie können die Situation wahrscheinlich verbessern, indem Sie ein einen Blick in <a href='https://yunohost.org/dns_local_network'>https://yunohost.org/dns_local_network</a> werfen",
|
||||
"diagnosis_http_nginx_conf_not_up_to_date": "Jemand hat anscheinend die Konfiguration von Nginx manuell geändert. Diese Änderung verhindert, dass YunoHost eine Diagnose durchführen kann, wenn er via HTTP erreichbar ist.",
|
||||
"diagnosis_http_bad_status_code": "Anscheinend beantwortet ein anderes Gerät als Ihr Server die Anfrage (Vielleicht ihr Internetrouter).<br>1. Die häufigste Ursache ist, dass Port 80 (und 443) <a href='https://yunohost.org/isp_box_config'>nicht richtig auf Ihren Server weitergeleitet wird</a>.<br> 2. Bei komplexeren Setups: Vergewissern Sie sich, dass keine Firewall und keine Reverse-Proxy interferieren.",
|
||||
"diagnosis_http_nginx_conf_not_up_to_date": "Die Konfiguration von Nginx scheint für diese Domäne manuell geändert worden zu sein. Dies hindert YunoHost daran festzustellen, ob es über HTTP erreichbar ist.",
|
||||
"diagnosis_http_bad_status_code": "Es sieht so aus als ob ein anderes Gerät (vielleicht dein Router/Modem) anstelle deines Servers antwortet.<br>1. Der häufigste Grund hierfür ist, dass Port 80 (und 443) <a href='https://yunohost.org/isp_box_config'> nicht korrekt zu deinem Server weiterleiten</a>.<br>2. Bei komplexeren Setups: prüfe ob deine Firewall oder Reverse-Proxy die Verbindung stören.",
|
||||
"diagnosis_never_ran_yet": "Sie haben kürzlich einen neuen YunoHost-Server installiert aber es gibt davon noch keinen Diagnosereport. Sie sollten eine Diagnose anstossen. Sie können das entweder vom Webadmin aus oder in der Kommandozeile machen. In der Kommandozeile verwenden Sie dafür den Befehl 'yunohost diagnosis run'.",
|
||||
"diagnosis_http_nginx_conf_not_up_to_date_details": "Um dieses Problem zu beheben, geben Sie in der Kommandozeile <cmd>yunohost tools regen-conf nginx --dry-run --with-diff</cmd> ein. Dieses Tool zeigt ihnen den Unterschied an. Wenn Sie damit einverstanden sind, können Sie mit <cmd>yunohost tools regen-conf nginx --force</cmd> die Änderungen übernehmen.",
|
||||
"diagnosis_backports_in_sources_list": "Sie haben anscheinend apt (den Paketmanager) für das Backports-Repository konfiguriert. Wir raten strikte davon ab, Pakete aus dem Backports-Repository zu installieren. Diese würden wahrscheinlich zu Instabilitäten und Konflikten führen. Es sei denn, Sie wissen was Sie tun.",
|
||||
|
@ -575,7 +575,7 @@
|
|||
"server_shutdown_confirm": "Der Server wird sofort heruntergefahren, sind Sie sicher? [{answers}]",
|
||||
"server_shutdown": "Der Server wird heruntergefahren",
|
||||
"root_password_replaced_by_admin_password": "Ihr Root Passwort wurde durch Ihr Admin Passwort ersetzt.",
|
||||
"show_tile_cant_be_enabled_for_regex": "Momentan können Sie 'show_tile' nicht aktivieren, weil die URL für die Berechtigung '{permission}' ein regulärer Ausdruck ist",
|
||||
"show_tile_cant_be_enabled_for_regex": "Du kannst 'show_tile' momentan nicht aktivieren, weil die URL für die Berechtigung '{permission}' ein regulärer Ausdruck ist",
|
||||
"show_tile_cant_be_enabled_for_url_not_defined": "Momentan können Sie 'show_tile' nicht aktivieren, weil Sie zuerst eine URL für die Berechtigung '{permission}' definieren müssen",
|
||||
"tools_upgrade_regular_packages_failed": "Konnte für die folgenden Pakete das Upgrade nicht durchführen: {packages_list}",
|
||||
"tools_upgrade_regular_packages": "Momentan werden Upgrades für das System (YunoHost-unabhängige) Pakete durchgeführt...",
|
||||
|
@ -595,15 +595,80 @@
|
|||
"disk_space_not_sufficient_update": "Es ist nicht genügend Speicherplatz frei, um diese Applikation zu aktuallisieren",
|
||||
"disk_space_not_sufficient_install": "Es ist nicht genügend Speicherplatz frei, um diese Applikation zu installieren",
|
||||
"danger": "Warnung:",
|
||||
"diagnosis_apps_bad_quality": "Diese App ist im YunoHost App Katalog momentan als kaputt gekennzeichnet. Dies mag ein temporäres Problem darstellen, das von den Maintainern versucht wird zu beheben. In der Zwischenzeit ist das Upgrade dieser App nicht möglich.",
|
||||
"config_apply_failed": "Die neue Konfiguration umzusetzen ist fehlgeschlagen: {error}",
|
||||
"diagnosis_apps_bad_quality": "Diese App ist im YunoHost-Applikationskatalog momentan als defekt gekennzeichnet. Es könnte sich dabei um einen vorübergehendes Problem handeln. Während der/die Betreuer:in versucht das Problem zu beheben, ist die Upgrade-Funktion für diese App gesperrt.",
|
||||
"config_apply_failed": "Anwenden der neuen Konfiguration fehlgeschlagen: {error}",
|
||||
"config_validate_date": "Sollte ein zulässiges Datum in folgendem Format sein: YYYY-MM-DD",
|
||||
"config_validate_email": "Sollte eine zulässige eMail sein",
|
||||
"config_forbidden_keyword": "Das Keyword '{keyword}' ist reserviert. Mit dieser id kannst du keine Konfigurationspanel erstellen",
|
||||
"config_forbidden_keyword": "Das Schlüsselwort '{keyword}' ist reserviert. Du kannst kein Konfigurationspanel mit einer Frage erstellen, die diese ID verwendet.",
|
||||
"config_no_panel": "Kein Konfigurationspanel gefunden.",
|
||||
"config_validate_color": "Sollte eine zulässige RGB hexadezimal Farbe sein",
|
||||
"diagnosis_apps_issue": "Ein Problem für die App {app} ist aufgetreten",
|
||||
"config_validate_time": "Sollte eine zulässige Zeit wie HH:MM sein",
|
||||
"config_validate_url": "Sollte eine zulässige web URL sein",
|
||||
"config_version_not_supported": "Konfigurationspanel Versionen '{version}' sind nicht unterstützt."
|
||||
"config_version_not_supported": "Konfigurationspanel Versionen '{version}' sind nicht unterstützt.",
|
||||
"diagnosis_apps_allgood": "Alle installierten Apps berücksichtigen die grundlegenden Paketierungspraktiken",
|
||||
"diagnosis_apps_broken": "Diese App ist im YunoHost-Applikationskatalog momentan als defekt gekennzeichnet. Es könnte sich dabei um einen vorübergehendes Problem handeln. Während der/die Betreuer:in versucht das Problem zu beheben, ist die Upgrade-Funktion für diese App gesperrt.",
|
||||
"diagnosis_apps_not_in_app_catalog": "Diese App fehlt im Applikationskatalog von YunoHost oder wird in diesem nicht mehr angezeigt. Sie müssen im Betracht ziehen, sie zu deinstallieren, weil sie keine Aktualisierungen mehr erhält und die Integrität und die Sicherheit Ihres Systems kompromittieren könnte.",
|
||||
"diagnosis_apps_outdated_ynh_requirement": "Die installierte Version dieser App erfordert nur YunoHost >=2.x, was darauf hinweist, dass die App nicht mehr auf dem Stand der guten Paketierungspraktiken und der empfohlenen Helper ist. Sie sollten wirklich in Betracht ziehen, sie zu aktualisieren.",
|
||||
"diagnosis_description_apps": "Applikationen",
|
||||
"config_cant_set_value_on_section": "Sie können nicht einen einzelnen Wert auf einen gesamten Konfigurationsbereich anwenden.",
|
||||
"diagnosis_apps_deprecated_practices": "Die installierte Version dieser App verwendet immer noch gewisse veraltete Paketierungspraktiken. Sie sollten die App wirklich aktualisieren.",
|
||||
"app_config_unable_to_apply": "Konnte die Werte des Konfigurations-Panels nicht anwenden.",
|
||||
"app_config_unable_to_read": "Konnte die Werte des Konfigurations-Panels nicht auslesen.",
|
||||
"config_unknown_filter_key": "Der Filterschlüssel '{filter_key}' ist inkorrekt.",
|
||||
"diagnosis_dns_specialusedomain": "Die Domäne {domain} basiert auf einer Top-Level-Domain (TLD) für spezielle Zwecke wie .local oder .test und deshalb wird von ihr nicht erwartet, dass sie echte DNS-Einträge besitzt.",
|
||||
"ldap_server_down": "LDAP-Server kann nicht erreicht werden",
|
||||
"diagnosis_http_special_use_tld": "Die Domäne {domain} basiert auf einer Top-Level-Domäne (TLD) für besondere Zwecke wie .local oder .test und wird daher voraussichtlich nicht außerhalb des lokalen Netzwerks zugänglich sein.",
|
||||
"domain_dns_push_managed_in_parent_domain": "Die automatische DNS-Konfiguration wird von der übergeordneten Domäne {parent_domain} verwaltet.",
|
||||
"domain_dns_push_already_up_to_date": "Die Einträge sind auf dem neuesten Stand, es gibt nichts zu tun.",
|
||||
"domain_config_auth_token": "Authentifizierungstoken",
|
||||
"domain_config_auth_key": "Authentifizierungsschlüssel",
|
||||
"domain_config_auth_secret": "Authentifizierungsgeheimnis",
|
||||
"domain_config_api_protocol": "API-Protokoll",
|
||||
"domain_unknown": "Domäne '{domain}' unbekannt",
|
||||
"ldap_server_is_down_restart_it": "Der LDAP-Dienst ist nicht erreichbar, versuche ihn neu zu starten...",
|
||||
"user_import_bad_file": "Deine CSV-Datei ist nicht korrekt formatiert und wird daher ignoriert, um einen möglichen Datenverlust zu vermeiden",
|
||||
"global_settings_setting_security_experimental_enabled": "Aktiviere experimentelle Sicherheitsfunktionen (nur aktivieren, wenn Du weißt was Du tust!)",
|
||||
"global_settings_setting_security_nginx_redirect_to_https": "HTTP-Anfragen standardmäßig auf HTTPs umleiten (NICHT AUSSCHALTEN, sofern Du nicht weißt was Du tust!)",
|
||||
"user_import_missing_columns": "Die folgenden Spalten fehlen: {columns}",
|
||||
"user_import_nothing_to_do": "Es muss kein:e Benutzer:in importiert werden",
|
||||
"user_import_partial_failed": "Der Import von Benutzer:innen ist teilweise fehlgeschlagen",
|
||||
"user_import_bad_line": "Ungültige Zeile {line}: {details}",
|
||||
"other_available_options": "… und {n} weitere verfügbare Optionen, die nicht angezeigt werden",
|
||||
"domain_dns_conf_special_use_tld": "Diese Domäne basiert auf einer Top-Level-Domäne (TLD) für besondere Zwecke wie .local oder .test und wird daher vermutlich keine eigenen DNS-Einträge haben.",
|
||||
"domain_dns_registrar_managed_in_parent_domain": "Diese Domäne ist eine Unterdomäne von {parent_domain_link}. Die Konfiguration des DNS-Registrars sollte auf der Konfigurationsseite von {parent_domain} verwaltet werden.",
|
||||
"domain_dns_registrar_not_supported": "YunoHost konnte den Registrar, der diese Domäne verwaltet, nicht automatisch erkennen. Du solltest die DNS-Einträge, wie unter https://yunohost.org/dns beschrieben, manuell konfigurieren.",
|
||||
"domain_dns_registrar_supported": "YunoHost hat automatisch erkannt, dass diese Domäne von dem Registrar **{registrar}** verwaltet wird. Wenn Du möchtest, konfiguriert YunoHost diese DNS-Zone automatisch, wenn Du die entsprechenden API-Zugangsdaten zur Verfügung stellst. Auf dieser Seite erfährst Du, wie Du deine API-Anmeldeinformationen erhältst: https://yunohost.org/registar_api_{registrar}. (Du kannst deine DNS-Einträge auch, wie unter https://yunohost.org/dns beschrieben, manuell konfigurieren)",
|
||||
"service_not_reloading_because_conf_broken": "Der Dienst '{name}' wird nicht neu geladen/gestartet, da seine Konfiguration fehlerhaft ist: {errors}",
|
||||
"user_import_failed": "Der Import von Benutzer:innen ist komplett fehlgeschlagen",
|
||||
"domain_dns_push_failed_to_list": "Auflistung der aktuellen Einträge über die API des Registrars fehlgeschlagen: {error}",
|
||||
"domain_dns_pushing": "DNS-Einträge übertragen…",
|
||||
"domain_dns_push_record_failed": "{action} für Eintrag {type}/{name} fehlgeschlagen: {error}",
|
||||
"domain_dns_push_success": "DNS-Einträge aktualisiert!",
|
||||
"domain_dns_push_failed": "Die Aktualisierung der DNS-Einträge ist leider gescheitert.",
|
||||
"domain_dns_push_partial_failure": "DNS-Einträge teilweise aktualisiert: einige Warnungen/Fehler wurden gemeldet.",
|
||||
"domain_config_features_disclaimer": "Bisher hat das Aktivieren/Deaktivieren von Mail- oder XMPP-Funktionen nur Auswirkungen auf die empfohlene und automatische DNS-Konfiguration, nicht auf die Systemkonfigurationen!",
|
||||
"domain_config_mail_in": "Eingehende E-Mails",
|
||||
"domain_config_mail_out": "Ausgehende E-Mails",
|
||||
"domain_config_xmpp": "Instant Messaging (XMPP)",
|
||||
"log_app_config_set": "Konfiguration auf die Applikation '{}' anwenden",
|
||||
"log_user_import": "Benutzer:innen importieren",
|
||||
"diagnosis_high_number_auth_failures": "In letzter Zeit gab es eine verdächtig hohe Anzahl von Authentifizierungsfehlern. Stelle sicher, dass fail2ban läuft und korrekt konfiguriert ist, oder verwende einen benutzerdefinierten Port für SSH, wie unter https://yunohost.org/security beschrieben.",
|
||||
"domain_dns_registrar_yunohost": "Dies ist eine nohost.me / nohost.st / ynh.fr Domäne, ihre DNS-Konfiguration wird daher automatisch von YunoHost ohne weitere Konfiguration übernommen. (siehe Befehl 'yunohost dyndns update')",
|
||||
"domain_config_auth_entrypoint": "API-Einstiegspunkt",
|
||||
"domain_config_auth_application_key": "Anwendungsschlüssel",
|
||||
"domain_config_auth_application_secret": "Geheimer Anwendungsschlüssel",
|
||||
"domain_config_auth_consumer_key": "Consumer-Schlüssel",
|
||||
"invalid_number_min": "Muss größer sein als {min}",
|
||||
"invalid_number_max": "Muss kleiner sein als {max}",
|
||||
"invalid_password": "Ungültiges Passwort",
|
||||
"ldap_attribute_already_exists": "LDAP-Attribut '{attribute}' existiert bereits mit dem Wert '{value}'",
|
||||
"user_import_success": "Benutzer:innen erfolgreich importiert",
|
||||
"domain_registrar_is_not_configured": "Der DNS-Registrar ist noch nicht für die Domäne '{domain}' konfiguriert.",
|
||||
"domain_dns_push_not_applicable": "Die automatische DNS-Konfiguration ist nicht auf die Domäne {domain} anwendbar. Konfiguriere die DNS-Einträge manuell, wie unter https://yunohost.org/dns_config beschrieben.",
|
||||
"domain_dns_registrar_experimental": "Bislang wurde die Schnittstelle zur API von **{registrar}** noch nicht außreichend von der YunoHost-Community getestet und geprüft. Der Support ist **sehr experimentell** – sei vorsichtig!",
|
||||
"domain_dns_push_failed_to_authenticate": "Die Authentifizierung bei der API des Registrars für die Domäne '{domain}' ist fehlgeschlagen. Wahrscheinlich sind die Anmeldedaten falsch? (Fehler: {error})",
|
||||
"log_domain_config_set": "Konfiguration für die Domäne '{}' aktualisieren",
|
||||
"log_domain_dns_push": "DNS-Einträge für die Domäne '{}' übertragen",
|
||||
"service_description_yunomdns": "Ermöglicht es dir, deinen Server über 'yunohost.local' in deinem lokalen Netzwerk zu erreichen"
|
||||
}
|
|
@ -51,7 +51,7 @@
|
|||
"domain_dyndns_already_subscribed": "Ya se ha suscrito a un dominio de DynDNS",
|
||||
"domain_dyndns_root_unknown": "Dominio raíz de DynDNS desconocido",
|
||||
"domain_exists": "El dominio ya existe",
|
||||
"domain_uninstall_app_first": "Estas aplicaciones están todavía instaladas en tu dominio:\n{apps}\n\nPor favor desinstálalas utilizando <code>yunohost app remove the_app_id</code> o cambialas a otro dominio usando <code>yunohost app change-url the_app_id</code> antes de continuar con el borrado del dominio.",
|
||||
"domain_uninstall_app_first": "Estas aplicaciones siguen instaladas en tu dominio:\n{apps}\n\nPor favor desinstálalas con el comando 'yunohost app remove the_app_id' o cámbialas a otro dominio usando <yunohost app change-url the_app_id' antes de suprimir el dominio",
|
||||
"done": "Hecho.",
|
||||
"downloading": "Descargando…",
|
||||
"dyndns_ip_update_failed": "No se pudo actualizar la dirección IP en DynDNS",
|
||||
|
@ -83,7 +83,7 @@
|
|||
"packages_upgrade_failed": "No se pudieron actualizar todos los paquetes",
|
||||
"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 (p.ej. alguien@example.com)",
|
||||
"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",
|
||||
"pattern_lastname": "Debe ser un apellido válido",
|
||||
"pattern_mailbox_quota": "Debe ser un tamaño con el sufijo «b/k/M/G/T» o «0» para no tener una cuota",
|
||||
|
@ -115,7 +115,7 @@
|
|||
"service_removed": "Servicio '{service}' eliminado",
|
||||
"service_start_failed": "No se pudo iniciar el servicio «{service}»\n\nRegistro de servicios recientes:{logs}",
|
||||
"service_started": "El servicio '{service}' comenzó",
|
||||
"service_stop_failed": "No se pudo detener el servicio «{service}»\n\nRegistro de servicios recientes:{logs}",
|
||||
"service_stop_failed": "Imposible detener el servicio '{service}'\n\nRegistro recientes del servicio:{logs}",
|
||||
"service_stopped": "Servicio '{service}' detenido",
|
||||
"service_unknown": "Servicio desconocido '{service}'",
|
||||
"ssowat_conf_generated": "Generada la configuración de SSOwat",
|
||||
|
@ -165,10 +165,10 @@
|
|||
"certmanager_unable_to_parse_self_CA_name": "No se pudo procesar el nombre de la autoridad de autofirma (archivo: {file})",
|
||||
"domains_available": "Dominios disponibles:",
|
||||
"backup_archive_broken_link": "No se pudo acceder al archivo de respaldo (enlace roto a {path})",
|
||||
"certmanager_acme_not_configured_for_domain": "El reto ACME no ha podido ser realizado para {domain} porque su configuración de nginx no tiene el el código correcto... Por favor, asegurate que la configuración de nginx es correcta ejecutando en el terminal `yunohost tools regen-conf nginx --dry-run --with-diff`.",
|
||||
"certmanager_acme_not_configured_for_domain": "El reto ACME no ha podido ser realizado para {domain} porque en su configuración de nginx falta el código correcto... Por favor, asegúrate que la configuración de nginx es correcta ejecutando en el terminal `yunohost tools regen-conf nginx --dry-run --with-diff`.",
|
||||
"domain_hostname_failed": "No se pudo establecer un nuevo nombre de anfitrión («hostname»). Esto podría causar problemas más tarde (no es seguro... podría ir bien).",
|
||||
"app_already_installed_cant_change_url": "Esta aplicación ya está instalada. La URL no se puede cambiar solo con esta función. Marque `app changeurl` si está disponible.",
|
||||
"app_change_url_identical_domains": "El antiguo y nuevo dominio/url_path son idénticos ('{domain} {path}'), no se realizarán cambios.",
|
||||
"app_change_url_identical_domains": "El antiguo y nuevo dominio/url_path son idénticos ('{domain}{path}'), no se realizarán cambios.",
|
||||
"app_change_url_no_script": "La aplicación «{app_name}» aún no permite la modificación de URLs. Quizás debería actualizarla.",
|
||||
"app_change_url_success": "El URL de la aplicación {app} es ahora {domain} {path}",
|
||||
"app_location_unavailable": "Este URL o no está disponible o está en conflicto con otra(s) aplicación(es) instalada(s):\n{apps}",
|
||||
|
@ -196,21 +196,21 @@
|
|||
"dyndns_domain_not_provided": "El proveedor de DynDNS {provider} no puede proporcionar el dominio {domain}.",
|
||||
"experimental_feature": "Aviso : esta funcionalidad es experimental y no se considera estable, no debería usarla a menos que sepa lo que está haciendo.",
|
||||
"good_practices_about_user_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).",
|
||||
"password_listed": "Esta contraseña se encuentra entre las contraseñas más utilizadas en el mundo. Por favor, elija algo más único.",
|
||||
"password_listed": "Esta contraseña se encuentra entre las contraseñas más utilizadas del mundo. Por favor, elija algo menos común y más robusto.",
|
||||
"password_too_simple_1": "La contraseña debe tener al menos 8 caracteres de longitud",
|
||||
"password_too_simple_2": "La contraseña tiene que ser de al menos 8 caracteres de longitud e incluir un número y caracteres en mayúsculas y minúsculas",
|
||||
"password_too_simple_3": "La contraseña tiene que ser de al menos 8 caracteres de longitud e incluir un número, mayúsculas, minúsculas y caracteres especiales",
|
||||
"password_too_simple_4": "La contraseña tiene que ser de al menos 12 caracteres de longitud e incluir un número, mayúsculas, minúsculas y caracteres especiales",
|
||||
"password_too_simple_2": "La contraseña debe ser de al menos 8 caracteres de longitud e incluir un número y caracteres en mayúsculas y minúsculas",
|
||||
"password_too_simple_3": "La contraseña debe ser de al menos 8 caracteres de longitud e incluir un número y caracteres en mayúsculas, minúsculas y caracteres especiales",
|
||||
"password_too_simple_4": "La contraseña debe ser de al menos 12 caracteres de longitud e incluir un número, mayúsculas, minúsculas y caracteres especiales",
|
||||
"update_apt_cache_warning": "Algo fue mal durante la actualización de la caché de APT (gestor de paquetes de Debian). Aquí tiene un volcado de las líneas de sources.list que podría ayudarle a identificar las líneas problemáticas:\n{sourceslist}",
|
||||
"update_apt_cache_failed": "No se pudo actualizar la caché de APT (gestor de paquetes de Debian). Aquí tiene un volcado de las líneas de sources.list que podría ayudarle a identificar las líneas problemáticas:\n{sourceslist}",
|
||||
"update_apt_cache_failed": "Imposible actualizar la caché de APT (gestor de paquetes de Debian). Aquí tienes un volcado de las líneas de sources.list que podrían ayudarte a identificar las líneas problemáticas:\n{sourceslist}",
|
||||
"tools_upgrade_special_packages_completed": "Actualización de paquetes de YunoHost completada.\nPulse [Intro] para regresar a la línea de órdenes",
|
||||
"tools_upgrade_special_packages_explanation": "La actualización especial continuará en segundo plano. No inicie ninguna otra acción en su servidor durante los próximos 10 minutos (dependiendo de la velocidad del hardware). Después de esto, es posible que deba volver a iniciar sesión en el administrador web. El registro de actualización estará disponible en Herramientas → Registro (en el webadmin) o usando 'yunohost log list' (desde la línea de comandos).",
|
||||
"tools_upgrade_special_packages": "Actualizando ahora paquetes «especiales» (relacionados con YunoHost)…",
|
||||
"tools_upgrade_regular_packages_failed": "No se pudieron actualizar los paquetes: {packages_list}",
|
||||
"tools_upgrade_regular_packages": "Actualizando ahora paquetes «normales» (no relacionados con YunoHost)…",
|
||||
"tools_upgrade_cant_unhold_critical_packages": "No se pudo liberar los paquetes críticos…",
|
||||
"tools_upgrade_cant_hold_critical_packages": "No se pudieron retener los paquetes críticos…",
|
||||
"this_action_broke_dpkg": "Esta acción rompió dpkg/APT(los gestores de paquetes del sistema)… Puede tratar de solucionar este problema conectando mediante SSH y ejecutando `sudo dpkg --configure -a`.",
|
||||
"tools_upgrade_cant_hold_critical_packages": "Imposible etiquetar con 'hold' los paquetes críticos…",
|
||||
"this_action_broke_dpkg": "Esta acción rompió dpkg/APT(los gestores de paquetes del sistema)… Puedes tratar de solucionar este problema conectándote mediante SSH y ejecutando `sudo apt install --fix-broken` and/or `sudo dpkg --configure -a`.",
|
||||
"service_reloaded_or_restarted": "El servicio '{service}' fue recargado o reiniciado",
|
||||
"service_reload_or_restart_failed": "No se pudo recargar o reiniciar el servicio «{service}»\n\nRegistro de servicios recientes:{logs}",
|
||||
"service_restarted": "Servicio '{service}' reiniciado",
|
||||
|
@ -239,9 +239,9 @@
|
|||
"restore_system_part_failed": "No se pudo restaurar la parte del sistema «{part}»",
|
||||
"restore_removing_tmp_dir_failed": "No se pudo eliminar un directorio temporal antiguo",
|
||||
"restore_not_enough_disk_space": "Espacio insuficiente (espacio: {free_space} B, espacio necesario: {needed_space} B, margen de seguridad: {margin} B)",
|
||||
"restore_may_be_not_enough_disk_space": "Parece que su sistema no tiene suficiente espacio libre (libre: {free_space} B, espacio necesario: {needed_space} B, margen de seguridad: {margin} B)",
|
||||
"restore_may_be_not_enough_disk_space": "Parece que su sistema no tiene suficiente espacio (libre: {free_space} B, espacio necesario: {needed_space} B, margen de seguridad: {margin} B)",
|
||||
"restore_extracting": "Extrayendo los archivos necesarios para el archivo…",
|
||||
"regenconf_pending_applying": "Aplicando la configuración pendiente para la categoría «{category}»…",
|
||||
"regenconf_pending_applying": "Aplicando la configuración pendiente para la categoría '{category}'...",
|
||||
"regenconf_failed": "No se pudo regenerar la configuración para la(s) categoría(s): {categories}",
|
||||
"regenconf_dry_pending_applying": "Comprobando la configuración pendiente que habría sido aplicada para la categoría «{category}»…",
|
||||
"regenconf_would_be_updated": "La configuración habría sido actualizada para la categoría «{category}»",
|
||||
|
@ -328,7 +328,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 administración. 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 usar 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 de contraseña) y / o una variación de caracteres (mayúsculas, minúsculas, dígitos y caracteres especiales).",
|
||||
"global_settings_unknown_type": "Situación imprevista, la configuración {setting} parece tener el tipo {unknown_type} pero no es un tipo compatible con el sistema.",
|
||||
"global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Permitir el uso de la llave (obsoleta) DSA para la configuración del demonio SSH",
|
||||
"global_settings_unknown_setting_from_settings_file": "Clave desconocida en la configuración: «{setting_key}», desechada y guardada en /etc/yunohost/settings-unknown.json",
|
||||
|
@ -346,11 +346,11 @@
|
|||
"global_settings_bad_choice_for_enum": "Opción errónea para la configuración {setting}, obtuvo «{choice}» pero las opciones disponibles son: {available_choices}",
|
||||
"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": "Esta orden muestra la configuración *recomendada*. No configura el DNS en realidad. Es su responsabilidad configurar la zona de DNS en su registrador según esta recomendación.",
|
||||
"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.",
|
||||
"dpkg_lock_not_available": "Esta orden no se puede ejecutar en este momento ,parece que programa está usando el bloqueo de dpkg (el gestor de paquetes del sistema)",
|
||||
"dpkg_is_broken": "No puede hacer esto en este momento porque dpkg/APT (los gestores de paquetes del sistema) parecen estar mal configurados... Puede tratar de solucionar este problema conectando a través de SSH y ejecutando `sudo apt install --fix-broken` y/o `sudo dpkg --configure -a`.",
|
||||
"confirm_app_install_thirdparty": "¡PELIGRO! Esta aplicación no forma parte del catálogo de aplicaciones de Yunohost. La instalación de aplicaciones de terceros puede comprometer la integridad y la seguridad de su sistema. Probablemente NO debería instalarlo a menos que sepa lo que está haciendo. NO se proporcionará SOPORTE si esta aplicación no funciona o rompe su sistema ... Si de todos modos está dispuesto a correr ese riesgo, escriba '{answers}'",
|
||||
"confirm_app_install_danger": "¡PELIGRO! ¡Se sabe que esta aplicación sigue siendo experimental (si no explícitamente no funciona)! Probablemente NO debería instalarlo a menos que sepa lo que está haciendo. NO se proporcionará SOPORTE si esta aplicación no funciona o rompe su sistema ... Si de todos modos está dispuesto a correr ese riesgo, escriba '{answers}'",
|
||||
"confirm_app_install_thirdparty": "¡PELIGRO! Esta aplicación no forma parte del catálogo de aplicaciones de YunoHost. La instalación de aplicaciones de terceros puede comprometer la integridad y seguridad de tu sistema. Probablemente NO deberías instalarla a menos que sepas lo que estás haciendo. NO se proporcionará NINGÚN SOPORTE si esta aplicación no funciona o rompe su sistema… Si de todos modos quieres correr ese riesgo, escribe '{answers}'",
|
||||
"confirm_app_install_danger": "¡PELIGRO! ¡Esta aplicación sigue siendo experimental (si no es expresamente no funcional)! Probablemente NO deberías instalarla a menos que sepas lo que estás haciendo. NO se proporcionará NINGÚN SOPORTE si esta aplicación no funciona o rompe tu sistema… Si de todos modos quieres correr ese riesgo, escribe '{answers}'",
|
||||
"confirm_app_install_warning": "Aviso: esta aplicación puede funcionar pero no está bien integrada en YunoHost. Algunas herramientas como la autentificación única y respaldo/restauración podrían no estar disponibles. ¿Instalar de todos modos? [{answers}] ",
|
||||
"backup_unable_to_organize_files": "No se pudo usar el método rápido de organización de los archivos en el archivo",
|
||||
"backup_permission": "Permiso de respaldo para {app}",
|
||||
|
@ -411,7 +411,7 @@
|
|||
"diagnosis_cache_still_valid": "(Caché aún válida para el diagnóstico de {category}. ¡No se volvera a comprobar de momento!)",
|
||||
"diagnosis_found_errors_and_warnings": "¡Encontrado(s) error(es) significativo(s) {errors} (y aviso(s) {warnings}) relacionado(s) con {category}!",
|
||||
"apps_catalog_init_success": "¡Sistema de catálogo de aplicaciones inicializado!",
|
||||
"apps_catalog_updating": "Actualizando el catálogo de aplicaciones…",
|
||||
"apps_catalog_updating": "Actualiza el catálogo de aplicaciones…",
|
||||
"apps_catalog_failed_to_download": "No se puede descargar el catálogo de aplicaciones {apps_catalog}: {error}",
|
||||
"apps_catalog_obsolete_cache": "El caché del catálogo de aplicaciones está vacío u obsoleto.",
|
||||
"apps_catalog_update_success": "¡El catálogo de aplicaciones ha sido actualizado!",
|
||||
|
@ -419,15 +419,15 @@
|
|||
"diagnosis_ignored_issues": "(+ {nb_ignored} problema(s) ignorado(s))",
|
||||
"diagnosis_found_errors": "¡Encontrado(s) error(es) significativo(s) {errors} relacionado(s) con {category}!",
|
||||
"diagnosis_found_warnings": "Encontrado elemento(s) {warnings} que puede(n) ser mejorado(s) para {category}.",
|
||||
"diagnosis_everything_ok": "¡Todo se ve bien para {category}!",
|
||||
"diagnosis_everything_ok": "¡Todo correcto en {category}!",
|
||||
"app_upgrade_script_failed": "Ha ocurrido un error en el script de actualización de la app",
|
||||
"diagnosis_no_cache": "Todavía no hay una caché de diagnóstico para la categoría '{category}'",
|
||||
"diagnosis_ip_no_ipv4": "El servidor no cuenta con ipv4 funcional.",
|
||||
"diagnosis_ip_not_connected_at_all": "¿¡Está conectado el servidor a internet!?",
|
||||
"diagnosis_ip_broken_resolvconf": "La resolución de nombres de dominio parece no funcionar en tu servidor, lo que parece estar relacionado con que <code>/etc/resolv.conf</code> no apunta a <code>127.0.0.1</code>.",
|
||||
"diagnosis_dns_missing_record": "Según la configuración DNS recomendada, deberías añadir un registro DNS\ntipo: {type}\nnombre: {name}\nvalor: {value}",
|
||||
"diagnosis_diskusage_low": "El almacenamiento {mountpoint} (en dispositivo {device}) solo tiene {free} ({free_percent}%) de espacio disponible. Ten cuidado.",
|
||||
"diagnosis_services_bad_status_tip": "Puedes intentar reiniciar el servicio, y si no funciona, echar un vistazo a los logs del servicio usando 'yunohost service log {service}' o a través de la sección 'Servicios' en webadmin.",
|
||||
"diagnosis_diskusage_low": "El almacenamiento <code>{mountpoint}</code> (en el dispositivo <code>{device}</code>) solo tiene {free} ({free_percent}%) de espacio disponible (de {total}). Ten cuidado.",
|
||||
"diagnosis_services_bad_status_tip": "Puedes intentar <a href='#/services/{service}'>reiniciar el servicio</a>, y si no funciona, echar un vistazo a <a href='#/services/{service}'>los logs del serviciode la administración web</a> (desde la línea de comandos puedes hacerlo con <cmd>yunohost service restart {service}</cmd> y <cmd>yunohost service log {service}</cmd>).",
|
||||
"diagnosis_ip_connected_ipv6": "¡El servidor está conectado a internet a través de IPv6!",
|
||||
"diagnosis_ip_no_ipv6": "El servidor no cuenta con IPv6 funcional.",
|
||||
"diagnosis_ip_dnsresolution_working": "¡DNS no está funcionando!",
|
||||
|
@ -438,8 +438,8 @@
|
|||
"diagnosis_dns_bad_conf": "Algunos registros DNS faltan o están mal cofigurados para el dominio {domain} (categoría {category})",
|
||||
"diagnosis_dns_discrepancy": "El siguiente registro DNS parace que no sigue la configuración recomendada <br>Tipo: <code>{type}</code><br>Nombre: <code>{name}</code><br>Valor Actual: <code>{current}</code><br>Valor esperado: <code>{value}</code>",
|
||||
"diagnosis_services_bad_status": "El servicio {service} está {status} :(",
|
||||
"diagnosis_diskusage_verylow": "El almacenamiento {mountpoint} (en el dispositivo {device}) sólo tiene {free} ({free_percent}%) de espacio disponible. Deberías considerar la posibilidad de limpiar algo de espacio.",
|
||||
"diagnosis_diskusage_ok": "¡El almacenamiento {mountpoint} (en el dispositivo {device}) todavía tiene {free} ({free_percent}%) de espacio libre!",
|
||||
"diagnosis_diskusage_verylow": "El almacenamiento <code>{mountpoint}</code>(en el dispositivo <code>{device}</code>) sólo tiene {free} ({free_percent}%) de espacio disponible(de {total}). ¡Deberías limpiar algo de espacio!",
|
||||
"diagnosis_diskusage_ok": "¡El almacenamiento <code>{mountpoint}</code> (en el dispositivo <code>{device}</code>) todavía tiene {free} ({free_percent}%) de espacio libre (de {total})!",
|
||||
"diagnosis_services_conf_broken": "¡Mala configuración para el servicio {service}!",
|
||||
"diagnosis_services_running": "¡El servicio {service} está en ejecución!",
|
||||
"diagnosis_failed": "Error al obtener el resultado del diagnóstico para la categoría '{category}': {error}",
|
||||
|
@ -452,7 +452,7 @@
|
|||
"diagnosis_swap_notsomuch": "Al sistema le queda solamente {total} de espacio de intercambio. Considera agregar al menos {recommended} para evitar que el sistema se quede sin memoria.",
|
||||
"diagnosis_mail_outgoing_port_25_blocked": "El puerto de salida 25 parece estar bloqueado. Intenta desbloquearlo con el panel de configuración de tu proveedor de servicios de Internet (o proveedor de halbergue). Mientras tanto, el servidor no podrá enviar correos electrónicos a otros servidores.",
|
||||
"diagnosis_regenconf_allgood": "Todos los archivos de configuración están en linea con la configuración recomendada!",
|
||||
"diagnosis_regenconf_manually_modified": "El archivo de configuración {file} parece que ha sido modificado manualmente.",
|
||||
"diagnosis_regenconf_manually_modified": "El archivo de configuración <code>{file}</code> parece que ha sido modificado manualmente.",
|
||||
"diagnosis_regenconf_manually_modified_details": "¡Esto probablemente esta BIEN si sabes lo que estás haciendo! YunoHost dejará de actualizar este fichero automáticamente... Pero ten en cuenta que las actualizaciones de YunoHost pueden contener importantes cambios que están recomendados. Si quieres puedes comprobar las diferencias mediante <cmd>yunohost tools regen-conf {category} --dry-run --with-diff</cmd> o puedes forzar el volver a las opciones recomendadas mediante el comando <cmd>yunohost tools regen-conf {category} --force</cmd>",
|
||||
"diagnosis_security_vulnerable_to_meltdown": "Pareces vulnerable a el colapso de vulnerabilidad critica de seguridad",
|
||||
"diagnosis_description_basesystem": "Sistema de base",
|
||||
|
@ -501,11 +501,11 @@
|
|||
"diagnosis_domain_expiration_not_found_details": "¿Parece que la información de WHOIS para el dominio {domain} no contiene información sobre la fecha de expiración?",
|
||||
"diagnosis_domain_not_found_details": "¡El dominio {domain} no existe en la base de datos WHOIS o ha expirado!",
|
||||
"diagnosis_domain_expiration_not_found": "No se pudo revisar la fecha de expiración para algunos dominios",
|
||||
"diagnosis_dns_try_dyndns_update_force": "La configuración DNS de este dominio debería ser administrada automáticamente por Yunohost. Si no es el caso, puede intentar forzar una actualización ejecutando <cmd>yunohost dyndns update --force</cmd>.",
|
||||
"diagnosis_dns_try_dyndns_update_force": "La configuración DNS de este dominio debería ser administrada automáticamente por YunoHost. Si no es el caso, puedes intentar forzar una actualización mediante <cmd>yunohost dyndns update --force</cmd>.",
|
||||
"diagnosis_ip_local": "IP Local: <code>{local}</code>",
|
||||
"diagnosis_ip_no_ipv6_tip": "Tener IPv6 funcionando no es obligatorio para que su servidor funcione, pero es mejor para la salud del Internet en general. IPv6 debería ser configurado automáticamente por el sistema o su proveedor si está disponible. De otra manera, es posible que tenga que configurar varias cosas manualmente, tal y como se explica en esta documentación <a href='https://yunohost.org/#/ipv6'>https://yunohost.org/#/ipv6</a>. Si no puede habilitar IPv6 o si parece demasiado técnico, puede ignorar esta advertencia con toda seguridad.",
|
||||
"diagnosis_display_tip": "Para ver los problemas encontrados, puede ir a la sección de diagnóstico del webadmin, o ejecutar 'yunohost diagnosis show --issues --human-readable' en la línea de comandos.",
|
||||
"diagnosis_package_installed_from_sury_details": "Algunos paquetes fueron accidentalmente instalados de un repositorio de terceros llamado Sury. El equipo Yunohost ha mejorado la estrategia para manejar estos pquetes, pero es posible que algunas instalaciones con aplicaciones de PHP7.3 en Stretch puedan tener algunas inconsistencias. Para solucionar esta situación, debería intentar ejecutar el siguiente comando: <cmd>{cmd_to_fix}</cmd>",
|
||||
"diagnosis_package_installed_from_sury_details": "Algunos paquetes fueron accidentalmente instalados de un repositorio de terceros llamado Sury. El equipo YunoHost ha mejorado la estrategia para manejar estos paquetes, pero es posible que algunas configuraciones que han instalado aplicaciones PHP7.3 al tiempo que presentes en Stretch tienen algunas inconsistencias. Para solucionar esta situación, deberías intentar ejecutar el siguiente comando: <cmd>{cmd_to_fix}</cmd>",
|
||||
"diagnosis_package_installed_from_sury": "Algunos paquetes del sistema deberían ser devueltos a una versión anterior",
|
||||
"certmanager_domain_not_diagnosed_yet": "Aún no hay resultado del diagnóstico para el dominio {domain}. Por favor ejecute el diagnóstico para las categorías 'Registros DNS' y 'Web' en la sección de diagnóstico para verificar si el dominio está listo para Let's Encrypt. (O si sabe lo que está haciendo, utilice '--no-checks' para deshabilitar esos chequeos.)",
|
||||
"backup_archive_corrupted": "Parece que el archivo de respaldo '{archive}' está corrupto : {error}",
|
||||
|
@ -555,7 +555,7 @@
|
|||
"diagnosis_mail_ehlo_bad_answer_details": "Podría ser debido a otra máquina en lugar de tu servidor.",
|
||||
"diagnosis_mail_ehlo_bad_answer": "Un servicio que no es SMTP respondió en el puerto 25 mediante IPv{ipversion}",
|
||||
"diagnosis_mail_ehlo_unreachable_details": "No pudo abrirse la conexión en el puerto 25 de tu servidor mediante IPv{ipversion}. Parece que no se puede contactar.<br>1. La causa más común en estos casos suele ser que el puerto 25 <a href='https://yunohost.org/isp_box_config'>no está correctamente redireccionado a tu servidor</a>.<br>2. También deberías asegurarte que el servicio postfix está en marcha.<br>3. En casos más complejos: asegurate que no estén interfiriendo ni el firewall ni el reverse-proxy.",
|
||||
"diagnosis_mail_ehlo_unreachable": "El servidor de correo SMTP no puede contactarse desde el exterior mediante IPv{ipversion}. No puede recibir correos",
|
||||
"diagnosis_mail_ehlo_unreachable": "El servidor de correo SMTP no puede contactarse desde el exterior mediante IPv{ipversion}. No puede recibir correos.",
|
||||
"diagnosis_mail_ehlo_ok": "¡El servidor de correo SMTP puede contactarse desde el exterior por lo que puede recibir correos!",
|
||||
"diagnosis_mail_outgoing_port_25_blocked_relay_vpn": "Algunos proveedores de internet no le permitirán desbloquear el puerto 25 porque no les importa la Neutralidad de la Red.<br> - Algunos proporcionan una alternativa usando <a href='https://yunohost.org/#/email_configure_relay'>un relay como servidor de correo</a> lo que implica que el relay podrá espiar tu trafico de correo.<br>- Una alternativa buena para la privacidad es utilizar una VPN *con una IP pública dedicada* para evitar estas limitaciones. Mira en <a href='https://yunohost.org/#/vpn_advantage'>https://yunohost.org/#/vpn_advantage</a><br>- Otra alternativa es cambiar de proveedor de inteernet a <a href='https://yunohost.org/#/isp'>uno más amable con la Neutralidad de la Red</a>",
|
||||
"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.",
|
||||
|
@ -567,5 +567,37 @@
|
|||
"app_config_unable_to_apply": "No se pudieron aplicar los valores del panel configuración.",
|
||||
"app_config_unable_to_read": "No se pudieron leer los valores del panel configuración.",
|
||||
"backup_create_size_estimation": "El archivo contendrá aproximadamente {size} de datos.",
|
||||
"config_cant_set_value_on_section": "No puede establecer un único valor en una sección de configuración completa."
|
||||
"config_cant_set_value_on_section": "No puede establecer un único valor en una sección de configuración completa.",
|
||||
"diagnosis_http_special_use_tld": "Le dominio {domain} está basado en un dominio de primer nivel (TLD) de uso especial, como un .local o .test y no debería estar expuesto fuera de la red local.",
|
||||
"domain_dns_push_failed": "La actualización de las entradas DNS ha fallado.",
|
||||
"domain_dns_push_partial_failure": "Entradas DNS actualizadas parcialmente: algunas advertencias/errores reportados.",
|
||||
"domain_unknown": "Dominio '{domain}' desconocido",
|
||||
"diagnosis_high_number_auth_failures": "Ultimamente ha habido un gran número de errores de autenticación. Asegúrate de que Fail2Ban está ejecutándose y correctamente configurado, o usa un puerto SSH personalizado como se explica en <a href=\"https://yunohost.org/security\">https://yunohost.org/security</a>.",
|
||||
"diagnosis_sshd_config_inconsistent": "Parece que el puerto SSH ha sido modificado manualmente en /etc/ssh/sshd_config. Desde YunoHost 4.2, hay un nuevo parámetro global 'security.ssh.port' disponible para evitar modificar manualmente la configuración.",
|
||||
"diagnosis_sshd_config_inconsistent_details": "Por favor ejecuta <cmd>yunohost settings set security.ssh.port -v TU_PUERTO_SSH</cmd> para definir el puerto SSH, y comprueba <cmd>yunohost tools regen-conf ssh --dry-run --with-diff</cmd> y <cmd>yunohost tools regen-conf ssh --force</cmd> para resetear tu configuración a las recomendaciones de YunoHost.",
|
||||
"config_forbidden_keyword": "'{keyword}' es una palabra reservada, no puedes crear ni usar un panel de configuración con una pregunta que use esta id.",
|
||||
"config_no_panel": "No se ha encontrado ningún panel de configuración.",
|
||||
"config_unknown_filter_key": "La clave de filtrado '{filter_key}' es incorrecta.",
|
||||
"config_validate_color": "Debe ser un valor hexadecimal RGB correcto",
|
||||
"danger": "Peligro:",
|
||||
"diagnosis_apps_issue": "Se ha detectado un problema con la aplicación {app}",
|
||||
"diagnosis_description_apps": "Aplicaciones",
|
||||
"diagnosis_rootfstotalspace_critical": "¡El sistema de ficheros raíz solo tiene un total de {space}! ¡Vas a quedarte sin espacio rápidamente! Se recomienda tener al menos 16GB para ese sistema de ficheros.",
|
||||
"diagnosis_rootfstotalspace_warning": "¡El sistema de ficheros raíz solo tiene un total de {space}! Podría ser suficiente, pero cuidado, puedes rellenarlo rápidamente… Se recomienda tener al menos 16GB para el sistema de ficheros raíz.",
|
||||
"diagnosis_apps_allgood": "Todas las aplicaciones instaladas respetan las prácticas básicas de empaquetado",
|
||||
"config_validate_date": "Debe ser una fecha válida en formato AAAA-MM-DD",
|
||||
"config_validate_email": "Debe ser una dirección de correo correcta",
|
||||
"config_validate_time": "Debe ser una hora valida en formato HH:MM",
|
||||
"config_validate_url": "Debe ser una URL válida",
|
||||
"config_version_not_supported": "Las versiones del panel de configuración '{version}' no están soportadas.",
|
||||
"domain_remove_confirm_apps_removal": "La supresión de este dominio también eliminará las siguientes aplicaciones:\n{apps}\n\n¿Seguro? [{answers}]",
|
||||
"domain_registrar_is_not_configured": "El registrador aún no ha configurado el dominio {domain}.",
|
||||
"diagnosis_apps_not_in_app_catalog": "Esta aplicación se encuentra ausente o ya no figura en el catálogo de aplicaciones de YunoHost. Deberías considerar desinstalarla ya que no recibirá actualizaciones y podría comprometer la integridad y seguridad de tu sistema.",
|
||||
"disk_space_not_sufficient_install": "No hay espacio libre suficiente para instalar esta aplicación",
|
||||
"disk_space_not_sufficient_update": "No hay espacio libre suficiente para actualizar esta aplicación",
|
||||
"diagnosis_dns_specialusedomain": "El dominio {domain} se basa en un dominio de primer nivel (TLD) de usos especiales como .local o .test y no debería tener entradas DNS reales.",
|
||||
"diagnosis_apps_bad_quality": "Esta aplicación está etiquetada como defectuosa en el catálogo de aplicaciones YunoHost. Podría ser un problema temporal mientras las personas responsables corrigen el asunto. Mientras tanto, la actualización de esta aplicación está desactivada.",
|
||||
"diagnosis_apps_broken": "Esta aplicación está etiquetada como defectuosa en el catálogo de aplicaciones YunoHost. Podría ser un problema temporal mientras las personas responsables corrigen el asunto. Mientras tanto, la actualización de esta aplicación está desactivada.",
|
||||
"diagnosis_apps_deprecated_practices": "La versión instalada de esta aplicación usa aún prácticas de empaquetado obsoletas. Deberías actualizarla.",
|
||||
"diagnosis_apps_outdated_ynh_requirement": "La versión instalada de esta aplicación solo necesita YunoHost >= 2.x, lo que indica que no está al día con la buena praxis de ayudas y empaquetado recomendadas. Deberías actualizarla."
|
||||
}
|
|
@ -413,7 +413,7 @@
|
|||
"diagnosis_ip_weird_resolvconf": "La résolution DNS semble fonctionner, mais il semble que vous utilisez un <code>/etc/resolv.conf</code> personnalisé.",
|
||||
"diagnosis_ip_weird_resolvconf_details": "Le fichier <code>/etc/resolv.conf</code> doit être un lien symbolique vers <code>/etc/resolvconf/run/resolv.conf</code> lui-même pointant vers <code>127.0.0.1</code> (dnsmasq). Si vous souhaitez configurer manuellement les résolveurs DNS, veuillez modifier <code>/etc/resolv.dnsmasq.conf</code>.",
|
||||
"diagnosis_dns_missing_record": "Selon la configuration DNS recommandée, vous devez ajouter un enregistrement DNS<br>Type : <code>{type}</code><br>Nom : <code>{name}</code><br>Valeur : <code>{value}</code>",
|
||||
"diagnosis_diskusage_ok": "L'espace de stockage <code>{mountpoint}</code> (sur le périphérique <code>{device}</code>) a encore {free} ({free_percent}%) espace restant (sur {total}) !",
|
||||
"diagnosis_diskusage_ok": "L'espace de stockage <code>{mountpoint}</code> (sur le périphérique <code>{device}</code>) a encore {free} ({free_percent}%) d'espace restant (sur {total}) !",
|
||||
"diagnosis_ram_ok": "Le système dispose encore de {available} ({available_percent}%) de RAM sur {total}.",
|
||||
"diagnosis_regenconf_allgood": "Tous les fichiers de configuration sont conformes à la configuration recommandée !",
|
||||
"diagnosis_security_vulnerable_to_meltdown": "Vous semblez vulnérable à la vulnérabilité de sécurité critique de Meltdown",
|
||||
|
@ -439,9 +439,9 @@
|
|||
"diagnosis_dns_bad_conf": "Certains enregistrements DNS sont manquants ou incorrects pour le domaine {domain} (catégorie {category})",
|
||||
"diagnosis_dns_discrepancy": "Cet enregistrement DNS ne semble pas correspondre à la configuration recommandée : <br>Type : <code>{type}</code><br>Nom : <code>{name}</code><br> La valeur actuelle est : <code>{current}</code><br> La valeur attendue est : <code>{value}</code>",
|
||||
"diagnosis_services_bad_status": "Le service {service} est {status} :-(",
|
||||
"diagnosis_diskusage_verylow": "L'espace de stockage <code>{mountpoint}</code> (sur l'appareil <code>{device}</code>) ne dispose que de {free} ({free_percent}%) espace restant (sur {total}). Vous devriez vraiment envisager de nettoyer de l'espace !",
|
||||
"diagnosis_diskusage_low": "L'espace de stockage <code>{mountpoint}</code> (sur l'appareil <code>{device}</code>) ne dispose que de {free} ({free_percent}%) espace restant (sur {total}). Faites attention.",
|
||||
"diagnosis_ram_verylow": "Le système ne dispose plus que de {available} ({available_percent}%)! (sur {total})",
|
||||
"diagnosis_diskusage_verylow": "L'espace de stockage <code>{mountpoint}</code> (sur l'appareil <code>{device}</code>) ne dispose que de {free} ({free_percent}%) d'espace restant (sur {total}). Vous devriez vraiment envisager de nettoyer de l'espace !",
|
||||
"diagnosis_diskusage_low": "L'espace de stockage <code>{mountpoint}</code> (sur l'appareil <code>{device}</code>) ne dispose que de {free} ({free_percent}%) d'espace restant (sur {total}). Faites attention.",
|
||||
"diagnosis_ram_verylow": "Le système ne dispose plus que de {available} ({available_percent}%) de RAM ! (sur {total})",
|
||||
"diagnosis_ram_low": "Le système n'a plus de {available} ({available_percent}%) RAM sur {total}. Faites attention.",
|
||||
"diagnosis_swap_none": "Le système n'a aucun espace de swap. Vous devriez envisager d'ajouter au moins {recommended} de swap pour éviter les situations où le système manque de mémoire.",
|
||||
"diagnosis_swap_notsomuch": "Le système ne dispose que de {total} de swap. Vous devez envisager d'avoir au moins {recommended} pour éviter les situations où le système manque de mémoire.",
|
||||
|
@ -670,5 +670,19 @@
|
|||
"domain_dns_conf_special_use_tld": "Ce domaine est basé sur un domaine de premier niveau (TLD) à usage spécial tel que .local ou .test et ne devrait donc pas avoir d'enregistrements DNS réels.",
|
||||
"other_available_options": "... et {n} autres options disponibles non affichées",
|
||||
"domain_config_auth_consumer_key": "Consumer key",
|
||||
"domain_unknown": "Domaine '{domain}' inconnu"
|
||||
"domain_unknown": "Domaine '{domain}' inconnu",
|
||||
"migration_0021_start": "Démarrage de la migration vers Bullseye",
|
||||
"migration_0021_patching_sources_list": "Mise à jour du fichier sources.lists...",
|
||||
"migration_0021_main_upgrade": "Démarrage de la mise à niveau générale...",
|
||||
"migration_0021_still_on_buster_after_main_upgrade": "Quelque chose s'est mal passé lors de la mise à niveau, le système semble toujours être sous Debian Buster",
|
||||
"migration_0021_yunohost_upgrade": "Démarrage de la mise à jour du noyau YunoHost...",
|
||||
"migration_0021_not_enough_free_space": "L'espace libre est très faible dans /var/ ! Vous devriez avoir au moins 1 Go de libre pour effectuer cette migration.",
|
||||
"migration_0021_system_not_fully_up_to_date": "Votre système n'est pas entièrement à jour. Veuillez effectuer une mise à jour normale avant de lancer la migration vers Bullseye.",
|
||||
"migration_0021_general_warning": "Veuillez noter que cette migration est une opération délicate. L'équipe YunoHost a fait de son mieux pour la revérifier et la tester, mais la migration pourrait quand même casser des éléments du système ou de ses applications.\n\nIl est donc recommandé :\n - de faire une sauvegarde de toute donnée ou application critique. Plus d'informations ici https://yunohost.org/backup ;\n - d'être patient après le lancement de la migration. Selon votre connexion internet et votre matériel, la mise à niveau peut prendre jusqu'à quelques heures.",
|
||||
"migration_0021_problematic_apps_warning": "Veuillez noter que des applications qui peuvent poser problèmes ont été détectées. Il semble qu'elles n'aient pas été installées à partir du catalogue d'applications YunoHost, ou bien qu'elles ne soient pas signalées comme \\\"fonctionnelles\\\". Par conséquent, il n'est pas possible de garantir que les applications suivantes fonctionneront encore après la mise à niveau : {problematic_apps}",
|
||||
"migration_0021_modified_files": "Veuillez noter que les fichiers suivants ont été modifiés manuellement et pourraient être écrasés à la suite de la mise à niveau : {manually_modified_files}",
|
||||
"migration_0021_cleaning_up": "Nettoyage du cache et des paquets qui ne sont plus nécessaires...",
|
||||
"migration_0021_patch_yunohost_conflicts": "Application du correctif pour contourner le problème de conflit...",
|
||||
"migration_0021_not_buster": "La distribution Debian actuelle n'est pas Buster !",
|
||||
"migration_description_0021_migrate_to_bullseye": "Mise à niveau du système vers Debian Bullseye et YunoHost 11.x"
|
||||
}
|
|
@ -670,5 +670,19 @@
|
|||
"domain_dns_push_managed_in_parent_domain": "A función de rexistro DNS automático está xestionada polo dominio nai {parent_domain}.",
|
||||
"ldap_attribute_already_exists": "Xa existe o atributo LDAP '{attribute}' con valor '{value}'",
|
||||
"log_domain_config_set": "Actualizar configuración para o dominio '{}'",
|
||||
"domain_unknown": "Dominio '{domain}' descoñecido"
|
||||
"domain_unknown": "Dominio '{domain}' descoñecido",
|
||||
"migration_0021_start": "Comezando a migración a Bullseye",
|
||||
"migration_0021_patching_sources_list": "Actualizando sources.list...",
|
||||
"migration_0021_main_upgrade": "Iniciando a actualización principal...",
|
||||
"migration_0021_still_on_buster_after_main_upgrade": "Algo fallou durante a actualización principal, o sistema semlla que aínda está en Debian Buster",
|
||||
"migration_0021_yunohost_upgrade": "Iniciando actualización compoñente core de YunoHost...",
|
||||
"migration_0021_not_buster": "A distribución Debian actual non é Buster!",
|
||||
"migration_0021_not_enough_free_space": "Queda pouco espazo en /var/! Deberías ter polo menos 1GB libre para facer a migración.",
|
||||
"migration_0021_problematic_apps_warning": "Detectamos que están instaladas estas app que poderían ser problemáticas. Semella que non foron instaladas desde o catálogo YunoHost, ou non están marcadas como que 'funcionan'. Así, non podemos garantir que seguiran funcionando ben tras a migración: {problematic_apps}",
|
||||
"migration_0021_modified_files": "Ten en conta que os seguintes ficheiros semella que foron editados manualmente e poderían ser sobrescritos durante a migración: {manually_modified_files}",
|
||||
"migration_0021_cleaning_up": "Limpando a caché e os paquetes que xa non son precisos...",
|
||||
"migration_0021_patch_yunohost_conflicts": "Solucionando os problemas e conflitos...",
|
||||
"migration_description_0021_migrate_to_bullseye": "Actualizar o sistema a Debian Bullseye e YunoHost 11.x",
|
||||
"migration_0021_system_not_fully_up_to_date": "O teu sistema non está completamente actualizado. Fai unha actualización normal antes de executar a migración a Bullseye.",
|
||||
"migration_0021_general_warning": "Ten en conta que a migración é unha operación delicada. O equipo de YunoHost fixo todo o que puido para revisalo e probalo, pero aínda así poderían acontecer fallos no sistema ou apps.\n\nAsí as cousas, é recomendable:\n - Facer unha copia de apoio dos datos e apps importantes. Máis info en https://yunohost.org/backup;\n - Ter paciencia unha vez inicias a migración: dependendo da túa conexión a internet e hardware, podería levarlle varias horas completar o proceso."
|
||||
}
|
||||
|
|
|
@ -42,5 +42,17 @@
|
|||
"app_start_install": "Memasang {app}...",
|
||||
"app_start_remove": "Menghapus {app}...",
|
||||
"app_manifest_install_ask_password": "Pilih kata sandi administrasi untuk aplikasi ini",
|
||||
"app_upgrade_several_apps": "Aplikasi-aplikasi berikut akan diperbarui: {apps}"
|
||||
"app_upgrade_several_apps": "Aplikasi-aplikasi berikut akan diperbarui: {apps}",
|
||||
"backup_app_failed": "Tidak dapat mencadangkan {app}",
|
||||
"backup_archive_name_exists": "Arsip cadangan dengan nama ini sudah ada.",
|
||||
"backup_created": "Cadangan dibuat",
|
||||
"backup_creation_failed": "Tidak dapat membuat arsip cadangan",
|
||||
"backup_delete_error": "Tidak dapat menghapus '{path}'",
|
||||
"backup_deleted": "Cadangan dihapus",
|
||||
"diagnosis_apps_issue": "Sebuah masalah ditemukan pada aplikasi {app}",
|
||||
"backup_applying_method_tar": "Membuat arsip TAR cadangan...",
|
||||
"backup_method_tar_finished": "Arsip TAR cadanagan dibuat",
|
||||
"backup_nothings_done": "Tak ada yang harus disimpan",
|
||||
"certmanager_cert_install_success": "Sertifikat Let's Encrypt sekarang sudah terpasang pada domain '{domain}'",
|
||||
"backup_mount_archive_for_restore": "Menyiapkan arsip untuk pemulihan..."
|
||||
}
|
|
@ -1,19 +1,19 @@
|
|||
{
|
||||
"action_invalid": "Ongeldige actie '{action}'",
|
||||
"admin_password": "Administrator wachtwoord",
|
||||
"admin_password_changed": "Het administratie wachtwoord werd gewijzigd",
|
||||
"admin_password_changed": "Het administratie wachtwoord is gewijzigd",
|
||||
"app_already_installed": "{app} is al geïnstalleerd",
|
||||
"app_argument_invalid": "Kies een geldige waarde voor '{name}': {error}",
|
||||
"app_argument_required": "Het '{name}' moet ingevuld worden",
|
||||
"app_extraction_failed": "Kan installatiebestanden niet uitpakken",
|
||||
"app_extraction_failed": "Het lukt niet om de installatiebestanden uit te pakken",
|
||||
"app_id_invalid": "Ongeldige app-id",
|
||||
"app_install_files_invalid": "Deze bestanden kunnen niet worden geïnstalleerd",
|
||||
"app_not_installed": "{app} is niet geïnstalleerd",
|
||||
"app_removed": "{app} succesvol verwijderd",
|
||||
"app_sources_fetch_failed": "Kan bronbestanden niet ophalen, klopt de URL?",
|
||||
"app_not_installed": "Het lukte niet om {app} te vinden in de lijst met geïnstalleerde apps: {all_apps}",
|
||||
"app_removed": "{app} is verwijderd",
|
||||
"app_sources_fetch_failed": "Het is niet gelukt bronbestanden op te halen, klopt de URL?",
|
||||
"app_unknown": "Onbekende app",
|
||||
"app_upgrade_failed": "Kan app {app} niet updaten",
|
||||
"app_upgraded": "{app} succesvol geüpgraded",
|
||||
"app_upgrade_failed": "Het is niet gelukt app {app} bij te werken: {error}",
|
||||
"app_upgraded": "{app} is bijgewerkt",
|
||||
"ask_firstname": "Voornaam",
|
||||
"ask_lastname": "Achternaam",
|
||||
"ask_new_admin_password": "Nieuw administratorwachtwoord",
|
||||
|
@ -69,8 +69,8 @@
|
|||
"user_unknown": "Gebruikersnaam {user} is onbekend",
|
||||
"user_update_failed": "Kan gebruiker niet bijwerken",
|
||||
"yunohost_configured": "YunoHost configuratie is OK",
|
||||
"admin_password_change_failed": "Wachtwoord kan niet veranderd worden",
|
||||
"app_argument_choice_invalid": "Ongeldige keuze voor argument '{name}'. Het moet een van de volgende keuzes zijn {choices}",
|
||||
"admin_password_change_failed": "Wachtwoord wijzigen is niet gelukt",
|
||||
"app_argument_choice_invalid": "Kiel een geldige waarde voor argument '{name}'; {value}' komt niet voor in de keuzelijst {choices}",
|
||||
"app_not_correctly_installed": "{app} schijnt niet juist geïnstalleerd te zijn",
|
||||
"app_not_properly_removed": "{app} werd niet volledig verwijderd",
|
||||
"app_requirements_checking": "Noodzakelijke pakketten voor {app} aan het controleren...",
|
||||
|
@ -98,18 +98,36 @@
|
|||
"app_install_failed": "Kan {app} niet installeren: {error}",
|
||||
"app_remove_after_failed_install": "Bezig de app te verwijderen na gefaalde installatie...",
|
||||
"app_manifest_install_ask_domain": "Kies het domein waar deze app op geïnstalleerd moet worden",
|
||||
"app_manifest_install_ask_path": "Kies het pad waar deze app geïnstalleerd moet worden",
|
||||
"app_manifest_install_ask_path": "Kies het URL-pad (achter het domein) waar deze app geïnstalleerd moet worden",
|
||||
"app_manifest_install_ask_admin": "Kies een administrator voor deze app",
|
||||
"app_change_url_success": "{app} URL is nu {domain}{path}",
|
||||
"app_full_domain_unavailable": "Sorry, deze app moet op haar eigen domein geïnstalleerd worden, maar andere apps zijn al geïnstalleerd op het domein '{domain}'. U kunt wel een subdomein aan deze app toewijden.",
|
||||
"app_full_domain_unavailable": "Sorry, deze app moet op haar eigen domein geïnstalleerd worden, maar andere apps zijn al geïnstalleerd op het domein '{domain}'. Een mogelijke oplossing is om een nieuw subdomein toe te voegen, speciaal voor deze app.",
|
||||
"app_install_script_failed": "Er is een fout opgetreden in het installatiescript van de app",
|
||||
"app_location_unavailable": "Deze URL is niet beschikbaar of is in conflict met de al geïnstalleerde app(s):\n{apps}",
|
||||
"app_manifest_install_ask_password": "Kies een administratiewachtwoord voor deze app",
|
||||
"app_manifest_install_ask_is_public": "Moet deze app zichtbaar zijn voor anomieme bezoekers?",
|
||||
"app_not_upgraded": "De app '{failed_app}' kon niet upgraden en daardoor zijn de upgrades van de volgende apps geannuleerd: {apps}",
|
||||
"app_start_install": "{app} installeren...",
|
||||
"app_start_remove": "{app} verwijderen...",
|
||||
"app_start_install": "Bezig met installeren van {app}...",
|
||||
"app_start_remove": "Bezig met verwijderen van {app}...",
|
||||
"app_start_backup": "Bestanden aan het verzamelen voor de backup van {app}...",
|
||||
"app_start_restore": "{app} herstellen...",
|
||||
"app_upgrade_several_apps": "De volgende apps zullen worden geüpgraded: {apps}"
|
||||
"app_upgrade_several_apps": "De volgende apps zullen worden geüpgraded: {apps}",
|
||||
"app_upgrade_script_failed": "Er is een fout opgetreden in het upgradescript van de app",
|
||||
"apps_already_up_to_date": "Alle apps zijn al bijgewerkt met de nieuwste versie",
|
||||
"app_restore_script_failed": "Er ging iets mis in het helstelscript van de app",
|
||||
"app_change_url_identical_domains": "De oude en nieuwe domeinnaam/url_path zijn identiek ('{domain}{path}'), er is niets te doen.",
|
||||
"app_already_up_to_date": "{app} is al de meest actuele versie",
|
||||
"app_action_broke_system": "Deze actie lijkt de volgende belangrijke services te hebben kapotgemaakt: {services}",
|
||||
"app_config_unable_to_apply": "De waarden in het configuratiescherm konden niet toegepast worden.",
|
||||
"app_config_unable_to_read": "Het is niet gelukt de waarden van het configuratiescherm te lezen.",
|
||||
"app_argument_password_no_default": "Foutmelding tijdens het lezen van wachtwoordargument '{name}': het wachtwoordargument mag om veiligheidsredenen geen standaardwaarde hebben.",
|
||||
"app_already_installed_cant_change_url": "Deze app is al geïnstalleerd. De URL kan niet veranderd worden met deze functie. Probeer of dat lukt via `app changeurl`.",
|
||||
"apps_catalog_init_success": "De app-catalogus is succesvol geinitieerd!",
|
||||
"apps_catalog_failed_to_download": "Het is niet gelukt de {apps_catalog} app-catalogus te downloaden: {error}",
|
||||
"app_packaging_format_not_supported": "Deze app kon niet geinstalleerd worden, omdat het pakketformaat niet ondersteund wordt door je Yunohost. Probeer of je Yunohost bijgewerkt kan worden.",
|
||||
"additional_urls_already_added": "Extra URL '{url:s}' is al toegevoegd in de extra URL voor privilege '{permission:s}'",
|
||||
"additional_urls_already_removed": "Extra URL '{url}' is al verwijderd in de extra URL voor privilege '{permission}'",
|
||||
"app_label_deprecated": "Dit commando is vervallen. Gebruik alsjeblieft het nieuwe commando 'yunohost user permission update' om het label van de app te beheren.",
|
||||
"app_change_url_no_script": "De app '{app_name}' ondersteunt nog geen URL-aanpassingen. Misschien wel na een upgrade.",
|
||||
"app_upgrade_some_app_failed": "Sommige apps konden niet worden bijgewerkt"
|
||||
}
|
121
locales/ru.json
121
locales/ru.json
|
@ -35,7 +35,7 @@
|
|||
"domain_dns_conf_is_just_a_recommendation": "Эта страница показывает вам *рекомендуемую* конфигурацию. Она *не* создаёт для вас конфигурацию DNS. Вы должны сами конфигурировать зону вашего DNS у вашего регистратора в соответствии с этой рекомендацией.",
|
||||
"good_practices_about_user_password": "Выберите пароль пользователя длиной не менее 8 символов, хотя рекомендуется использовать более длинные (например, парольную фразу) и / или использовать символы различного типа (прописные, строчные буквы, цифры и специальные символы).",
|
||||
"password_too_simple_3": "Пароль должен содержать не менее 8 символов и содержать цифры, заглавные и строчные буквы и специальные символы",
|
||||
"upnp_enabled": "UPnP включён",
|
||||
"upnp_enabled": "UPnP включен",
|
||||
"user_deleted": "Пользователь удалён",
|
||||
"ask_lastname": "Фамилия",
|
||||
"app_action_broke_system": "Это действие, по-видимому, нарушило эти важные службы: {services}",
|
||||
|
@ -51,7 +51,7 @@
|
|||
"ask_password": "Пароль",
|
||||
"app_remove_after_failed_install": "Удаление приложения после сбоя установки...",
|
||||
"app_upgrade_script_failed": "Внутри скрипта обновления приложения произошла ошибка",
|
||||
"upnp_disabled": "UPnP отключён",
|
||||
"upnp_disabled": "UPnP отключен",
|
||||
"app_manifest_install_ask_domain": "Выберите домен, в котором должно быть установлено это приложение",
|
||||
"app_manifest_install_ask_path": "Выберите URL путь (часть после домена), по которому должно быть установлено это приложение",
|
||||
"app_manifest_install_ask_admin": "Выберите пользователя администратора для этого приложения",
|
||||
|
@ -73,5 +73,120 @@
|
|||
"user_unknown": "Неизвестный пользователь: {user}",
|
||||
"yunohost_already_installed": "YunoHost уже установлен",
|
||||
"yunohost_configured": "Теперь YunoHost настроен",
|
||||
"upgrading_packages": "Обновление пакетов..."
|
||||
"upgrading_packages": "Обновление пакетов...",
|
||||
"app_requirements_unmeet": "Необходимые требования для {app} не выполнены, пакет {pkgname} ({version}) должен быть {spec}",
|
||||
"app_make_default_location_already_used": "Невозможно сделать '{app}' приложением по умолчанию на домене, '{domain}' уже используется '{other_app}'",
|
||||
"app_config_unable_to_apply": "Не удалось применить значения панели конфигурации.",
|
||||
"app_config_unable_to_read": "Не удалось прочитать значения панели конфигурации.",
|
||||
"app_install_failed": "Невозможно установить {app}: {error}",
|
||||
"apps_catalog_init_success": "Система каталога приложений инициализирована!",
|
||||
"backup_abstract_method": "Этот метод резервного копирования еще не реализован",
|
||||
"backup_actually_backuping": "Создание резервного архива из собранных файлов...",
|
||||
"backup_applying_method_custom": "Вызов пользовательского метода резервного копирования {method}'...",
|
||||
"backup_archive_app_not_found": "Не удалось найти {app} в резервной копии",
|
||||
"backup_applying_method_tar": "Создание резервной копии в TAR-архиве...",
|
||||
"backup_archive_broken_link": "Не удалось получить доступ к резервной копии (неправильная ссылка {path})",
|
||||
"apps_catalog_failed_to_download": "Невозможно загрузить каталог приложений {apps_catalog}: {error}",
|
||||
"apps_catalog_obsolete_cache": "Кэш каталога приложений пуст или устарел.",
|
||||
"backup_archive_cant_retrieve_info_json": "Не удалось загрузить информацию об архиве '{archive}'... info.json не может быть получен (или не является корректным json).",
|
||||
"app_packaging_format_not_supported": "Это приложение не может быть установлено, поскольку его формат не поддерживается вашей версией YunoHost. Возможно, вам следует обновить систему.",
|
||||
"app_restore_failed": "Не удалось восстановить {app}: {error}",
|
||||
"app_restore_script_failed": "Произошла ошибка внутри сценария восстановления приложения",
|
||||
"ask_user_domain": "Домен, используемый для адреса электронной почты пользователя и учетной записи XMPP",
|
||||
"app_not_upgraded": "Не удалось обновить приложение '{failed_app}', и, как следствие, обновление следующих приложений было отменено: {apps}",
|
||||
"app_start_backup": "Сбор файлов для резервного копирования {app}...",
|
||||
"app_start_install": "Устанавливается {app}...",
|
||||
"backup_app_failed": "Не удалось создать резервную копию {app}",
|
||||
"backup_archive_name_exists": "Резервная копия с таким именем уже существует.",
|
||||
"backup_archive_name_unknown": "Неизвестный локальный архив резервного копирования с именем '{name}'",
|
||||
"backup_archive_open_failed": "Не удалось открыть архив резервной копии",
|
||||
"backup_archive_corrupted": "Похоже, что архив резервной копии '{archive}' поврежден : {error}",
|
||||
"certmanager_cert_install_success_selfsigned": "Самоподписанный сертификат для домена '{domain}' установлен",
|
||||
"backup_created": "Создана резервная копия",
|
||||
"config_unknown_filter_key": "Ключ фильтра '{filter_key}' неверен.",
|
||||
"config_validate_date": "Должна быть правильная дата в формате YYYY-MM-DD",
|
||||
"config_validate_email": "Должен быть правильный email",
|
||||
"config_validate_time": "Должно быть правильное время формата HH:MM",
|
||||
"backup_ask_for_copying_if_needed": "Хотите ли вы временно выполнить резервное копирование с использованием {size}MB? (Этот способ используется, поскольку некоторые файлы не могут быть подготовлены более эффективным методом.)",
|
||||
"backup_permission": "Разрешить резервное копирование для {app}",
|
||||
"certmanager_domain_dns_ip_differs_from_public_ip": "DNS-записи для домена '{domain}' отличаются от IP этого сервера. Пожалуйста, проверьте категорию 'DNS-записи' (основные) в диагностике для получения дополнительной информации. Если вы недавно изменили свою A-запись, пожалуйста, подождите, пока она распространится (некоторые программы проверки распространения DNS доступны в интернете). (Если вы знаете, что делаете, используйте '--no-checks', чтобы отключить эти проверки.)",
|
||||
"certmanager_domain_not_diagnosed_yet": "Для домена {domain} еще нет результатов диагностики. Пожалуйста, перезапустите диагностику для категорий 'DNS-записи' и 'Web', чтобы проверить, готов ли домен к Let's Encrypt. (Или, если вы знаете, что делаете, используйте '--no-checks', чтобы отключить эти проверки.)",
|
||||
"config_validate_url": "Должна быть правильная ссылка",
|
||||
"config_version_not_supported": "Версии конфигурационной панели '{version}' не поддерживаются.",
|
||||
"confirm_app_install_danger": "ОПАСНО! Это приложение все еще является экспериментальным (если не сказать, что оно явно не работает)! Вам не следует устанавливать его, если вы не знаете, что делаете. Если это приложение не будет работать или сломает вашу систему, мы не будем оказывать техническую поддержку... Если вы все равно готовы рискнуть, введите '{answers}'",
|
||||
"confirm_app_install_thirdparty": "ВАЖНО! Это приложение не входит в каталог приложений YunoHost. Установка сторонних приложений может нарушить целостность и безопасность вашей системы. Вам не следует устанавливать его, если вы не знаете, что делаете. ТЕХНИЧЕСКОЙ ПОДДЕРЖКИ НЕ БУДЕТ, если это приложение не будет работать или сломает вашу систему... Если вы все равно готовы рискнуть, введите '{answers}'",
|
||||
"config_apply_failed": "Не удалось применить новую конфигурацию: {error}",
|
||||
"config_cant_set_value_on_section": "Вы не можете установить одно значение на весь раздел конфигурации.",
|
||||
"config_forbidden_keyword": "Ключевое слово '{keyword}' зарезервировано, вы не можете создать или использовать панель конфигурации с вопросом с таким id.",
|
||||
"config_no_panel": "Панель конфигурации не найдена.",
|
||||
"danger": "Опасно:",
|
||||
"certmanager_warning_subdomain_dns_record": "Субдомен '{subdomain}' не соответствует IP-адресу основного домена '{domain}'. Некоторые функции будут недоступны, пока вы не исправите это и не перегенерируете сертификат.",
|
||||
"app_argument_password_no_default": "Ошибка при парсинге аргумента пароля '{name}': аргумент пароля не может иметь значение по умолчанию по причинам безопасности",
|
||||
"custom_app_url_required": "Вы должны указать URL для обновления вашего пользовательского приложения {app}",
|
||||
"backup_creation_failed": "Не удалось создать резервную копию",
|
||||
"backup_csv_addition_failed": "Не удалось добавить файлы для резервного копирования в CSV-файл",
|
||||
"backup_csv_creation_failed": "Не удалось создать CSV-файл, необходимый для восстановления",
|
||||
"backup_deleted": "Резервная копия удалена",
|
||||
"backup_delete_error": "Не удалось удалить '{path}'",
|
||||
"backup_method_copy_finished": "Создание копии бэкапа завершено",
|
||||
"backup_method_tar_finished": "Создан резервный TAR-архив",
|
||||
"backup_mount_archive_for_restore": "Подготовка архива для восстановления...",
|
||||
"backup_method_custom_finished": "Пользовательский метод резервного копирования '{method}' завершен",
|
||||
"backup_nothings_done": "Нечего сохранять",
|
||||
"backup_output_directory_required": "Вы должны выбрать каталог для сохранения резервной копии",
|
||||
"backup_system_part_failed": "Не удалось создать резервную копию системной части '{part}'",
|
||||
"certmanager_cert_renew_success": "Обновлен сертификат Let's Encrypt для домена '{domain}'",
|
||||
"certmanager_cert_signing_failed": "Не удалось подписать новый сертификат",
|
||||
"diagnosis_apps_bad_quality": "В настоящее время это приложение отмечено как неработающее в каталоге приложений YunoHost. Это может быть временной проблемой, пока мэинтейнеры пытаются исправить проблему. Пока что обновление этого приложения отключено.",
|
||||
"diagnosis_apps_broken": "В настоящее время это приложение отмечено как неработающее в каталоге приложений YunoHost. Это может быть временной проблемой, пока мэинтейнеры пытаются исправить проблему. Пока что обновления для этого приложения отключены.",
|
||||
"diagnosis_apps_allgood": "Все установленные приложения соблюдают основные правила упаковки",
|
||||
"diagnosis_apps_issue": "Обнаружена проблема для приложения {app}",
|
||||
"diagnosis_apps_not_in_app_catalog": "Этого приложения нет в каталоге приложений YunoHost. Если оно было там раньше, а теперь удалено, вам стоит подумать об удалении этого приложения, так как оно больше не получит обновлений и может нарушить целостность и безопасность вашей системы.",
|
||||
"diagnosis_apps_deprecated_practices": "Установленная версия этого приложения все еще использует некоторые устаревшие пакеты. Вам стоит подумать об обновлении.",
|
||||
"additional_urls_already_added": "Этот URL '{url}' уже добавлен в дополнительный URL для разрешения '{permission}'",
|
||||
"additional_urls_already_removed": "Этот URL '{url}' уже удален из дополнительных URL для разрешения '{permission}'",
|
||||
"app_action_cannot_be_ran_because_required_services_down": "Для выполнения этого действия должны быть запущены следующие службы: {services}. Попробуйте перезапустить их, чтобы продолжить (и, возможно, выяснить, почему они не работают).",
|
||||
"app_unsupported_remote_type": "Неподдерживаемый удаленный тип, используемый для приложения",
|
||||
"backup_archive_system_part_not_available": "Системная часть '{part}' недоступна в этой резервной копии",
|
||||
"backup_output_directory_not_empty": "Вы должны выбрать пустой каталог для сохранения",
|
||||
"backup_archive_writing_error": "Не удалось добавить файлы '{source}' (названные в архиве '{dest}') для резервного копирования в архив '{archive}'",
|
||||
"backup_cant_mount_uncompress_archive": "Не удалось смонтировать несжатый архив как защищенный от записи",
|
||||
"backup_copying_to_organize_the_archive": "Копирование {size}MB для создания архива",
|
||||
"backup_couldnt_bind": "Не удалось связать {src} с {dest}.",
|
||||
"backup_output_directory_forbidden": "Выберите другой каталог для сохранения. Резервные копии не могут быть созданы в подкаталогах /bin, /boot, /dev, /etc, /lib, /root, /run, /sbin, /sys, /usr, /var или /home/yunohost.backup/archives",
|
||||
"backup_with_no_backup_script_for_app": "Приложение '{app}' не имеет сценария резервного копирования. Оно будет проигнорировано.",
|
||||
"certmanager_attempt_to_renew_nonLE_cert": "Сертификат для домена '{domain}' не выпущен Let's Encrypt. Невозможно продлить его автоматически!",
|
||||
"certmanager_attempt_to_renew_valid_cert": "Срок действия сертификата для домена '{domain}' НЕ истекает! (Вы можете использовать --force, если знаете, что делаете)",
|
||||
"certmanager_cannot_read_cert": "При попытке открыть текущий сертификат для домена {domain} произошло что-то неправильное (файл: {file}), причина: {reason}",
|
||||
"certmanager_cert_install_success": "Сертификат Let's Encrypt для домена '{domain}' установлен",
|
||||
"certmanager_domain_cert_not_selfsigned": "Сертификат для домена {domain} не самоподписанный. Вы уверены, что хотите заменить его? (Для этого используйте '--force'.)",
|
||||
"certmanager_certificate_fetching_or_enabling_failed": "Попытка использовать новый сертификат для {domain} не сработала...",
|
||||
"certmanager_domain_http_not_working": "Похоже, домен {domain} не доступен через HTTP. Пожалуйста, проверьте категорию 'Web' в диагностике для получения дополнительной информации. (Если вы знаете, что делаете, используйте '--no-checks', чтобы отключить эти проверки.)",
|
||||
"certmanager_hit_rate_limit": "Для этого набора доменов {domain} в последнее время было выпущено слишком много сертификатов. Пожалуйста, повторите попытку позже. См. https://letsencrypt.org/docs/rate-limits/ для получения более подробной информации",
|
||||
"certmanager_no_cert_file": "Не удалось прочитать файл сертификата для домена {domain} (файл: {file})",
|
||||
"confirm_app_install_warning": "Предупреждение: Это приложение может работать, но пока еще недостаточно интегрировано в YunoHost. Некоторые функции, такие как единая регистрация и резервное копирование/восстановление, могут быть недоступны. Все равно устанавливать? [{answers}] ",
|
||||
"yunohost_not_installed": "YunoHost установлен неправильно. Пожалуйста, запустите 'yunohost tools postinstall'",
|
||||
"backup_cleaning_failed": "Не удалось очистить временную папку резервного копирования",
|
||||
"certmanager_attempt_to_replace_valid_cert": "Вы пытаетесь перезаписать хороший и действительный сертификат для домена {domain}! (Используйте --force для обхода)",
|
||||
"backup_create_size_estimation": "Архив будет содержать около {size} данных.",
|
||||
"diagnosis_description_regenconf": "Конфигурации системы",
|
||||
"diagnosis_description_services": "Проверка статусов сервисов",
|
||||
"config_validate_color": "Должен быть правильный hex цвета RGB",
|
||||
"diagnosis_basesystem_hardware": "Аппаратная архитектура сервера – {virt} {arch}",
|
||||
"certmanager_acme_not_configured_for_domain": "Задача ACME не может быть запущена для {domain} прямо сейчас, потому что в его nginx conf отсутствует соответствующий фрагмент кода... Пожалуйста, убедитесь, что конфигурация вашего nginx обновлена, используя `yunohost tools regen-conf nginx --dry-run --with-diff`.",
|
||||
"diagnosis_basesystem_ynh_single_version": "{package} версия: {version} ({repo})",
|
||||
"diagnosis_description_mail": "Email",
|
||||
"diagnosis_basesystem_kernel": "Версия ядра Linux на сервере {kernel_version}",
|
||||
"diagnosis_description_apps": "Приложения",
|
||||
"diagnosis_diskusage_low": "В хранилище <code>{mountpoint}</code> (на устройстве <code>{device}</code>) осталось {free} ({free_percent}%) места (из {total}). Будьте осторожны.",
|
||||
"diagnosis_description_dnsrecords": "DNS записи",
|
||||
"diagnosis_description_ip": "Интернет-соединение",
|
||||
"diagnosis_description_basesystem": "Основная система",
|
||||
"diagnosis_description_web": "Web",
|
||||
"diagnosis_basesystem_host": "На сервере запущен Debian {debian_version}",
|
||||
"diagnosis_dns_bad_conf": "Некоторые записи DNS для домена {domain} (категория {category}) отсутствуют или неверны",
|
||||
"diagnosis_description_systemresources": "Системные ресурсы",
|
||||
"backup_with_no_restore_script_for_app": "{app} не имеет сценария восстановления, вы не сможете автоматически восстановить это приложение из резервной копии.",
|
||||
"diagnosis_description_ports": "Открытые порты",
|
||||
"diagnosis_basesystem_hardware_model": "Модель сервера {model}"
|
||||
}
|
|
@ -345,7 +345,7 @@
|
|||
"diagnosis_security_vulnerable_to_meltdown": "Схоже, що ви вразливі до критичної вразливості безпеки Meltdown",
|
||||
"diagnosis_rootfstotalspace_critical": "Коренева файлова система має тільки {space}, що дуже тривожно! Скоріше за все, дисковий простір закінчиться дуже скоро! Рекомендовано мати не менше 16 ГБ для кореневої файлової системи.",
|
||||
"diagnosis_rootfstotalspace_warning": "Коренева файлова система має тільки {space}. Можливо це нормально, але будьте обережні, тому що в кінцевому підсумку дисковий простір може швидко закінчитися... Рекомендовано мати не менше 16 ГБ для кореневої файлової системи.",
|
||||
"diagnosis_regenconf_manually_modified_details": "Можливо це нормально, якщо ви знаєте, що робите! YunoHost перестане оновлювати цей файл автоматично... Але врахуйте, що оновлення YunoHost можуть містити важливі рекомендовані зміни. Якщо ви хочете, ви можете перевірити відмінності за допомогою команди <cmd>yunohost tools regen-conf {category} --dry-run --with-diff</cmd> і примусово повернути рекомендовану конфігурацію за допомогою команди <cmd>yunohost tools regen-conf {category} --force</cmd>",
|
||||
"diagnosis_regenconf_manually_modified_details": "Можливо це нормально, якщо ви знаєте, що робите! YunoHost перестане оновлювати цей файл автоматично. Але врахуйте, що оновлення YunoHost можуть містити важливі рекомендовані зміни. Якщо хочете, ви можете перевірити відмінності за допомогою команди <cmd>yunohost tools regen-conf {category} --dry-run --with-diff</cmd> і примусово повернути рекомендовану конфігурацію за допомогою команди <cmd>yunohost tools regen-conf {category} --force</cmd>",
|
||||
"diagnosis_regenconf_manually_modified": "Конфігураційний файл <code>{file}</code>, схоже, було змінено вручну.",
|
||||
"diagnosis_regenconf_allgood": "Усі конфігураційні файли відповідають рекомендованій конфігурації!",
|
||||
"diagnosis_mail_queue_too_big": "Занадто багато відкладених листів у поштовій черзі (листів: {nb_pending})",
|
||||
|
@ -670,5 +670,19 @@
|
|||
"domain_dns_pushing": "Передання записів DNS...",
|
||||
"ldap_attribute_already_exists": "Атрибут LDAP '{attribute}' вже існує зі значенням '{value}'",
|
||||
"domain_dns_push_already_up_to_date": "Записи вже оновлені, нічого не потрібно робити.",
|
||||
"domain_unknown": "Домен '{domain}' є невідомим"
|
||||
"domain_unknown": "Домен '{domain}' є невідомим",
|
||||
"migration_0021_start": "Початок міграції на Bullseye",
|
||||
"migration_0021_patching_sources_list": "Виправлення sources.lists...",
|
||||
"migration_0021_main_upgrade": "Початок основного оновлення...",
|
||||
"migration_0021_yunohost_upgrade": "Початок оновлення ядра YunoHost...",
|
||||
"migration_0021_not_buster": "Поточний дистрибутив Debian не є Buster!",
|
||||
"migration_0021_problematic_apps_warning": "Зверніть увагу, що були виявлені наступні, ймовірно проблемні встановлені застосунки. Схоже, що вони не були встановлені з каталогу застосунків YunoHost або не зазначені як «робочі». Отже, не можна гарантувати, що вони будуть працювати після оновлення: {problematic_apps}",
|
||||
"migration_0021_modified_files": "Зверніть увагу, що такі файли були змінені вручну і можуть бути перезаписані після оновлення: {manually_modified_files}",
|
||||
"migration_0021_cleaning_up": "Очищення кеш-пам'яті і пакетів, які більше не потрібні...",
|
||||
"migration_0021_patch_yunohost_conflicts": "Застосування виправлення для вирішення проблеми конфлікту...",
|
||||
"migration_0021_still_on_buster_after_main_upgrade": "Щось пішло не так під час основного оновлення, здається, що система все ще працює на Debian Buster",
|
||||
"migration_0021_not_enough_free_space": "Вільного місця в /var/ досить мало! У вас повинно бути не менше 1 ГБ вільного місця, щоб запустити цю міграцію.",
|
||||
"migration_0021_system_not_fully_up_to_date": "Ваша система не повністю оновлена. Будь ласка, виконайте регулярне оновлення перед запуском міграції на Bullseye.",
|
||||
"migration_0021_general_warning": "Будь ласка, зверніть увагу, що ця міграція є делікатною операцією. Команда YunoHost зробила все можливе, щоб перевірити і протестувати її, але міграція все ще може порушити частину системи або її застосунків.\n\nТому рекомендовано:\n - Виконати резервне копіювання всіх важливих даних або застосунків. Подробиці на сайті https://yunohost.org/backup; \n - Наберіться терпіння після запуску міграції: В залежності від вашого з'єднання з Інтернетом і апаратного забезпечення, оновлення може зайняти до декількох годин.",
|
||||
"migration_description_0021_migrate_to_bullseye": "Оновлення системи до Debian Bullseye і YunoHost 11.x"
|
||||
}
|
27
src/app.py
27
src/app.py
|
@ -104,7 +104,7 @@ def app_list(full=False):
|
|||
try:
|
||||
app_info_dict = app_info(app_id, full=full)
|
||||
except Exception as e:
|
||||
logger.error("Failed to read info for %s : %s" % (app_id, e))
|
||||
logger.error(f"Failed to read info for {app_id} : {e}")
|
||||
continue
|
||||
app_info_dict["id"] = app_id
|
||||
out.append(app_info_dict)
|
||||
|
@ -609,7 +609,7 @@ def app_upgrade(app=[], url=None, file=None, force=False, no_safety_backup=False
|
|||
if upgrade_failed or broke_the_system:
|
||||
|
||||
# display this if there are remaining apps
|
||||
if apps[number + 1 :]:
|
||||
if apps[number + 1:]:
|
||||
not_upgraded_apps = apps[number:]
|
||||
logger.error(
|
||||
m18n.n(
|
||||
|
@ -1015,7 +1015,6 @@ def app_remove(operation_logger, app, purge=False):
|
|||
remove_script = f"{tmp_workdir_for_app}/scripts/remove"
|
||||
|
||||
env_dict = {}
|
||||
app_id, app_instance_nb = _parse_app_instance_name(app)
|
||||
env_dict = _make_environment_for_app_script(app, workdir=tmp_workdir_for_app)
|
||||
env_dict["YNH_APP_PURGE"] = str(1 if purge else 0)
|
||||
|
||||
|
@ -1143,7 +1142,8 @@ def app_setting(app, key, value=None, delete=False):
|
|||
)
|
||||
|
||||
permissions = user_permission_list(full=True, apps=[app])["permissions"]
|
||||
permission_name = "%s.legacy_%s_uris" % (app, key.split("_")[0])
|
||||
key_ = key.split("_")[0]
|
||||
permission_name = f"{app}.legacy_{key_}_uris"
|
||||
permission = permissions.get(permission_name)
|
||||
|
||||
# GET
|
||||
|
@ -1482,11 +1482,7 @@ def app_action_run(operation_logger, app, action, args=None):
|
|||
shutil.rmtree(tmp_workdir_for_app)
|
||||
|
||||
if retcode not in action_declaration.get("accepted_return_codes", [0]):
|
||||
msg = "Error while executing action '%s' of app '%s': return code %s" % (
|
||||
action,
|
||||
app,
|
||||
retcode,
|
||||
)
|
||||
msg = f"Error while executing action '{action}' of app '{app}': return code {retcode}"
|
||||
operation_logger.error(msg)
|
||||
raise YunohostError(msg, raw_msg=True)
|
||||
|
||||
|
@ -1550,9 +1546,12 @@ class AppConfigPanel(ConfigPanel):
|
|||
error=message,
|
||||
)
|
||||
|
||||
def _call_config_script(self, action, env={}):
|
||||
def _call_config_script(self, action, env=None):
|
||||
from yunohost.hook import hook_exec
|
||||
|
||||
if env is None:
|
||||
env = {}
|
||||
|
||||
# Add default config script if needed
|
||||
config_script = os.path.join(
|
||||
APPS_SETTING_PATH, self.entity, "scripts", "config"
|
||||
|
@ -1909,7 +1908,8 @@ def _set_default_ask_questions(arguments):
|
|||
for question in questions_with_default
|
||||
):
|
||||
# The key is for example "app_manifest_install_ask_domain"
|
||||
key = "app_manifest_%s_ask_%s" % (script_name, arg["name"])
|
||||
arg_name = arg["name"]
|
||||
key = f"app_manifest_{script_name}_ask_{arg_name}"
|
||||
arg["ask"] = m18n.n(key)
|
||||
|
||||
# Also it in fact doesn't make sense for any of those questions to have an example value nor a default value...
|
||||
|
@ -1917,7 +1917,7 @@ def _set_default_ask_questions(arguments):
|
|||
if "example" in arg:
|
||||
del arg["example"]
|
||||
if "default" in arg:
|
||||
del arg["domain"]
|
||||
del arg["default"]
|
||||
|
||||
return arguments
|
||||
|
||||
|
@ -2317,7 +2317,8 @@ def _make_environment_for_app_script(
|
|||
env_dict["YNH_APP_BASEDIR"] = workdir
|
||||
|
||||
for arg_name, arg_value in args.items():
|
||||
env_dict["YNH_%s%s" % (args_prefix, arg_name.upper())] = str(arg_value)
|
||||
arg_name_upper = arg_name.upper()
|
||||
env_dict[f"YNH_{args_prefix}{arg_name_upper}"] = str(arg_value)
|
||||
|
||||
return env_dict
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ def _load_apps_catalog():
|
|||
)
|
||||
except Exception as e:
|
||||
raise YunohostError(
|
||||
"Unable to read cache for apps_catalog %s : %s" % (cache_file, e),
|
||||
f"Unable to read cache for apps_catalog {cache_file} : {e}",
|
||||
raw_msg=True,
|
||||
)
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ MB_ALLOWED_TO_ORGANIZE = 10
|
|||
logger = getActionLogger("yunohost.backup")
|
||||
|
||||
|
||||
class BackupRestoreTargetsManager(object):
|
||||
class BackupRestoreTargetsManager:
|
||||
|
||||
"""
|
||||
BackupRestoreTargetsManager manage the targets
|
||||
|
@ -1574,7 +1574,7 @@ class RestoreManager:
|
|||
#
|
||||
# Backup methods #
|
||||
#
|
||||
class BackupMethod(object):
|
||||
class BackupMethod:
|
||||
|
||||
"""
|
||||
BackupMethod is an abstract class that represents a way to backup and
|
||||
|
@ -2384,7 +2384,7 @@ def backup_list(with_info=False, human_readable=False):
|
|||
# Get local archives sorted according to last modification time
|
||||
# (we do a realpath() to resolve symlinks)
|
||||
archives = glob("%s/*.tar.gz" % ARCHIVES_PATH) + glob("%s/*.tar" % ARCHIVES_PATH)
|
||||
archives = set([os.path.realpath(archive) for archive in archives])
|
||||
archives = {os.path.realpath(archive) for archive in archives}
|
||||
archives = sorted(archives, key=lambda x: os.path.getctime(x))
|
||||
# Extract only filename without the extension
|
||||
|
||||
|
@ -2424,7 +2424,7 @@ def backup_download(name):
|
|||
)
|
||||
return
|
||||
|
||||
archive_file = "%s/%s.tar" % (ARCHIVES_PATH, name)
|
||||
archive_file = f"{ARCHIVES_PATH}/{name}.tar"
|
||||
|
||||
# Check file exist (even if it's a broken symlink)
|
||||
if not os.path.lexists(archive_file):
|
||||
|
@ -2466,7 +2466,7 @@ def backup_info(name, with_details=False, human_readable=False):
|
|||
elif name.endswith(".tar"):
|
||||
name = name[: -len(".tar")]
|
||||
|
||||
archive_file = "%s/%s.tar" % (ARCHIVES_PATH, name)
|
||||
archive_file = f"{ARCHIVES_PATH}/{name}.tar"
|
||||
|
||||
# Check file exist (even if it's a broken symlink)
|
||||
if not os.path.lexists(archive_file):
|
||||
|
@ -2484,7 +2484,7 @@ def backup_info(name, with_details=False, human_readable=False):
|
|||
"backup_archive_broken_link", path=archive_file
|
||||
)
|
||||
|
||||
info_file = "%s/%s.info.json" % (ARCHIVES_PATH, name)
|
||||
info_file = f"{ARCHIVES_PATH}/{name}.info.json"
|
||||
|
||||
if not os.path.exists(info_file):
|
||||
tar = tarfile.open(
|
||||
|
@ -2595,10 +2595,10 @@ def backup_delete(name):
|
|||
|
||||
hook_callback("pre_backup_delete", args=[name])
|
||||
|
||||
archive_file = "%s/%s.tar" % (ARCHIVES_PATH, name)
|
||||
if os.path.exists(archive_file + ".gz"):
|
||||
archive_file = f"{ARCHIVES_PATH}/{name}.tar"
|
||||
if not os.path.exists(archive_file) and os.path.exists(archive_file + ".gz"):
|
||||
archive_file += ".gz"
|
||||
info_file = "%s/%s.info.json" % (ARCHIVES_PATH, name)
|
||||
info_file = f"{ARCHIVES_PATH}/{name}.info.json"
|
||||
|
||||
files_to_delete = [archive_file, info_file]
|
||||
|
||||
|
@ -2697,5 +2697,5 @@ def binary_to_human(n, customary=False):
|
|||
for s in reversed(symbols):
|
||||
if n >= prefix[s]:
|
||||
value = float(n) / prefix[s]
|
||||
return "%.1f%s" % (value, s)
|
||||
return "{:.1f}{}".format(value, s)
|
||||
return "%s" % n
|
||||
|
|
|
@ -70,28 +70,28 @@ PRODUCTION_CERTIFICATION_AUTHORITY = "https://acme-v02.api.letsencrypt.org"
|
|||
#
|
||||
|
||||
|
||||
def certificate_status(domain_list, full=False):
|
||||
def certificate_status(domains, full=False):
|
||||
"""
|
||||
Print the status of certificate for given domains (all by default)
|
||||
|
||||
Keyword argument:
|
||||
domain_list -- Domains to be checked
|
||||
domains -- Domains to be checked
|
||||
full -- Display more info about the certificates
|
||||
"""
|
||||
|
||||
import yunohost.domain
|
||||
from yunohost.domain import domain_list, _assert_domain_exists
|
||||
|
||||
# If no domains given, consider all yunohost domains
|
||||
if domain_list == []:
|
||||
domain_list = yunohost.domain.domain_list()["domains"]
|
||||
if domains == []:
|
||||
domains = domain_list()["domains"]
|
||||
# Else, validate that yunohost knows the domains given
|
||||
else:
|
||||
for domain in domain_list:
|
||||
yunohost.domain._assert_domain_exists(domain)
|
||||
for domain in domains:
|
||||
_assert_domain_exists(domain)
|
||||
|
||||
certificates = {}
|
||||
|
||||
for domain in domain_list:
|
||||
for domain in domains:
|
||||
status = _get_status(domain)
|
||||
|
||||
if not full:
|
||||
|
@ -237,28 +237,28 @@ def _certificate_install_selfsigned(domain_list, force=False):
|
|||
|
||||
|
||||
def _certificate_install_letsencrypt(
|
||||
domain_list, force=False, no_checks=False, staging=False
|
||||
domains, force=False, no_checks=False, staging=False
|
||||
):
|
||||
import yunohost.domain
|
||||
from yunohost.domain import domain_list, _assert_domain_exists
|
||||
|
||||
if not os.path.exists(ACCOUNT_KEY_FILE):
|
||||
_generate_account_key()
|
||||
|
||||
# If no domains given, consider all yunohost domains with self-signed
|
||||
# certificates
|
||||
if domain_list == []:
|
||||
for domain in yunohost.domain.domain_list()["domains"]:
|
||||
if domains == []:
|
||||
for domain in domain_list()["domains"]:
|
||||
|
||||
status = _get_status(domain)
|
||||
if status["CA_type"]["code"] != "self-signed":
|
||||
continue
|
||||
|
||||
domain_list.append(domain)
|
||||
domains.append(domain)
|
||||
|
||||
# Else, validate that yunohost knows the domains given
|
||||
else:
|
||||
for domain in domain_list:
|
||||
yunohost.domain._assert_domain_exists(domain)
|
||||
for domain in domains:
|
||||
_assert_domain_exists(domain)
|
||||
|
||||
# Is it self-signed?
|
||||
status = _get_status(domain)
|
||||
|
@ -273,7 +273,7 @@ def _certificate_install_letsencrypt(
|
|||
)
|
||||
|
||||
# Actual install steps
|
||||
for domain in domain_list:
|
||||
for domain in domains:
|
||||
|
||||
if not no_checks:
|
||||
try:
|
||||
|
@ -294,10 +294,7 @@ def _certificate_install_letsencrypt(
|
|||
try:
|
||||
_fetch_and_enable_new_certificate(domain, staging, no_checks=no_checks)
|
||||
except Exception as e:
|
||||
msg = "Certificate installation for %s failed !\nException: %s" % (
|
||||
domain,
|
||||
e,
|
||||
)
|
||||
msg = f"Certificate installation for {domain} failed !\nException: {e}"
|
||||
logger.error(msg)
|
||||
operation_logger.error(msg)
|
||||
if no_checks:
|
||||
|
@ -312,25 +309,25 @@ def _certificate_install_letsencrypt(
|
|||
|
||||
|
||||
def certificate_renew(
|
||||
domain_list, force=False, no_checks=False, email=False, staging=False
|
||||
domains, force=False, no_checks=False, email=False, staging=False
|
||||
):
|
||||
"""
|
||||
Renew Let's Encrypt certificate for given domains (all by default)
|
||||
|
||||
Keyword argument:
|
||||
domain_list -- Domains for which to renew the certificates
|
||||
domains -- Domains for which to renew the certificates
|
||||
force -- Ignore the validity threshold (15 days)
|
||||
no-check -- Disable some checks about the reachability of web server
|
||||
before attempting the renewing
|
||||
email -- Emails root if some renewing failed
|
||||
"""
|
||||
|
||||
import yunohost.domain
|
||||
from yunohost.domain import domain_list, _assert_domain_exists
|
||||
|
||||
# If no domains given, consider all yunohost domains with Let's Encrypt
|
||||
# certificates
|
||||
if domain_list == []:
|
||||
for domain in yunohost.domain.domain_list()["domains"]:
|
||||
if domains == []:
|
||||
for domain in domain_list()["domains"]:
|
||||
|
||||
# Does it have a Let's Encrypt cert?
|
||||
status = _get_status(domain)
|
||||
|
@ -348,17 +345,17 @@ def certificate_renew(
|
|||
)
|
||||
continue
|
||||
|
||||
domain_list.append(domain)
|
||||
domains.append(domain)
|
||||
|
||||
if len(domain_list) == 0 and not email:
|
||||
if len(domains) == 0 and not email:
|
||||
logger.info("No certificate needs to be renewed.")
|
||||
|
||||
# Else, validate the domain list given
|
||||
else:
|
||||
for domain in domain_list:
|
||||
for domain in domains:
|
||||
|
||||
# Is it in Yunohost domain list?
|
||||
yunohost.domain._assert_domain_exists(domain)
|
||||
_assert_domain_exists(domain)
|
||||
|
||||
status = _get_status(domain)
|
||||
|
||||
|
@ -386,7 +383,7 @@ def certificate_renew(
|
|||
)
|
||||
|
||||
# Actual renew steps
|
||||
for domain in domain_list:
|
||||
for domain in domains:
|
||||
|
||||
if not no_checks:
|
||||
try:
|
||||
|
@ -450,39 +447,25 @@ def _email_renewing_failed(domain, exception_message, stack=""):
|
|||
subject_ = "Certificate renewing attempt for %s failed!" % domain
|
||||
|
||||
logs = _tail(50, "/var/log/yunohost/yunohost-cli.log")
|
||||
text = """
|
||||
An attempt for renewing the certificate for domain %s failed with the following
|
||||
message = f"""\
|
||||
From: {from_}
|
||||
To: {to_}
|
||||
Subject: {subject_}
|
||||
|
||||
|
||||
An attempt for renewing the certificate for domain {domain} failed with the following
|
||||
error :
|
||||
|
||||
%s
|
||||
%s
|
||||
{exception_message}
|
||||
{stack}
|
||||
|
||||
Here's the tail of /var/log/yunohost/yunohost-cli.log, which might help to
|
||||
investigate :
|
||||
|
||||
%s
|
||||
{logs}
|
||||
|
||||
-- Certificate Manager
|
||||
|
||||
""" % (
|
||||
domain,
|
||||
exception_message,
|
||||
stack,
|
||||
logs,
|
||||
)
|
||||
|
||||
message = """\
|
||||
From: %s
|
||||
To: %s
|
||||
Subject: %s
|
||||
|
||||
%s
|
||||
""" % (
|
||||
from_,
|
||||
to_,
|
||||
subject_,
|
||||
text,
|
||||
)
|
||||
"""
|
||||
|
||||
import smtplib
|
||||
|
||||
|
@ -520,7 +503,7 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False):
|
|||
# Prepare certificate signing request
|
||||
logger.debug("Prepare key and certificate signing request (CSR) for %s...", domain)
|
||||
|
||||
domain_key_file = "%s/%s.pem" % (TMP_FOLDER, domain)
|
||||
domain_key_file = f"{TMP_FOLDER}/{domain}.pem"
|
||||
_generate_key(domain_key_file)
|
||||
_set_permissions(domain_key_file, "root", "ssl-cert", 0o640)
|
||||
|
||||
|
@ -529,7 +512,7 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False):
|
|||
# Sign the certificate
|
||||
logger.debug("Now using ACME Tiny to sign the certificate...")
|
||||
|
||||
domain_csr_file = "%s/%s.csr" % (TMP_FOLDER, domain)
|
||||
domain_csr_file = f"{TMP_FOLDER}/{domain}.csr"
|
||||
|
||||
if staging:
|
||||
certification_authority = STAGING_CERTIFICATION_AUTHORITY
|
||||
|
@ -568,12 +551,7 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False):
|
|||
else:
|
||||
folder_flag = "letsencrypt"
|
||||
|
||||
new_cert_folder = "%s/%s-history/%s-%s" % (
|
||||
CERT_FOLDER,
|
||||
domain,
|
||||
date_tag,
|
||||
folder_flag,
|
||||
)
|
||||
new_cert_folder = f"{CERT_FOLDER}/{domain}-history/{date_tag}-{folder_flag}"
|
||||
|
||||
os.makedirs(new_cert_folder)
|
||||
|
||||
|
@ -630,7 +608,7 @@ def _prepare_certificate_signing_request(domain, key_file, output_folder):
|
|||
csr.add_extensions(
|
||||
[
|
||||
crypto.X509Extension(
|
||||
"subjectAltName".encode("utf8"),
|
||||
b"subjectAltName",
|
||||
False,
|
||||
("DNS:" + subdomain).encode("utf8"),
|
||||
)
|
||||
|
@ -834,7 +812,7 @@ def _backup_current_cert(domain):
|
|||
cert_folder_domain = os.path.join(CERT_FOLDER, domain)
|
||||
|
||||
date_tag = datetime.utcnow().strftime("%Y%m%d.%H%M%S")
|
||||
backup_folder = "%s-backups/%s" % (cert_folder_domain, date_tag)
|
||||
backup_folder = f"{cert_folder_domain}-backups/{date_tag}"
|
||||
|
||||
shutil.copytree(cert_folder_domain, backup_folder)
|
||||
|
||||
|
|
|
@ -46,10 +46,10 @@ class MyDiagnoser(Diagnoser):
|
|||
elif os.path.exists("/sys/devices/virtual/dmi/id/sys_vendor"):
|
||||
model = read_file("/sys/devices/virtual/dmi/id/sys_vendor").strip()
|
||||
if os.path.exists("/sys/devices/virtual/dmi/id/product_name"):
|
||||
model = "%s %s" % (
|
||||
model,
|
||||
read_file("/sys/devices/virtual/dmi/id/product_name").strip(),
|
||||
)
|
||||
product_name = read_file(
|
||||
"/sys/devices/virtual/dmi/id/product_name"
|
||||
).strip()
|
||||
model = f"{model} {product_name}"
|
||||
hardware["data"]["model"] = model
|
||||
hardware["details"] = ["diagnosis_basesystem_hardware_model"]
|
||||
|
||||
|
@ -120,7 +120,7 @@ class MyDiagnoser(Diagnoser):
|
|||
bad_sury_packages = list(self.bad_sury_packages())
|
||||
if bad_sury_packages:
|
||||
cmd_to_fix = "apt install --allow-downgrades " + " ".join(
|
||||
["%s=%s" % (package, version) for package, version in bad_sury_packages]
|
||||
[f"{package}={version}" for package, version in bad_sury_packages]
|
||||
)
|
||||
yield dict(
|
||||
meta={"test": "packages_from_sury"},
|
||||
|
@ -137,7 +137,7 @@ class MyDiagnoser(Diagnoser):
|
|||
summary="diagnosis_backports_in_sources_list",
|
||||
)
|
||||
|
||||
if self.number_of_recent_auth_failure() > 500:
|
||||
if self.number_of_recent_auth_failure() > 750:
|
||||
yield dict(
|
||||
meta={"test": "high_number_auth_failure"},
|
||||
status="WARNING",
|
||||
|
|
|
@ -171,10 +171,7 @@ class MyDiagnoser(Diagnoser):
|
|||
|
||||
assert (
|
||||
resolvers != []
|
||||
), "Uhoh, need at least one IPv%s DNS resolver in %s ..." % (
|
||||
protocol,
|
||||
resolver_file,
|
||||
)
|
||||
), f"Uhoh, need at least one IPv{protocol} DNS resolver in {resolver_file} ..."
|
||||
|
||||
# So let's try to ping the first 4~5 resolvers (shuffled)
|
||||
# If we succesfully ping any of them, we conclude that we are indeed connected
|
||||
|
@ -224,7 +221,7 @@ class MyDiagnoser(Diagnoser):
|
|||
try:
|
||||
return download_text(url, timeout=30).strip()
|
||||
except Exception as e:
|
||||
logger.debug(
|
||||
"Could not get public IPv%s : %s" % (str(protocol), str(e))
|
||||
)
|
||||
protocol = str(protocol)
|
||||
e = str(e)
|
||||
self.logger_debug(f"Could not get public IPv{protocol} : {e}")
|
||||
return None
|
||||
|
|
|
@ -59,7 +59,6 @@ class MyDiagnoser(Diagnoser):
|
|||
def check_domain(self, domain, is_main_domain):
|
||||
|
||||
if is_special_use_tld(domain):
|
||||
categories = []
|
||||
yield dict(
|
||||
meta={"domain": domain},
|
||||
data={},
|
||||
|
@ -139,7 +138,7 @@ class MyDiagnoser(Diagnoser):
|
|||
# If status is okay and there's actually no expected records
|
||||
# (e.g. XMPP disabled)
|
||||
# then let's not yield any diagnosis line
|
||||
if not records and "status" == "SUCCESS":
|
||||
if not records and status == "SUCCESS":
|
||||
continue
|
||||
|
||||
output = dict(
|
||||
|
|
|
@ -133,7 +133,7 @@ class MyDiagnoser(Diagnoser):
|
|||
d for d in disk_partitions if d.mountpoint in ["/", "/var"]
|
||||
]
|
||||
main_space = sum(
|
||||
[psutil.disk_usage(d.mountpoint).total for d in main_disk_partitions]
|
||||
psutil.disk_usage(d.mountpoint).total for d in main_disk_partitions
|
||||
)
|
||||
if main_space < 10 * GB:
|
||||
yield dict(
|
||||
|
@ -157,7 +157,7 @@ class MyDiagnoser(Diagnoser):
|
|||
kills_count = self.recent_kills_by_oom_reaper()
|
||||
if kills_count:
|
||||
kills_summary = "\n".join(
|
||||
["%s (x%s)" % (proc, count) for proc, count in kills_count]
|
||||
[f"{proc} (x{count})" for proc, count in kills_count]
|
||||
)
|
||||
|
||||
yield dict(
|
||||
|
@ -203,9 +203,11 @@ def human_size(bytes_):
|
|||
# Adapted from https://stackoverflow.com/a/1094933
|
||||
for unit in ["", "ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]:
|
||||
if abs(bytes_) < 1024.0:
|
||||
return "%s %sB" % (round_(bytes_), unit)
|
||||
bytes_ = round_(bytes_)
|
||||
return f"{bytes_} {unit}B"
|
||||
bytes_ /= 1024.0
|
||||
return "%s %sB" % (round_(bytes_), "Yi")
|
||||
bytes_ = round_(bytes_)
|
||||
return f"{bytes_} YiB"
|
||||
|
||||
|
||||
def round_(n):
|
||||
|
|
|
@ -633,7 +633,7 @@ class Diagnoser:
|
|||
elif ipversion == 6:
|
||||
socket.getaddrinfo = getaddrinfo_ipv6_only
|
||||
|
||||
url = "https://%s/%s" % (DIAGNOSIS_SERVER, uri)
|
||||
url = "https://{}/{}".format(DIAGNOSIS_SERVER, uri)
|
||||
try:
|
||||
r = requests.post(url, json=data, timeout=timeout)
|
||||
finally:
|
||||
|
@ -695,7 +695,7 @@ def _email_diagnosis_issues():
|
|||
from yunohost.domain import _get_maindomain
|
||||
|
||||
maindomain = _get_maindomain()
|
||||
from_ = "diagnosis@%s (Automatic diagnosis on %s)" % (maindomain, maindomain)
|
||||
from_ = "diagnosis@{} (Automatic diagnosis on {})".format(maindomain, maindomain)
|
||||
to_ = "root"
|
||||
subject_ = "Issues found by automatic diagnosis on %s" % maindomain
|
||||
|
||||
|
@ -708,16 +708,16 @@ def _email_diagnosis_issues():
|
|||
content = _dump_human_readable_reports(issues)
|
||||
|
||||
message = """\
|
||||
From: %s
|
||||
To: %s
|
||||
Subject: %s
|
||||
From: {}
|
||||
To: {}
|
||||
Subject: {}
|
||||
|
||||
%s
|
||||
{}
|
||||
|
||||
---
|
||||
|
||||
%s
|
||||
""" % (
|
||||
{}
|
||||
""".format(
|
||||
from_,
|
||||
to_,
|
||||
subject_,
|
||||
|
|
|
@ -762,7 +762,7 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
|||
changes = {"delete": [], "update": [], "create": [], "unchanged": []}
|
||||
|
||||
type_and_names = sorted(
|
||||
set([(r["type"], r["name"]) for r in current_records + wanted_records])
|
||||
{(r["type"], r["name"]) for r in current_records + wanted_records}
|
||||
)
|
||||
comparison = {
|
||||
type_and_name: {"current": [], "wanted": []} for type_and_name in type_and_names
|
||||
|
@ -857,7 +857,6 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
|||
ignored = ""
|
||||
|
||||
if action == "create":
|
||||
old_content = record.get("old_content", "(None)")[:30]
|
||||
new_content = record.get("content", "(None)")[:30]
|
||||
return f"{name:>20} [{t:^5}] {new_content:^30} {ignored}"
|
||||
elif action == "update":
|
||||
|
@ -867,7 +866,7 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
|||
f"{name:>20} [{t:^5}] {old_content:^30} -> {new_content:^30} {ignored}"
|
||||
)
|
||||
elif action == "unchanged":
|
||||
old_content = new_content = record.get("content", "(None)")[:30]
|
||||
old_content = record.get("content", "(None)")[:30]
|
||||
return f"{name:>20} [{t:^5}] {old_content:^30}"
|
||||
else:
|
||||
old_content = record.get("content", "(None)")[:30]
|
||||
|
|
|
@ -507,17 +507,17 @@ def _set_domain_settings(domain: str, settings: dict) -> None:
|
|||
|
||||
|
||||
def domain_cert_status(domain_list, full=False):
|
||||
import yunohost.certificate
|
||||
from yunohost.certificate import certificate_status
|
||||
|
||||
return yunohost.certificate.certificate_status(domain_list, full)
|
||||
return certificate_status(domain_list, full)
|
||||
|
||||
|
||||
def domain_cert_install(
|
||||
domain_list, force=False, no_checks=False, self_signed=False, staging=False
|
||||
):
|
||||
import yunohost.certificate
|
||||
from yunohost.certificate import certificate_install
|
||||
|
||||
return yunohost.certificate.certificate_install(
|
||||
return certificate_install(
|
||||
domain_list, force, no_checks, self_signed, staging
|
||||
)
|
||||
|
||||
|
@ -525,9 +525,9 @@ def domain_cert_install(
|
|||
def domain_cert_renew(
|
||||
domain_list, force=False, no_checks=False, email=False, staging=False
|
||||
):
|
||||
import yunohost.certificate
|
||||
from yunohost.certificate import certificate_renew
|
||||
|
||||
return yunohost.certificate.certificate_renew(
|
||||
return certificate_renew(
|
||||
domain_list, force, no_checks, email, staging
|
||||
)
|
||||
|
||||
|
@ -537,12 +537,12 @@ def domain_dns_conf(domain):
|
|||
|
||||
|
||||
def domain_dns_suggest(domain):
|
||||
import yunohost.dns
|
||||
from yunohost.dns import domain_dns_suggest
|
||||
|
||||
return yunohost.dns.domain_dns_suggest(domain)
|
||||
return domain_dns_suggest(domain)
|
||||
|
||||
|
||||
def domain_dns_push(domain, dry_run, force, purge):
|
||||
import yunohost.dns
|
||||
from yunohost.dns import domain_dns_push
|
||||
|
||||
return yunohost.dns.domain_dns_push(domain, dry_run, force, purge)
|
||||
return domain_dns_push(domain, dry_run, force, purge)
|
||||
|
|
|
@ -151,7 +151,7 @@ def dyndns_subscribe(operation_logger, domain=None, key=None):
|
|||
try:
|
||||
error = json.loads(r.text)["error"]
|
||||
except Exception:
|
||||
error = 'Server error, code: %s. (Message: "%s")' % (r.status_code, r.text)
|
||||
error = f'Server error, code: {r.status_code}. (Message: "{r.text}")'
|
||||
raise YunohostError("dyndns_registration_failed", error=error)
|
||||
|
||||
# Yunohost regen conf will add the dyndns cron job if a private key exists
|
||||
|
@ -196,7 +196,7 @@ def dyndns_update(
|
|||
|
||||
# If key is not given, pick the first file we find with the domain given
|
||||
elif key is None:
|
||||
keys = glob.glob("/etc/yunohost/dyndns/K{0}.+*.private".format(domain))
|
||||
keys = glob.glob(f"/etc/yunohost/dyndns/K{domain}.+*.private")
|
||||
|
||||
if not keys:
|
||||
raise YunohostValidationError("dyndns_key_not_found")
|
||||
|
@ -262,15 +262,13 @@ def dyndns_update(
|
|||
else:
|
||||
return None
|
||||
|
||||
raise YunohostError(
|
||||
"Failed to resolve %s for %s" % (rdtype, domain), raw_msg=True
|
||||
)
|
||||
raise YunohostError(f"Failed to resolve {rdtype} for {domain}", raw_msg=True)
|
||||
|
||||
old_ipv4 = resolve_domain(domain, "A")
|
||||
old_ipv6 = resolve_domain(domain, "AAAA")
|
||||
|
||||
logger.debug("Old IPv4/v6 are (%s, %s)" % (old_ipv4, old_ipv6))
|
||||
logger.debug("Requested IPv4/v6 are (%s, %s)" % (ipv4, ipv6))
|
||||
logger.debug(f"Old IPv4/v6 are ({old_ipv4}, {old_ipv6})")
|
||||
logger.debug(f"Requested IPv4/v6 are ({ipv4}, {ipv6})")
|
||||
|
||||
# no need to update
|
||||
if (not force and not dry_run) and (old_ipv4 == ipv4 and old_ipv6 == ipv6):
|
||||
|
|
|
@ -156,7 +156,7 @@ def hook_list(action, list_by="name", show_info=False):
|
|||
try:
|
||||
d[priority].add(name)
|
||||
except KeyError:
|
||||
d[priority] = set([name])
|
||||
d[priority] = {name}
|
||||
|
||||
elif list_by == "name" or list_by == "folder":
|
||||
if show_info:
|
||||
|
@ -197,7 +197,7 @@ def hook_list(action, list_by="name", show_info=False):
|
|||
or (f.startswith("__") and f.endswith("__"))
|
||||
):
|
||||
continue
|
||||
path = "%s%s/%s" % (folder, action, f)
|
||||
path = f"{folder}{action}/{f}"
|
||||
priority, name = _extract_filename_parts(f)
|
||||
_append_hook(d, priority, name, path)
|
||||
|
||||
|
@ -407,7 +407,7 @@ def _hook_exec_bash(path, args, chdir, env, user, return_format, loggers):
|
|||
if not chdir:
|
||||
# use the script directory as current one
|
||||
chdir, cmd_script = os.path.split(path)
|
||||
cmd_script = "./{0}".format(cmd_script)
|
||||
cmd_script = f"./{cmd_script}"
|
||||
else:
|
||||
cmd_script = path
|
||||
|
||||
|
|
|
@ -469,7 +469,7 @@ class RedactingFormatter(Formatter):
|
|||
)
|
||||
|
||||
|
||||
class OperationLogger(object):
|
||||
class OperationLogger:
|
||||
|
||||
"""
|
||||
Instances of this class represents unit operation done on the ynh instance.
|
||||
|
@ -544,7 +544,7 @@ class OperationLogger(object):
|
|||
# We use proc.open_files() to list files opened / actively used by this proc
|
||||
# We only keep files matching a recent yunohost operation log
|
||||
active_logs = sorted(
|
||||
[f.path for f in proc.open_files() if f.path in recent_operation_logs],
|
||||
(f.path for f in proc.open_files() if f.path in recent_operation_logs),
|
||||
key=os.path.getctime,
|
||||
reverse=True,
|
||||
)
|
||||
|
|
|
@ -15,6 +15,7 @@ from yunohost.utils.packages import (
|
|||
get_ynh_package_version,
|
||||
_list_upgradable_apt_packages,
|
||||
)
|
||||
from yunohost.service import _get_services, _save_services
|
||||
|
||||
logger = getActionLogger("yunohost.migration")
|
||||
|
||||
|
@ -24,6 +25,7 @@ N_CURRENT_YUNOHOST = 4
|
|||
N_NEXT_DEBAN = 11
|
||||
N_NEXT_YUNOHOST = 11
|
||||
|
||||
|
||||
class MyMigration(Migration):
|
||||
|
||||
"Upgrade the system to Debian Bullseye and Yunohost 11.x"
|
||||
|
@ -75,13 +77,17 @@ class MyMigration(Migration):
|
|||
_force_clear_hashes(["/etc/mysql/my.cnf"])
|
||||
rm("/etc/mysql/mariadb.cnf", force=True)
|
||||
rm("/etc/mysql/my.cnf", force=True)
|
||||
self.apt_install("mariadb-common --reinstall -o Dpkg::Options::='--force-confmiss'")
|
||||
self.apt_install(
|
||||
"mariadb-common --reinstall -o Dpkg::Options::='--force-confmiss'"
|
||||
)
|
||||
|
||||
#
|
||||
# /usr/share/yunohost/yunohost-config/ssl/yunoCA -> /usr/share/yunohost/ssl
|
||||
#
|
||||
if os.path.exists("/usr/share/yunohost/yunohost-config/ssl/yunoCA"):
|
||||
os.system("mv /usr/share/yunohost/yunohost-config/ssl/yunoCA /usr/share/yunohost/ssl")
|
||||
os.system(
|
||||
"mv /usr/share/yunohost/yunohost-config/ssl/yunoCA /usr/share/yunohost/ssl"
|
||||
)
|
||||
rm("/usr/share/yunohost/yunohost-config", recursive=True, force=True)
|
||||
|
||||
#
|
||||
|
@ -108,6 +114,33 @@ class MyMigration(Migration):
|
|||
os.system("apt autoremove --assume-yes")
|
||||
os.system("apt clean --assume-yes")
|
||||
|
||||
# Force add sury if it's not there yet
|
||||
# This is to solve some weird issue with php-common breaking php7.3-common,
|
||||
# hence breaking many php7.3-deps
|
||||
# hence triggering some dependency conflict (or foobar-ynh-deps uninstall)
|
||||
# Adding it there shouldnt be a big deal - Yunohost 11.x does add it
|
||||
# through its regen conf anyway.
|
||||
if not os.path.exists("/etc/apt/sources.list.d/extra_php_version.list"):
|
||||
open("/etc/apt/sources.list.d/extra_php_version.list", "w").write(
|
||||
"deb https://packages.sury.org/php/ bullseye main"
|
||||
)
|
||||
os.system(
|
||||
'wget --timeout 900 --quiet "https://packages.sury.org/php/apt.gpg" --output-document=- | gpg --dearmor >"/etc/apt/trusted.gpg.d/extra_php_version.gpg"'
|
||||
)
|
||||
|
||||
os.system("apt update")
|
||||
|
||||
# Force explicit install of php7.4-fpm to make sure it's ll be there
|
||||
# during 0022_php73_to_php74_pools migration
|
||||
self.apt_install("php7.4-fpm -o Dpkg::Options::='--force-confmiss'")
|
||||
|
||||
# Remove legacy postgresql service record added by helpers,
|
||||
# will now be dynamically handled by the core in bullseye
|
||||
services = _get_services()
|
||||
if "postgresql" in services:
|
||||
del services["postgresql"]
|
||||
_save_services(services)
|
||||
|
||||
#
|
||||
# Yunohost upgrade
|
||||
#
|
||||
|
@ -181,10 +214,10 @@ class MyMigration(Migration):
|
|||
message = m18n.n("migration_0021_general_warning")
|
||||
|
||||
# FIXME: re-enable this message with updated topic link once we release the migration as stable
|
||||
#message = (
|
||||
# message = (
|
||||
# "N.B.: This migration has been tested by the community over the last few months but has only been declared stable recently. If your server hosts critical services and if you are not too confident with debugging possible issues, we recommend you to wait a little bit more while we gather more feedback and polish things up. If on the other hand you are relatively confident with debugging small issues that may arise, you are encouraged to run this migration ;)! You can read about remaining known issues and feedback from the community here: https://forum.yunohost.org/t/12195\n\n"
|
||||
# + message
|
||||
#)
|
||||
# )
|
||||
|
||||
if problematic_apps:
|
||||
message += "\n\n" + m18n.n(
|
||||
|
@ -261,7 +294,6 @@ class MyMigration(Migration):
|
|||
|
||||
call_async_output(cmd, callbacks, shell=True)
|
||||
|
||||
|
||||
def patch_yunohost_conflicts(self):
|
||||
#
|
||||
# This is a super dirty hack to remove the conflicts from yunohost's debian/control file
|
||||
|
@ -281,6 +313,8 @@ class MyMigration(Migration):
|
|||
# We want to keep conflicting with apache/bind9 tho
|
||||
new_conflicts = "Conflicts: apache2, bind9"
|
||||
|
||||
command = f"sed -i /var/lib/dpkg/status -e 's@{conflicts}@{new_conflicts}@g'"
|
||||
command = (
|
||||
f"sed -i /var/lib/dpkg/status -e 's@{conflicts}@{new_conflicts}@g'"
|
||||
)
|
||||
logger.debug(f"Running: {command}")
|
||||
os.system(command)
|
||||
|
|
|
@ -38,11 +38,11 @@ class MyMigration(Migration):
|
|||
# Ignore the "www.conf" (default stuff, probably don't want to touch it ?)
|
||||
oldphp_pool_files = [f for f in oldphp_pool_files if f != "www.conf"]
|
||||
|
||||
for f in oldphp_pool_files:
|
||||
for pf in oldphp_pool_files:
|
||||
|
||||
# Copy the files to the php7.4 pool
|
||||
src = "{}/{}".format(OLDPHP_POOLS, f)
|
||||
dest = "{}/{}".format(NEWPHP_POOLS, f)
|
||||
# Copy the files to the php7.3 pool
|
||||
src = "{}/{}".format(OLDPHP_POOLS, pf)
|
||||
dest = "{}/{}".format(NEWPHP_POOLS, pf)
|
||||
copy2(src, dest)
|
||||
|
||||
# Replace the socket prefix if it's found
|
||||
|
@ -56,17 +56,17 @@ class MyMigration(Migration):
|
|||
c = "sed -i '1i {}' {}".format(MIGRATION_COMMENT, dest)
|
||||
os.system(c)
|
||||
|
||||
app_id = os.path.basename(f)[: -len(".conf")]
|
||||
app_id = os.path.basename(pf)[: -len(".conf")]
|
||||
if _is_installed(app_id):
|
||||
_patch_legacy_php_versions_in_settings(
|
||||
"/etc/yunohost/apps/%s/" % app_id
|
||||
)
|
||||
|
||||
nginx_conf_files = glob.glob("/etc/nginx/conf.d/*.d/%s.conf" % app_id)
|
||||
for f in nginx_conf_files:
|
||||
for nf in nginx_conf_files:
|
||||
# Replace the socket prefix if it's found
|
||||
c = "sed -i -e 's@{}@{}@g' {}".format(
|
||||
OLDPHP_SOCKETS_PREFIX, NEWPHP_SOCKETS_PREFIX, f
|
||||
OLDPHP_SOCKETS_PREFIX, NEWPHP_SOCKETS_PREFIX, nf
|
||||
)
|
||||
os.system(c)
|
||||
|
||||
|
|
|
@ -139,7 +139,8 @@ def user_permission_list(
|
|||
continue
|
||||
main_perm_label = permissions[main_perm_name]["label"]
|
||||
infos["sublabel"] = infos["label"]
|
||||
infos["label"] = "%s (%s)" % (main_perm_label, infos["label"])
|
||||
label_ = infos["label"]
|
||||
infos["label"] = f"{main_perm_label} ({label_})"
|
||||
|
||||
if short:
|
||||
permissions = list(permissions.keys())
|
||||
|
@ -664,13 +665,11 @@ def permission_sync_to_user():
|
|||
currently_allowed_users = set(permission_infos["corresponding_users"])
|
||||
|
||||
# These are the users that should be allowed because they are member of a group that is allowed for this permission ...
|
||||
should_be_allowed_users = set(
|
||||
[
|
||||
user
|
||||
for group in permission_infos["allowed"]
|
||||
for user in groups[group]["members"]
|
||||
]
|
||||
)
|
||||
should_be_allowed_users = {
|
||||
user
|
||||
for group in permission_infos["allowed"]
|
||||
for user in groups[group]["members"]
|
||||
}
|
||||
|
||||
# Note that a LDAP operation with the same value that is in LDAP crash SLAP.
|
||||
# So we need to check before each ldap operation that we really change something in LDAP
|
||||
|
|
|
@ -48,7 +48,7 @@ logger = log.getActionLogger("yunohost.regenconf")
|
|||
@is_unit_operation([("names", "configuration")])
|
||||
def regen_conf(
|
||||
operation_logger,
|
||||
names=[],
|
||||
names=None,
|
||||
with_diff=False,
|
||||
force=False,
|
||||
dry_run=False,
|
||||
|
@ -66,6 +66,9 @@ def regen_conf(
|
|||
|
||||
"""
|
||||
|
||||
if names is None:
|
||||
names = []
|
||||
|
||||
result = {}
|
||||
|
||||
# Return the list of pending conf
|
||||
|
@ -617,12 +620,9 @@ def _process_regen_conf(system_conf, new_conf=None, save=True):
|
|||
|
||||
"""
|
||||
if save:
|
||||
backup_path = os.path.join(
|
||||
BACKUP_CONF_DIR,
|
||||
"{0}-{1}".format(
|
||||
system_conf.lstrip("/"), datetime.utcnow().strftime("%Y%m%d.%H%M%S")
|
||||
),
|
||||
)
|
||||
system_conf_ = system_conf.lstrip("/")
|
||||
now_ = datetime.utcnow().strftime("%Y%m%d.%H%M%S")
|
||||
backup_path = os.path.join(BACKUP_CONF_DIR, f"{system_conf_}-{now_}")
|
||||
backup_dir = os.path.dirname(backup_path)
|
||||
|
||||
if not os.path.isdir(backup_dir):
|
||||
|
|
|
@ -589,7 +589,7 @@ def _run_service_command(action, service):
|
|||
% (action, ", ".join(possible_actions))
|
||||
)
|
||||
|
||||
cmd = "systemctl %s %s" % (action, service)
|
||||
cmd = f"systemctl {action} {service}"
|
||||
|
||||
need_lock = services[service].get("need_lock", False) and action in [
|
||||
"start",
|
||||
|
@ -637,7 +637,7 @@ def _give_lock(action, service, p):
|
|||
else:
|
||||
systemctl_PID_name = "ControlPID"
|
||||
|
||||
cmd_get_son_PID = "systemctl show %s -p %s" % (service, systemctl_PID_name)
|
||||
cmd_get_son_PID = f"systemctl show {service} -p {systemctl_PID_name}"
|
||||
son_PID = 0
|
||||
# As long as we did not found the PID and that the command is still running
|
||||
while son_PID == 0 and p.poll() is None:
|
||||
|
@ -650,9 +650,7 @@ def _give_lock(action, service, p):
|
|||
# If we found a PID
|
||||
if son_PID != 0:
|
||||
# Append the PID to the lock file
|
||||
logger.debug(
|
||||
"Giving a lock to PID %s for service %s !" % (str(son_PID), service)
|
||||
)
|
||||
logger.debug(f"Giving a lock to PID {son_PID} for service {service} !")
|
||||
append_to_file(MOULINETTE_LOCK, "\n%s" % str(son_PID))
|
||||
|
||||
return son_PID
|
||||
|
@ -832,7 +830,9 @@ def _get_journalctl_logs(service, number="all"):
|
|||
services = _get_services()
|
||||
systemd_service = services.get(service, {}).get("actual_systemd_service", service)
|
||||
try:
|
||||
return check_output(f"journalctl --no-hostname --no-pager -u {systemd_service} -n{number}")
|
||||
return check_output(
|
||||
f"journalctl --no-hostname --no-pager -u {systemd_service} -n{number}"
|
||||
)
|
||||
except Exception:
|
||||
import traceback
|
||||
|
||||
|
|
|
@ -224,7 +224,7 @@ def settings_set(key, value):
|
|||
try:
|
||||
trigger_post_change_hook(key, old_value, value)
|
||||
except Exception as e:
|
||||
logger.error("Post-change hook for setting %s failed : %s" % (key, e))
|
||||
logger.error(f"Post-change hook for setting {key} failed : {e}")
|
||||
raise
|
||||
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ def test_apps_catalog_update_nominal(mocker):
|
|||
catalog = app_catalog(with_categories=True)
|
||||
|
||||
assert "apps" in catalog
|
||||
assert set(catalog["apps"].keys()) == set(["foo", "bar"])
|
||||
assert set(catalog["apps"].keys()) == {"foo", "bar"}
|
||||
|
||||
assert "categories" in catalog
|
||||
assert [c["id"] for c in catalog["categories"]] == ["yolo", "swag"]
|
||||
|
|
|
@ -70,7 +70,7 @@ def legacy_app(request):
|
|||
|
||||
app_install(
|
||||
os.path.join(get_test_apps_dir(), "legacy_app_ynh"),
|
||||
args="domain=%s&path=%s&is_public=%s" % (main_domain, "/", 1),
|
||||
args="domain={}&path={}&is_public={}".format(main_domain, "/", 1),
|
||||
force=True,
|
||||
)
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ def secondary_domain(request):
|
|||
|
||||
def app_expected_files(domain, app):
|
||||
|
||||
yield "/etc/nginx/conf.d/%s.d/%s.conf" % (domain, app)
|
||||
yield "/etc/nginx/conf.d/{}.d/{}.conf".format(domain, app)
|
||||
if app.startswith("legacy_app"):
|
||||
yield "/var/www/%s/index.html" % app
|
||||
yield "/etc/yunohost/apps/%s/settings.yml" % app
|
||||
|
@ -152,7 +152,7 @@ def install_legacy_app(domain, path, public=True):
|
|||
|
||||
app_install(
|
||||
os.path.join(get_test_apps_dir(), "legacy_app_ynh"),
|
||||
args="domain=%s&path=%s&is_public=%s" % (domain, path, 1 if public else 0),
|
||||
args="domain={}&path={}&is_public={}".format(domain, path, 1 if public else 0),
|
||||
force=True,
|
||||
)
|
||||
|
||||
|
@ -170,7 +170,7 @@ def install_break_yo_system(domain, breakwhat):
|
|||
|
||||
app_install(
|
||||
os.path.join(get_test_apps_dir(), "break_yo_system_ynh"),
|
||||
args="domain=%s&breakwhat=%s" % (domain, breakwhat),
|
||||
args="domain={}&breakwhat={}".format(domain, breakwhat),
|
||||
force=True,
|
||||
)
|
||||
|
||||
|
@ -338,7 +338,7 @@ def test_legacy_app_failed_remove(mocker, secondary_domain):
|
|||
|
||||
# The remove script runs with set -eu and attempt to remove this
|
||||
# file without -f, so will fail if it's not there ;)
|
||||
os.remove("/etc/nginx/conf.d/%s.d/%s.conf" % (secondary_domain, "legacy_app"))
|
||||
os.remove("/etc/nginx/conf.d/{}.d/{}.conf".format(secondary_domain, "legacy_app"))
|
||||
|
||||
# TODO / FIXME : can't easily validate that 'app_not_properly_removed'
|
||||
# is triggered for weird reasons ...
|
||||
|
|
|
@ -99,7 +99,7 @@ def test_registerurl():
|
|||
|
||||
app_install(
|
||||
os.path.join(get_test_apps_dir(), "register_url_app_ynh"),
|
||||
args="domain=%s&path=%s" % (maindomain, "/urlregisterapp"),
|
||||
args="domain={}&path={}".format(maindomain, "/urlregisterapp"),
|
||||
force=True,
|
||||
)
|
||||
|
||||
|
@ -109,7 +109,7 @@ def test_registerurl():
|
|||
with pytest.raises(YunohostError):
|
||||
app_install(
|
||||
os.path.join(get_test_apps_dir(), "register_url_app_ynh"),
|
||||
args="domain=%s&path=%s" % (maindomain, "/urlregisterapp"),
|
||||
args="domain={}&path={}".format(maindomain, "/urlregisterapp"),
|
||||
force=True,
|
||||
)
|
||||
|
||||
|
@ -119,7 +119,7 @@ def test_registerurl_baddomain():
|
|||
with pytest.raises(YunohostError):
|
||||
app_install(
|
||||
os.path.join(get_test_apps_dir(), "register_url_app_ynh"),
|
||||
args="domain=%s&path=%s" % ("yolo.swag", "/urlregisterapp"),
|
||||
args="domain={}&path={}".format("yolo.swag", "/urlregisterapp"),
|
||||
force=True,
|
||||
)
|
||||
|
||||
|
@ -234,7 +234,7 @@ def test_normalize_permission_path_with_unknown_domain():
|
|||
def test_normalize_permission_path_conflicting_path():
|
||||
app_install(
|
||||
os.path.join(get_test_apps_dir(), "register_url_app_ynh"),
|
||||
args="domain=%s&path=%s" % (maindomain, "/url/registerapp"),
|
||||
args="domain={}&path={}".format(maindomain, "/url/registerapp"),
|
||||
force=True,
|
||||
)
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ def app_is_installed(app):
|
|||
|
||||
# These are files we know should be installed by the app
|
||||
app_files = []
|
||||
app_files.append("/etc/nginx/conf.d/%s.d/%s.conf" % (maindomain, app))
|
||||
app_files.append("/etc/nginx/conf.d/{}.d/{}.conf".format(maindomain, app))
|
||||
app_files.append("/var/www/%s/index.html" % app)
|
||||
app_files.append("/etc/importantfile")
|
||||
|
||||
|
@ -214,7 +214,7 @@ def install_app(app, path, additionnal_args=""):
|
|||
|
||||
app_install(
|
||||
os.path.join(get_test_apps_dir(), app),
|
||||
args="domain=%s&path=%s%s" % (maindomain, path, additionnal_args),
|
||||
args="domain={}&path={}{}".format(maindomain, path, additionnal_args),
|
||||
force=True,
|
||||
)
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ def teardown_function(function):
|
|||
def install_changeurl_app(path):
|
||||
app_install(
|
||||
os.path.join(get_test_apps_dir(), "change_url_app_ynh"),
|
||||
args="domain=%s&path=%s" % (maindomain, path),
|
||||
args="domain={}&path={}".format(maindomain, path),
|
||||
force=True,
|
||||
)
|
||||
|
||||
|
|
|
@ -347,7 +347,7 @@ def check_permission_for_apps():
|
|||
# {"bar", "foo"}
|
||||
# and compare this to the list of installed apps ...
|
||||
|
||||
app_perms_prefix = set(p.split(".")[0] for p in app_perms)
|
||||
app_perms_prefix = {p.split(".")[0] for p in app_perms}
|
||||
|
||||
assert set(_installed_apps()) == app_perms_prefix
|
||||
|
||||
|
@ -398,7 +398,7 @@ def test_permission_list():
|
|||
assert res["wiki.main"]["allowed"] == ["all_users"]
|
||||
assert res["blog.main"]["allowed"] == ["alice"]
|
||||
assert res["blog.api"]["allowed"] == ["visitors"]
|
||||
assert set(res["wiki.main"]["corresponding_users"]) == set(["alice", "bob"])
|
||||
assert set(res["wiki.main"]["corresponding_users"]) == {"alice", "bob"}
|
||||
assert res["blog.main"]["corresponding_users"] == ["alice"]
|
||||
assert res["blog.api"]["corresponding_users"] == []
|
||||
assert res["wiki.main"]["url"] == "/"
|
||||
|
@ -442,7 +442,7 @@ def test_permission_create_main(mocker):
|
|||
res = user_permission_list(full=True)["permissions"]
|
||||
assert "site.main" in res
|
||||
assert res["site.main"]["allowed"] == ["all_users"]
|
||||
assert set(res["site.main"]["corresponding_users"]) == set(["alice", "bob"])
|
||||
assert set(res["site.main"]["corresponding_users"]) == {"alice", "bob"}
|
||||
assert res["site.main"]["protected"] is False
|
||||
|
||||
|
||||
|
@ -630,8 +630,8 @@ def test_permission_add_group(mocker):
|
|||
user_permission_update("wiki.main", add="alice")
|
||||
|
||||
res = user_permission_list(full=True)["permissions"]
|
||||
assert set(res["wiki.main"]["allowed"]) == set(["all_users", "alice"])
|
||||
assert set(res["wiki.main"]["corresponding_users"]) == set(["alice", "bob"])
|
||||
assert set(res["wiki.main"]["allowed"]) == {"all_users", "alice"}
|
||||
assert set(res["wiki.main"]["corresponding_users"]) == {"alice", "bob"}
|
||||
|
||||
|
||||
def test_permission_remove_group(mocker):
|
||||
|
@ -680,7 +680,7 @@ def test_permission_reset(mocker):
|
|||
|
||||
res = user_permission_list(full=True)["permissions"]
|
||||
assert res["blog.main"]["allowed"] == ["all_users"]
|
||||
assert set(res["blog.main"]["corresponding_users"]) == set(["alice", "bob"])
|
||||
assert set(res["blog.main"]["corresponding_users"]) == {"alice", "bob"}
|
||||
|
||||
|
||||
def test_permission_reset_idempotency():
|
||||
|
@ -690,7 +690,7 @@ def test_permission_reset_idempotency():
|
|||
|
||||
res = user_permission_list(full=True)["permissions"]
|
||||
assert res["blog.main"]["allowed"] == ["all_users"]
|
||||
assert set(res["blog.main"]["corresponding_users"]) == set(["alice", "bob"])
|
||||
assert set(res["blog.main"]["corresponding_users"]) == {"alice", "bob"}
|
||||
|
||||
|
||||
def test_permission_change_label(mocker):
|
||||
|
@ -1013,9 +1013,7 @@ def test_permission_app_install():
|
|||
assert res["permissions_app.dev"]["url"] == "/dev"
|
||||
|
||||
assert res["permissions_app.main"]["allowed"] == ["all_users"]
|
||||
assert set(res["permissions_app.main"]["corresponding_users"]) == set(
|
||||
["alice", "bob"]
|
||||
)
|
||||
assert set(res["permissions_app.main"]["corresponding_users"]) == {"alice", "bob"}
|
||||
|
||||
assert res["permissions_app.admin"]["allowed"] == ["alice"]
|
||||
assert res["permissions_app.admin"]["corresponding_users"] == ["alice"]
|
||||
|
|
|
@ -1977,7 +1977,7 @@ def test_question_file_from_api():
|
|||
|
||||
from base64 import b64encode
|
||||
|
||||
b64content = b64encode("helloworld".encode())
|
||||
b64content = b64encode(b"helloworld")
|
||||
questions = [
|
||||
{
|
||||
"name": "some_file",
|
||||
|
|
|
@ -281,7 +281,7 @@ def test_update_group_add_user(mocker):
|
|||
user_group_update("dev", add=["bob"])
|
||||
|
||||
group_res = user_group_list()["groups"]
|
||||
assert set(group_res["dev"]["members"]) == set(["alice", "bob"])
|
||||
assert set(group_res["dev"]["members"]) == {"alice", "bob"}
|
||||
|
||||
|
||||
def test_update_group_add_user_already_in(mocker):
|
||||
|
|
40
src/tools.py
40
src/tools.py
|
@ -224,7 +224,7 @@ def tools_postinstall(
|
|||
disk_partitions = sorted(psutil.disk_partitions(), key=lambda k: k.mountpoint)
|
||||
main_disk_partitions = [d for d in disk_partitions if d.mountpoint in ["/", "/var"]]
|
||||
main_space = sum(
|
||||
[psutil.disk_usage(d.mountpoint).total for d in main_disk_partitions]
|
||||
psutil.disk_usage(d.mountpoint).total for d in main_disk_partitions
|
||||
)
|
||||
GB = 1024 ** 3
|
||||
if not force_diskspace and main_space < 10 * GB:
|
||||
|
@ -236,28 +236,24 @@ def tools_postinstall(
|
|||
|
||||
# If this is a nohost.me/noho.st, actually check for availability
|
||||
if not ignore_dyndns and is_yunohost_dyndns_domain(domain):
|
||||
# (Except if the user explicitly said he/she doesn't care about dyndns)
|
||||
if ignore_dyndns:
|
||||
dyndns = False
|
||||
# Check if the domain is available...
|
||||
else:
|
||||
try:
|
||||
available = _dyndns_available(domain)
|
||||
# If an exception is thrown, most likely we don't have internet
|
||||
# connectivity or something. Assume that this domain isn't manageable
|
||||
# and inform the user that we could not contact the dyndns host server.
|
||||
except Exception:
|
||||
logger.warning(
|
||||
m18n.n(
|
||||
"dyndns_provider_unreachable", provider="dyndns.yunohost.org"
|
||||
)
|
||||
try:
|
||||
available = _dyndns_available(domain)
|
||||
# If an exception is thrown, most likely we don't have internet
|
||||
# connectivity or something. Assume that this domain isn't manageable
|
||||
# and inform the user that we could not contact the dyndns host server.
|
||||
except Exception:
|
||||
logger.warning(
|
||||
m18n.n(
|
||||
"dyndns_provider_unreachable", provider="dyndns.yunohost.org"
|
||||
)
|
||||
)
|
||||
|
||||
if available:
|
||||
dyndns = True
|
||||
# If not, abort the postinstall
|
||||
else:
|
||||
raise YunohostValidationError("dyndns_unavailable", domain=domain)
|
||||
if available:
|
||||
dyndns = True
|
||||
# If not, abort the postinstall
|
||||
else:
|
||||
raise YunohostValidationError("dyndns_unavailable", domain=domain)
|
||||
else:
|
||||
dyndns = False
|
||||
|
||||
|
@ -978,7 +974,7 @@ def _tools_migrations_run_before_app_restore(backup_version, app_id):
|
|||
raise
|
||||
|
||||
|
||||
class Migration(object):
|
||||
class Migration:
|
||||
|
||||
# Those are to be implemented by daughter classes
|
||||
|
||||
|
@ -1005,7 +1001,7 @@ class Migration(object):
|
|||
def description(self):
|
||||
return m18n.n("migration_description_%s" % self.id)
|
||||
|
||||
def ldap_migration(run):
|
||||
def ldap_migration(self, run):
|
||||
def func(self):
|
||||
|
||||
# Backup LDAP before the migration
|
||||
|
|
38
src/user.py
38
src/user.py
|
@ -97,7 +97,7 @@ def user_list(fields=None):
|
|||
and values[0].strip() == "/bin/false",
|
||||
}
|
||||
|
||||
attrs = set(["uid"])
|
||||
attrs = {"uid"}
|
||||
users = {}
|
||||
|
||||
if not fields:
|
||||
|
@ -159,7 +159,7 @@ def user_create(
|
|||
# On affiche les differents domaines possibles
|
||||
Moulinette.display(m18n.n("domains_available"))
|
||||
for domain in domain_list()["domains"]:
|
||||
Moulinette.display("- {}".format(domain))
|
||||
Moulinette.display(f"- {domain}")
|
||||
|
||||
maindomain = _get_maindomain()
|
||||
domain = Moulinette.prompt(
|
||||
|
@ -208,7 +208,7 @@ def user_create(
|
|||
uid_guid_found = uid not in all_uid and uid not in all_gid
|
||||
|
||||
# Adapt values for LDAP
|
||||
fullname = "%s %s" % (firstname, lastname)
|
||||
fullname = f"{firstname} {lastname}"
|
||||
|
||||
attr_dict = {
|
||||
"objectClass": [
|
||||
|
@ -326,8 +326,8 @@ def user_delete(operation_logger, username, purge=False, from_import=False):
|
|||
subprocess.call(["nscd", "-i", "passwd"])
|
||||
|
||||
if purge:
|
||||
subprocess.call(["rm", "-rf", "/home/{0}".format(username)])
|
||||
subprocess.call(["rm", "-rf", "/var/mail/{0}".format(username)])
|
||||
subprocess.call(["rm", "-rf", f"/home/{username}"])
|
||||
subprocess.call(["rm", "-rf", f"/var/mail/{username}"])
|
||||
|
||||
hook_callback("post_user_delete", args=[username, purge])
|
||||
|
||||
|
@ -1256,25 +1256,25 @@ def user_group_remove(groupname, usernames, force=False, sync_perm=True):
|
|||
|
||||
|
||||
def user_permission_list(short=False, full=False, apps=[]):
|
||||
import yunohost.permission
|
||||
from yunohost.permission import user_permission_list
|
||||
|
||||
return yunohost.permission.user_permission_list(
|
||||
return user_permission_list(
|
||||
short, full, absolute_urls=True, apps=apps
|
||||
)
|
||||
|
||||
|
||||
def user_permission_update(permission, label=None, show_tile=None, sync_perm=True):
|
||||
import yunohost.permission
|
||||
from yunohost.permission import user_permission_update
|
||||
|
||||
return yunohost.permission.user_permission_update(
|
||||
return user_permission_update(
|
||||
permission, label=label, show_tile=show_tile, sync_perm=sync_perm
|
||||
)
|
||||
|
||||
|
||||
def user_permission_add(permission, names, protected=None, force=False, sync_perm=True):
|
||||
import yunohost.permission
|
||||
from yunohost.permission import user_permission_update
|
||||
|
||||
return yunohost.permission.user_permission_update(
|
||||
return user_permission_update(
|
||||
permission, add=names, protected=protected, force=force, sync_perm=sync_perm
|
||||
)
|
||||
|
||||
|
@ -1282,23 +1282,23 @@ def user_permission_add(permission, names, protected=None, force=False, sync_per
|
|||
def user_permission_remove(
|
||||
permission, names, protected=None, force=False, sync_perm=True
|
||||
):
|
||||
import yunohost.permission
|
||||
from yunohost.permission import user_permission_update
|
||||
|
||||
return yunohost.permission.user_permission_update(
|
||||
return user_permission_update(
|
||||
permission, remove=names, protected=protected, force=force, sync_perm=sync_perm
|
||||
)
|
||||
|
||||
|
||||
def user_permission_reset(permission, sync_perm=True):
|
||||
import yunohost.permission
|
||||
from yunohost.permission import user_permission_reset
|
||||
|
||||
return yunohost.permission.user_permission_reset(permission, sync_perm=sync_perm)
|
||||
return user_permission_reset(permission, sync_perm=sync_perm)
|
||||
|
||||
|
||||
def user_permission_info(permission):
|
||||
import yunohost.permission
|
||||
from yunohost.permission import user_permission_info
|
||||
|
||||
return yunohost.permission.user_permission_info(permission)
|
||||
return user_permission_info(permission)
|
||||
|
||||
|
||||
#
|
||||
|
@ -1327,9 +1327,9 @@ def user_ssh_remove_key(username, key):
|
|||
def _convertSize(num, suffix=""):
|
||||
for unit in ["K", "M", "G", "T", "P", "E", "Z"]:
|
||||
if abs(num) < 1024.0:
|
||||
return "%3.1f%s%s" % (num, unit, suffix)
|
||||
return "{:3.1f}{}{}".format(num, unit, suffix)
|
||||
num /= 1024.0
|
||||
return "%.1f%s%s" % (num, "Yi", suffix)
|
||||
return "{:.1f}{}{}".format(num, "Yi", suffix)
|
||||
|
||||
|
||||
def _hash_user_password(password):
|
||||
|
|
|
@ -52,7 +52,10 @@ CONFIG_PANEL_VERSION_SUPPORTED = 1.0
|
|||
# Those js-like evaluate functions are used to eval safely visible attributes
|
||||
# The goal is to evaluate in the same way than js simple-evaluate
|
||||
# https://github.com/shepherdwind/simple-evaluate
|
||||
def evaluate_simple_ast(node, context={}):
|
||||
def evaluate_simple_ast(node, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
operators = {
|
||||
ast.Not: op.not_,
|
||||
ast.Mult: op.mul,
|
||||
|
@ -678,7 +681,7 @@ class ConfigPanel:
|
|||
yield (panel, section, option)
|
||||
|
||||
|
||||
class Question(object):
|
||||
class Question:
|
||||
hide_user_input_in_prompt = False
|
||||
pattern: Optional[Dict] = None
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ def get_public_ip(protocol=4):
|
|||
):
|
||||
ip = read_file(cache_file).strip()
|
||||
ip = ip if ip else None # Empty file (empty string) means there's no IP
|
||||
logger.debug("Reusing IPv%s from cache: %s" % (protocol, ip))
|
||||
logger.debug(f"Reusing IPv{protocol} from cache: {ip}")
|
||||
else:
|
||||
ip = get_public_ip_from_remote_server(protocol)
|
||||
logger.debug("IP fetched: %s" % ip)
|
||||
|
@ -87,7 +87,7 @@ def get_public_ip_from_remote_server(protocol=4):
|
|||
try:
|
||||
return download_text(url, timeout=30).strip()
|
||||
except Exception as e:
|
||||
logger.debug("Could not get public IPv%s : %s" % (str(protocol), str(e)))
|
||||
logger.debug(f"Could not get public IPv{protocol} : {e}")
|
||||
return None
|
||||
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ def assert_password_is_strong_enough(profile, password):
|
|||
PasswordValidator(profile).validate(password)
|
||||
|
||||
|
||||
class PasswordValidator(object):
|
||||
class PasswordValidator:
|
||||
def __init__(self, profile):
|
||||
"""
|
||||
Initialize a password validator.
|
||||
|
|
|
@ -49,7 +49,7 @@ def yunopaste(data):
|
|||
raw_msg=True,
|
||||
)
|
||||
|
||||
return "%s/raw/%s" % (paste_server, url)
|
||||
return "{}/raw/{}".format(paste_server, url)
|
||||
|
||||
|
||||
def anonymize(data):
|
||||
|
|
36
src/vendor/acme_tiny/acme_tiny.py
vendored
36
src/vendor/acme_tiny/acme_tiny.py
vendored
|
@ -38,7 +38,7 @@ def get_crt(
|
|||
)
|
||||
out, err = proc.communicate(cmd_input)
|
||||
if proc.returncode != 0:
|
||||
raise IOError("{0}\n{1}".format(err_msg, err))
|
||||
raise IOError("{}\n{}".format(err_msg, err))
|
||||
return out
|
||||
|
||||
# helper function - make request and automatically parse json response
|
||||
|
@ -74,7 +74,7 @@ def get_crt(
|
|||
raise IndexError(resp_data) # allow 100 retrys for bad nonces
|
||||
if code not in [200, 201, 204]:
|
||||
raise ValueError(
|
||||
"{0}:\nUrl: {1}\nData: {2}\nResponse Code: {3}\nResponse: {4}".format(
|
||||
"{}:\nUrl: {}\nData: {}\nResponse Code: {}\nResponse: {}".format(
|
||||
err_msg, url, data, code, resp_data
|
||||
)
|
||||
)
|
||||
|
@ -89,7 +89,7 @@ def get_crt(
|
|||
{"jwk": jwk} if acct_headers is None else {"kid": acct_headers["Location"]}
|
||||
)
|
||||
protected64 = _b64(json.dumps(protected).encode("utf8"))
|
||||
protected_input = "{0}.{1}".format(protected64, payload64).encode("utf8")
|
||||
protected_input = "{}.{}".format(protected64, payload64).encode("utf8")
|
||||
out = _cmd(
|
||||
["openssl", "dgst", "-sha256", "-sign", account_key],
|
||||
stdin=subprocess.PIPE,
|
||||
|
@ -125,8 +125,8 @@ def get_crt(
|
|||
pub_hex, pub_exp = re.search(
|
||||
pub_pattern, out.decode("utf8"), re.MULTILINE | re.DOTALL
|
||||
).groups()
|
||||
pub_exp = "{0:x}".format(int(pub_exp))
|
||||
pub_exp = "0{0}".format(pub_exp) if len(pub_exp) % 2 else pub_exp
|
||||
pub_exp = "{:x}".format(int(pub_exp))
|
||||
pub_exp = "0{}".format(pub_exp) if len(pub_exp) % 2 else pub_exp
|
||||
alg = "RS256"
|
||||
jwk = {
|
||||
"e": _b64(binascii.unhexlify(pub_exp.encode("utf-8"))),
|
||||
|
@ -140,9 +140,9 @@ def get_crt(
|
|||
log.info("Parsing CSR...")
|
||||
out = _cmd(
|
||||
["openssl", "req", "-in", csr, "-noout", "-text"],
|
||||
err_msg="Error loading {0}".format(csr),
|
||||
err_msg="Error loading {}".format(csr),
|
||||
)
|
||||
domains = set([])
|
||||
domains = set()
|
||||
common_name = re.search(r"Subject:.*? CN\s?=\s?([^\s,;/]+)", out.decode("utf8"))
|
||||
if common_name is not None:
|
||||
domains.add(common_name.group(1))
|
||||
|
@ -155,7 +155,7 @@ def get_crt(
|
|||
for san in subject_alt_names.group(1).split(", "):
|
||||
if san.startswith("DNS:"):
|
||||
domains.add(san[4:])
|
||||
log.info("Found domains: {0}".format(", ".join(domains)))
|
||||
log.info("Found domains: {}".format(", ".join(domains)))
|
||||
|
||||
# get the ACME directory of urls
|
||||
log.info("Getting directory...")
|
||||
|
@ -178,7 +178,7 @@ def get_crt(
|
|||
{"contact": contact},
|
||||
"Error updating contact details",
|
||||
)
|
||||
log.info("Updated contact details:\n{0}".format("\n".join(account["contact"])))
|
||||
log.info("Updated contact details:\n{}".format("\n".join(account["contact"])))
|
||||
|
||||
# create a new order
|
||||
log.info("Creating new order...")
|
||||
|
@ -194,46 +194,46 @@ def get_crt(
|
|||
auth_url, None, "Error getting challenges"
|
||||
)
|
||||
domain = authorization["identifier"]["value"]
|
||||
log.info("Verifying {0}...".format(domain))
|
||||
log.info("Verifying {}...".format(domain))
|
||||
|
||||
# find the http-01 challenge and write the challenge file
|
||||
challenge = [c for c in authorization["challenges"] if c["type"] == "http-01"][
|
||||
0
|
||||
]
|
||||
token = re.sub(r"[^A-Za-z0-9_\-]", "_", challenge["token"])
|
||||
keyauthorization = "{0}.{1}".format(token, thumbprint)
|
||||
keyauthorization = "{}.{}".format(token, thumbprint)
|
||||
wellknown_path = os.path.join(acme_dir, token)
|
||||
with open(wellknown_path, "w") as wellknown_file:
|
||||
wellknown_file.write(keyauthorization)
|
||||
|
||||
# check that the file is in place
|
||||
try:
|
||||
wellknown_url = "http://{0}/.well-known/acme-challenge/{1}".format(
|
||||
wellknown_url = "http://{}/.well-known/acme-challenge/{}".format(
|
||||
domain, token
|
||||
)
|
||||
assert disable_check or _do_request(wellknown_url)[0] == keyauthorization
|
||||
except (AssertionError, ValueError) as e:
|
||||
raise ValueError(
|
||||
"Wrote file to {0}, but couldn't download {1}: {2}".format(
|
||||
"Wrote file to {}, but couldn't download {}: {}".format(
|
||||
wellknown_path, wellknown_url, e
|
||||
)
|
||||
)
|
||||
|
||||
# say the challenge is done
|
||||
_send_signed_request(
|
||||
challenge["url"], {}, "Error submitting challenges: {0}".format(domain)
|
||||
challenge["url"], {}, "Error submitting challenges: {}".format(domain)
|
||||
)
|
||||
authorization = _poll_until_not(
|
||||
auth_url,
|
||||
["pending"],
|
||||
"Error checking challenge status for {0}".format(domain),
|
||||
"Error checking challenge status for {}".format(domain),
|
||||
)
|
||||
if authorization["status"] != "valid":
|
||||
raise ValueError(
|
||||
"Challenge did not pass for {0}: {1}".format(domain, authorization)
|
||||
"Challenge did not pass for {}: {}".format(domain, authorization)
|
||||
)
|
||||
os.remove(wellknown_path)
|
||||
log.info("{0} verified!".format(domain))
|
||||
log.info("{} verified!".format(domain))
|
||||
|
||||
# finalize the order with the csr
|
||||
log.info("Signing certificate...")
|
||||
|
@ -251,7 +251,7 @@ def get_crt(
|
|||
"Error checking order status",
|
||||
)
|
||||
if order["status"] != "valid":
|
||||
raise ValueError("Order failed: {0}".format(order))
|
||||
raise ValueError("Order failed: {}".format(order))
|
||||
|
||||
# download the certificate
|
||||
certificate_pem, _, _ = _send_signed_request(
|
||||
|
|
Loading…
Add table
Reference in a new issue